PhysicsCharacterNode jitters

I use a PhysicsCharacterNode on top of a BoxCollisionShape, when the character moves however, it jitters a lot. The character can also be seen ‘bumping’ up and down when standing still.


normen said:
The walkDirection vector of the PhysicsCharacterNode is framerate independent, you only need to set it once and the character will move correctly at all framerates.
The jitter can be reduced by lowering the stepSize of the character node. Note that character nodes are not "real" physics but a simple version.
Yes, the child of the character node should be modified, the character node itself is moved by the physics.
Cheers,
Normen


This seems promising, but I didn't manage to find any mention of 'stepSize' in the sources. I have also tried updating the geometric state in simpleUpdate().

EDIT: By bumping I mean that the character sinks into the BoxCollisionShape and then bumps up.
1 Like

The stepSize is an argument for the PhysicsCharacterNode constructor

Got it, but it doesn’t remove the jitter. :frowning:

Maybe this code can help, it’s a modified version of the ‘Hello Collision’ tutorial which shows the same stuttering behavior.



[java]

class actionListener(ActionListener):

def init(self, parent):

self.parent = parent



def onAction(self, binding, value, tpf):

if binding == “LMouse”:

if value:

self.parent.mouse_move = True

else:

self.parent.mouse_move = False



class HelloCollision(SimpleApplication):

def simpleInitApp(self):



self.mouse_move = False

self.flyCam.setEnabled(False)



bulletAppState = BulletAppState()

self.stateManager.attach(bulletAppState)



self.viewPort.setBackgroundColor(ColorRGBA(0.7,0.8,1,1))

self.setupKeys()



dl = DirectionalLight()

dl.setColor(ColorRGBA.White)

dl.setDirection(Vector3f(2.8, -2.8, -2.8).normalize())

self.rootNode.addLight(dl)



self.assetManager.registerLocator(“town.zip”, ZipLocator.getName())

sceneModel = self.assetManager.loadModel(“main.scene”)

sceneModel.setLocalScale(2)



self.sceneModel = sceneModel



sceneShape = CollisionShapeFactory.createMeshCompoundShape(sceneModel)

landscape = PhysicsNode(sceneModel, sceneShape, 0)

landscape.attachDebugShape(self.assetManager)



player = PhysicsCharacterNode(CapsuleCollisionShape(1.5, 6, 1), .05)

player.setJumpSpeed(20)

player.setFallSpeed(30)

player.setGravity(30)

player.setLocalTranslation(Vector3f(0, 10, 0))



self.ninja = self.assetManager.loadModel(“Models/Ninja/Ninja.mesh.xml”)

self.ninja.scale(0.05, 0.05, 0.05)

self.ninja.setLocalTranslation(Vector3f(0, -3.0, 0.0))

player.attachChild(self.ninja)



self.rootNode.attachChild(landscape)

self.rootNode.attachChild(player)

bulletAppState.getPhysicsSpace().add(landscape)

bulletAppState.getPhysicsSpace().add(player)

self.player = player



def setupKeys(self):

self.inputManager.addMapping(“LMouse”, [MouseButtonTrigger(MouseInput.BUTTON_LEFT)])

self.inputManager.addListener(actionListener(self), [“LMouse”])



def simpleUpdate(self, tpf):

self.player.setWalkDirection(Vector3f(1,0,0)



def simpleRender(self, rm):

self.cam.lookAt(self.player.getLocalTranslation(),Vector3f.ZERO)

location = self.player.getLocalTranslation()

self.cam.setLocation(Vector3f(

location.x + 30

, location.y + 60

, location.z + 30))



if name == “main”:

a = HelloCollision()

a.start()

[/java]



I posted a thread earlier here about ‘flickering camera’, where I pointed out that a ‘ChaseCamera’ would work. After some ‘better’ investigation however, it turns out that ‘ChaseCamera’ wont work either. :cry:



EDIT: Java version of the above

[java]

import com.jme3.app.SimpleApplication;

import com.jme3.asset.plugins.ZipLocator;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

import com.jme3.bullet.collision.shapes.CompoundCollisionShape;

import com.jme3.bullet.nodes.PhysicsCharacterNode;

import com.jme3.bullet.nodes.PhysicsNode;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.light.DirectionalLight;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial;

import com.jme3.input.ChaseCamera;



public class Main extends SimpleApplication {



private BulletAppState bulletAppState;

private Spatial sceneModel;

private PhysicsNode landscape;

private PhysicsCharacterNode player;

private Vector3f walkDirection = new Vector3f();

private boolean left = false, right = false, up = false, down = false;



public static void main(String[] args) {

Main app = new Main();

app.start();

}



public void simpleInitApp() {

/** Set up Physics */

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);



flyCam.setEnabled(false);



viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));



DirectionalLight dl = new DirectionalLight();

dl.setColor(ColorRGBA.White.clone().multLocal(2)); // bright white light

dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalize());

rootNode.addLight(dl);



assetManager.registerLocator(“town.zip”, ZipLocator.class.getName());

sceneModel = assetManager.loadModel(“main.scene”);

sceneModel.setLocalScale(2f);



CompoundCollisionShape sceneShape =

CollisionShapeFactory.createMeshCompoundShape((Node) sceneModel);

landscape = new PhysicsNode(sceneModel, sceneShape, 0);



player = new PhysicsCharacterNode(new CapsuleCollisionShape(1.5f, 6f, 1), .05f);

player.setJumpSpeed(20);

player.setFallSpeed(30);

player.setGravity(30);

player.attachDebugShape(assetManager);

player.setLocalTranslation(new Vector3f(0, 10, 0));



rootNode.attachChild(landscape);

rootNode.attachChild(player);

bulletAppState.getPhysicsSpace().add(landscape);

bulletAppState.getPhysicsSpace().add(player);



ChaseCamera chaseCam = new ChaseCamera(cam, player, inputManager);

player.setWalkDirection(new Vector3f(0.5f,0,0));

}

}

[/java]

Might it have something with ‘mesh density’ to do?









Above is mine, below is the ‘TestWalkingChar’ example.



EDIT: Seems not, I tried with some terrain and it still stutters.

The jittering is a known bug that can be worked around by adding an additional rootNode.updateGeometricState() at the beginning of simpleUpdate() but this might bring other problems.

Adding ‘updateGeometricState()’ doesn’t really help. Also, how come the ‘TestWalkingChar’ example works just fine?

Because its using the workaround I just suggested :roll:

I’ve tried it and it works fine :slight_smile: This is what I have added to fix the jitter issue, and have noticed no other issues in a test scene.



[java]

/*

  • Time per frame

    */

    @Override

    public void simpleUpdate(float tpf) {

    //debugging jittery movement

    rootNode.updateGeometricState();

    }

    [/java]

Ah, it works now, but only with ‘chaseCamera’.



The workaround isn’t in the example, since it was removed.

Yes, but its still in alpha-3. Theres only two ways: Either you have jitter and the code is in the test or your dont and its not. Since you said you dont have jitter the code should be in your version.

Ah well, no matter.

With ‘updateLogicalState’, ‘updateGeometricState()’ and a ‘ChaseCamera’ it works, now I just have to work on that camera.

Thanks for helping.

I worked around the problem in the chase camera by adding some kind on low pass filter on the position of the spatial.

Jittering are very slight movements, each update i compute the distance between last position and current position, if it’s lesser than an arbitrary threshold i don’t move the camera.

This avoid the jitter of the camera, but it can reduce the precision of the movement.