Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package mygame;
- import com.jme3.app.SimpleApplication;
- import com.jme3.bullet.BulletAppState;
- import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
- import com.jme3.bullet.collision.shapes.SphereCollisionShape;
- import com.jme3.bullet.nodes.PhysicsCharacterNode;
- import com.jme3.bullet.nodes.PhysicsNode;
- import com.jme3.font.BitmapText;
- import com.jme3.input.KeyInput;
- import com.jme3.input.MouseInput;
- import com.jme3.input.controls.ActionListener;
- import com.jme3.input.controls.KeyTrigger;
- import com.jme3.input.controls.MouseButtonTrigger;
- import com.jme3.light.DirectionalLight;
- import com.jme3.material.Material;
- import com.jme3.math.ColorRGBA;
- import com.jme3.math.FastMath;
- import com.jme3.math.Plane;
- import com.jme3.math.Quaternion;
- import com.jme3.math.Vector2f;
- import com.jme3.math.Vector3f;
- import com.jme3.post.FilterPostProcessor;
- import com.jme3.post.filters.FogFilter;
- import com.jme3.renderer.Camera;
- import com.jme3.renderer.RenderManager;
- import com.jme3.renderer.queue.RenderQueue.Bucket;
- import com.jme3.renderer.queue.RenderQueue.ShadowMode;
- import com.jme3.scene.Geometry;
- import com.jme3.scene.Node;
- import com.jme3.scene.shape.Quad;
- import com.jme3.scene.shape.Sphere;
- import com.jme3.terrain.geomipmap.TerrainLodControl;
- import com.jme3.terrain.geomipmap.TerrainQuad;
- import com.jme3.terrain.heightmap.AbstractHeightMap;
- import com.jme3.terrain.heightmap.ImageBasedHeightMap;
- import com.jme3.texture.Texture;
- import com.jme3.texture.Texture.WrapMode;
- import com.jme3.util.TangentBinormalGenerator;
- import com.jme3.water.SimpleWaterProcessor;
- import game.LifeFormObject;
- import game.camera.ThirdpersonCamera;
- import game.player.Player;
- import java.util.ArrayList;
- import java.util.List;
- import jme3tools.converters.ImageToAwt;
- /**
- * test
- * @author normenhansen
- */
- public class Main extends SimpleApplication implements ActionListener {
- private Player playerGeom;
- private PhysicsCharacterNode player;
- private BulletAppState bulletAppState;
- private TerrainQuad terrain;
- Material mat_terrain;
- private Vector3f walkDirection = new Vector3f();
- private boolean left = false, right = false, turnLeft = false, turnRight = false, up = false, down = false, shoot = false;
- private Node mainNode;
- private FilterPostProcessor fpp;
- private boolean enabled=true;
- private FogFilter fog;
- private Vector3f preJumpDirection = new Vector3f();
- private Vector3f preJumpDirectionLeft = new Vector3f();
- private BitmapText ch;
- private BitmapText npcMark;
- private LifeFormObject npc;
- private ThirdpersonCamera chaseCam;
- public static void main(String[] args) {
- Main app = new Main();
- app.start();
- }
- @Override
- public void simpleInitApp() {
- try {
- mainNode = new Node();
- bulletAppState = new BulletAppState();
- stateManager.attach(bulletAppState);
- 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);
- // flyCam.setMoveSpeed(50);
- // flyCam.setDragToRotate(true);
- flyCam.setEnabled(false);
- fpp=new FilterPostProcessor(assetManager);
- fog=new FogFilter();
- fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f));
- fog.setFogDistance(170);
- fog.setFogDensity(0.8f);
- fpp.addFilter(fog);
- viewPort.addProcessor(fpp);
- setupKeys();
- /** 1. Create terrain material and load four textures into it. */
- mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
- /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */
- mat_terrain.setTexture("m_Alpha",
- assetManager.loadTexture("MatDefs/HeightMaps/mountains512-alpha.png"));
- /** 1.2) Add GRASS texture into the red layer (m_Tex1). */
- Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
- grass.setWrap(WrapMode.Repeat);
- mat_terrain.setTexture("m_Tex1", grass);
- mat_terrain.setFloat("m_Tex1Scale", 64f);
- /** 1.3) Add DIRT texture into the green layer (m_Tex2) */
- Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
- dirt.setWrap(WrapMode.Repeat);
- mat_terrain.setTexture("m_Tex2", dirt);
- mat_terrain.setFloat("m_Tex2Scale", 32f);
- /** 1.4) Add ROAD texture into the blue layer (m_Tex3) */
- Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
- rock.setWrap(WrapMode.Repeat);
- mat_terrain.setTexture("m_Tex3", rock);
- mat_terrain.setFloat("m_Tex3Scale", 128f);
- playerGeom = new Player("Hero", assetManager);
- player = playerGeom.getPhysicsNode();
- chaseCam = new ThirdpersonCamera(cam, player, inputManager);
- chaseCam.setUseCursor(true);
- chaseCam.setDefaultDistance(40);
- chaseCam.setMaxDistance(60);
- chaseCam.setRotationSensitivity(3f);
- chaseCam.setTrailingEnabled(true);
- chaseCam.setUseLeftMouseToRotate(false);
- /** Bumpy rock with shiny light effect. Uses Texture from jme3-test-data library! Needs light source! */
- Sphere rock2 = new Sphere(32,32, 2f);
- Geometry shiny_rock = new Geometry("Shiny rock", rock2);
- rock2.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres
- TangentBinormalGenerator.generate(rock2); // for lighting effect
- Material mat_lit = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
- mat_lit.setTexture("m_DiffuseMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond.png"));
- mat_lit.setTexture("m_NormalMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png"));
- mat_lit.setFloat("m_Shininess", 5f); // [0,128]
- shiny_rock.setMaterial(mat_lit);
- SphereCollisionShape rockShape = new SphereCollisionShape(2f);
- PhysicsNode rockNode = new PhysicsNode(shiny_rock, rockShape, 6.0f);
- rockNode.setLocalTranslation(220.59f,-94.49f,83.24f);
- rockNode.setShadowMode(ShadowMode.CastAndReceive);
- rootNode.attachChild(rockNode);
- bulletAppState.getPhysicsSpace().add(rockNode);
- npc = new LifeFormObject("wewt", "Sinbad", 0.5f, mainNode, assetManager);
- npc.setLocalTranslation(new Vector3f(220.59f,-94.49f,83.24f));
- mainNode.attachChild(npc);
- // mainNode.updateGeometricState();
- bulletAppState.getPhysicsSpace().add(npc);
- /** 2. Create the height map */
- AbstractHeightMap heightmap = null;
- Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
- heightmap = new ImageBasedHeightMap(
- ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));
- heightmap.load();
- /** 3. We have prepared material and heightmap. Now we create the actual terrain:
- * 3.1) We create a TerrainQuad and name it "my terrain".
- * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
- * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
- * 3.4) As LOD step scale we supply Vector3f(1,1,1).
- * 3.5) At last, we supply the prepared heightmap itself.
- */
- terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());
- terrain.setShadowMode(ShadowMode.CastAndReceive);
- /** 4. We give the terrain its material, position & scale it, and attach it. */
- terrain.setMaterial(mat_terrain);
- HeightfieldCollisionShape terrainCollisionShape
- = new HeightfieldCollisionShape(terrain.getHeightMap());
- PhysicsNode terrainNode = new PhysicsNode(terrain, terrainCollisionShape, 0);
- terrainNode.setLocalTranslation(0, -100, 0);
- // terrainNode.setLocalScale(terrain.getLocalScale());
- mainNode.attachChild(terrainNode);
- mainNode.attachChild(player);
- rootNode.attachChild(mainNode);
- bulletAppState.getPhysicsSpace().add(terrainNode);
- bulletAppState.getPhysicsSpace().add(player);
- viewPort.getCamera().setFrustumFar(150f);
- /** 5. The LOD (level of detail) depends on were the camera is: */
- List<Camera> cameras = new ArrayList<Camera>();
- cameras.add(getCamera());
- TerrainLodControl control = new TerrainLodControl(terrain, cameras);
- terrain.addControl(control);
- // mainNode.attachChild(SkyFactory.createSky(assetManager, assetManager.loadTexture(new TextureKey("Textures/Sky/Bright/BrightSky.dds", false)), true));
- SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
- waterProcessor.setReflectionScene(mainNode);
- // we set the water plane
- Vector3f waterLocation=new Vector3f(0,-6,0);
- waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
- viewPort.addProcessor(waterProcessor);
- // we set wave properties
- waterProcessor.setWaterDepth(50); // transparency of water
- waterProcessor.setDistortionScale(0.1f); // strength of waves
- waterProcessor.setWaveSpeed(0.01f); // speed of waves
- // we define the wave size by setting the size of the texture coordinates
- Quad quad = new Quad(200,200);
- quad.scaleTextureCoordinates(new Vector2f(6f,6f));
- // we create the water geometry from the quad
- Geometry water=new Geometry("water", quad);
- water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
- water.setLocalTranslation(55.9f, -99.2f, 140);
- water.setShadowMode(ShadowMode.Receive);
- water.setMaterial(waterProcessor.getMaterial());
- water.setQueueBucket(Bucket.Transparent);
- rootNode.attachChild(water);
- initCursor();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- @Override
- public void simpleUpdate(float tpf) {
- //TODO: add update code
- handlePlayer(tpf);
- moveCursor();
- }
- @Override
- public void simpleRender(RenderManager rm) {
- //TODO: add render code
- }
- private void setupKeys() {
- inputManager.addMapping("strafeLeft", new KeyTrigger(KeyInput.KEY_Q));
- inputManager.addMapping("strafeRight", new KeyTrigger(KeyInput.KEY_E));
- inputManager.addMapping("turnRight", new KeyTrigger(KeyInput.KEY_D));
- inputManager.addMapping("turnLeft", new KeyTrigger(KeyInput.KEY_A));
- inputManager.addMapping("moveForward", new KeyTrigger(KeyInput.KEY_W));
- inputManager.addMapping("moveBackwards", new KeyTrigger(KeyInput.KEY_S));
- inputManager.addMapping("Jumps", new KeyTrigger(KeyInput.KEY_SPACE));
- inputManager.addListener(this, "strafeLeft");
- inputManager.addListener(this, "strafeRight");
- inputManager.addListener(this, "moveForward");
- inputManager.addListener(this, "moveBackwards");
- inputManager.addListener(this, "Jumps");
- inputManager.addListener(this, "turnRight");
- inputManager.addListener(this, "turnLeft");
- inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
- inputManager.addListener(this, "shoot");
- System.out.println(MouseInput.BUTTON_LEFT);
- }
- /** These are our custom actions triggered by key presses.
- * We do not walk yet, we just keep track of the direction the user pressed. */
- public void onAction(String binding, boolean value, float tpf) {
- if (binding.equals("strafeLeft")) {
- if (value) { left = true; } else { left = false; }
- } else if (binding.equals("strafeRight")) {
- if (value) { right = true; } else { right = false; }
- } else if (binding.equals("turnRight")) {
- if (value) { turnRight = true; } else { turnRight = false; }
- } else if (binding.equals("turnLeft")) {
- if (value) { turnLeft = true; } else { turnLeft = false; }
- } else if (binding.equals("moveForward")) {
- if (value) { up = true; } else { up = false; }
- } else if (binding.equals("moveBackwards")) {
- if (value) { down = true; } else { down = false; }
- } else if (binding.equals("Jumps")) {
- preJumpDirection = cam.getDirection().clone().multLocal(0.6f);
- preJumpDirectionLeft = cam.getLeft().clone().multLocal(0.4f);
- playerGeom.jump();
- } else if(binding.equals("shoot")) {
- if (value) { shoot = true; } else { shoot = false; }
- }
- }
- private void handlePlayer(float tpf) {
- Vector3f camDir = null;
- Vector3f camLeft = null;
- // Fix the mid-air mouse controll issue!
- if(player.onGround()) {
- camDir = cam.getDirection().clone().multLocal(0.6f);
- camLeft = cam.getLeft().clone().multLocal(0.4f);
- } else {
- camDir = preJumpDirection;
- camLeft = preJumpDirectionLeft;
- }
- walkDirection.set(0, 0, 0);
- if (left) { walkDirection.addLocal(camLeft); }
- if (right) { walkDirection.addLocal(camLeft.negate()); }
- if (up) { walkDirection.addLocal(camDir); }
- if (down) { walkDirection.addLocal(camDir.negate()); }
- if (shoot) { fog.setFogDensity(0); }
- player.setWalkDirection(walkDirection);
- if (turnLeft) { playerGeom.turnLeft(tpf); }
- if (turnRight) { playerGeom.turnRight(tpf); }
- cam.setLocation(player.getLocalTranslation());
- }
- protected void initCursor() {
- guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
- ch = new BitmapText(guiFont, false);
- ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
- ch.setText("> + <");
- ch.setColor(ColorRGBA.Orange);
- ch.setLocalTranslation(
- settings.getWidth() / 2 -guiFont.getCharSet().getRenderedSize()/3*2,
- settings.getHeight() / 2 + ch.getLineHeight()/2, 0);
- guiNode.attachChild(ch);
- this.chaseCam.setUseCursor(false);
- }
- protected void moveCursor() {
- Vector2f cursorPosition = inputManager.getCursorPosition();
- ch.setLocalTranslation(
- cursorPosition.x -guiFont.getCharSet().getRenderedSize()/3*2,
- cursorPosition.y + ch.getLineHeight()/2, 0);
- }
- }
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package game;
- import com.jme3.asset.AssetManager;
- import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
- import com.jme3.bullet.nodes.PhysicsCharacterNode;
- import com.jme3.scene.Node;
- import com.jme3.scene.Spatial;
- /**
- *
- * @author krol
- */
- public class LifeFormObject extends PhysicsCharacterNode {
- Spatial model;
- float step;
- Node floorNode;
- AssetManager assetManager;
- String name;
- public LifeFormObject(String name, String objectClass, float step, Node floorNode, AssetManager assetManager) {
- super(new CapsuleCollisionShape(5f,5f,1), 1f);
- this.step = step;
- this.floorNode = floorNode;
- this.assetManager = assetManager;
- this.name = name;
- Spatial myModel = this.assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
- //this.setCollisionShape(CollisionShapeFactory.createBoxCompoundShape((Node)myModel));
- //this.setMass(1f);
- this.setName(name);
- this.updateGeometricState();
- if (objectClass.equals("Sinbad")) {
- setModel(myModel);
- }
- }
- public LifeFormObject(Spatial model) {
- }
- public void setModel(Spatial model) {
- if(this.model != null) {
- this.detachChild((Node)model);
- }
- this.model = model;
- this.attachChild((Node)model);
- }
- public void update(float tpf) {
- System.out.println("Pos: " + this.model.getLocalTranslation());
- }
- public Spatial getModel() {
- return this.model;
- }
- }
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package game.camera;
- import com.jme3.export.InputCapsule;
- import com.jme3.export.JmeExporter;
- import com.jme3.export.JmeImporter;
- import com.jme3.export.OutputCapsule;
- import com.jme3.input.InputManager;
- import com.jme3.input.MouseInput;
- import com.jme3.input.controls.ActionListener;
- import com.jme3.input.controls.AnalogListener;
- import com.jme3.input.controls.MouseAxisTrigger;
- import com.jme3.input.controls.MouseButtonTrigger;
- import com.jme3.math.FastMath;
- import com.jme3.math.Vector3f;
- import com.jme3.renderer.Camera;
- import com.jme3.renderer.RenderManager;
- import com.jme3.renderer.ViewPort;
- import com.jme3.scene.Spatial;
- import com.jme3.scene.control.Control;
- import java.io.IOException;
- /**
- *
- * @author krol
- */
- public class ThirdpersonCamera implements ActionListener, AnalogListener, Control {
- private Spatial target = null;
- private float minVerticalRotation = 0.00f;
- private float maxVerticalRotation = FastMath.PI / 2;
- private float minDistance = 1.0f;
- private float maxDistance = 40.0f;
- private float distance = 20;
- private float zoomSpeed = 2f;
- private float rotationSpeed = 1.0f;
- private float rotation = 0;
- private float trailingRotationInertia = 0.05f;
- private float zoomSensitivity = 5f;
- private float rotationSensitivity = 5f;
- private float chasingSensitivity = 5f;
- private float trailingSensitivity = 0.5f;
- private float vRotation = FastMath.PI / 6;
- private boolean smoothMotion = false;
- private boolean trailingEnabled = true;
- private float rotationLerpFactor = 0;
- private float trailingLerpFactor = 0;
- private boolean rotating = false;
- private boolean vRotating = false;
- private float targetRotation = rotation;
- private InputManager inputManager;
- private Vector3f initialUpVec;
- private float targetVRotation = vRotation;
- private float vRotationLerpFactor = 0;
- private float targetDistance = distance;
- private float distanceLerpFactor = 0;
- private boolean zooming = false;
- private boolean trailing = false;
- private boolean chasing = false;
- private boolean canRotate;
- private float offsetDistance = 0.002f;
- private Vector3f prevPos;
- private boolean targetMoves = false;
- private boolean enabled = true;
- private Camera cam = null;
- private Vector3f targetDir;
- private float previousTargetRotation;
- private Vector3f pos;
- private Boolean invertMouse = false;
- private Boolean useLeftMouseButtonToRotate = true, useRightMouseButtonToRotate = true, useCursor = true;
- public ThirdpersonCamera( Camera cam, final Spatial target ) {
- this.target = target;
- this.cam = cam;
- initialUpVec = cam.getUp().clone();
- computePosition();
- target.addControl(this);
- prevPos = new Vector3f(target.getWorldTranslation());
- cam.setLocation(pos);
- }
- public ThirdpersonCamera( Camera cam, final Spatial target, InputManager inputManager ) {
- this(cam, target);
- registerWithInput(inputManager);
- }
- public void onAction(String name, boolean keyPressed, float tpf) {
- if ((name.equals("mouseButtonLeft") || name.equals("mouseButtonRight")) && enabled) {
- if (keyPressed) {
- if(name.equals("mouseButtonLeft") && this.useLeftMouseButtonToRotate) {
- canRotate = true;
- } else if (name.equals("mouseButtonRight") && this.useRightMouseButtonToRotate) {
- canRotate = true;
- } else {
- canRotate = false;
- }
- } else {
- canRotate = false;
- }
- }
- }
- boolean zoomin;
- public void onAnalog(String name, float value, float tpf) {
- if (name.equals("mouseLeft")) {
- rotateCamera(-value);
- } else if (name.equals("mouseRight")) {
- rotateCamera(value);
- } else if (name.equals("Up")) {
- vRotateCamera(value);
- } else if (name.equals("Down")) {
- vRotateCamera(-value);
- } else if (name.equals("ZoomIn")) {
- zoomCamera(value);
- if (zoomin == false) {
- distanceLerpFactor = 0;
- }
- zoomin = true;
- } else if (name.equals("ZoomOut")) {
- zoomCamera(-value);
- if (zoomin == true) {
- distanceLerpFactor = 0;
- }
- zoomin = false;
- }
- }
- /**
- * Registers inputs with the input manager
- * @param inputManager
- */
- public void registerWithInput(InputManager inputManager) {
- String[] inputs = {"mouseButtonRight", "mouseButtonLeft", "Down", "Up", "mouseLeft", "mouseRight", "ZoomIn", "ZoomOut"};
- this.inputManager = inputManager;
- inputManager.addMapping("Down", new MouseAxisTrigger(1, true));
- inputManager.addMapping("Up", new MouseAxisTrigger(1, false));
- inputManager.addMapping("ZoomIn", new MouseAxisTrigger(2, true));
- inputManager.addMapping("ZoomOut", new MouseAxisTrigger(2, false));
- inputManager.addMapping("mouseLeft", new MouseAxisTrigger(0, true));
- inputManager.addMapping("mouseRight", new MouseAxisTrigger(0, false));
- inputManager.addMapping("mouseButtonRight", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
- inputManager.addMapping("mouseButtonLeft", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
- inputManager.addListener(this, inputs);
- }
- private void computePosition() {
- float hDistance = (distance) * FastMath.sin((FastMath.PI / 2) - vRotation);
- pos = new Vector3f(hDistance * FastMath.cos(rotation), (distance) * FastMath.sin(vRotation), hDistance * FastMath.sin(rotation));
- pos = pos.add(target.getWorldTranslation());
- }
- //rotate the camera around the target on the horizontal plane
- private void rotateCamera(float value) {
- if (!canRotate || !enabled) {
- return;
- }
- rotating = true;
- targetRotation += value * rotationSpeed;
- }
- //move the camera toward or away the target
- private void zoomCamera(float value) {
- if (!enabled) {
- return;
- }
- zooming = true;
- targetDistance += value * zoomSpeed;
- if (targetDistance > maxDistance) {
- targetDistance = maxDistance;
- }
- if (targetDistance < minDistance) {
- targetDistance = minDistance;
- }
- if ((targetVRotation < minVerticalRotation) && (targetDistance > (minDistance + 1.0f))) {
- targetVRotation = minVerticalRotation;
- }
- }
- //rotate the camera around the target on the vertical plane
- private void vRotateCamera(float value) {
- if (!canRotate || !enabled) {
- return;
- }
- vRotating = true;
- // this negated "value" makes the camera not to be inverted!
- if (!this.invertMouse) {
- targetVRotation += -value * rotationSpeed;
- } else {
- targetVRotation += value * rotationSpeed;
- }
- if (targetVRotation > maxVerticalRotation) {
- targetVRotation = maxVerticalRotation;
- }
- if ((targetVRotation < minVerticalRotation) && (targetDistance > (minDistance + 1.0f))) {
- targetVRotation = minVerticalRotation;
- }
- }
- /**
- * Updates the camera, should only be called internally
- */
- protected void updateCamera(float tpf) {
- if (enabled) {
- if (smoothMotion) {
- //computation of target direction
- targetDir = target.getWorldTranslation().subtract(prevPos);
- float dist = targetDir.length();
- //Low pass filtering on the target postition to avoid shaking when physics are enabled.
- if (offsetDistance < dist) {
- //target moves, start chasing.
- chasing = true;
- //target moves, start trailing if it has to.
- if (trailingEnabled) {
- trailing = true;
- }
- //target moves...
- targetMoves = true;
- } else {
- //if target was moving, we compute a slight offset in rotation to avoid a rought stop of the cam
- //We do not if the player is rotationg the cam
- if (targetMoves && !canRotate) {
- if (targetRotation - rotation > trailingRotationInertia) {
- targetRotation = rotation + trailingRotationInertia;
- } else if (targetRotation - rotation < -trailingRotationInertia) {
- targetRotation = rotation - trailingRotationInertia;
- }
- }
- //Target stops
- targetMoves = false;
- }
- //the user is rotating the cam by dragging the mouse
- if (canRotate) {
- //reseting the trailing lerp factor
- trailingLerpFactor = 0;
- //stop trailing user has the control
- trailing = false;
- }
- if (trailingEnabled && trailing) {
- if (targetMoves) {
- //computation if the inverted direction of the target
- Vector3f a = targetDir.negate().normalizeLocal();
- //the x unit vector
- Vector3f b = Vector3f.UNIT_X;
- //2d is good enough
- a.y = 0;
- //computation of the rotation angle between the x axis and the trail
- if (targetDir.z > 0) {
- targetRotation = FastMath.TWO_PI - FastMath.acos(a.dot(b));
- } else {
- targetRotation = FastMath.acos(a.dot(b));
- }
- if (targetRotation - rotation > FastMath.PI || targetRotation - rotation < -FastMath.PI) {
- targetRotation -= FastMath.TWO_PI;
- }
- //if there is an important change in the direction while trailing reset of the lerp factor to avoid jumpy movements
- if (targetRotation != previousTargetRotation && FastMath.abs(targetRotation - previousTargetRotation) > FastMath.PI / 8) {
- trailingLerpFactor = 0;
- }
- previousTargetRotation = targetRotation;
- }
- //computing lerp factor
- trailingLerpFactor = Math.min(trailingLerpFactor + tpf * tpf * trailingSensitivity, 1);
- //computing rotation by linear interpolation
- rotation = FastMath.interpolateLinear(trailingLerpFactor, rotation, targetRotation);
- //if the rotation is near the target rotation we're good, that's over
- if (targetRotation + 0.01f >= rotation && targetRotation - 0.01f <= rotation) {
- trailing = false;
- trailingLerpFactor = 0;
- }
- }
- //linear interpolation of the distance while chasing
- if (chasing) {
- distance = target.getWorldTranslation().subtract(cam.getLocation()).length();
- distanceLerpFactor = Math.min(distanceLerpFactor + (tpf * tpf * chasingSensitivity * 0.05f), 1);
- distance = FastMath.interpolateLinear(distanceLerpFactor, distance, targetDistance);
- if (targetDistance + 0.01f >= distance && targetDistance - 0.01f <= distance) {
- distanceLerpFactor = 0;
- chasing = false;
- }
- }
- //linear interpolation of the distance while zooming
- if (zooming) {
- distanceLerpFactor = Math.min(distanceLerpFactor + (tpf * tpf * zoomSensitivity), 1);
- distance = FastMath.interpolateLinear(distanceLerpFactor, distance, targetDistance);
- if (targetDistance + 0.1f >= distance && targetDistance - 0.1f <= distance) {
- zooming = false;
- distanceLerpFactor = 0;
- }
- }
- //linear interpolation of the rotation while rotating horizontally
- if (rotating) {
- rotationLerpFactor = Math.min(rotationLerpFactor + tpf * tpf * rotationSensitivity, 1);
- rotation = FastMath.interpolateLinear(rotationLerpFactor, rotation, targetRotation);
- if (targetRotation + 0.01f >= rotation && targetRotation - 0.01f <= rotation) {
- rotating = false;
- rotationLerpFactor = 0;
- }
- }
- //linear interpolation of the rotation while rotating vertically
- if (vRotating) {
- vRotationLerpFactor = Math.min(vRotationLerpFactor + tpf * tpf * rotationSensitivity, 1);
- vRotation = FastMath.interpolateLinear(vRotationLerpFactor, vRotation, targetVRotation);
- if (targetVRotation + 0.01f >= vRotation && targetVRotation - 0.01f <= vRotation) {
- vRotating = false;
- vRotationLerpFactor = 0;
- }
- }
- //computing the position
- computePosition();
- //setting the position at last
- cam.setLocation(pos);
- } else {
- //easy no smooth motion
- vRotation = targetVRotation;
- rotation = targetRotation;
- distance = targetDistance;
- computePosition();
- cam.setLocation(pos);
- }
- //keeping track on the previous position of the target
- prevPos = new Vector3f(target.getWorldTranslation());
- //the cam looks at the target
- cam.lookAt(target.getWorldTranslation(), initialUpVec);
- }
- inputManager.setCursorVisible(this.useCursor);
- }
- /**
- * Return the enabled/disabled state of the camera
- * @return true if the camera is enabled
- */
- public boolean isEnabled() {
- return enabled;
- }
- /**
- * Enable or disable the camera
- * @param enabled true to enable
- */
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- if (!enabled) {
- canRotate = false; // reset this flag in-case it was on before
- }
- }
- /**
- * Returns the max zoom distance of the camera (default is 40)
- * @return maxDistance
- */
- public float getMaxDistance() {
- return maxDistance;
- }
- /**
- * Sets the max zoom distance of the camera (default is 40)
- * @param maxDistance
- */
- public void setMaxDistance(float maxDistance) {
- this.maxDistance = maxDistance;
- }
- /**
- * Returns the min zoom distance of the camera (default is 1)
- * @return minDistance
- */
- public float getMinDistance() {
- return minDistance;
- }
- /**
- * Sets the min zoom distance of the camera (default is 1)
- * @return minDistance
- */
- public void setMinDistance(float minDistance) {
- this.minDistance = minDistance;
- }
- /**
- * clone this camera for a spatial
- * @param spatial
- * @return
- */
- public Control cloneForSpatial(Spatial spatial) {
- ThirdpersonCamera cc = new ThirdpersonCamera(cam, spatial, inputManager);
- cc.setMaxDistance(getMaxDistance());
- cc.setMinDistance(getMinDistance());
- return cc;
- }
- /**
- * Sets the spacial for the camera control, should only be used internally
- * @param spatial
- */
- public void setSpatial(Spatial spatial) {
- target = spatial;
- }
- /**
- * update the camera control, should on ly be used internally
- * @param tpf
- */
- public void update(float tpf) {
- updateCamera(tpf);
- }
- /**
- * renders the camera control, should on ly be used internally
- * @param rm
- * @param vp
- */
- public void render(RenderManager rm, ViewPort vp) {
- //nothing to render
- }
- /**
- * Write the camera
- * @param ex the exporter
- * @throws IOException
- */
- public void write(JmeExporter ex) throws IOException {
- OutputCapsule capsule = ex.getCapsule(this);
- capsule.write(maxDistance, "maxDistance", 40);
- capsule.write(minDistance, "minDistance", 1);
- }
- /**
- * Read the camera
- * @param im
- * @throws IOException
- */
- public void read(JmeImporter im) throws IOException {
- InputCapsule ic = im.getCapsule(this);
- maxDistance = ic.readFloat("maxDistance", 40);
- minDistance = ic.readFloat("minDistance", 1);
- }
- /**
- *
- * @deprecated use getMaxVerticalRotation()
- */
- @Deprecated
- public float getMaxHeight() {
- return getMaxVerticalRotation();
- }
- /**
- *
- * @deprecated use setMaxVerticalRotation()
- */
- @Deprecated
- public void setMaxHeight(float maxHeight) {
- setMaxVerticalRotation(maxHeight);
- }
- /**
- *
- * @deprecated use getMinVerticalRotation()
- */
- @Deprecated
- public float getMinHeight() {
- return getMinVerticalRotation();
- }
- /**
- *
- * @deprecated use setMinVerticalRotation()
- */
- @Deprecated
- public void setMinHeight(float minHeight) {
- setMinVerticalRotation(minHeight);
- }
- /**
- * returns the maximal vertical rotation angle of the camera around the target
- * @return
- */
- public float getMaxVerticalRotation() {
- return maxVerticalRotation;
- }
- /**
- * sets the maximal vertical rotation angle of the camera around the target default is Pi/2;
- * @param maxVerticalRotation
- */
- public void setMaxVerticalRotation(float maxVerticalRotation) {
- this.maxVerticalRotation = maxVerticalRotation;
- }
- /**
- * returns the minimal vertical rotation angle of the camera around the target
- * @return
- */
- public float getMinVerticalRotation() {
- return minVerticalRotation;
- }
- /**
- * sets the minimal vertical rotation angle of the camera around the target default is 0;
- * @param minHeight
- */
- public void setMinVerticalRotation(float minHeight) {
- this.minVerticalRotation = minHeight;
- }
- /**
- * returns true is smmoth motion is enabled for this chase camera
- * @return
- */
- public boolean isSmoothMotion() {
- return smoothMotion;
- }
- /**
- * Enables smooth motion for this chase camera
- * @param smoothMotion
- */
- public void setSmoothMotion(boolean smoothMotion) {
- this.smoothMotion = smoothMotion;
- }
- /**
- * returns the chasing sensitivity
- * @return
- */
- public float getChasingSensitivity() {
- return chasingSensitivity;
- }
- /**
- * Sets the chasing sensitivity, the lower the value the slower the camera will go in the trail of the target when it moves
- * @param chasingSensitivity
- */
- public void setChasingSensitivity(float chasingSensitivity) {
- this.chasingSensitivity = chasingSensitivity;
- }
- /**
- * Returns the rotation sensitivity
- * @return
- */
- public float getRotationSensitivity() {
- return rotationSensitivity;
- }
- /**
- * Sets the rotation sensitivity, the lower the value the slower the camera will rotates around the target when draging with the mouse
- * default is 5
- * @param rotationSensitivity
- */
- public void setRotationSensitivity(float rotationSensitivity) {
- this.rotationSensitivity = rotationSensitivity;
- }
- /**
- * returns true if the trailing is enabled
- * @return
- */
- public boolean isTrailingEnabled() {
- return trailingEnabled;
- }
- /**
- * Enable the camera trailing : The camera smoothly go in the targets trail when it moves.
- * @param trailingEnabled
- */
- public void setTrailingEnabled(boolean trailingEnabled) {
- this.trailingEnabled = trailingEnabled;
- }
- /**
- * returns the trailing rotation inertia
- * @return
- */
- public float getTrailingRotationInertia() {
- return trailingRotationInertia;
- }
- /**
- * Sets the trailing rotation inertia : default is 0.1. This prevent the camera to roughtly stop when the target stops moving
- * before the camera reached the trail position.
- * @param trailingRotationInertia
- */
- public void setTrailingRotationInertia(float trailingRotationInertia) {
- this.trailingRotationInertia = trailingRotationInertia;
- }
- /**
- * returns the trailing sensitivity
- * @return
- */
- public float getTrailingSensitivity() {
- return trailingSensitivity;
- }
- /**
- * Sets the trailing sensitivity, the lower the value, the slower the camera will go in the target trail when it moves.
- * default is 0.5;
- * @param trailingSensitivity
- */
- public void setTrailingSensitivity(float trailingSensitivity) {
- this.trailingSensitivity = trailingSensitivity;
- }
- /**
- * returns the zoom sensitivity
- * @return
- */
- public float getZoomSensitivity() {
- return zoomSensitivity;
- }
- /**
- * Sets the zoom sensitivity, the lower the value, the slower the camera will zoom in and out.
- * default is 5.
- * @param zoomSensitivity
- */
- public void setZoomSensitivity(float zoomSensitivity) {
- this.zoomSensitivity = zoomSensitivity;
- }
- /**
- * Sets the default distance at start of applicaiton
- * @param defaultDistance
- */
- public void setDefaultDistance(float defaultDistance) {
- distance = defaultDistance;
- targetDistance = distance;
- }
- /**
- * sets the default horizontal rotation of the camera at start of the application
- * @param angle
- */
- public void setDefaultHorizontalRotation(float angle) {
- rotation = angle;
- targetRotation = angle;
- }
- /**
- * sets the default vertical rotation of the camera at start of the application
- * @param angle
- */
- public void setDefaultVerticalRotation(float angle) {
- vRotation = angle;
- targetVRotation = angle;
- }
- public void setInvertedMouse(boolean invert) {
- this.invertMouse = invert;
- registerWithInput(this.inputManager);
- }
- public void setUseLeftMouseToRotate(Boolean use) {
- this.useLeftMouseButtonToRotate = use;
- registerWithInput(this.inputManager);
- }
- public void setUseRightMouseToRotate(Boolean use) {
- this.useRightMouseButtonToRotate = use;
- registerWithInput(this.inputManager);
- }
- public void setUseCursor(Boolean use) {
- this.useCursor = use;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement