• Runtimes
  • [libGDX] Can't update physics if using batch transormation matrix

Hi,
I'm implementing the new runtime in my engine and trying to get working Spine's physics. The problem is that I don't move or scale skeletons directly using Skeleton#setPosition and Skeleton#setScale but the Spine entity is transformed using a Transformation Matrix applied to the Batch. This allow me to rotate and transorm with custom origin point other then nicely support custom world units etc. However for runtime the skeleton is never moving and thus physics don't get applied.

I saw two new methods physicsTranslate and physicsRotate, which I suppose may set position only for the physics but I was not able to get it working.. Just had a bunch of weird effects.

I hope I explain myself 🙂

Related Discussions
...

Something like this seems to work but I don't know if I covered all the cases or if I did the things in the right order

        if (transformComponent.x != lastX || transformComponent.y != lastY) {
            float scaleX = transformComponent.scaleX * (transformComponent.flipX ? -1 : 1);
            float scaleY = transformComponent.scaleY * (transformComponent.flipY ? -1 : 1);
            int directionX = scaleX > 0 ? 1 : -1;
            int directionY = scaleY > 0 ? 1 : -1;
            spineObjectComponent.skeleton.physicsTranslate(directionX * (transformComponent.x - lastX) / spineObjectComponent.worldMultiplier, directionY * (transformComponent.y - lastY) / spineObjectComponent.worldMultiplier);
            lastX = transformComponent.x;
            lastY = transformComponent.y;
        }

        if (transformComponent.rotation != lastRotation) {
            spineObjectComponent.skeleton.physicsRotate(transformComponent.originX, transformComponent.originY, lastRotation - transformComponent.rotation);
            lastRotation = transformComponent.rotation;
        }

        spineObjectComponent.state.update(world.getDelta()); // Update the animation time.
        spineObjectComponent.state.apply(spineObjectComponent.skeleton);
        spineObjectComponent.skeleton.update(world.getDelta());
        spineObjectComponent.skeleton.updateWorldTransform(Skeleton.Physics.update);

However it feels strange the physics time step... I'm testing on a 165hz monitor and physics doesn't looks smooth.. it's like at 60hz

To transfer movement of the skeleton's world coordinates to physics, use Skeleton physicsTranslate. You probably don't need physicsRotate. Rotation in physics will still occur since the update rate is rapid.

I can't tell if your physicsTranslate math is correct. It should be the distance in world coordinates the skeleton was moved. If it's wrong the physics movement can be jerky. You can probably remove the call to physicsRotate.

While some parts of physics use the application update rate, some physics calculations run at the frame rate specified in the editor for the constraint, regardless of the application's update rate. Make sure you don't updateWorldTransform with Physics.update multiple times per frame. Only use it for the final updateWorldTransform, as it advances the physics constraint state.

Thank you so much, I still need to discover all new features and miss the FPS setting in the editor 🙂
Yes, the math to calculate the delta for movement is correct, indeed it works, I've also removed the physicsRotate and nothing seems changed.

I've only one last doubt, I use a fixed time step with accumulator. So if the Physics.update should be called only at the last call, what should I use meanwhile? It works both if I use Physics.none and Physics.pose, what's the difference?

  • Nate ответили на это сообщение.

    I might not need to call updateWorldTransform at all! Just have one call per frame after the fixed time step loop, please correct me if I'm wrong

    • Nate ответили на это сообщение.

      fgnm I use a fixed time step with accumulator. So if the Physics.update should be called only at the last call, what should I use meanwhile?

      Physics constraints do their own accumulation. Just make sure updateWorldTransform is called with Physics.update only once per frame.

      fgnm I might not need to call updateWorldTransform at all!

      updateWorldTransform is called after posing the skeleton. Sometimes you may need to call it, manipulate bones using their world position, then call it again. See what the enum values do here:
      http://esotericsoftware.com/spine-api-reference#Physics

      Alright, thanks for all!