how can I smooth my automated camera system??

Started by Minigame, May 01, 2015, 05:13:44 AM

Previous topic - Next topic

Minigame

Ok so I've perfected the movement system for my game, but it uses 8 directions for player rotations (A* paths) and my camera seems to be EXTREMELY twitchy / jerky because of that..

My question is how can I smooth the camera system? Here's the code I'm using to make the camera follow the player.



public void update() {
                // I think the following 3 lines is what makes the camera seem to jerk or twitch, since the player rotates in 1 of 8 directions.. and the camera snaps to the player
camera.setPositionToCenter(abstractHuman.getModel());
camera.align(abstractHuman.getModel()); // align the camera with the player
camera.rotateY(cameraRotation);

camera.rotateCameraX((float) Math.toRadians(30)); // angle
camera.moveCamera(Camera.CAMERA_MOVEOUT, 90); // zoom
}


I've tried timers for camera updating but they only cut down on the amount of twitchy/jerky camera movements. How can I make something smoother?

EgonOlsen

You can try interpolate the rotation matrices. The car example for desktop jPCT contains some crude code that does this.

Minigame

I ended up adding a focus point (invisible sphere) to the code, and translating it to the player's position. Here's the source if anybody wants an RPG-suitable camera foundation.



import org.lwjgl.input.Keyboard;

import com.threed.jpct.Camera;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.World;

/**
* An RPG style jPCT camera system.
*/
public class CameraManager {

private final Player player;
private final Object3D orb;
private final Camera camera;
private float cameraRotation = 0;
private float cameraRotationSpeed = 0.042f;
private boolean rotateCameraLeft;
private boolean rotateCameraRight;
private boolean firstPersonMode = false;

/**
* Initialize the camera manager.
*/
public CameraManager(final Camera camera, final Player player, final World world) {
this.camera = camera;
this.player = player;
this.orb = Primitives.getSphere(1);
orb.setVisibility(false);
orb.compile();
world.addObject(orb);
}

/**
* Poll keyboard input. Keyboard.KEY_'s used: KEY_LEFT, KEY_RIGHT, KEY_TAB
*/
public void pollKeyboard(int keyCode, boolean pressed) {
/*
* Let the user control camera rotation so they can have a 360 degree vision range.
* Also give them the option to view the virtual world using a third person camera.
*/
switch (keyCode) {
case Keyboard.KEY_LEFT:
rotateCameraLeft = pressed;
break;
case Keyboard.KEY_RIGHT:
rotateCameraRight = pressed;
break;
case Keyboard.KEY_TAB:
firstPersonMode = !firstPersonMode;
break;
}
}

/**
* Update the camera.
*/
public void update() {
if (rotateCameraLeft) {
if (firstPersonMode) {
player.rotateLeft(cameraRotationSpeed);
} else {
cameraRotation += cameraRotationSpeed;
}
}
if (rotateCameraRight) {
if (firstPersonMode) {
player.rotateRight(cameraRotationSpeed);
} else {
cameraRotation -= cameraRotationSpeed;
}
}

// Translate the cameras invisible focus point to the player position
orb.clearTranslation();
orb.translate(player.getModel().getTransformedCenter());

camera.setPositionToCenter(orb/*abstractHuman.getModel()*/);
camera.align(orb/*abstractHuman.getModel()*/); // Align the camera with the player
camera.rotateY(cameraRotation);

if (firstPersonMode) {
camera.rotateCameraX((float) Math.toRadians(10)); // angle
camera.moveCamera(Camera.CAMERA_MOVEUP, 3.8f); // height ("eye level")
camera.moveCamera(Camera.CAMERA_MOVEIN, 0.5f); // move camera slightly forward,
// so we're not seeing out from inside of the players head model..
} else {
camera.rotateCameraX((float) Math.toRadians(30)); // angle
camera.moveCamera(Camera.CAMERA_MOVEOUT, 45); // zoom
}
}

}