I’ve switched to using jme3 (from javafx) a few days ago and am loving porting my game to it. If I cut right to the chase, I noticed that if I use a ChaseCamera and set it to follow a physics object that is being moved rapidly it doesn’t quite follow it correctly - resulting in unwanted shaking and glitching as seen if you test the provided example. My hipotesis would is that the camera is being translated in the rendering thread which is out of sync with the physics thread and that causes the problem. Any ways of fixing this?
package mainpkg;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.ChaseCamera;
import com.jme3.light.AmbientLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
public class MCVE extends SimpleApplication implements PhysicsTickListener{
private static Node object = new Node();;
private static BulletAppState physics = new BulletAppState();
private static RigidBodyControl ctrl = new RigidBodyControl(2f);
@Override
public void simpleInitApp() {
stateManager.attach(physics);
flyCam.setEnabled(false); // remove flycam
ChaseCamera camera = new ChaseCamera (cam, object, inputManager);
camera.setSmoothMotion(false);
camera.setDownRotateOnCloseViewOnly(false);
camera.setMaxVerticalRotation(90);
camera.setInvertVerticalAxis(true);
camera.setMinDistance(0.05f);
camera.setMaxDistance(500);
AmbientLight al=new AmbientLight();
al.setColor(ColorRGBA.White);
rootNode.addLight(al);
cam.setFrustumPerspective(80f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 800000f);
physics.getPhysicsSpace().setGravity(new Vector3f(0, 0f, 0));
Material blank = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md");
Geometry brick_geo = new Geometry("box", new Box(1,1,1));
brick_geo.setMaterial(blank);
object.attachChild(brick_geo);
object.addControl(ctrl);
rootNode.attachChild(object);
physics.getPhysicsSpace().add(ctrl);
physics.getPhysicsSpace().addTickListener(this);
}
public static void main(String args[]) {
MCVE app = new MCVE();
app.start();
}
@Override
public void prePhysicsTick(PhysicsSpace arg0, float arg1) {
ctrl.applyCentralForce(new Vector3f(50,0,0));
}
@Override
public void physicsTick(PhysicsSpace arg0, float arg1) {}
}
I am currently using the provided ChaseCam but intend to write my own later when I get to it since I need a custom one (answers heading in that direction would be great).
@afonsolage Yes I have tried smooth motion (along with everything else that the main tutorial explains), it has the exact same problem, but also can’t follow the object properly and slingshots around a bit. I’ll take a look at that example, although it does not use physics movement which is the thing i’m having problems with.
@normen I see. But why isn’t the camera programmed to move last? That’s how I always did it in other engines (when I did it manually) and would make much more sense as it isn’t following the place where the object was, but where it is now.
P.S. If someone actually tried to test the code I provided, yeah that would be great.
Alright so I tried to remove the chasecam alltogether and move the provided cam manually but it gives the same results, no matter if I move it first, last or in the prePhysicsTick method.
Using this:
The ChaseCamera adds a control to the target spatial. Obviously this control is added before the physics control. Do the physics setup first and then do the chase camera setup last.
For reference, simpleUpdate() is run BEFORE anything else. Definitely NOT last.
Order goes like this:
-process input
-app state updates
-simpleUpdate
-control updates
-app state render
-actual render
-simpleRender
-app state post render
In this case, the only place to do something “LAST” with the camera is in an app state’s render method or as the last control. (Really FlyByCamera and ChaseCamera should have been app states.)
Well in the code I did it should have ran the next frame, thus making it lag behind again apaprently. That order is definitely something I need to keep in the back of my mind.
Yeah, it wasn’t done last… it was done early on the following frame…which is basically your original problem.
Note: I’m not a magician, nor do I have total-code-recall… I simply know the secret (apparently) key to look at engine source code. If you find the secret key then you can look, too.