How to get aware that physics simulation has finished

chp

03-04-2008 12:08:34

Hint: using NxOgre 0.9-38

I want to execute some code after the physics simulation has finished. I have tried to use the checkResults(...) method of the OgreNxScene, for checking if simulation has ended, but this doesn't work, because nxogre itself uses the method and "blocks" my call to it. To illustrate the problem I will describe what I want to accomplish.

Let's say one has a box which should hover. To accomplish that he has to add a force (mass * gravity). When a ogre framelistener is used to apply the force to the actor with addForceAtPos(). The box will fly away. Because the applied force will only be reset if physics simulation is done and there are more than one frames rendered while simulation is running, so the forces applied would accumulate.

Hence, I would get aware of the point of time when the physics simulation has finished. So I can set the force to apply only once per simulation run.

Somewhat like a listener would be nice. I have searched the forum but I found nothing appropriate.

Thanks for your help

betajaen

03-04-2008 13:45:48

I think your looking to much into this; I've done hovering boxes and it doesn't require access to the checkResults function.

I just came up this in Cake (and spent to much time on it);

hover = mScene->createBody("Hover;cube.1m.mesh", new NxOgre::Cube(1), Vector3(0,0.5,0), "mass: 10");
hover->setLinearDamping(10.0f); // Cheating a little.


On every frame:

float mass = 10;
Ogre::Vector3 grav = mScene->getGravity();
float displacement = hover->getGlobalPositionAsOgreVector3().y - 5.0f;
float eq = -mScene->getGravity().y * mass * -displacement;
hover->addForce(Vector3(0, eq,0), NX_SMOOTH_IMPULSE);


5.0f is the target vertical position.

Obviously that is Bleeding code there, but you can convert it to 0.9 very easily.

chp

03-04-2008 14:00:32

thanks for you fast reply. but that isn't that what i'm looking for. i am using the following code. (The code is in python but should be the same in c++)


move(self, position, force):
gPos = self.pickedBody.getGlobalPosition()
fc = position - gPos
fc *= force
fc -= 2 * math.sqrt(force) * self.pickedBody.getPointVelocity(gPos)
grav = physx.NxVec3()
self.physicsScene.getNxScene().getGravity(grav)
grav = ogre.Vector3(grav.x, grav.y, grav.z)
antiGrav = grav * self.pickedBody.getMass()
fc -= antiGrav
self.pickedBody.addForceAtPos(fc, gPos)


The frame listener calls this method every frame. The problem is that the force which is applied in simulation depends on the frame rate. The higher the frame rate the higher the force which is applied is. Hence, the probleme will be solved if the above mentioned method is called only once per simulation run.

So it is not about a hovering box, more it is about the box following the mouse cursor (which is the position passed to the method)

betajaen

03-04-2008 14:13:52

You can inject your own time step and control NxOgre exactly how you like it:

mPhysXDriver->simulate(deltaTime) / mPhysXDriver->render();

Just turn of the framelistener "framelistener: no" as Params in World.

chp

03-04-2008 14:20:24

Thank you I will try this. May be I also try to use joints instead of forces. So that the mouse cursor is a static object and the grabbed object will be connected with a join

betajaen

03-04-2008 14:39:42

That may work. Some of the Ageia Examples use a fixed or more probably a distance joint.