I don't quite get it. Input tutorials leans towards keyboard input(I don't plan to use any). Mouse input information seems orientated from a Third person view. I'm wondering does anyone have any code based around the idea of the mouse movement moving the camera around a central object? If I move the mouse right, the camera rotates right direction around say 0.0.0
My head hasn't yet wrapped around the input system yet.
there was a post about a similar topic not too long ago:
http://www.jmonkeyengine.com/jmeforum/index.php?topic=7960.0
But if you want to use mouse Input you could use the following example also:
The following example uses GameControls and two Rotationcontrollers to rotate a Cameranode around a static Box at location 0.0.0.
Only the Camera moves, not the Box.
This example also shows the difference between MouseAxisBinding (left,right) and MouseOffsetBinding (up, down)
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.input.controls.GameControl;
import com.jme.input.controls.GameControlManager;
import com.jme.input.controls.binding.MouseAxisBinding;
import com.jme.input.controls.binding.MouseOffsetBinding;
import com.jme.input.controls.controller.Axis;
import com.jme.input.controls.controller.RotationController;
import com.jme.math.Vector3f;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
public class TestRotateAroundPoint extends SimpleGame {
@Override
protected void simpleInitGame() {
// remove SimpleGame Inputs
input.removeAllFromAttachedHandlers();
input = new InputHandler();
// create a GamecontrolManager
GameControlManager manager = new GameControlManager();
// create 4 GameControls, always 2 per Axis
// with MouseAxisBinding control the rotation directly
GameControl left = manager.addControl("left");
left.addBinding(new MouseAxisBinding(MouseAxisBinding.AXIS_X, true));
GameControl right = manager.addControl("right");
right.addBinding(new MouseAxisBinding(MouseAxisBinding.AXIS_X, false));
// MouseOffsetBinding uses the offset from the center of the screen
// to the mouse cursor, to determine the rotation speed
GameControl up = manager.addControl("up");
up.addBinding(new MouseOffsetBinding(MouseAxisBinding.AXIS_Y, true));
GameControl down = manager.addControl("down");
down.addBinding(new MouseOffsetBinding(MouseAxisBinding.AXIS_Y, false));
// create a static Box at location 0.0.0 to look at
Box centerBox = new Box("center", new Vector3f(), 0.5f, 0.5f, 0.5f);
centerBox.setModelBound(new BoundingSphere());
centerBox.updateModelBound();
centerBox.lock();
rootNode.attachChild(centerBox);
// create a Node which we can rotate and where we attach our Cameranode to
Node rotationNode = new Node("rotation node");
rootNode.attachChild(rotationNode);
// create a CameraNode and attach it to the previous Node, then move it back some
CameraNode camNode = new CameraNode("camera node", display.getRenderer().getCamera());
rotationNode.attachChild(camNode);
camNode.setLocalTranslation(0, 0, -10);
// create two controllers which rotate the node around the X and Y axis
RotationController rotateY = new RotationController(rotationNode,
left, right, 2, Axis.Y);
rotationNode.addController(rotateY);
RotationController rotateX = new RotationController(rotationNode,
up, down, 2, Axis.X);
rotationNode.addController(rotateX);
// show the mousecursor
MouseInput.get().setCursorVisible(true);
}
public static void main(String[] args) {
new TestRotateAroundPoint().start();
}
}
hmm, can't seem to find MouseOffsetBinding.
I'm also using gamestates, but I'll figure that out. Thanks for the quick reply.
I am having some troubles though.
I'm trying to get the camera from a CameraGameState to create the CameraNode(as listed above). I'm think this
is causing the error.
Exception in thread "main" java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glMatrixMode(GL11.java:1960)
at com.jme.scene.state.lwjgl.records.RendererRecord.switchMode(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLCamera.doFrustumChange(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLCamera.apply(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLCamera.<init>(Unknown Source)
at com.jme.renderer.lwjgl.LWJGLRenderer.createCamera(Unknown Source)
at com.jmex.game.state.CameraGameState.initCamera(Unknown Source)
at com.jmex.game.state.CameraGameState.<init>(Unknown Source)
at sre.roam.AgentJME.<init>(Unknown Source)
at sre.roam.app.<init>(Unknown Source)
at sre.roam.Roam.<init>(Unknown Source)
at sre.roam.Roam.main(Unknown Source)
MouseOffsetBinding is new, so you would have to use the current svn version.
Nullpointer Exceptions in GL11 classes are usually caused by not calling the method in the main thread.
Use the GameTaskQueueManager to create the camera inside the OpenGL thread.
Worked perfectly however, I find that the node rotates on it's own axis rather than just rotating around the object. So not exactly the end result, but good start. Thank you.
So my head is starting to wrap around how this input is working. So I decided to move on to the next step and start working on the mouse button interaction. This is where the binding system started to confuse my little head. Out of the methods provided and some of the experiments I could not change the when I want the left and right to rotate. I thought I could move to the next step, but i'm not seeing it.
So how would I go about only rotating when I'm holding down the right mouse button.
Also I'm finding that the node is also rotating on it's axis. where I would prefer that the camera doesn't tilt. Sorry for all these questions, It's been awhile since dabbling in jME.
well in the example we attached two nodes to the root node.
first the rotation node, which is at location 0,0,0 and is being rotated around its own axis.
attached to this rotation node we have the camera node, which we translated 10 units backwards.
so, when we now rotate the rotation node around the Y axis, the camera node will move in a perfect circle around around 0,0,0.
in the example i attached two RotationControllers to rotate the node around X and Y axis, if you remove the 2nd controller (rotateX) the cam will only move sideway and not tilt.
to rotate only then a button is pressed, you could simply create your own MouseBinding which extends either MouseOffset or MouseAxisBinding and overwrite getValue()
class MyMouseBinding extends MouseOffsetBinding {
public MyMouseBinding(int axis, boolean reverse) {
super(axis, reverse);
}
/**
* only return values if the left (first) Mousebutton is pressed.
*/
@Override
public float getValue() {
if (!MouseInput.get().isButtonDown(0)) {
return 0;
}
return super.getValue();
}
}
Sorry, I wasn’t clear. When rotating left/right around the say 0.0.0 normaly isn’t a problem. The thing is if you start moving up or down and then going left or right. The camera does not stay parrallel along the say the floor.
[img=http://img219.imageshack.us/img219/9559/badanglefy0.th.jpg]
bad angle
Is there a way to remove an axis so that it doesn't do this?
Also I tried using this code to deal with the mouse button press. I would prefer to avoid extending anything if I can.
InputAction leftButtonAction = new InputAction(){
public void performAction( InputActionEvent evt ){
System.out.println( "button action performed" );
if(evt.getTriggerPressed()){
// hide mouse and bind rotation
MouseInput.get().setCursorVisible(false);
right.addBinding(xBindRight);
left.addBinding(xBindLeft);
up.addBinding(yBindUp);
down.addBinding(yBindDown);
}else{
//show mouse and unbind rotation
MouseInput.get().setCursorVisible(true);
right.clearBindings();
left.clearBindings();
up.clearBindings();
down.clearBindings();
}
}
};
input.addAction( leftButtonAction, InputHandler.DEVICE_MOUSE, 0 /*right button*/, InputHandler.AXIS_NONE, false );
by the way thanx for the quick replies core_dump your the man. maybe I can get a demo up in a few days at least by next week
You can simply create a new InputHandler if you need one in your GameState.
just call input.update() in the GameStates update method.
About the camera behaviour…
You could keep the RotationController around the Y Axis, so your Camera circles around your object when you move the mouse left and right.
But additionally create a new TranslationController which translates the node up and down.
With a few code changes you can create a TranslationController from the RotationController and switch it easily.
// instead of rotating around X …
RotationController rotateX = new RotationController(rotationNode, up, down, 2, Axis.X);
// we translate along Y
TranslationController rotateX = new TranslationController(rotationNode, up, down, 2, Axis.Y);
// new and shiny TranslationController
public class TranslationController extends Controller {
private Spatial spatial;
private GameControl positive;
private GameControl negative;
private float multiplier;
private Vector3f dir;
public TranslationController(Spatial spatial, GameControl positive, GameControl negative, float multiplier, Axis axis) {
this.spatial = spatial;
this.positive = positive;
this.negative = negative;
this.multiplier = multiplier;
if (axis == Axis.X) {
dir = new Vector3f(1.0f, 0.0f, 0.0f);
} else if (axis == Axis.Y) {
dir = new Vector3f(0.0f, 1.0f, 0.0f);
} else if (axis == Axis.Z) {
dir = new Vector3f(0.0f, 0.0f, 1.0f);
} else {
throw new RuntimeException("Unknown axis: " + axis);
}
}
public void update(float time) {
float value = positive.getValue() - negative.getValue();
float delta = (value * time) * multiplier;
if (value != 0.0f) {
spatial.getLocalTranslation().addLocal(dir.mult(delta));
}
}
public GameControl getPositive() {
return positive;
}
public void setPositive(GameControl positive) {
this.positive = positive;
}
public GameControl getNegative() {
return negative;
}
public void setNegative(GameControl negative) {
this.negative = negative;
}
public float getMultiplier() {
return multiplier;
}
public void setMultiplier(float multiplier) {
this.multiplier = multiplier;
}
}
Thank you so much. I'm going to sit with how it works for now. I understand how InputHandler works now. I'm slowly getting a hand on how the api is set up. I'm not going to pursue fixing the angular rotation problem for now, but I'll leave the last part of the problem
I noticed that when using the TranslationController(thank you) that all i'm doing is moving the camera up and down. Which is good. however i'm not actually looking down at the object anymore. Simply put I want to be able to look down, but when I move left and right I want to keep the camera parrallel with the ground so that angle doesn't change.
I thank you so much for the help. I'm going to move on to getting textures into the game for now.