1
\$\begingroup\$

I'm trying to implement the https://gafferongames.com/post/fix_your_timestep article but I have jitter on the position interpolation.

video of the problem

I have the following PhysX manager class update method :

 const float fixedTimeStep = 1.0f / 60.0f; // 60Hz
 float deltaTime = TimeManager::GetInstance()->DeltaTimeF();        
 if (deltaTime > 0.25f)
     deltaTime = 0.25f;
 accumulator += deltaTime;

 static std::unordered_map<PxRigidDynamic*, PhysXState> statesBefore{};
 static std::unordered_map<PxRigidDynamic*, PhysXState> statesAfter{};

 if (statesBefore.empty()) {
     RetrieveCurrentState(statesBefore);
     RetrieveCurrentState(statesAfter);
 }

 while (accumulator >= fixedTimeStep)
 {
     statesBefore = statesAfter;

     mScene->simulate(fixedTimeStep, nullptr, GSimulateScratchMemory, GSimulateScratchMemorySize);
     accumulator = std::max(accumulator - fixedTimeStep, 0.f);
     mScene->fetchResults(true);

     RetrieveCurrentState(statesAfter);
 }

 // Calculate the interpolation factor for rendering
 float alpha = accumulator / fixedTimeStep;

 for (const auto& [body, stateBefore] : statesBefore) {
     if (statesAfter.find(body) != statesAfter.end()) {
         const auto& stateAfter = statesAfter.at(body);
         PhysXState interpolatedState{};
         InterpolateStates(stateBefore, stateAfter, alpha, interpolatedState);

         // Update the interpolated state in the body userptr moveable body
         auto userPtr = static_cast<CollisionParam*>(body->userData);
         if (userPtr && userPtr->Body) {
             userPtr->Body->SetInterpolatedState(interpolatedState);
         }
     }
 } 

This is how I retrieve the current state:

void RetrieveCurrentState(std::unordered_map<PxRigidDynamic*, PhysXState>& states) {
    states.clear();
    for (auto rigidBody : mRigidBodies) {
        PhysXState state;

        physx::PxTransform transform = rigidBody->getGlobalPose();
        state.Position = glm::vec3(transform.p.x, transform.p.y, transform.p.z);
        state.Orientation = glm::quat(transform.q.w, transform.q.x, transform.q.y, transform.q.z);

        physx::PxVec3 linearVelocity = rigidBody->getLinearVelocity();
        state.Velocity = glm::vec3(linearVelocity.x, linearVelocity.y, linearVelocity.z);

        physx::PxVec3 angularVelocity = rigidBody->getAngularVelocity();
        state.AngularVelocity = glm::vec3(angularVelocity.x, angularVelocity.y, angularVelocity.z);

        states[rigidBody] = state;
    }
}

And here is how I interpolate:

void InterpolateStates(const PhysXState& previous, const PhysXState& current, float alpha, PhysXState& interpolated)
{
    interpolated.Position = glm::mix(previous.Position, current.Position, alpha);
    interpolated.Orientation = glm::slerp(previous.Orientation, current.Orientation, alpha);
    interpolated.Velocity = glm::mix(previous.Velocity, current.Velocity, alpha);
    interpolated.AngularVelocity = glm::mix(previous.AngularVelocity, current.AngularVelocity, alpha);
}

Finally here is how I retrieve the interpolated position (currently using only the position as a test phase) to feed it into the graphics module:

prop.Transform.setLocalPosition(prop.MoveableBody->GetInterpolatedPosition());

What could be wrong and the movement is shaky/jittery ? Let me know if you need to see more code.

\$\endgroup\$
5
  • \$\begingroup\$ It would be great if you could attach a video or gif, someone may recognise the behaviour and pinpoint your issue more quickly. \$\endgroup\$
    – liggiorgio
    Commented Aug 3 at 21:35
  • \$\begingroup\$ @liggiorgio Thanks for the comment. I've edited the description above to include a video \$\endgroup\$
    – Mike F
    Commented Aug 4 at 10:46
  • \$\begingroup\$ I've also seen this happen as a consequence of a camera follow script. Do you observe the same jitter in a scene with a stationary camera and an object moving in the camera's field of view, or is it only when you have the camera following the ship like this? Do you observe it when the ship is moving at a constant velocity, or only when accelerating/decelerating (in which case it could be due to your ship control code having a glitch in the case of non-linear motion)? \$\endgroup\$
    – DMGregory
    Commented Aug 4 at 10:53
  • \$\begingroup\$ @DMGregory Good observation but it is not the camera. I made the camera stationary and the spaceship moving towards it and it (the spaceship) was still shaky. I'm currently testing with using the interpolated position only on the spaceship so nothing else was affected. I observe it mostly on high speed movement, constant speed or accelerating/decelerating. \$\endgroup\$
    – Mike F
    Commented Aug 4 at 11:07
  • \$\begingroup\$ Note that if I make the PhysX timestep variable, and equal to the frame time, the problem goes away. I think the problem lies somewhere in the code that I posted. \$\endgroup\$
    – Mike F
    Commented Aug 4 at 11:11

0

You must log in to answer this question.

Browse other questions tagged .