Physics Engine organisation

Started by
1 comment, last by EJH 13 years, 8 months ago
Hello!

I am developping a physic engine, but I am encountering some problems.

To explain them, I begin to explain the structure of my engine:
- I use the boost smart pointers
- There are 3 main categories: the objects, the interactions (apply forces on the objects) and the engine (managing the objects and the interactions)
- the engine has a weak pointer to the objects. The interactions have a weak pointer to the objects they use. The objects are so own by other stuff that can delete them at any time, not by the engine and the interactions.
- the engine and the interactions derivate from ObjectUser. ObjectUser has a method RemoveObject( boost::shared_ptr<Object> ), which allows to tell the ObjectUsers to stop using an object. Because an object has the list of every ObjectUser using itself, it can tell them to stop using itself with RemoveObject( shared_from_this() ).

Still reading? ;) Thanks!

Here are my two problems:
- when an object is deleted, it should inform all its ObjectUsers. Unfortunately, shared_from_this cannot be called in the destructor, so RemoveObject cannot be done.
- An object can be deleted when an interaction is computing, what is bad if the interaction has a list of weak pointer to objects. For example, the interaction Collision has a list of objects able to collide. Making colliding an object O, O decides that it has collided too much and makes itself be deleted. O calls RemoveObject on the collision Interaction. Then, the collision interaction modifies its list of Objects to remove O, while it is using its list in the Collision method => problem: there is an iterator on a cell of the list and this cell is removed from the list.

Anybody has an idea of a beautifull way to delete the objects?
Thanks!
Advertisement
First of all, never ever name a class "object". From here on in, I'm going to be calling that class PhysicsObject.


Quote:- when an object is deleted, it should inform all its ObjectUsers. Unfortunately, shared_from_this cannot be called in the destructor, so RemoveObject cannot be done.
You can lazily delete weak pointers when you fail to lock them.
Quote:An object can be deleted when an interaction is computing, what is bad if the interaction has a list of weak pointer to objects.
Don't do that. Instead, save up a list to delete at the end of the timestep. But....


It looks like you're trying to hitch way too many wagons to your objects' lifetimes. What happens when you want to remove an PhysicsObject from a simulation, but still keep it around for some other purpose? Object lifetimes -- whether GC'ed or refcounted -- are far too blunt an instrument to use for the details of membership in a simulation.

Introduce a concept of being "in the simulation" which is independent of object lifetime. Objects notify their users when they're removed from the simulation, not when they're deleted -- in fact, when they're deleted, by definition they should have no users, because they can't be deleted until they're removed from the simulation.
At a high level, what does your collision routine look like? Generally, breaking everything up into passes is easiest:

- compile list of references to potentially colliding objects
- collide all objects, if an object "dies", immediately remove the reference from from the potential collision list
- delete objects from memory no longer needed by the game

During collision, you need to immediately remove references from the potential collision set so that they don't continue to collide with things after they die. For example:

- projectiles from 2 different players hit something during the same physics update
- if the first hit destroys the object and you don't remove the reference, then both players would get credit for destroying the object. Or, if it was 2 projectiles from the same player, they would receive double credit.

This happens fairly often especially if you have a lot of area effects.

This topic is closed to new replies.

Advertisement