Advertisement
Guest User

Untitled

a guest
Jan 8th, 2011
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 39.57 KB | None | 0 0
  1. package mygame;
  2.  
  3. import com.jme3.app.SimpleApplication;
  4. import com.jme3.bullet.BulletAppState;
  5. import com.jme3.bullet.collision.shapes.HeightfieldCollisionShape;
  6. import com.jme3.bullet.collision.shapes.SphereCollisionShape;
  7. import com.jme3.bullet.nodes.PhysicsCharacterNode;
  8. import com.jme3.bullet.nodes.PhysicsNode;
  9. import com.jme3.font.BitmapText;
  10. import com.jme3.input.KeyInput;
  11. import com.jme3.input.MouseInput;
  12. import com.jme3.input.controls.ActionListener;
  13. import com.jme3.input.controls.KeyTrigger;
  14. import com.jme3.input.controls.MouseButtonTrigger;
  15. import com.jme3.light.DirectionalLight;
  16. import com.jme3.material.Material;
  17. import com.jme3.math.ColorRGBA;
  18. import com.jme3.math.FastMath;
  19. import com.jme3.math.Plane;
  20. import com.jme3.math.Quaternion;
  21. import com.jme3.math.Vector2f;
  22. import com.jme3.math.Vector3f;
  23. import com.jme3.post.FilterPostProcessor;
  24. import com.jme3.post.filters.FogFilter;
  25. import com.jme3.renderer.Camera;
  26. import com.jme3.renderer.RenderManager;
  27. import com.jme3.renderer.queue.RenderQueue.Bucket;
  28. import com.jme3.renderer.queue.RenderQueue.ShadowMode;
  29. import com.jme3.scene.Geometry;
  30. import com.jme3.scene.Node;
  31. import com.jme3.scene.shape.Quad;
  32. import com.jme3.scene.shape.Sphere;
  33. import com.jme3.terrain.geomipmap.TerrainLodControl;
  34. import com.jme3.terrain.geomipmap.TerrainQuad;
  35. import com.jme3.terrain.heightmap.AbstractHeightMap;
  36. import com.jme3.terrain.heightmap.ImageBasedHeightMap;
  37. import com.jme3.texture.Texture;
  38. import com.jme3.texture.Texture.WrapMode;
  39. import com.jme3.util.TangentBinormalGenerator;
  40. import com.jme3.water.SimpleWaterProcessor;
  41. import game.LifeFormObject;
  42. import game.camera.ThirdpersonCamera;
  43. import game.player.Player;
  44. import java.util.ArrayList;
  45. import java.util.List;
  46. import jme3tools.converters.ImageToAwt;
  47.  
  48.  
  49. /**
  50.  * test
  51.  * @author normenhansen
  52.  */
  53. public class Main extends SimpleApplication implements ActionListener {
  54.  
  55.     private Player playerGeom;
  56.     private PhysicsCharacterNode player;
  57.     private BulletAppState bulletAppState;
  58.     private TerrainQuad terrain;
  59.  
  60.     Material mat_terrain;
  61.  
  62.  
  63.     private Vector3f walkDirection = new Vector3f();
  64.     private boolean left = false, right = false, turnLeft = false, turnRight = false, up = false, down = false, shoot = false;
  65.  
  66.     private Node mainNode;
  67.  
  68.     private FilterPostProcessor fpp;
  69.     private boolean enabled=true;
  70.     private FogFilter fog;
  71.  
  72.     private Vector3f preJumpDirection = new Vector3f();
  73.     private Vector3f preJumpDirectionLeft = new Vector3f();
  74.     private BitmapText ch;
  75.     private BitmapText npcMark;
  76.     private LifeFormObject npc;
  77.     private ThirdpersonCamera chaseCam;
  78.  
  79.     public static void main(String[] args) {
  80.       Main app = new Main();
  81.       app.start();
  82.     }
  83.  
  84.     @Override
  85.     public void simpleInitApp() {
  86.  
  87.       try {
  88.  
  89.         mainNode = new Node();
  90.         bulletAppState = new BulletAppState();
  91.         stateManager.attach(bulletAppState);
  92.        
  93.         DirectionalLight dl = new DirectionalLight();
  94.         dl.setColor(ColorRGBA.White.clone().multLocal(2)); // bright white light
  95.         dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalize());
  96.         rootNode.addLight(dl);
  97.        
  98.         // flyCam.setMoveSpeed(50);
  99.         // flyCam.setDragToRotate(true);
  100.         flyCam.setEnabled(false);
  101.  
  102.         fpp=new FilterPostProcessor(assetManager);
  103.         fog=new FogFilter();
  104.         fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f));
  105.         fog.setFogDistance(170);
  106.         fog.setFogDensity(0.8f);
  107.         fpp.addFilter(fog);
  108.         viewPort.addProcessor(fpp);
  109.  
  110.         setupKeys();
  111.        
  112.  
  113.         /** 1. Create terrain material and load four textures into it. */
  114.         mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
  115.  
  116.         /** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */
  117.         mat_terrain.setTexture("m_Alpha",
  118.                    assetManager.loadTexture("MatDefs/HeightMaps/mountains512-alpha.png"));
  119.  
  120.         /** 1.2) Add GRASS texture into the red layer (m_Tex1). */
  121.         Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
  122.         grass.setWrap(WrapMode.Repeat);
  123.         mat_terrain.setTexture("m_Tex1", grass);
  124.         mat_terrain.setFloat("m_Tex1Scale", 64f);
  125.  
  126.         /** 1.3) Add DIRT texture into the green layer (m_Tex2) */
  127.         Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
  128.         dirt.setWrap(WrapMode.Repeat);
  129.         mat_terrain.setTexture("m_Tex2", dirt);
  130.         mat_terrain.setFloat("m_Tex2Scale", 32f);
  131.  
  132.         /** 1.4) Add ROAD texture into the blue layer (m_Tex3) */
  133.         Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
  134.         rock.setWrap(WrapMode.Repeat);
  135.         mat_terrain.setTexture("m_Tex3", rock);
  136.         mat_terrain.setFloat("m_Tex3Scale", 128f);
  137.  
  138.         playerGeom = new Player("Hero", assetManager);
  139.  
  140.         player = playerGeom.getPhysicsNode();
  141.        
  142.  
  143.         chaseCam = new ThirdpersonCamera(cam, player, inputManager);
  144.         chaseCam.setUseCursor(true);
  145.         chaseCam.setDefaultDistance(40);
  146.         chaseCam.setMaxDistance(60);
  147.         chaseCam.setRotationSensitivity(3f);
  148.         chaseCam.setTrailingEnabled(true);
  149.         chaseCam.setUseLeftMouseToRotate(false);
  150.  
  151.  
  152.         /** Bumpy rock with shiny light effect. Uses Texture from jme3-test-data library! Needs light source! */
  153.         Sphere rock2 = new Sphere(32,32, 2f);
  154.         Geometry shiny_rock = new Geometry("Shiny rock", rock2);
  155.         rock2.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres
  156.         TangentBinormalGenerator.generate(rock2);           // for lighting effect
  157.         Material mat_lit = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
  158.         mat_lit.setTexture("m_DiffuseMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond.png"));
  159.         mat_lit.setTexture("m_NormalMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png"));
  160.         mat_lit.setFloat("m_Shininess", 5f); // [0,128]
  161.         shiny_rock.setMaterial(mat_lit);
  162.  
  163.         SphereCollisionShape rockShape = new SphereCollisionShape(2f);
  164.         PhysicsNode rockNode = new PhysicsNode(shiny_rock, rockShape, 6.0f);
  165.         rockNode.setLocalTranslation(220.59f,-94.49f,83.24f);
  166.        
  167.         rockNode.setShadowMode(ShadowMode.CastAndReceive);
  168.  
  169.         rootNode.attachChild(rockNode);
  170.         bulletAppState.getPhysicsSpace().add(rockNode);
  171.  
  172.  
  173.         npc = new LifeFormObject("wewt", "Sinbad", 0.5f, mainNode, assetManager);
  174.         npc.setLocalTranslation(new Vector3f(220.59f,-94.49f,83.24f));
  175.  
  176.  
  177.         mainNode.attachChild(npc);
  178.         // mainNode.updateGeometricState();
  179.         bulletAppState.getPhysicsSpace().add(npc);
  180.         /** 2. Create the height map */
  181.         AbstractHeightMap heightmap = null;
  182.         Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
  183.         heightmap = new ImageBasedHeightMap(
  184.           ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));
  185.         heightmap.load();
  186.  
  187.  
  188.         /** 3. We have prepared material and heightmap. Now we create the actual terrain:
  189.          * 3.1) We create a TerrainQuad and name it "my terrain".
  190.          * 3.2) A good value for terrain tiles is 64x64 -- so we supply 64+1=65.
  191.          * 3.3) We prepared a heightmap of size 512x512 -- so we supply 512+1=513.
  192.          * 3.4) As LOD step scale we supply Vector3f(1,1,1).
  193.          * 3.5) At last, we supply the prepared heightmap itself.
  194.          */
  195.         terrain = new TerrainQuad("my terrain", 65, 513, heightmap.getHeightMap());
  196.        
  197.         terrain.setShadowMode(ShadowMode.CastAndReceive);
  198.  
  199.         /** 4. We give the terrain its material, position & scale it, and attach it. */
  200.         terrain.setMaterial(mat_terrain);
  201.  
  202.         HeightfieldCollisionShape terrainCollisionShape
  203.                 = new HeightfieldCollisionShape(terrain.getHeightMap());
  204.         PhysicsNode terrainNode = new PhysicsNode(terrain, terrainCollisionShape, 0);
  205.         terrainNode.setLocalTranslation(0, -100, 0);
  206.         // terrainNode.setLocalScale(terrain.getLocalScale());
  207.  
  208.  
  209.         mainNode.attachChild(terrainNode);
  210.         mainNode.attachChild(player);
  211.        
  212.         rootNode.attachChild(mainNode);
  213.        
  214.         bulletAppState.getPhysicsSpace().add(terrainNode);
  215.         bulletAppState.getPhysicsSpace().add(player);
  216.  
  217.  
  218.         viewPort.getCamera().setFrustumFar(150f);
  219.  
  220.         /** 5. The LOD (level of detail) depends on were the camera is: */
  221.         List<Camera> cameras = new ArrayList<Camera>();
  222.         cameras.add(getCamera());
  223.         TerrainLodControl control = new TerrainLodControl(terrain, cameras);
  224.         terrain.addControl(control);
  225.  
  226.         // mainNode.attachChild(SkyFactory.createSky(assetManager, assetManager.loadTexture(new TextureKey("Textures/Sky/Bright/BrightSky.dds", false)), true));
  227.  
  228.  
  229.         SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
  230.         waterProcessor.setReflectionScene(mainNode);
  231.  
  232.         // we set the water plane
  233.         Vector3f waterLocation=new Vector3f(0,-6,0);
  234.         waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
  235.         viewPort.addProcessor(waterProcessor);
  236.         // we set wave properties
  237.         waterProcessor.setWaterDepth(50);         // transparency of water
  238.         waterProcessor.setDistortionScale(0.1f); // strength of waves
  239.         waterProcessor.setWaveSpeed(0.01f);       // speed of waves
  240.        
  241.  
  242.         // we define the wave size by setting the size of the texture coordinates
  243.         Quad quad = new Quad(200,200);
  244.         quad.scaleTextureCoordinates(new Vector2f(6f,6f));
  245.  
  246.         // we create the water geometry from the quad
  247.         Geometry water=new Geometry("water", quad);
  248.         water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
  249.         water.setLocalTranslation(55.9f, -99.2f, 140);
  250.         water.setShadowMode(ShadowMode.Receive);
  251.         water.setMaterial(waterProcessor.getMaterial());
  252.         water.setQueueBucket(Bucket.Transparent);
  253.  
  254.         rootNode.attachChild(water);
  255.  
  256.         initCursor();
  257.  
  258.       } catch (Exception e) {
  259.         e.printStackTrace();
  260.       }
  261.     }
  262.  
  263.     @Override
  264.     public void simpleUpdate(float tpf) {
  265.       //TODO: add update code
  266.       handlePlayer(tpf);
  267.       moveCursor();
  268.     }
  269.  
  270.     @Override
  271.     public void simpleRender(RenderManager rm) {
  272.         //TODO: add render code
  273.     }
  274.  
  275.     private void setupKeys() {
  276.       inputManager.addMapping("strafeLeft",  new KeyTrigger(KeyInput.KEY_Q));
  277.       inputManager.addMapping("strafeRight", new KeyTrigger(KeyInput.KEY_E));
  278.       inputManager.addMapping("turnRight", new KeyTrigger(KeyInput.KEY_D));
  279.       inputManager.addMapping("turnLeft", new KeyTrigger(KeyInput.KEY_A));
  280.       inputManager.addMapping("moveForward",    new KeyTrigger(KeyInput.KEY_W));
  281.       inputManager.addMapping("moveBackwards",  new KeyTrigger(KeyInput.KEY_S));
  282.       inputManager.addMapping("Jumps",  new KeyTrigger(KeyInput.KEY_SPACE));
  283.       inputManager.addListener(this, "strafeLeft");
  284.       inputManager.addListener(this, "strafeRight");
  285.       inputManager.addListener(this, "moveForward");
  286.       inputManager.addListener(this, "moveBackwards");
  287.       inputManager.addListener(this, "Jumps");
  288.       inputManager.addListener(this, "turnRight");
  289.       inputManager.addListener(this, "turnLeft");
  290.       inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  291.       inputManager.addListener(this, "shoot");
  292.       System.out.println(MouseInput.BUTTON_LEFT);
  293.     }
  294.  
  295.         /** These are our custom actions triggered by key presses.
  296.      * We do not walk yet, we just keep track of the direction the user pressed. */
  297.     public void onAction(String binding, boolean value, float tpf) {
  298.       if (binding.equals("strafeLeft")) {
  299.         if (value) { left = true; }  else { left = false; }
  300.       } else if (binding.equals("strafeRight")) {
  301.         if (value) { right = true; } else { right = false; }
  302.       } else if (binding.equals("turnRight")) {
  303.         if (value) { turnRight = true; } else { turnRight = false; }
  304.       } else if (binding.equals("turnLeft")) {
  305.         if (value) { turnLeft = true; } else { turnLeft = false; }
  306.       } else if (binding.equals("moveForward")) {
  307.         if (value) { up = true; }    else { up = false; }
  308.       } else if (binding.equals("moveBackwards")) {
  309.         if (value) { down = true; }  else { down = false; }
  310.       } else if (binding.equals("Jumps")) {
  311.      
  312.         preJumpDirection = cam.getDirection().clone().multLocal(0.6f);
  313.         preJumpDirectionLeft = cam.getLeft().clone().multLocal(0.4f);
  314.        
  315.         playerGeom.jump();
  316.       } else if(binding.equals("shoot")) {
  317.           if (value) { shoot = true; } else { shoot = false; }
  318.       }
  319.     }
  320.  
  321.     private void handlePlayer(float tpf) {
  322.       Vector3f camDir = null;
  323.       Vector3f camLeft = null;
  324.  
  325.       // Fix the mid-air mouse controll issue!
  326.       if(player.onGround()) {
  327.  
  328.         camDir = cam.getDirection().clone().multLocal(0.6f);
  329.         camLeft = cam.getLeft().clone().multLocal(0.4f);
  330.  
  331.       } else {
  332.         camDir = preJumpDirection;
  333.         camLeft = preJumpDirectionLeft;
  334.        
  335.       }
  336.       walkDirection.set(0, 0, 0);
  337.      
  338.       if (left)  { walkDirection.addLocal(camLeft); }
  339.       if (right) { walkDirection.addLocal(camLeft.negate()); }
  340.      
  341.       if (up)    { walkDirection.addLocal(camDir); }
  342.       if (down)  { walkDirection.addLocal(camDir.negate()); }
  343.       if (shoot) { fog.setFogDensity(0); }
  344.      
  345.       player.setWalkDirection(walkDirection);
  346.      
  347.       if (turnLeft) { playerGeom.turnLeft(tpf); }
  348.       if (turnRight) { playerGeom.turnRight(tpf); }
  349.       cam.setLocation(player.getLocalTranslation());
  350.     }
  351.  
  352.     protected void initCursor() {
  353.       guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
  354.       ch = new BitmapText(guiFont, false);
  355.       ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
  356.       ch.setText("> + <");
  357.       ch.setColor(ColorRGBA.Orange);
  358.       ch.setLocalTranslation(
  359.               settings.getWidth() / 2 -guiFont.getCharSet().getRenderedSize()/3*2,
  360.               settings.getHeight() / 2 + ch.getLineHeight()/2, 0);
  361.       guiNode.attachChild(ch);
  362.       this.chaseCam.setUseCursor(false);
  363.     }
  364.  
  365.     protected void moveCursor() {
  366.       Vector2f cursorPosition = inputManager.getCursorPosition();
  367.       ch.setLocalTranslation(
  368.         cursorPosition.x -guiFont.getCharSet().getRenderedSize()/3*2,
  369.         cursorPosition.y + ch.getLineHeight()/2, 0);
  370.     }
  371. }
  372.  
  373.  
  374. /*
  375.  * To change this template, choose Tools | Templates
  376.  * and open the template in the editor.
  377.  */
  378.  
  379. package game;
  380.  
  381. import com.jme3.asset.AssetManager;
  382. import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
  383. import com.jme3.bullet.nodes.PhysicsCharacterNode;
  384. import com.jme3.scene.Node;
  385. import com.jme3.scene.Spatial;
  386.  
  387. /**
  388.  *
  389.  * @author krol
  390.  */
  391. public class LifeFormObject extends PhysicsCharacterNode {
  392.  
  393.   Spatial model;
  394.   float step;
  395.   Node floorNode;
  396.   AssetManager assetManager;
  397.   String name;
  398.  
  399.   public LifeFormObject(String name, String objectClass, float step, Node floorNode, AssetManager assetManager) {
  400.  
  401.     super(new CapsuleCollisionShape(5f,5f,1), 1f);
  402.     this.step = step;
  403.     this.floorNode = floorNode;
  404.     this.assetManager = assetManager;
  405.     this.name = name;
  406.     Spatial myModel = this.assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
  407.  
  408.     //this.setCollisionShape(CollisionShapeFactory.createBoxCompoundShape((Node)myModel));
  409.     //this.setMass(1f);
  410.     this.setName(name);
  411.     this.updateGeometricState();
  412.     if (objectClass.equals("Sinbad")) {
  413.       setModel(myModel);
  414.     }
  415.    
  416.   }
  417.  
  418.   public LifeFormObject(Spatial model) {
  419.    
  420.   }
  421.  
  422.   public void setModel(Spatial model) {
  423.     if(this.model != null) {
  424.       this.detachChild((Node)model);
  425.     }
  426.     this.model = model;
  427.     this.attachChild((Node)model);
  428.   }
  429.  
  430.   public void update(float tpf) {
  431.     System.out.println("Pos: " + this.model.getLocalTranslation());
  432.   }
  433.  
  434.   public Spatial getModel() {
  435.     return this.model;
  436.   }
  437.  
  438. }
  439.  
  440. /*
  441.  * To change this template, choose Tools | Templates
  442.  * and open the template in the editor.
  443.  */
  444.  
  445. package game.camera;
  446.  
  447. import com.jme3.export.InputCapsule;
  448. import com.jme3.export.JmeExporter;
  449. import com.jme3.export.JmeImporter;
  450. import com.jme3.export.OutputCapsule;
  451. import com.jme3.input.InputManager;
  452. import com.jme3.input.MouseInput;
  453. import com.jme3.input.controls.ActionListener;
  454. import com.jme3.input.controls.AnalogListener;
  455. import com.jme3.input.controls.MouseAxisTrigger;
  456. import com.jme3.input.controls.MouseButtonTrigger;
  457. import com.jme3.math.FastMath;
  458. import com.jme3.math.Vector3f;
  459. import com.jme3.renderer.Camera;
  460. import com.jme3.renderer.RenderManager;
  461. import com.jme3.renderer.ViewPort;
  462. import com.jme3.scene.Spatial;
  463. import com.jme3.scene.control.Control;
  464. import java.io.IOException;
  465.  
  466. /**
  467.  *
  468.  * @author krol
  469.  */
  470. public class ThirdpersonCamera implements ActionListener, AnalogListener, Control {
  471.  
  472.   private Spatial target = null;
  473.   private float minVerticalRotation = 0.00f;
  474.   private float maxVerticalRotation = FastMath.PI / 2;
  475.   private float minDistance = 1.0f;
  476.   private float maxDistance = 40.0f;
  477.   private float distance = 20;
  478.   private float zoomSpeed = 2f;
  479.   private float rotationSpeed = 1.0f;
  480.   private float rotation = 0;
  481.   private float trailingRotationInertia = 0.05f;
  482.   private float zoomSensitivity = 5f;
  483.   private float rotationSensitivity = 5f;
  484.   private float chasingSensitivity = 5f;
  485.   private float trailingSensitivity = 0.5f;
  486.   private float vRotation = FastMath.PI / 6;
  487.   private boolean smoothMotion = false;
  488.   private boolean trailingEnabled = true;
  489.   private float rotationLerpFactor = 0;
  490.   private float trailingLerpFactor = 0;
  491.   private boolean rotating = false;
  492.   private boolean vRotating = false;
  493.   private float targetRotation = rotation;
  494.   private InputManager inputManager;
  495.   private Vector3f initialUpVec;
  496.   private float targetVRotation = vRotation;
  497.   private float vRotationLerpFactor = 0;
  498.   private float targetDistance = distance;
  499.   private float distanceLerpFactor = 0;
  500.   private boolean zooming = false;
  501.   private boolean trailing = false;
  502.   private boolean chasing = false;
  503.   private boolean canRotate;
  504.   private float offsetDistance = 0.002f;
  505.   private Vector3f prevPos;
  506.   private boolean targetMoves = false;
  507.   private boolean enabled = true;
  508.   private Camera cam = null;
  509.   private Vector3f targetDir;
  510.   private float previousTargetRotation;
  511.   private Vector3f pos;
  512.   private Boolean invertMouse = false;
  513.   private Boolean useLeftMouseButtonToRotate = true, useRightMouseButtonToRotate = true, useCursor = true;
  514.  
  515.   public ThirdpersonCamera( Camera cam, final Spatial target ) {
  516.     this.target = target;
  517.     this.cam = cam;
  518.     initialUpVec = cam.getUp().clone();
  519.     computePosition();
  520.     target.addControl(this);
  521.     prevPos = new Vector3f(target.getWorldTranslation());
  522.     cam.setLocation(pos);
  523.   }
  524.  
  525.   public ThirdpersonCamera( Camera cam, final Spatial target, InputManager inputManager ) {
  526.     this(cam, target);
  527.     registerWithInput(inputManager);
  528.   }
  529.  
  530.   public void onAction(String name, boolean keyPressed, float tpf) {
  531.         if ((name.equals("mouseButtonLeft") || name.equals("mouseButtonRight")) && enabled) {
  532.             if (keyPressed) {
  533.                 if(name.equals("mouseButtonLeft") && this.useLeftMouseButtonToRotate) {
  534.                   canRotate = true;
  535.                 } else if (name.equals("mouseButtonRight") && this.useRightMouseButtonToRotate) {
  536.                   canRotate = true;
  537.                 } else {
  538.                   canRotate = false;
  539.                 }
  540.             } else {
  541.                 canRotate = false;
  542.             }
  543.         }
  544.  
  545.  
  546.     }
  547.     boolean zoomin;
  548.  
  549.     public void onAnalog(String name, float value, float tpf) {
  550.         if (name.equals("mouseLeft")) {
  551.             rotateCamera(-value);
  552.         } else if (name.equals("mouseRight")) {
  553.             rotateCamera(value);
  554.         } else if (name.equals("Up")) {
  555.             vRotateCamera(value);
  556.         } else if (name.equals("Down")) {
  557.             vRotateCamera(-value);
  558.         } else if (name.equals("ZoomIn")) {
  559.             zoomCamera(value);
  560.             if (zoomin == false) {
  561.                 distanceLerpFactor = 0;
  562.             }
  563.             zoomin = true;
  564.         } else if (name.equals("ZoomOut")) {
  565.             zoomCamera(-value);
  566.             if (zoomin == true) {
  567.                 distanceLerpFactor = 0;
  568.             }
  569.             zoomin = false;
  570.         }
  571.  
  572.     }
  573.  
  574.  
  575.     /**
  576.      * Registers inputs with the input manager
  577.      * @param inputManager
  578.      */
  579.     public void registerWithInput(InputManager inputManager) {
  580.         String[] inputs = {"mouseButtonRight", "mouseButtonLeft", "Down", "Up", "mouseLeft", "mouseRight", "ZoomIn", "ZoomOut"};
  581.  
  582.         this.inputManager = inputManager;
  583.        
  584.         inputManager.addMapping("Down", new MouseAxisTrigger(1, true));
  585.         inputManager.addMapping("Up", new MouseAxisTrigger(1, false));
  586.         inputManager.addMapping("ZoomIn", new MouseAxisTrigger(2, true));
  587.         inputManager.addMapping("ZoomOut", new MouseAxisTrigger(2, false));
  588.         inputManager.addMapping("mouseLeft", new MouseAxisTrigger(0, true));
  589.         inputManager.addMapping("mouseRight", new MouseAxisTrigger(0, false));
  590.         inputManager.addMapping("mouseButtonRight", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
  591.         inputManager.addMapping("mouseButtonLeft", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
  592.  
  593.         inputManager.addListener(this, inputs);
  594.     }
  595.  
  596.     private void computePosition() {
  597.  
  598.         float hDistance = (distance) * FastMath.sin((FastMath.PI / 2) - vRotation);
  599.         pos = new Vector3f(hDistance * FastMath.cos(rotation), (distance) * FastMath.sin(vRotation), hDistance * FastMath.sin(rotation));
  600.         pos = pos.add(target.getWorldTranslation());
  601.     }
  602.  
  603.     //rotate the camera around the target on the horizontal plane
  604.     private void rotateCamera(float value) {
  605.         if (!canRotate || !enabled) {
  606.             return;
  607.         }
  608.         rotating = true;
  609.         targetRotation += value * rotationSpeed;
  610.  
  611.  
  612.     }
  613.  
  614.     //move the camera toward or away the target
  615.     private void zoomCamera(float value) {
  616.         if (!enabled) {
  617.             return;
  618.         }
  619.  
  620.         zooming = true;
  621.         targetDistance += value * zoomSpeed;
  622.         if (targetDistance > maxDistance) {
  623.             targetDistance = maxDistance;
  624.         }
  625.         if (targetDistance < minDistance) {
  626.             targetDistance = minDistance;
  627.         }
  628.         if ((targetVRotation < minVerticalRotation) && (targetDistance > (minDistance + 1.0f))) {
  629.             targetVRotation = minVerticalRotation;
  630.         }
  631.     }
  632.  
  633.     //rotate the camera around the target on the vertical plane
  634.     private void vRotateCamera(float value) {
  635.         if (!canRotate || !enabled) {
  636.             return;
  637.         }
  638.         vRotating = true;
  639.  
  640.         // this negated "value" makes the camera not to be inverted!
  641.         if (!this.invertMouse) {
  642.           targetVRotation += -value * rotationSpeed;
  643.         } else {
  644.           targetVRotation += value * rotationSpeed;
  645.         }
  646.         if (targetVRotation > maxVerticalRotation) {
  647.             targetVRotation = maxVerticalRotation;
  648.         }
  649.         if ((targetVRotation < minVerticalRotation) && (targetDistance > (minDistance + 1.0f))) {
  650.             targetVRotation = minVerticalRotation;
  651.         }
  652.     }
  653.  
  654.     /**
  655.      * Updates the camera, should only be called internally
  656.      */
  657.     protected void updateCamera(float tpf) {
  658.         if (enabled) {
  659.             if (smoothMotion) {
  660.                 //computation of target direction
  661.                 targetDir = target.getWorldTranslation().subtract(prevPos);
  662.                 float dist = targetDir.length();
  663.  
  664.                 //Low pass filtering on the target postition to avoid shaking when physics are enabled.
  665.                 if (offsetDistance < dist) {
  666.                     //target moves, start chasing.
  667.                     chasing = true;
  668.                     //target moves, start trailing if it has to.
  669.                     if (trailingEnabled) {
  670.                         trailing = true;
  671.                     }
  672.                     //target moves...
  673.                     targetMoves = true;
  674.                 } else {
  675.                     //if target was moving, we compute a slight offset in rotation to avoid a rought stop of the cam
  676.                     //We do not if the player is rotationg the cam
  677.                     if (targetMoves && !canRotate) {
  678.                         if (targetRotation - rotation > trailingRotationInertia) {
  679.                             targetRotation = rotation + trailingRotationInertia;
  680.                         } else if (targetRotation - rotation < -trailingRotationInertia) {
  681.                             targetRotation = rotation - trailingRotationInertia;
  682.                         }
  683.                     }
  684.                     //Target stops
  685.                     targetMoves = false;
  686.                 }
  687.  
  688.                 //the user is rotating the cam by dragging the mouse
  689.                 if (canRotate) {
  690.                     //reseting the trailing lerp factor
  691.                     trailingLerpFactor = 0;
  692.                     //stop trailing user has the control
  693.                     trailing = false;
  694.                 }
  695.  
  696.  
  697.                 if (trailingEnabled && trailing) {
  698.                     if (targetMoves) {
  699.                         //computation if the inverted direction of the target
  700.                         Vector3f a = targetDir.negate().normalizeLocal();
  701.                         //the x unit vector
  702.                         Vector3f b = Vector3f.UNIT_X;
  703.                         //2d is good enough
  704.                         a.y = 0;
  705.                         //computation of the rotation angle between the x axis and the trail
  706.                         if (targetDir.z > 0) {
  707.                             targetRotation = FastMath.TWO_PI - FastMath.acos(a.dot(b));
  708.                         } else {
  709.                             targetRotation = FastMath.acos(a.dot(b));
  710.                         }
  711.                         if (targetRotation - rotation > FastMath.PI || targetRotation - rotation < -FastMath.PI) {
  712.                             targetRotation -= FastMath.TWO_PI;
  713.                         }
  714.  
  715.                         //if there is an important change in the direction while trailing reset of the lerp factor to avoid jumpy movements
  716.                         if (targetRotation != previousTargetRotation && FastMath.abs(targetRotation - previousTargetRotation) > FastMath.PI / 8) {
  717.                             trailingLerpFactor = 0;
  718.                         }
  719.                         previousTargetRotation = targetRotation;
  720.                     }
  721.                     //computing lerp factor
  722.                     trailingLerpFactor = Math.min(trailingLerpFactor + tpf * tpf * trailingSensitivity, 1);
  723.                     //computing rotation by linear interpolation
  724.                     rotation = FastMath.interpolateLinear(trailingLerpFactor, rotation, targetRotation);
  725.  
  726.                     //if the rotation is near the target rotation we're good, that's over
  727.                     if (targetRotation + 0.01f >= rotation && targetRotation - 0.01f <= rotation) {
  728.                         trailing = false;
  729.                         trailingLerpFactor = 0;
  730.                     }
  731.                 }
  732.  
  733.                 //linear interpolation of the distance while chasing
  734.                 if (chasing) {
  735.                     distance = target.getWorldTranslation().subtract(cam.getLocation()).length();
  736.                     distanceLerpFactor = Math.min(distanceLerpFactor + (tpf * tpf * chasingSensitivity * 0.05f), 1);
  737.                     distance = FastMath.interpolateLinear(distanceLerpFactor, distance, targetDistance);
  738.                     if (targetDistance + 0.01f >= distance && targetDistance - 0.01f <= distance) {
  739.                         distanceLerpFactor = 0;
  740.                         chasing = false;
  741.                     }
  742.                 }
  743.  
  744.                 //linear interpolation of the distance while zooming
  745.                 if (zooming) {
  746.                     distanceLerpFactor = Math.min(distanceLerpFactor + (tpf * tpf * zoomSensitivity), 1);
  747.                     distance = FastMath.interpolateLinear(distanceLerpFactor, distance, targetDistance);
  748.                     if (targetDistance + 0.1f >= distance && targetDistance - 0.1f <= distance) {
  749.                         zooming = false;
  750.                         distanceLerpFactor = 0;
  751.                     }
  752.                 }
  753.  
  754.                 //linear interpolation of the rotation while rotating horizontally
  755.                 if (rotating) {
  756.                     rotationLerpFactor = Math.min(rotationLerpFactor + tpf * tpf * rotationSensitivity, 1);
  757.                     rotation = FastMath.interpolateLinear(rotationLerpFactor, rotation, targetRotation);
  758.                     if (targetRotation + 0.01f >= rotation && targetRotation - 0.01f <= rotation) {
  759.                         rotating = false;
  760.                         rotationLerpFactor = 0;
  761.                     }
  762.                 }
  763.  
  764.                 //linear interpolation of the rotation while rotating vertically
  765.                 if (vRotating) {
  766.                     vRotationLerpFactor = Math.min(vRotationLerpFactor + tpf * tpf * rotationSensitivity, 1);
  767.                     vRotation = FastMath.interpolateLinear(vRotationLerpFactor, vRotation, targetVRotation);
  768.                     if (targetVRotation + 0.01f >= vRotation && targetVRotation - 0.01f <= vRotation) {
  769.                         vRotating = false;
  770.                         vRotationLerpFactor = 0;
  771.                     }
  772.                 }
  773.                 //computing the position
  774.                 computePosition();
  775.                 //setting the position at last
  776.                 cam.setLocation(pos);
  777.             } else {
  778.                 //easy no smooth motion
  779.                 vRotation = targetVRotation;
  780.                 rotation = targetRotation;
  781.                 distance = targetDistance;
  782.                 computePosition();
  783.                 cam.setLocation(pos);
  784.             }
  785.             //keeping track on the previous position of the target
  786.             prevPos = new Vector3f(target.getWorldTranslation());
  787.  
  788.             //the cam looks at the target
  789.             cam.lookAt(target.getWorldTranslation(), initialUpVec);
  790.         }
  791.         inputManager.setCursorVisible(this.useCursor);
  792.     }
  793.  
  794.     /**
  795.      * Return the enabled/disabled state of the camera
  796.      * @return true if the camera is enabled
  797.      */
  798.     public boolean isEnabled() {
  799.         return enabled;
  800.     }
  801.  
  802.     /**
  803.      * Enable or disable the camera
  804.      * @param enabled true to enable
  805.      */
  806.     public void setEnabled(boolean enabled) {
  807.         this.enabled = enabled;
  808.         if (!enabled) {
  809.             canRotate = false; // reset this flag in-case it was on before
  810.         }
  811.     }
  812.  
  813.     /**
  814.      * Returns the max zoom distance of the camera (default is 40)
  815.      * @return maxDistance
  816.      */
  817.     public float getMaxDistance() {
  818.         return maxDistance;
  819.     }
  820.  
  821.     /**
  822.      * Sets the max zoom distance of the camera (default is 40)
  823.      * @param maxDistance
  824.      */
  825.     public void setMaxDistance(float maxDistance) {
  826.         this.maxDistance = maxDistance;
  827.     }
  828.  
  829.     /**
  830.      * Returns the min zoom distance of the camera (default is 1)
  831.      * @return minDistance
  832.      */
  833.     public float getMinDistance() {
  834.         return minDistance;
  835.     }
  836.  
  837.     /**
  838.      * Sets the min zoom distance of the camera (default is 1)
  839.      * @return minDistance
  840.      */
  841.     public void setMinDistance(float minDistance) {
  842.         this.minDistance = minDistance;
  843.     }
  844.  
  845.     /**
  846.      * clone this camera for a spatial
  847.      * @param spatial
  848.      * @return
  849.      */
  850.     public Control cloneForSpatial(Spatial spatial) {
  851.         ThirdpersonCamera cc = new ThirdpersonCamera(cam, spatial, inputManager);
  852.         cc.setMaxDistance(getMaxDistance());
  853.         cc.setMinDistance(getMinDistance());
  854.         return cc;
  855.     }
  856.  
  857.     /**
  858.      * Sets the spacial for the camera control, should only be used internally
  859.      * @param spatial
  860.      */
  861.     public void setSpatial(Spatial spatial) {
  862.         target = spatial;
  863.     }
  864.  
  865.     /**
  866.      * update the camera control, should on ly be used internally
  867.      * @param tpf
  868.      */
  869.     public void update(float tpf) {
  870.         updateCamera(tpf);
  871.     }
  872.  
  873.     /**
  874.      * renders the camera control, should on ly be used internally
  875.      * @param rm
  876.      * @param vp
  877.      */
  878.     public void render(RenderManager rm, ViewPort vp) {
  879.         //nothing to render
  880.     }
  881.  
  882.     /**
  883.      * Write the camera
  884.      * @param ex the exporter
  885.      * @throws IOException
  886.      */
  887.     public void write(JmeExporter ex) throws IOException {
  888.         OutputCapsule capsule = ex.getCapsule(this);
  889.         capsule.write(maxDistance, "maxDistance", 40);
  890.         capsule.write(minDistance, "minDistance", 1);
  891.     }
  892.  
  893.     /**
  894.      * Read the camera
  895.      * @param im
  896.      * @throws IOException
  897.      */
  898.     public void read(JmeImporter im) throws IOException {
  899.         InputCapsule ic = im.getCapsule(this);
  900.         maxDistance = ic.readFloat("maxDistance", 40);
  901.         minDistance = ic.readFloat("minDistance", 1);
  902.     }
  903.  
  904.     /**
  905.      *
  906.      * @deprecated use getMaxVerticalRotation()
  907.      */
  908.     @Deprecated
  909.     public float getMaxHeight() {
  910.         return getMaxVerticalRotation();
  911.     }
  912.  
  913.     /**
  914.      *
  915.      * @deprecated use setMaxVerticalRotation()
  916.      */
  917.     @Deprecated
  918.     public void setMaxHeight(float maxHeight) {
  919.         setMaxVerticalRotation(maxHeight);
  920.     }
  921.  
  922.     /**
  923.      *
  924.      * @deprecated use getMinVerticalRotation()
  925.      */
  926.     @Deprecated
  927.     public float getMinHeight() {
  928.         return getMinVerticalRotation();
  929.     }
  930.  
  931.     /**
  932.      *
  933.      * @deprecated use setMinVerticalRotation()
  934.      */
  935.     @Deprecated
  936.     public void setMinHeight(float minHeight) {
  937.         setMinVerticalRotation(minHeight);
  938.     }
  939.  
  940.     /**
  941.      * returns the maximal vertical rotation angle of the camera around the target
  942.      * @return
  943.      */
  944.     public float getMaxVerticalRotation() {
  945.         return maxVerticalRotation;
  946.     }
  947.  
  948.     /**
  949.      * sets the maximal vertical rotation angle of the camera around the target default is Pi/2;
  950.      * @param maxVerticalRotation
  951.      */
  952.     public void setMaxVerticalRotation(float maxVerticalRotation) {
  953.         this.maxVerticalRotation = maxVerticalRotation;
  954.     }
  955.  
  956.     /**
  957.      * returns the minimal vertical rotation angle of the camera around the target
  958.      * @return
  959.      */
  960.     public float getMinVerticalRotation() {
  961.         return minVerticalRotation;
  962.     }
  963.  
  964.     /**
  965.      * sets the minimal vertical rotation angle of the camera around the target default is 0;
  966.      * @param minHeight
  967.      */
  968.     public void setMinVerticalRotation(float minHeight) {
  969.         this.minVerticalRotation = minHeight;
  970.     }
  971.  
  972.     /**
  973.      * returns true is smmoth motion is enabled for this chase camera
  974.      * @return
  975.      */
  976.     public boolean isSmoothMotion() {
  977.         return smoothMotion;
  978.     }
  979.  
  980.     /**
  981.      * Enables smooth motion for this chase camera
  982.      * @param smoothMotion
  983.      */
  984.     public void setSmoothMotion(boolean smoothMotion) {
  985.         this.smoothMotion = smoothMotion;
  986.     }
  987.  
  988.     /**
  989.      * returns the chasing sensitivity
  990.      * @return
  991.      */
  992.     public float getChasingSensitivity() {
  993.         return chasingSensitivity;
  994.     }
  995.  
  996.     /**
  997.      * Sets the chasing sensitivity, the lower the value the slower the camera will go in the trail of the target when it moves
  998.      * @param chasingSensitivity
  999.      */
  1000.     public void setChasingSensitivity(float chasingSensitivity) {
  1001.         this.chasingSensitivity = chasingSensitivity;
  1002.     }
  1003.  
  1004.     /**
  1005.      * Returns the rotation sensitivity
  1006.      * @return
  1007.      */
  1008.     public float getRotationSensitivity() {
  1009.         return rotationSensitivity;
  1010.     }
  1011.  
  1012.     /**
  1013.      * Sets the rotation sensitivity, the lower the value the slower the camera will rotates around the target when draging with the mouse
  1014.      * default is 5
  1015.      * @param rotationSensitivity
  1016.      */
  1017.     public void setRotationSensitivity(float rotationSensitivity) {
  1018.         this.rotationSensitivity = rotationSensitivity;
  1019.     }
  1020.  
  1021.     /**
  1022.      * returns true if the trailing is enabled
  1023.      * @return
  1024.      */
  1025.     public boolean isTrailingEnabled() {
  1026.         return trailingEnabled;
  1027.     }
  1028.  
  1029.     /**
  1030.      * Enable the camera trailing : The camera smoothly go in the targets trail when it moves.
  1031.      * @param trailingEnabled
  1032.      */
  1033.     public void setTrailingEnabled(boolean trailingEnabled) {
  1034.         this.trailingEnabled = trailingEnabled;
  1035.     }
  1036.  
  1037.     /**
  1038.      * returns the trailing rotation inertia
  1039.      * @return
  1040.      */
  1041.     public float getTrailingRotationInertia() {
  1042.         return trailingRotationInertia;
  1043.     }
  1044.  
  1045.     /**
  1046.      * Sets the trailing rotation inertia : default is 0.1. This prevent the camera to roughtly stop when the target stops moving
  1047.      * before the camera reached the trail position.
  1048.      * @param trailingRotationInertia
  1049.      */
  1050.     public void setTrailingRotationInertia(float trailingRotationInertia) {
  1051.         this.trailingRotationInertia = trailingRotationInertia;
  1052.     }
  1053.  
  1054.     /**
  1055.      * returns the trailing sensitivity
  1056.      * @return
  1057.      */
  1058.     public float getTrailingSensitivity() {
  1059.         return trailingSensitivity;
  1060.     }
  1061.  
  1062.     /**
  1063.      * Sets the trailing sensitivity, the lower the value, the slower the camera will go in the target trail when it moves.
  1064.      * default is 0.5;
  1065.      * @param trailingSensitivity
  1066.      */
  1067.     public void setTrailingSensitivity(float trailingSensitivity) {
  1068.         this.trailingSensitivity = trailingSensitivity;
  1069.     }
  1070.  
  1071.     /**
  1072.      * returns the zoom sensitivity
  1073.      * @return
  1074.      */
  1075.     public float getZoomSensitivity() {
  1076.         return zoomSensitivity;
  1077.     }
  1078.  
  1079.     /**
  1080.      * Sets the zoom sensitivity, the lower the value, the slower the camera will zoom in and out.
  1081.      * default is 5.
  1082.      * @param zoomSensitivity
  1083.      */
  1084.     public void setZoomSensitivity(float zoomSensitivity) {
  1085.         this.zoomSensitivity = zoomSensitivity;
  1086.     }
  1087.  
  1088.     /**
  1089.      * Sets the default distance at start of applicaiton
  1090.      * @param defaultDistance
  1091.      */
  1092.     public void setDefaultDistance(float defaultDistance) {
  1093.         distance = defaultDistance;
  1094.         targetDistance = distance;
  1095.     }
  1096.  
  1097.     /**
  1098.      * sets the default horizontal rotation of the camera at start of the application
  1099.      * @param angle
  1100.      */
  1101.     public void setDefaultHorizontalRotation(float angle) {
  1102.         rotation = angle;
  1103.         targetRotation = angle;
  1104.     }
  1105.  
  1106.     /**
  1107.      * sets the default vertical rotation of the camera at start of the application
  1108.      * @param angle
  1109.      */
  1110.     public void setDefaultVerticalRotation(float angle) {
  1111.         vRotation = angle;
  1112.         targetVRotation = angle;
  1113.     }
  1114.  
  1115.     public void setInvertedMouse(boolean invert) {
  1116.       this.invertMouse = invert;
  1117.       registerWithInput(this.inputManager);
  1118.     }
  1119.  
  1120.     public void setUseLeftMouseToRotate(Boolean use) {
  1121.       this.useLeftMouseButtonToRotate = use;
  1122.       registerWithInput(this.inputManager);
  1123.     }
  1124.  
  1125.     public void setUseRightMouseToRotate(Boolean use) {
  1126.       this.useRightMouseButtonToRotate = use;
  1127.       registerWithInput(this.inputManager);
  1128.     }
  1129.  
  1130.     public void setUseCursor(Boolean use) {
  1131.       this.useCursor = use;
  1132.     }
  1133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement