diff --git a/src/sg/SpaceGame.java b/src/sg/SpaceGame.java index 2ff0a59..2615ac4 100644 --- a/src/sg/SpaceGame.java +++ b/src/sg/SpaceGame.java @@ -38,7 +38,7 @@ public class SpaceGame extends SimplePhysicsGame { rootNode.attachChild(shipNode); //environment - environment = new Environment(rootNode); + environment = new Environment(rootNode, getPhysicsSpace()); rootNode.attachChild(environment); //light diff --git a/src/sg/env/Environment.java b/src/sg/env/Environment.java index f43c7de..711cda9 100644 --- a/src/sg/env/Environment.java +++ b/src/sg/env/Environment.java @@ -11,6 +11,8 @@ import com.jme.scene.state.TextureState; import com.jme.system.DisplaySystem; import com.jmex.effects.LensFlare; import com.jmex.effects.LensFlareFactory; +import com.jmex.physics.PhysicsSpace; +import com.jmex.physics.StaticPhysicsNode; public class Environment extends Node { private static final long serialVersionUID = 1L; @@ -20,13 +22,15 @@ public class Environment extends Node { * */ private Node localNode; - public Environment(Node parentNode){ + public Environment(Node parentNode, PhysicsSpace physicsSpace){ buildLocalNode(); - buildEnvoriment(); + buildEnvoriment(physicsSpace); } - private void buildEnvoriment(){ - Node station = SGUtil.loadModel("sg/data/models/stations/station.3ds"); + private void buildEnvoriment(PhysicsSpace physicsSpace){ + StaticPhysicsNode station = physicsSpace.createStaticNode(); + Node stationModel = SGUtil.loadModel("sg/data/models/stations/station.3ds"); + station.attachChild(stationModel); station.setLocalTranslation(new Vector3f( 500, 0, 0)); this.attachChild(station); diff --git a/src/sg/input/GlobalInputHandler.java b/src/sg/input/GlobalInputHandler.java index 5d38109..12b3b38 100644 --- a/src/sg/input/GlobalInputHandler.java +++ b/src/sg/input/GlobalInputHandler.java @@ -3,21 +3,43 @@ package sg.input; import com.jme.input.InputHandler; import com.jme.input.KeyBindingManager; import com.jme.input.KeyInput; +import com.jme.math.Vector3f; +import com.jme.scene.Node; +import com.jmex.physics.DynamicPhysicsNode; public abstract class GlobalInputHandler extends InputHandler { + protected final Vector3f appliedForce; + protected Node shipNode; + protected DynamicPhysicsNode shipPhysNode; - public GlobalInputHandler(){ + public GlobalInputHandler(Node shipNode, DynamicPhysicsNode shipPhysNode){ + appliedForce = new Vector3f(); + this.shipNode = shipNode; + this.shipPhysNode = shipPhysNode; + KeyBindingManager manager = KeyBindingManager.getKeyBindingManager(); manager.set("input_first", KeyInput.KEY_F1); manager.set("input_third", KeyInput.KEY_F2); + + manager.set("accelerate", KeyInput.KEY_W); + manager.set("break", KeyInput.KEY_S); } - + public void update(float tpf){ super.update(tpf); /* if ( KeyBindingManager.getKeyBindingManager().isValidCommand( "input_first", false ) ) { this = new FirstPersonHandler(ship, cam); } - */ + */ + Vector3f rotation = shipPhysNode.getWorldRotation().getRotationColumn(0); + if ( KeyBindingManager.getKeyBindingManager().isValidCommand("accelerate", true ) ) { + appliedForce.set(rotation.mult(700)).multLocal(tpf); + shipPhysNode.addForce(appliedForce); + } + else if ( KeyBindingManager.getKeyBindingManager().isValidCommand("break", true ) ) { + appliedForce.set(rotation.mult(-700)).multLocal(tpf); + shipPhysNode.addForce(appliedForce); + } } } diff --git a/src/sg/input/SGFirstPersonHandler.java b/src/sg/input/SGFirstPersonHandler.java index 4f8e0d7..7c315a9 100644 --- a/src/sg/input/SGFirstPersonHandler.java +++ b/src/sg/input/SGFirstPersonHandler.java @@ -2,22 +2,16 @@ package sg.input; import com.jme.input.KeyBindingManager; import com.jme.input.KeyInput; -import com.jme.math.Vector3f; import com.jme.renderer.Camera; import com.jme.scene.Node; import com.jmex.physics.DynamicPhysicsNode; public class SGFirstPersonHandler extends GlobalInputHandler{ - private final Vector3f appliedForce = new Vector3f(); - private Vector3f rotation; - private Node ship; - private DynamicPhysicsNode shipNode; private Camera cam; - public SGFirstPersonHandler(Node ship, DynamicPhysicsNode shipNode, Camera cam){ - this.ship = ship; - this.shipNode = shipNode; + public SGFirstPersonHandler(Node ship, DynamicPhysicsNode shipPhysNode, Camera cam){ + super(ship, shipPhysNode); this.cam = cam; KeyBindingManager manager = KeyBindingManager.getKeyBindingManager(); @@ -33,15 +27,6 @@ public class SGFirstPersonHandler extends GlobalInputHandler{ public void update(float time){ super.update(time); - rotation = ship.getLocalRotation().getRotationColumn(2); - if ( KeyBindingManager.getKeyBindingManager().isValidCommand("forw", true ) ) { - appliedForce.set(rotation.mult(-700)).multLocal(time); - shipNode.addForce(appliedForce); - } - else if ( KeyBindingManager.getKeyBindingManager().isValidCommand("backw", true ) ) { - appliedForce.set(rotation.mult(700)).multLocal(time); - shipNode.addForce(appliedForce); - } - + } } diff --git a/src/sg/input/SGThirdPersonHandler.java b/src/sg/input/SGThirdPersonHandler.java index 469a38e..af0133b 100644 --- a/src/sg/input/SGThirdPersonHandler.java +++ b/src/sg/input/SGThirdPersonHandler.java @@ -1,6 +1,7 @@ package sg.input; import com.jme.input.ChaseCamera; +import com.jme.input.MouseInput; import com.jme.input.RelativeMouse; import com.jme.input.action.InputActionEvent; import com.jme.input.thirdperson.ThirdPersonMouseLook; @@ -10,17 +11,24 @@ import com.jme.math.Vector3f; import com.jme.renderer.Camera; import com.jme.scene.Node; import com.jme.scene.Spatial; +import com.jmex.physics.DynamicPhysicsNode; public class SGThirdPersonHandler extends GlobalInputHandler{ protected Camera cam; - protected Node ship; - public SGThirdPersonHandler(Camera cam, Spatial ship){ + public SGThirdPersonHandler(Node ship, DynamicPhysicsNode shipPhysNode, Camera cam){ + super(ship, shipPhysNode); + SGChaseCamera ccam = new SGChaseCamera(cam, ship); + ccam.getMouseLook().setRotateTarget(true); + ccam.getMouseLook().setTargetTurnSpeed(FastMath.PI); this.addToAttachedHandlers(ccam); } + //******************************************************************************** + //******************************************************************************** + class SGChaseCamera extends ChaseCamera{ public SGChaseCamera(Camera arg0, Spatial arg1) { super(arg0, arg1); @@ -42,7 +50,7 @@ public class SGThirdPersonHandler extends GlobalInputHandler{ } } - + //******************************************************************************** class SGThirdPersonMouseLook extends ThirdPersonMouseLook{ float targetTurnSpeed = 1f; @@ -50,29 +58,148 @@ public class SGThirdPersonHandler extends GlobalInputHandler{ super(mouse, camera, target); } - public void performAction(InputActionEvent event) { - super.performAction(event); + public void performAction(InputActionEvent event) { + if (!enabled) + return; - //if (mouse.getLocalTranslation().x != 0 || mouse.getLocalTranslation().y != 0) { - Vector3f camL = camera.getCamera().getLocation(); - //center coordinates to spatial - float x = target.getLocalTranslation().x - camL.x; - float z = target.getLocalTranslation().z - camL.z; - float y = target.getLocalTranslation().y - camL.y; - float c = FastMath.sqrt(x*x + z*z); + float time = 0.01f; + if (lookMouse == -1 || MouseInput.get().isButtonDown(lookMouse)) { + camera.setLooking(true); + if (mouse.getLocalTranslation().x != 0) { + float amount; + if(invertRotate) { + amount = -time * mouse.getLocalTranslation().x; + } else { + amount = time * mouse.getLocalTranslation().x; + } + rotateRight(amount, time); + updated = true; + } else if (rotateTarget) + rotateRight(0, time); + if (!lockAscent && mouse.getLocalTranslation().y != 0) { + float amount = time * mouse.getLocalTranslation().y; + rotateUp(amount); + updated = true; + } + } else camera.setLooking(false); - // Tower rotation - float angle = FastMath.acos(x/c); - if(camL.z < 0 && angle > 0) angle = -Math.abs(angle); - if(camL.z > 0 && angle < 0) angle = Math.abs(angle); - target.getLocalRotation().fromAngleAxis(angle+FastMath.PI, new Vector3f(0,0,1)); + updateFromJoystick(time); + + int wdelta = MouseInput.get().getWheelDelta(); + if (wdelta != 0) { + float amount = time * -wdelta; + rollIn(amount); + updated = true; + } - //gun rotation - c = FastMath.sqrt(x*x + y*y + z*z); - angle = FastMath.tan(y/c); - target.getLocalRotation().fromAngleAxis(angle+FastMath.PI/5, new Vector3f(0,1,0)); - //} - + if (updated) + camera.getCamera().onFrameChange(); + } + + private void rollIn(float amount) { + camera.getIdealSphereCoords().x = clampRollIn(camera + .getIdealSphereCoords().x + + (amount * rollInSpeed)); + } + + protected void rotateRight(float amount, float time) { + Vector3f camPos = camera.getCamera().getLocation(); + Vector3f targetPos = target.getWorldTranslation(); + + float azimuthAccel = (amount * mouseXSpeed); + difTemp.set(camPos).subtractLocal(targetPos); + + if (worldUpVec.z == 1) { + float y = difTemp.y; + difTemp.y = difTemp.z; + difTemp.z = y; + } + + FastMath.cartesianToSpherical(difTemp, sphereTemp); + sphereTemp.y = FastMath.normalize(sphereTemp.y + (azimuthAccel), + -FastMath.TWO_PI, FastMath.TWO_PI); + FastMath.sphericalToCartesian(sphereTemp, rightTemp); + + if (worldUpVec.z == 1) { + float y = rightTemp.y; + rightTemp.y = rightTemp.z; + rightTemp.z = y; + } + + rightTemp.addLocal(targetPos); + camPos.set(rightTemp); + if (camera.isMaintainAzimuth()) { + camera.setForceAzimuthUpdate(true); + } + if (rotateTarget) { + //First figure out the current facing vector. + target.getLocalRotation().getRotationColumn(0, rightTemp); + + // get angle between vectors + rightTemp.normalizeLocal(); + difTemp.y = 0; + difTemp.negateLocal().normalizeLocal(); + float angle = rightTemp.angleBetween(difTemp); + + // calc how much angle we'll do + float maxAngle = targetTurnSpeed * time; + if (angle < 0 && -maxAngle > angle) { + angle = -maxAngle; + } else if (angle > 0 && maxAngle < angle) { + angle = maxAngle; + } + + //figure out rotation axis by taking cross product + Vector3f rotAxis = rightTemp.crossLocal(difTemp).normalizeLocal(); + + // Build a rotation quat and apply current local rotation. + Quaternion q = rotTemp; + q.fromAngleNormalAxis(angle, rotAxis); + q.mult(target.getLocalRotation(), target.getLocalRotation()); + } } + + private void rotateUp(float amount) { + if (invertedY) + amount *= -1; + Vector3f camPos = camera.getCamera().getLocation(); + Vector3f targetPos = target.getWorldTranslation(); + + float thetaAccel = (amount * mouseYSpeed); + difTemp.set(camPos).subtractLocal(targetPos).subtractLocal( + camera.getTargetOffset()); + + if (worldUpVec.z == 1) { + float y = difTemp.y; + difTemp.y = difTemp.z; + difTemp.z = y; + } + + FastMath.cartesianToSpherical(difTemp, sphereTemp); + camera.getIdealSphereCoords().z = clampUpAngle(sphereTemp.z + + (thetaAccel)); + } + + private float clampUpAngle(float r) { + if (Float.isInfinite(r) || Float.isNaN(r)) + return r; + if (r > maxAscent) + r = maxAscent; + else if (r < minAscent) + r = minAscent; + return r; + } + + private float clampRollIn(float r) { + if (Float.isInfinite(r) || Float.isNaN(r)) + return 100f; + if (r > maxRollOut) + r = maxRollOut; + else if (r < minRollOut) + r = minRollOut; + return r; + } } + + } diff --git a/src/sg/states/InGameState.java b/src/sg/states/InGameState.java index f214372..6f9a434 100644 --- a/src/sg/states/InGameState.java +++ b/src/sg/states/InGameState.java @@ -8,6 +8,7 @@ import sg.util.SGUtil; import com.jme.input.InputHandler; import com.jme.light.PointLight; +import com.jme.math.FastMath; import com.jme.math.Vector3f; import com.jme.renderer.ColorRGBA; import com.jme.renderer.Renderer; @@ -49,16 +50,19 @@ public class InGameState extends CameraGameState { rootNode.attachChild(staticNode); // environment - environment = new Environment(rootNode); + environment = new Environment(rootNode, physicsSpace); rootNode.attachChild(environment); // ship - Node ship = SGUtil.loadModel("sg/data/models/ships/G6.3ds"); + DynamicPhysicsNode ship = physicsSpace.createDynamicNode(); + Node shipModel = SGUtil.loadModel("sg/data/models/ships/G6.3ds"); + shipModel.getLocalRotation().fromAngleAxis(-90*FastMath.DEG_TO_RAD, Vector3f.UNIT_Y); + ship.attachChild(shipModel); ship.setLocalTranslation(new Vector3f( 0, 0, 40)); rootNode.attachChild(ship); // inputs - input = new SGThirdPersonHandler( cam, ship ); + input = new SGThirdPersonHandler( ship, ship ,cam ); // lights /** Set up a basic, default light. */