Quaternions, Camera and Inputs

Well I began scripting my game today (jME is very nice), and I am running into quite a number of annoying roadblocks. Mainly, I am trying to get rid of the other camera types and implement my own type, its going fine so far, I got scrolling to work, it responds properly to my WASD keys, with a minor problem. It moves “forward/backward” “left/right”, but in a very literal sense, It is not moving forward in the direction of my camera. My basic goal is to create a RTS camera, so zooming will be done by the mouse wheel. When I press my W key, I want my camera to move forward (only in the X axis in relation to the direction the camera is facing, but the Z offset of the camera from the ground should remain the same. I hope I make sense, here is my current “move forward” code:



[java]cam.setLocation(cam.getLocation().add(5, 0, 0));[/java]



My next and last major problem is that I want to limit the camera movement just a little bit before the camera reaches the edge of the map, or the current rootNode.getWorldBounding(). How can I accomplish this?



SIDE NOTE The funny part is that I actually had some more major issues that I worked on literally for an hour and a half before deciding to post this, but as I was describing the problem, I came up with solutions lol.



Thank you for the help in advance!

You should not implement your own camera but your own CameraControl but I guess you are doing that.

This doc should give you some more ideas how you can leverage the jme3 api to compute movement, rotation and the likes:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies

Thank you for that link, it actually explains quite a bit to me, however I still don’t really understand how to move a location forward in respect to the rotation though. I am trying various trigonometry, this gives me semi accurate results but moves a bit to the left / right on the process:

[java]float[] angles = cam.getRotation().toAngles(null);

float ySin = (float)Math.sin(angles[1]);

Vector3f forward = new Vector3f(ySin,0,0);

Vector3f backward = new Vector3f(-ySin,0,0);

if(name.equals(“MoveUp”))

cam.setLocation(cam.getLocation().scaleAdd(1, forward));

//cam.setLocation(cam.getLocation().add(5, 0, 0));

if(name.equals(“MoveDown”))

cam.setLocation(cam.getLocation().scaleAdd(1, backward));[/java]



EDIT again as I was posting I found my own solution for moving forward and backwards using trigonometry:



[java]float[] angles = cam.getRotation().toAngles(null);

float ySin = (float)Math.sin(angles[1]);

float yCos = (float)Math.cos(angles[1]);



if(name.equals(“MoveUp”))

cam.setLocation(cam.getLocation().add(ySin,0,yCos));

if(name.equals(“MoveDown”))

cam.setLocation(cam.getLocation().add(-ySin,0,-yCos));[/java]



Now the only thing relation to location movement I need to get down is moving left and right, or strafing I guess in respect to the rotation

Start using quaternions, they are good and will allow you to combine some things more easily. Think less in terms of rotation around some axis and more in terms of rotating a direction vector because thats whats mostly happening internally.

I understand what I did isnt exactly the most efficient thing to do, and I really appreciate your help too, its just I am not familiar with quaternions at all, I mean I went the the euclid site, I looked at the link you gave me above, but quaternions is just not something that is clicking in me, I mean I am sure if I understood it completely, then I could finish this camera stuff, its just that I am so used to thinking about location and moving location in terms of rotation.

I think probably 90% of the people who use quaternions don’t understand how or why they work… just that they do. :slight_smile:



Best to treat them like a magic black box that is equivalent to a 3x3 rotation matrix except that it gives you a few niftier and more efficient features (interpolation for example).

You don’t need to understand quaternions, its not easy to think in 4 dimensions, just know how to use them in jme3 :wink: The examples show how you can rotate a vector with a quaternion, now all you need to know that the quaternion that defines the rotation of the camera (or any object) is a relative rotation from the y-up / z-forward “default” orientation.

Lool well said , in any case I accomplished all my goals, however in the most inefficient methods possible, do you have any suggestions on how I can (first of all shorten) improve this code?:

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

float[] angles = cam.getRotation().toAngles(null);

float ySin = (float)Math.sin(angles[1]);

float yCos = (float)Math.cos(angles[1]);

Quaternion strafe = new Quaternion(new float[]{angles[0],angles[1] + (float)(90*(Math.PI / 180)),angles[2]});

float strafeYSin = (float)Math.sin(strafe.toAngles(null)[1]);

float strafeYCos = (float)Math.cos(strafe.toAngles(null)[1]);

if(name.equals("MoveUp"))

if(worldBounds.contains(cam.getLocation().add(ySin,0,yCos)))

cam.setLocation(cam.getLocation().add(ySin,0,yCos));

if(name.equals("MoveDown"))

if(worldBounds.contains(cam.getLocation().add(-ySin,0,-yCos)))

cam.setLocation(cam.getLocation().add(-ySin,0,-yCos));

if(name.equals("MoveLeft"))

if(worldBounds.contains(cam.getLocation().add(strafeYSin,0,strafeYCos)))

cam.setLocation(cam.getLocation().add(strafeYSin, 0, strafeYCos));

if(name.equals("MoveRight"))

if(worldBounds.contains(cam.getLocation().add(-strafeYSin,0,-strafeYCos)))

cam.setLocation(cam.getLocation().add(-strafeYSin, 0, -strafeYCos));

if(name.equals("RotateLeft"))

{

angles[1] += .025;

cam.setRotation(new Quaternion(angles));

}

if(name.equals("RotateRight"))

{

angles[1] -= .025;

cam.setRotation(new Quaternion(angles));

}

}[/java]



The only way I accomplished strafing is to create a imaginary rot quaternion that is facing 90 degrees to the left ( as seen), and then I just do the same trick I do to move forward.

Its ok, but you should augment the values with tpf to make it framerate independent.

Alright thanks, I guess I will figure that one out, thank you normen