Mouselook in JME3

There must be an easy answer to this… :smiley:



I’m trying to make a node rotate with mouse movement (e.g. the ‘player’ node wants mouselook). Searching this forum only seems to come up with MouseLook and FirstPersonHandler stuff which isn’t (as far as I can tell) in JME3. I disabled the FlyCam (which had the mouselook I wanted, but not as a node).



How do I capture the mouse and have it control where a node is looking? :slight_smile:



Thanks!

If it were me… I’d just look at the source code for FlyCam and see how it does it. The general idea is that you add an analog listener for the mouse axes and then set a rotation based on the values you get from that listener.



The part of FlyCam that calculates the rotation should be exactly what you need… it’s just how you apply that rotation that’s different.

1 Like

If you are talking about getting a node to face the mouse pointer … basic idea :



figure out the position of the mouse in world space - cast a ray from the camera to the mouse and get the contact point (Vector3f)

figure out where that point is relative to your node - mouse contact point subtract node position

create a new Quaternion and rotate it so it lines up with the vector from the above step - quaternion lookAt contact point subtract node position

apply that Quaternion to your node - node rotation = quaternion above

Good idea… this is the ugly code that rotates the camera:



[java] protected void rotateCamera(float value, Vector3f axis){

if (dragToRotate){

if (canRotate){

// value = -value;

}else{

return;

}

}



Matrix3f mat = new Matrix3f();

mat.fromAngleNormalAxis(rotationSpeed * value, axis);



Vector3f up = cam.getUp();

Vector3f left = cam.getLeft();

Vector3f dir = cam.getDirection();



mat.mult(up, up);

mat.mult(left, left);

mat.mult(dir, dir);



Quaternion q = new Quaternion();

q.fromAxes(left, up, dir);

q.normalize();



cam.setAxes(q);

}[/java]



Unfortunately, Nodes don’t have “getUp()” etc. I’m assuming I can get this information from getLocalRotation.getRotationColumn(…) though…

You could to this a different way… I’m assuming you want “quake style” rotation where there is no roll, only pitch and yaw…



In which case, keep the yaw and pitch as values and use the mouse to adjust them. Then convert those into a single rotation. I don’t know if q.fromAngles( pitch, yaw, 0 ) does it or if you have to combine a pitch quaternion and a yaw quaternion separately.



Just in case definitions are necessary:

-pitch is shaking your head yes

-yaw is shaking your head no

-roll is cocking your head to look at someone like you don’t know what they are talking about. :slight_smile: There, just like that. :wink:

1 Like

Sweeeet! This works:

[java] public float Yaw, Pitch;

private Quaternion rotator = new Quaternion();

public void Rotate(float value, boolean pitch) {

if( pitch ) {

Pitch += value;

} else Yaw += value;

rotator.fromAngles(Pitch, Yaw, 0);

myNode.setLocalRotation(rotator);

}

[/java]

Oh, and this is the code to capture the mouse (and the WASD keys):

[java] mouseInput.setCursorVisible(false);

inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));

inputManager.addMapping("Forward", new KeyTrigger(KeyInput.KEY_W));

inputManager.addMapping("Back", new KeyTrigger(KeyInput.KEY_S));

inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));

inputManager.addMapping("MouseXU", new MouseAxisTrigger(MouseInput.AXIS_X, true));

inputManager.addMapping("MouseYU", new MouseAxisTrigger(MouseInput.AXIS_Y, true));

inputManager.addMapping("MouseXD", new MouseAxisTrigger(MouseInput.AXIS_X, false));

inputManager.addMapping("MouseYD", new MouseAxisTrigger(MouseInput.AXIS_Y, false));

inputManager.addListener(myListener, new String[]{"Left", "Right",

"Forward", "Back", "MouseXD", "MouseYD", "MouseXU",

"MouseYU"});

[/java]

[java] private AnalogListener myListener = new AnalogListener() {

public void onAnalog(String name, float value, float tpf) {

if (name.equals("Forward")) {

myWorld.Player.AccelForward(Entity.WALK_ACCEL, Entity.MAX_WALK_SPEED);

} else if( name.equals("Back")) {

myWorld.Player.AccelForward(-Entity.WALK_ACCEL, Entity.MAX_WALK_SPEED);

}

if( name.equals("Left") ) {

myWorld.Player.AccelLeft(Entity.WALK_ACCEL, Entity.MAX_WALK_SPEED);

} else if( name.equals("Right") ) {

myWorld.Player.AccelLeft(-Entity.WALK_ACCEL, Entity.MAX_WALK_SPEED);

}

if( name.equals("MouseXU") ) {

myWorld.Player.Rotate(value, false);

}

if( name.equals("MouseYU") ) {

myWorld.Player.Rotate(value, true);

}

if( name.equals("MouseXD") ) {

myWorld.Player.Rotate(-value, false);

}

if( name.equals("MouseYD") ) {

myWorld.Player.Rotate(-value, true);

}

}

};

[/java]

Thanks everyone :slight_smile:

1 Like