← Back to team overview

lucadestudios team mailing list archive

Re: Physics Engine

 

2009/2/27 Carsten Haubold <carstenhaubold@xxxxxxxxxxxxxx>:
> I've updated the Physics UML a bit, it can be found is in
> trunk/engine/doc/Physics
> There are a lot of methods still missing and the internally running thread
> needs to be modelled too..
>
> Basic usage will be:
>
> physics::Engine* _engine = new physics::Engine();
> physics::World* _world = new physics::World(world dimensions in x,y,z);
>
> _engine->setWorld(world);
> _engine->setNetworkClient(_networkManager); //whatever is used to send
> messages from the physics engine to the server, sending objects will be
> performed from the main thread, not the internal physics thread
>

It feels like that should be something in the middle here... do we
need to tightly couple the network manager to the physics engine like
this? Would perhaps a way of registering for collision events using
the observer pattern work better? (e.g.
_engine->register_observer(physics_observer*) )

> //for each object to be simulated
> physics::PhysicsObject* myObject = new physics::PhysicsObject(mass,
> centerOfMass, elasticity, position, orientation);
> myRenderObject->linkTo(myObject); //used to retrieve position and rotation
> matrix from the physics engine via _physicsObject->getTranslationMatrix()
>

Looks great, my only worry is the threading.. obviously the physics
thread needs to update the PhysicsObject. Assume the calling thread is
A and the physics thread is B. With the above design, thread A might
hold a pointer to the physics object, and will try to access it while
thread B is updating it. This is easily circumvented using an internal
message queue in the physics subsystem (so thread B passes a message
to the physics engine, the physics engine then updates the object in
the same thread as the caller) this would require an engine->update()
call to process the queued events however.

> //for playing sounds or other notifications:
> void myCallback(const Contact& cont);
> myObject->registerCollisionCallback(&myCallback);
>
> _engine->spawnObject(myObject); //will spawn in currently selected world
>

Looks good, same threading point applies though.

> ***********************************************************
> //in the main loop:
> _engine->update(deltaTime);

Ah ok you have an update (didn't read this far :P) but do you really
need to pass deltaTime? Don't physics engines require a constant
timestep to be reliable? If it's in a thread then the timestep can be
arbitrary and completely decoupled from the framerate.

>
> //for all incoming Packets:
> _engine->handlePacket(packet); //this is allowed to set positions of objects
> directly
>

_engine would need to be a node_observer (in my networking design) and
it will be notified when a packet is received, and just before a
packet is sent. So this integrates quite well.

> //***********************************************************
> //modifying the state of the physical world just works with events  as soon
> as the simulation thread runs, no direct access to the PhysicsObjects!
> //the events cannot set positions of models directly but just interacts with
> forces
> _engine->handleEvent( any of: SpawnObjectEvent, ApplyForceEvent,
> DestroyObject,...);
>

You've almost answered my question, about the thread safety, but if
direct access to a Physics object is still available it might still be
an issue.

>
> Thats just a rough sketch, I'm not sure about the extra physics thread so
> that might change, but no big changes I hope...
> Let me know what you think about that
>
> Cheers
> Carsten
>
> _______________________________________________
> Mailing list: https://launchpad.net/~lucadestudios
> Post to     : lucadestudios@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~lucadestudios
> More help   : https://help.launchpad.net/ListHelp
>
>

Generally it looks great! Nice work :D

Luke.



References