PhysX3.3 Update loop strategy - How to get the velocity of CCT/kinematic ind. of render/physX update

Hi,

I want to have some advices on how to implement an efficient physX3 update loop. What I want is something like the physX 2 behavior.

I am creating a physX3 plugin for 3dgamestudio. Basically, I have done the following :

  1. Get current time step
  2. Subdivide timestep into substeps
  3. Execute scene.simulate per substep
  4. Sync render objects based on physX objects

All of these are done without using pXtask and are completelly synchronous to the engine’s update loop.

Now, the problem is that when defining the engine and the physX simulation to run at different frequencies, this method partially fails :

  • Getting the velocity of a PH_CHAR is not working (returning 0)
  • Setting targetpose for kinematic characters also fails
  • ...

I then wanted to ask if someone have some theory on how to implement a working physX simulation loop. The physX2 update loop (with physX managed substep) is working perfetlly in this case. Will implementing a multithreaded/async stepper solve my problem?

Hi,

I dont know if you solved your problem, but you should read this one (when you arent doing it yet)

Maybe you get a hint what happend there.
I didnt do anything in PhysX multithreaded, so I cant help you there.

This is how I do the (semi) fixed timestep.
Its much much better than a “real deltatime” timestep.
But I guess you know this before.

mStepSize = 0.01f; // Modify to your needs
mAccumulator += mDeltaTime; // mDeltaTime should be high resolution - my values are mostly 0.016
if (mAccumulator > 0.05f) mAccumulator = 0.05f; // Modify to your needs, destorys the spiral of death

while (mAccumulator >= mStepSize)
{
mAccumulator -= mStepSize;
mScene->simulate(mStepSize);	
mScene->fetchResults(true);
}

I hope I could help you.

Hi,

Thanks for your answer. Actually, I have Implemented a similar stepper, but my problem is that perhaps I made some mistakes in physX update frequency. When the render updates slowly than physX, I have 0 when trying to get the velocity of kinematic actors (cct and kinematic)

I have create a demo here [url]https://github.com/finalherizo/GSPhysXUpdate/[/url]. My real problem is that I can’t have a valid velocity when moving kinematic actors. Every time I want to move a kinematic actor I get the current target pos, add the displacement then set kinematic target. The kinematic actor is moving only when not using active transforms(but querying all actors) but I can’t have the velocities. Is it the right way to do it or I’m totally wrong (There was no such problem with physX2).

Hi,

I took a look into the source, but I didnt compile it.
My first impression was that you didnt use the semi-fixed-timestepper.
I guess you didnt read Fix Your Timestep! | Gaffer On Games .

Take a look into it, my post before is the implementation of it.
Just use it, its not hard to change it in your code.

Hi,
Thanks for your answer.
I have changed my update code. I think that the update is OK, my problem is that I want to get the velocity of a kinematic actor while using setKinematicTarget to move it. Apparently it is moving if I do setkinematicTarget(retulr of getKinematicTarget) in my move function but I can’t have the velocity (master branch of the example). It is working if I save the target, set it every frame (semi-fixed) but only when rendering fps is above the physX step.

Is there a better way to get the velocity of a kinematic actor like in physX2?

physx::PxReal frameTime = stepSize; // Frame time
	if (frameTime > mFixedSubStepSize * 2)
		frameTime = mFixedSubStepSize * 2;

	mAccumulator += frameTime;

	substepSize = mFixedSubStepSize; // dt
	substepCount = physx::PxMax((physx::PxU32)(mAccumulator / mFixedSubStepSize), physx::PxU32(0));

	mAccumulator -= physx::PxReal(substepCount)*substepSize;

	// Alpha calculations
	physx::PxReal alpha = mAccumulator / mFixedSubStepSize;

Hi, did I understand you correctly?

You want to move a kinematic object - and want to get the velocity of it?
You already had the velocity, this is the displacment vector and after each
update (call of simulate() and fetch()) the velocity returns zero.
So you have to update it continuously for every frame.

Here look at the description of PxRigidDynamic::setKinematicTarget(…)

@name Kinematic Actors
*/

	/**
	\brief Moves kinematically controlled dynamic actors through the game world.

	You set a dynamic actor to be kinematic using the PxRigidBodyFlag::eKINEMATIC flag
	with setRigidBodyFlag().
	
	The move command will result in a velocity that will move the body into 
	the desired pose. After the move is carried out during a single time step, 
	the velocity is returned to zero. Thus, you must continuously call 
	this in every time step for kinematic actors so that they move along a path.
	
	This function simply stores the move destination until the next simulation
	step is processed, so consecutive calls will simply overwrite the stored target variable.

	The motion is always fully carried out.	

	\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.

	<b>Sleeping:</b> This call wakes the actor if it is sleeping and will set the wake counter to #PxSceneDesc::wakeCounterResetValue.

	\param[in] destination The desired pose for the kinematic actor, in the global frame. <b>Range:</b> rigid body transform.

	@see getKinematicTarget() PxRigidBodyFlag setRigidBodyFlag()
	*/
	virtual		void				setKinematicTarget(const PxTransform& destination) = 0;

Hi,

Thanks for you answer, as my update frequency can be lower than the physX step frequency, and in this cases, I get 0 for the velocity. The only solution I can think of by now is to cache the velocity so I’ll still be able to get them after they return to zero. Perhaps there are better solutions to achieve what I want without doing that.