Rotating camera

I’ve figured out how to use a motion path and cinematics to automatically fly a camera around my terrain as though I was on an invisible roller coaster. I’m going to use that to produce a video.



But what happens if in the midst of my roller coaster ride, I want to stop somewhere and then from a fixed position pan my camera around from one angle to another? And then get back in my imaginary roller coaster and keep going?



I tried creating a path with only two nodes (both the same) and then defined the track as



[java]MotionTrack track = new MotionTrack(camNode, path,10f);

track.setDirectionType(MotionTrack.Direction.Rotation);

track.setRotation(new Quaternion().fromAngles(0.0f, FastMath.TWO_PI, 0.0f));[/java]



But that just turned the camera in that direction and stayed there. How do I get a pan effect with the camera rotating from one angle to another?



Kevin

I could just manually interpolate the camera rotation by moving it a fraction of the angle every tenth of a second, I suppose. But is there a better way?



If not, then should I use something like java.util.Timer to set the timed rotation events or is there a more specific jMonkeyEngine way to do this?



Kevin

Yes, moving the camera by hand is probably the best, our tutorials show how you can properly use the tpf (time per frame) variable to do this. Basically you just need to multiply TWO_PI value by x+=tpf and apply the rotation each frame to get the TWO_PI rotation within one second. Also you might want to use direction vectors as using rotations can quickly become confusing due to gimbal lock etc.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_main_event_loop

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies

Thanks normen! Extremely helpful as always.



I’m now calling this function in simpleUpdate:



[java]public void panCamera(Float time, Vector3f startDirection, Float startTime, Vector3f endDirection, Float endTime) {

if (time > startTime && time < endTime) {

Float interp = (time - startTime) / (endTime - startTime);

Vector3f lookat = FastMath.interpolateLinear(interp, startDirection, endDirection);

cam.lookAtDirection(lookat.normalizeLocal(), Vector3f.UNIT_Y);

}

}[/java]



to interpolate between two camera directions and a starting and ending time (in seconds) and this works, but the resulting animation is a bit jerky. Is this because I have failed to include tpf somewhere?



Kevin

Yes, most probably. I don’t see where framerate independency is implemented in that code unless you augment “time” with tpf each frame.

Since I move the camera every fraction of a second based on the time (I am using the LwjglTimer), then is that not frame rate independent?



If the frame rate is lower I would think that simpleUpdate would be called less often and so the camera would be rotated in larger chunks. Perhaps the jerkiness is just happening because I have a slow graphics card or a too low frame rate?



I will try increasing the frame rate to see if that makes a difference. Upgrading my graphics card would be more difficult. However, since I intend to get jMonkeyEngine to ultimately output directly to video, (this project is to create a Youtube video), the graphics card may not matter.

Just use the tpf variable and the update() methods of the various classes. No timers, no frame counting necessary:

[java]

float time = 0;

public void update(float tpf){

time += tpf;

}

[/java]