Hello,
I’ve juste make a control for my game and want to share it.
When you add it to a spatial, your camera follow it at first person and you can control the camera rotation.
[java]
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.Quaternion;
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.AbstractControl;
/**
-
This control when attached to a spatial, follow him at the first person
-
@author Kyu
-
@version 0.1
*/
public class FirstPersonCameraControl extends AbstractControl implements ActionListener, AnalogListener
{
protected Camera camera;
protected InputManager inputManager;protected float rotationSpeed = 1.0f;
protected float rotation;
protected float vRotation;protected float minVerticalRotation = FastMath.DEG_TO_RAD * -90;
protected float maxVerticalRotation = FastMath.DEG_TO_RAD * 90;protected boolean isRotating;
protected boolean isVRotating;
protected boolean dragToRotate;
protected boolean hideCursorOnRotate = true;
protected boolean canRotate = true;protected boolean isMoving;
protected Vector3f location;
protected Vector3f lastLocation = new Vector3f();
protected Vector3f locationCorrection = new Vector3f(Vector3f.ZERO);protected boolean invertYaxis;
protected boolean invertXaxis;/**
- Mapping
*/
protected final String FirstCamDown = “FirstCamDown”;
protected final String FirstCamUp = “FirstCamUp”;
protected final String FirstCamZoomIn = “FirstCamZoomIn”;
protected final String FirstCamZoomOut = “FirstCamZoomOut”;
protected final String FirstCamMoveLeft = “FirstCamMoveLeft”;
protected final String FirstCamMoveRight = “FirstCamMoveRight”;
protected final String FirstCamToggleRotate = “FirstCamToggleRotate”;
/**
- Temporary variables
*/
private Quaternion quadTemp = new Quaternion();
/**
- Temporary variable used for location computing
*/
private Vector3f vecTemp = new Vector3f();
/**
- Constructor to follow a spatial by his translation
-
@param cam the camera used to follow spatial
*/
public FirstPersonCameraControl(Camera cam)
{
this.camera = cam;
}
/**
-
Constructor to follow a spatial and have freedom on view
-
@param cam the camera where view should be controlled by inputs
-
@param inputManager the InputManager to attach mapping
*/
public FirstPersonCameraControl(Camera cam, InputManager inputManager)
{
this.camera = cam;registerWithInput(inputManager);
}
/**
-
Register mapping
-
@param inputManager the InputManager where attach mapping
*/
public final void registerWithInput(InputManager inputManager)
{
this.inputManager = inputManager;String[] inputs = {
FirstCamToggleRotate,
FirstCamDown,
FirstCamUp,
FirstCamMoveLeft,
FirstCamMoveRight,
};inputManager.addMapping(FirstCamDown, new MouseAxisTrigger(MouseInput.AXIS_Y, ((!invertYaxis) ? false : true)));
inputManager.addMapping(FirstCamUp, new MouseAxisTrigger(MouseInput.AXIS_Y, ((!invertYaxis) ? true : false)));inputManager.addMapping(FirstCamMoveLeft, new MouseAxisTrigger(MouseInput.AXIS_X, ((!invertXaxis) ? false : true)));
inputManager.addMapping(FirstCamMoveRight, new MouseAxisTrigger(MouseInput.AXIS_X, ((!invertXaxis) ? true : false)));inputManager.addMapping(FirstCamToggleRotate, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addMapping(FirstCamToggleRotate, new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));inputManager.addListener(this, inputs);
}
@Override
public void onAction(String name, boolean isPressed, float tpf)
{
if (dragToRotate && enabled)
{
if (name.equals(FirstCamToggleRotate) && enabled)
{
canRotate = isPressed;if (hideCursorOnRotate) { inputManager.setCursorVisible(!isPressed); } } }
}
@Override
public void onAnalog(String name, float value, float tpf)
{
if(!enabled || !canRotate)
return;switch (name) { case FirstCamMoveLeft: rotateCamera(-value); break; case FirstCamMoveRight: rotateCamera(value); break; case FirstCamUp: vRotateCamera(value); break; case FirstCamDown: vRotateCamera(-value); break; }
}
/**
- Rotate the camera on the horizontal axis (used internally)
-
@param value value to rotate in radian
*/
protected void rotateCamera(float value)
{
isRotating = true;
rotation += value * rotationSpeed;
}
/**
-
Rotate the camera on the vertical axis (used internally)
-
@param value value to rotate in radian
*/
protected void vRotateCamera(float value)
{
isVRotating = true;
float lastGoodRot = vRotation;vRotation += value * rotationSpeed;
if (vRotation -minVerticalRotation)
vRotation = lastGoodRot;
}
/**
-
Update the control (used by jme thread)
-
@param tpf time since last frame
*/
@Override
protected void controlUpdate(float tpf)
{
if(!enabled)
return;if(location != null)
lastLocation.set(location);location = spatial.getLocalTranslation();
isMoving = lastLocation.equals(location);
if(isMoving)
{
vecTemp.zero();
vecTemp.addLocal(location);
vecTemp.addLocal(locationCorrection);
camera.setLocation(vecTemp);
}if(!isRotating && ! isVRotating)
return;quadTemp.fromAngles(vRotation, rotation, 0);
camera.setRotation(quadTemp);
}
/**
- Update the render thread (used in jme thread)
- @param renderManager
-
@param viewPort
*/
@Override
protected void controlRender(RenderManager renderManager, ViewPort viewPort)
{
}
/**
-
Set the spatial where the control was attached (used internally)
-
@param spatial the spatial where control was attached
*/
@Override
public void setSpatial(Spatial spatial)
{
super.setSpatial(spatial);if(spatial == null)
{
enabled = false;return;
}
else
enabled = true;boolean _showMouse = false;
if(dragToRotate)
{
_showMouse = true;
if(canRotate)
{
if(hideCursorOnRotate)
_showMouse = false;
else
_showMouse = true;
}}
inputManager.setCursorVisible(_showMouse);
}
/**
- Set the speed of camera rotation
-
@param rotationSpeed speed of the rotation; 1f is the origin value;
*/
public void setRotationSpeed(float rotationSpeed)
{
this.rotationSpeed = rotationSpeed;
}
/**
- Set the minimal vertical rotation of the camera
-
@param minVerticalRotation minimal vertical rotation value of the camera in degree
*/
public void setMinVerticalRotation(float minVerticalRotation)
{
this.minVerticalRotation = FastMath.DEG_TO_RAD * minVerticalRotation;
}
/**
- Set the maximal vertical rotation of the camera
-
@param maxVerticalRotation maximal vertical rotation value of the camera in degree
*/
public void setMaxVerticalRotation(float maxVerticalRotation)
{
this.maxVerticalRotation = FastMath.DEG_TO_RAD * maxVerticalRotation;
}
/**
-
Need to click to rotate the camera
-
@param dragToRotate need to click or not to rotate the camera
*/
public void setDragToRotate(boolean dragToRotate)
{
this.dragToRotate = dragToRotate;
this.canRotate = !dragToRotate;inputManager.setCursorVisible(dragToRotate);
}
/**
- Hide the cursor when drag to rotate
-
@param hideCursorOnRotate hide cursor
*/
public void setHideCursorOnRotate(boolean hideCursorOnRotate)
{
this.hideCursorOnRotate = hideCursorOnRotate;
}
/**
- Invert the X axis
-
@param invertXaxis invert X axis
*/
public void setInvertXaxis(boolean invertXaxis)
{
this.invertXaxis = invertXaxis;
}
/**
- Invert the Y axis
-
@param invertYaxis invert Y axis
*/
public void setInvertYaxis(boolean invertYaxis)
{
this.invertYaxis = invertYaxis;
}
/**
- Translate the origin of the camera on X axis
-
@param x location on X axis
*/
public void setXCorrection(float x)
{
locationCorrection.setX(x);
}
/**
- Translate the origin of the camera on Y axis
-
@param y location on Y axis
*/
public void setYCorrection(float y)
{
locationCorrection.setY(y);
}
/**
- Translate the origin of the camera on Z axis
-
@param z location on Z axis
*/
public void setZCorrection(float z)
{
locationCorrection.setZ(z);
}
/**
- Get the rotation speed of camera
-
@return camera rotation speed
*/
public float getRotationSpeed()
{
return rotationSpeed;
}
/**
- Get the minimal vertical rotation of the camera
-
@return minimal vertical rotation
*/
public float getMinVerticalRotation()
{
return minVerticalRotation;
}
/**
- Get the maximal vertical rotation of the camera
-
@return maximal vertical rotation
*/
public float getMaxVerticalRotation()
{
return maxVerticalRotation;
}
/**
- Get the camera horizontal rotation state
-
@return boolean
*/
public boolean isIsRotating()
{
return isRotating;
}
/**
- Get the camera vertical rotation state
-
@return boolean
*/
public boolean isIsVRotating()
{
return isVRotating;
}
/**
- Get the DragRoRotate mode state
-
@return boolean
*/
public boolean isDragToRotate()
{
return dragToRotate;
}
/**
-
@return if hide the cursor in DragToRotate mode when dragging
*/
public boolean isHideCursorOnRotate()
{
return hideCursorOnRotate;
}
/**
- Get if can rotate the camera
-
@return boolean
*/
public boolean isCanRotate()
{
return canRotate;
}
/**
- Get if spatial is moving
-
@return boolean
*/
public boolean isIsMoving()
{
return isMoving;
}
/**
- Get the correction location
-
@return location
*/
public Vector3f getLocationCorrection()
{
return locationCorrection;
}
/**
- Get if Y axis is inverted
-
@return boolean
*/
public boolean isInvertYaxis()
{
return invertYaxis;
}
/**
- Get if X axis is inverted
-
@return boolean
*/
public boolean isInvertXaxis()
{
return invertXaxis;
}
- Mapping
}
[/java]
or pastebin : pastebin
You can give me advise, i take it in consideration to improve this.
Sorry if my english is bad and thank you for this great engine