[SOLVED]Camera that follow a object

How I can make a camera that follow a object from back,at a distinct angle,for exemple the car the fancycar demo?

Thank you very much @anthyon @normen and @pspeed !

with the help of @normen and @pspeed the solution is:

[java]

public void simpleUpdate(float tpf) {

this.cam.setLocation( carNode.localToWorld( new Vector3f( 0, 10 /* units above car*/, 10 /* units behind car*/ ), null));

this.cam.lookAt(this.carNode.getWorldTranslation(), Vector3f.UNIT_Y);

}

[/java]

1 Like

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:camera#chase_camera

I’ve used that,does the work partially.

This is the full TestFancyCar.java file:

[java]package mygame;



import com.jme3.bullet.BulletAppState;

import com.jme3.app.SimpleApplication;

import com.jme3.bounding.BoundingBox;

import com.jme3.bullet.PhysicsSpace;

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

import com.jme3.bullet.control.VehicleControl;

import com.jme3.bullet.objects.VehicleWheel;

import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.light.DirectionalLight;

import com.jme3.math.FastMath;

import com.jme3.math.Matrix3f;

import com.jme3.math.Vector3f;

import com.jme3.renderer.queue.RenderQueue.ShadowMode;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial;

import com.jme3.shadow.BasicShadowRenderer;



public class TestFancyCar extends SimpleApplication implements ActionListener {



private BulletAppState bulletAppState;

private VehicleControl player;

private VehicleWheel fr, fl, br, bl;

private Node node_fr, node_fl, node_br, node_bl;

private float wheelRadius;

private float steeringValue = 0;

private float accelerationValue = 0;

private Node carNode;



public static void main(String[] args) {

TestFancyCar app = new TestFancyCar();

app.start();

}

private Spatial target;

private Spatial car;

private Object chaseCam;



private void setupKeys() {

inputManager.addMapping(“Lefts”, new KeyTrigger(KeyInput.KEY_H));

inputManager.addMapping(“Rights”, new KeyTrigger(KeyInput.KEY_K));

inputManager.addMapping(“Ups”, new KeyTrigger(KeyInput.KEY_U));

inputManager.addMapping(“Downs”, new KeyTrigger(KeyInput.KEY_J));

inputManager.addMapping(“Space”, new KeyTrigger(KeyInput.KEY_SPACE));

inputManager.addMapping(“Reset”, new KeyTrigger(KeyInput.KEY_RETURN));

inputManager.addListener(this, “Lefts”);

inputManager.addListener(this, “Rights”);

inputManager.addListener(this, “Ups”);

inputManager.addListener(this, “Downs”);

inputManager.addListener(this, “Space”);

inputManager.addListener(this, “Reset”);

}



@Override

public void simpleInitApp() {

bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

// bulletAppState.getPhysicsSpace().enableDebug(assetManager);

if (settings.getRenderer().startsWith(“LWJGL”)) {

BasicShadowRenderer bsr = new BasicShadowRenderer(assetManager, 512);

bsr.setDirection(new Vector3f(-0.5f, -0.3f, -0.3f).normalizeLocal());

viewPort.addProcessor(bsr);

}

cam.setFrustumFar(150f);

flyCam.setMoveSpeed(10);



setupKeys();

PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());

// setupFloor();

buildPlayer();



DirectionalLight dl = new DirectionalLight();

dl.setDirection(new Vector3f(-0.5f, -1f, -0.3f).normalizeLocal());

rootNode.addLight(dl);



dl = new DirectionalLight();

dl.setDirection(new Vector3f(0.5f, -0.1f, 0.3f).normalizeLocal());

rootNode.addLight(dl);

}



private PhysicsSpace getPhysicsSpace() {

return bulletAppState.getPhysicsSpace();

}



// public void setupFloor() {

// Material mat = assetManager.loadMaterial(“Textures/Terrain/BrickWall/BrickWall.j3m”);

// mat.getTextureParam(“DiffuseMap”).getTextureValue().setWrap(WrapMode.Repeat);

//// mat.getTextureParam(“NormalMap”).getTextureValue().setWrap(WrapMode.Repeat);

//// mat.getTextureParam(“ParallaxMap”).getTextureValue().setWrap(WrapMode.Repeat);

//

// Box floor = new Box(Vector3f.ZERO, 140, 1f, 140);

// floor.scaleTextureCoordinates(new Vector2f(112.0f, 112.0f));

// Geometry floorGeom = new Geometry(“Floor”, floor);

// floorGeom.setShadowMode(ShadowMode.Receive);

// floorGeom.setMaterial(mat);

//

// PhysicsNode tb = new PhysicsNode(floorGeom, new MeshCollisionShape(floorGeom.getMesh()), 0);

// tb.setLocalTranslation(new Vector3f(0f, -6, 0f));

//// tb.attachDebugShape(assetManager);

// rootNode.attachChild(tb);

// getPhysicsSpace().add(tb);

// }



private Geometry findGeom(Spatial spatial, String name) {

if (spatial instanceof Node) {

Node node = (Node) spatial;

for (int i = 0; i < node.getQuantity(); i++) {

Spatial child = node.getChild(i);

Geometry result = findGeom(child, name);

if (result != null) {

return result;

}

}

} else if (spatial instanceof Geometry) {

if (spatial.getName().startsWith(name)) {

return (Geometry) spatial;

}

}

return null;

}



private void buildPlayer() {

float stiffness = 120.0f;//200=f1 car

float compValue = 0.2f; //(lower than damp!)

float dampValue = 0.3f;

final float mass = 400;



//Load model and get chassis Geometry

carNode = (Node)assetManager.loadModel(“Models/Ferrari/Car.scene”);

carNode.setShadowMode(ShadowMode.Cast);

Geometry chasis = findGeom(carNode, “Car”);

BoundingBox box = (BoundingBox) chasis.getModelBound();



//Create a hull collision shape for the chassis

CollisionShape carHull = CollisionShapeFactory.createDynamicMeshShape(chasis);



//Create a vehicle control

player = new VehicleControl(carHull, mass);

carNode.addControl(player);



//Setting default values for wheels

player.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));

player.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));

player.setSuspensionStiffness(stiffness);

player.setMaxSuspensionForce(10000);



//Create four wheels and add them at their locations

//note that our fancy car actually goes backwards…

Vector3f wheelDirection = new Vector3f(0, -1, 0);

Vector3f wheelAxle = new Vector3f(-1, 0, 0);



Geometry wheel_fr = findGeom(carNode, “WheelFrontRight”);

wheel_fr.center();

box = (BoundingBox) wheel_fr.getModelBound();

wheelRadius = box.getYExtent();

float back_wheel_h = (wheelRadius * 1.7f) - 1f;

float front_wheel_h = (wheelRadius * 1.9f) - 1f;

player.addWheel(wheel_fr.getParent(), box.getCenter().add(0, -front_wheel_h, 0),

wheelDirection, wheelAxle, 0.2f, wheelRadius, true);



Geometry wheel_fl = findGeom(carNode, “WheelFrontLeft”);

wheel_fl.center();

box = (BoundingBox) wheel_fl.getModelBound();

player.addWheel(wheel_fl.getParent(), box.getCenter().add(0, -front_wheel_h, 0),

wheelDirection, wheelAxle, 0.2f, wheelRadius, true);



Geometry wheel_br = findGeom(carNode, “WheelBackRight”);

wheel_br.center();

box = (BoundingBox) wheel_br.getModelBound();

player.addWheel(wheel_br.getParent(), box.getCenter().add(0, -back_wheel_h, 0),

wheelDirection, wheelAxle, 0.2f, wheelRadius, false);



Geometry wheel_bl = findGeom(carNode, “WheelBackLeft”);

wheel_bl.center();

box = (BoundingBox) wheel_bl.getModelBound();

player.addWheel(wheel_bl.getParent(), box.getCenter().add(0, -back_wheel_h, 0),

wheelDirection, wheelAxle, 0.2f, wheelRadius, false);



player.getWheel(2).setFrictionSlip(4);

player.getWheel(3).setFrictionSlip(4);



rootNode.attachChild(carNode);

getPhysicsSpace().add(player);

}



public void onAction(String binding, boolean value, float tpf) {

if (binding.equals(“Lefts”)) {

if (value) {

steeringValue += .5f;

} else {

steeringValue += -.5f;

}

player.steer(steeringValue);

} else if (binding.equals(“Rights”)) {

if (value) {

steeringValue += -.5f;

} else {

steeringValue += .5f;

}

player.steer(steeringValue);

} //note that our fancy car actually goes backwards…

else if (binding.equals(“Ups”)) {

if (value) {

accelerationValue -= 800;

} else {

accelerationValue += 800;

}

player.accelerate(accelerationValue);

player.setCollisionShape(CollisionShapeFactory.createDynamicMeshShape(findGeom(carNode, “Car”)));

} else if (binding.equals(“Downs”)) {

if (value) {

player.brake(40f);

} else {

player.brake(0f);

}

} else if (binding.equals(“Reset”)) {

if (value) {

System.out.println(“Reset”);

player.setPhysicsLocation(Vector3f.ZERO);

player.setPhysicsRotation(new Matrix3f());

player.setLinearVelocity(Vector3f.ZERO);

player.setAngularVelocity(Vector3f.ZERO);

player.resetSuspension();

} else {

}

}

}



@Override

public void simpleUpdate(float tpf) {

flyCam.setEnabled(false);

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

}

}[/java]

I’ve modified the last part,but the camera just follow the car,I want to be allways at back of the car.

try chaseCam.setDefaultHorizontalRotation(FastMath.DEG_TO_RAD90);

chaseCam.setDefaultVerticalRotation(FastMath.DEG_TO_RAD
5);

chaseCam.setDefaultDistance(10);



or something like that until it gets to the angle you want.

1 Like

@wezrule: well I see his point, and your solution will not satisfy the requirements. Though the initial location of the camera will be set behind the car, but as the car turns around, the camera will not follow it from behind. In this case the camera should take a path on a circle, but the location of the cam cannot be set, when using chaseCamera, as far as my test run. :frowning:

@anthyon bah your right :P, i didn’t think this through enough

shaseCam.setTrailingEnabled(true);

Don’t work,camera doesn’t stay at back of the car.

asasinuxp said:
stay at back of the car

Nobody doesn't know how to do this?