hkpCharacterRigidBody problem with async stepping

hkpCharacterRigidBody problem with async stepping

We've made player character use hkpCharacterRigidBody and we wanted to
use async stepping. Everything works just
fine up until player gets on one of the elevators (keyframed object that is
moving vertically). Then the interpolation causes the elevator to shake.
It looks like that interpolation does not consider the character to be on a moving object and only considers its linear velocity. Is there a way to overcome this?

7 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

The docs in 'Havok Physics/Hello World!/Simulating a Physics World/Stepping the Simulation' have great info on stepping options and dos and don'ts.

Proper async stepping should not cause this. Just to be safe, have you tested without an async step?Are the physics and graphics timesteps completely decoupled(*)? Is your physics timestep fixed? Are you using hkpRigidBody::approxCurrentTransform() to sync your object positions? How and when in the timestep are you moving the elevator? I recommend using hkpKeyFrameUtility::applyHardKeyFrame() to move the elevator, but more importantly you will want to execute this at a safe time. The docs for "2.4.4 Asynchronous Stepping" explain how and when you can do game/physics interactions safely.

* I do not recommend decoupling your physics and game step if possible. Run them in paralleland sync them at the end of the frame for your game/graphics update.

Let me know know how this goes,

1. I have tested without async stepping. And everything looks ok if the graphics fps is <60.2. VSync is an option in our game and everything works as it should when it's turned on. But we need a way to smooth the camera movement when VSync is turned off. Why? Becouse camera rotation is updated every graphics frame and camera position is updated every physics frame. And this causes unplesent feeling and flickering when strafing at higher graphics fps rates (>60).2. Yes I do usehkpRigidBody::approxCurrentTransform() with hkpWorld::getCurrentTime()3. Elevator is a keyframed object and it moves at the physics world step. We set it's velocity manually andit's calculatedat every framelike this:Vec3 vel = currentPos - targetPos;vel *= physicsInvDelta;4. We update the character controller just before the world step (every graphics frame) like this (pseudo code):float timeDelta = GameDelta(); // graphics deltahkStepInfo stepInfo;if( timeDelta < 0.001f ) timeDelta = 0.001f; stepInfo.m_deltaTime = timeDelta; stepInfo.m_invDeltaTime = 1.0f / timeDelta;m_characterController->checkSupport(stepInfo, ground);// velocity calculations...m_characterController->setLinearVelocity( calculated_velocity, physics_delta/*not a graphics delta. In our code its always 1/60s*/ );

I'm not clear why you are stepping the character on the graphics frame.Would you mind drawing out the steps? How often is game/graphics stepping, how often is physics stepping, and where are the updates done for each?Using the graphics step to update the character controller is likely to cause problems. Calling checkSupport with a smaller step than physics is running means checkSupport will not be looking far enough ahead. You want to be stepping the character with physics.I hope this helps; let me know how it's going,-Tyler

q. I'm not clear why you are stepping the character on the graphics frame.

a. It's rather for the sake of our code not the simulation (rb controller is only stepped on the simulation step, isn't it?).

q. Would you mind drawing out the steps? How often is game/graphics
stepping, how often is physics stepping, and where are the updates done
for each?

a. Game/graphics is stepping as frequently as they can (sometimes even more then 200fps). Physics is stepping with 60fps. Also the graphics are being rendered on the seperate thread (it just gathers needed transformation info in between frames).

How is the world stepped:

// code: from game to physics (like setting linear velocity for character)
// then execute code that looks like this:
m_havokWorld->setFrameTimeMarker( m_frameDelta );

while ( !m_havokWorld->isSimulationAtMarker() )
ASSERT( m_havokWorld->isSimulationAtPsi() );

m_havokWorld->initMtStep( GetHavokJobQueue(), m_physicsStepDelta );

GetHavokJobThreadPool()->processAllJobs( GetHavokJobQueue() );
GetHavokJobQueue()->processAllJobs( );


m_havokWorld->finishMtStep( GetHavokJobQueue(), GetHavokJobThreadPool() );

// code: from physics to game (like calling havokBody->approxTransformAt(GetHavokTime(), transform);
// GetHavokTime() returns m_havokWorld->getCurrentTime()

q. Using the graphics step to update the character controller is likely to
cause problems. Calling checkSupport with a smaller step than physics is
running means checkSupport will not be looking far enough ahead. You
want to be stepping the character with physics.

a. I've fixed that but it didn't fixed our main problem with "jumping" controller on the elevator.

Also I need to point out that we are useing havok 660 - was there any issues in the older releases with async stepping you know of?

Alright let's see...

1) I never clarified: you see the shaking on the character, not the elevator itself, correct? And does it happen when the elevator is going up or down?2) I tried to repro this in the 6.60 demo framework without success. There's a platform rb character demo in 'Demo\Demos\Physics\UseCase\CharacterControl\CharacterRigidBody\PlatformsCharacterRb'. Can you modify the demo to repro the issue? Or vice versa, try making your code more like the demo.3) You can try using hkpKeyFrameUtility::applyHardKeyFrameAsynchronously to keyframe your elevator around. I doubt this is the issue, but it won't hurt to try.4) It sounds like this isn't the issue, but just to be safe - What threads are reading/writing physics-game data? Are you they synchronized? ( does graphics read position while physics is writing? )5) Is this character specific? Do other objects jitter when they're on the elevator?6) If it is character specific, try checking your character velocity calculations. You're using the physics delta for checkSupport(), correct? Is the character velocity being modifying by anything other than checkSupport()? (See the velocity update in the demo referenced above.)

Your world stepping looks good. I also checked and could not find any relevant async step issues with releases 6.60 or later.

If you're still having issues I'd be happy to look at a VDB capture of the issue. If you have not already, looking at this scenario in the VDB may expose the problem. For more info on setting up the VDB and capturing a movie, see the docs under: Common Havok Components/Visualzation/Remote visualization with the Visual Debugger.
It may be easiest to avoid the decoupling the physics and graphics step. If the scenario is just graphics running too fast, you could try updating physics on the same thread, but less frequently (only update physics once 1/60s has passed). On that same note you could apply half-stepping so that you don't get a frame time spike every N frames when physics runs. See the docs under: Havok Physics/Hello World!/Simulating a Physics World/Stepping the Simulation/"Half" Stepping. I realize you are using an async step because you want to smoothly update the camera with the graphics step. You could try updating the camera position in the graphics update, then use a proxy object in physics (key frame it around). What are you using physics for in the camera? If collision detection is your only issue then you could have the proxy listen for collisions and (smoothly) re-sync the real camera position.
I hope this helps! Let me know how it goes,Tyler

  • If you don't use applyHardKeyFrame on the elevator, your scene will shake. That's because the interpolation code uses the velocity vector.
  • Make sure your interpolation value is correct. For example if you wrongly calculate the difference in time between last physics step and current graphic frame, then it will shake. IIRC there where many interpolation utility functions, and some of them accepted a normalized value (between 0 and 1) while other required a delta time in seconds.
  • assert() that the intepolation value is never <0 or >1.0 (or the delta time between each physics step). And also check that the next value used is >= than the one used in the previous frame (unless a new physics step has been made). This could be caused by an unfortunate combination of a QueryPerformanceCounter bug, buggy Bios, Cool 'n Quiet (or Intel's equivalent which name I always forget), and/or multi core CPUs.
  • If certain conditions are met, QueryPerformanceCounter (or getTickCount, etc) can go backwards in time.
  • If you're using multiple threads, make sure when you're reading the position values you're not in a race condition.
  • If graphics framerate is lower than physic's; make sure you're not mistaking it for frame skipping.


Matias N. Goldberg Intel Havok Physics Innovation Contest Winner * Most Innovative Use of Physics in a Game (2nd Place) * Best Physics Knowledge Base Entry (2nd Place)

Connectez-vous pour laisser un commentaire.