Hi!
I'm trying to rotate my camera such an Euler angles and I'm really having serious problems
I'll try a lot of things, like converting this angles to an quaternion, to a Matrix , with some codes I found on Internet, and then applying it directly to the cam but it has not the results I want. So I decided to use the CameraNode to make it easy, but also having problems.
First of all I want to say that I'm using Polhemus, a system of Tracking, which return me the angles in Euler mode. So this is because I can't change "the type of the angles". In openGL, I simply do something like:
glRotatef( ds.pnoInfo[1].az , 0.0f , 1.0f , 0.0f );
glRotatef( ds.pnoInfo[1].el , 1.0f , 0.0f , 0.0f );
glRotatef( ds.pnoInfo[1].roll , 0.0f , 0.0f , 1.0f );
and it works fine.
In jME I'll try several things but I think this ones are the most cute.
mNodeCam.setLocalRotation((new Quaternion(new float[] {ds.pnoInfo[1].az,0,0})));
mNodeCam.updateWorldData(0);
mNodeCam.setLocalRotation(new Quaternion(new float[] {0,ds.pnoInfo[1].el(),0}));
mNodeCam.updateWorldData(0);
mNodeCam.setLocalRotation(new Quaternion(new float[] {0,0,ds.pnoInfo[1].roll}));
mNodeCam.updateWorldData(0);
or
mNodeCam.setLocalRotation((new Quaternion(new float[] {ds.pnoInfo[1].az,0,0})));
mNodeCam.setLocalRotation(new Quaternion(new float[] {0,ds.pnoInfo[1].el(),0}));
mNodeCam.setLocalRotation(new Quaternion(new float[] {0,0,ds.pnoInfo[1].roll}));
mNodeCam.updateWorldData(0);
The Polhemus return the angles in radians.
Anyone knows what can be happening? Because I don't know what else try. If there is any suggest completely different of this, I'll also accept it
Thanks!
i think thats what you want:
/** fromAngles builds a quaternion from the Euler rotation angles (x,y,z). */
getLocalRotation().fromAngles(ds.pnoInfo[1].el, ds.pnoInfo[1].az, ds.pnoInfo[1].roll );
It could be a good solution I'll try it tomorrow.
Thankss!!!
Hi there,
I tried something similar than yours, but it doesn't work
I mean, I can't do getLocalRoatation because what I want is set, but I've got the idea, and I make a Quaternion using this function (fromAngles). The code was:
Quaternion mRotation = new Quaternion();
mRotation.fromAngles(ds.pnoInfo[1].el, ds.pnoInfo[1].az, ds.pnoInfo[1].roll );
rootNode.setLocalRotation(mRotation);
As you can see, I'll do it in a rootNode that contains a box (just to make it easier to verify if it's going well), but the only thing I've got it's a simple rotation in the Z Axis.
I think the problem it's next:
In openGL you can accumulate the operations, so when you do an rotation in X Axis and then another rotation in Y Axis is not the same than if you first do the rotation in Y Axis and then in X axis. So notice that in my code openGL:
glRotatef( ds.pnoInfo[1].az , 0.0f , 1.0f , 0.0f );
glRotatef( ds.pnoInfo[1].el , 1.0f , 0.0f , 0.0f );
glRotatef( ds.pnoInfo[1].roll , 0.0f , 0.0f , 1.0f );
I first do an rotation in Y Axis then in X Axis and finally in Z Axis... Anyway to do it?
Lots of thanks.
You can multiply quaternions to perform a delta rotation.
// Create a quaternion which represents the desired delta rotation.
// In this case I'm only rotating in the X axis.
Quaternion delta = new Quaternion(new float[]{.01f, 0, 0});
// multLocal() performs the multiplication AND updates the quaternion.
// mult() would perform the multiplication and return the result withoutout
// performing an update.
Quaternion current = ...
current.multLocal(delta);
Sorry if I don't inderstand it at all, but I think that what your code do is "auto Increment" the rotation, and in my case I have new angles in each update gived by my sensor. So I think it doesn't works. Thanks anyway
the two code pieces do the same.
rootNode.getLocalRotation()mRotation)fromAngles(ds.pnoInfo[1].el, ds.pnoInfo[1].az, ds.pnoInfo[1].roll );;
and
Quaternion mRotation = new Quaternion();
mRotation.fromAngles(ds.pnoInfo[1].el, ds.pnoInfo[1].az, ds.pnoInfo[1].roll );
rootNode.setLocalRotation(mRotation);
the 2nd version creates a new Quaternion while the first version used the already existing one.
Here is a modified TestRotateAboutPoint to show absolute and relative rotation
package jmetest.scene;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.scene.Node;
import com.jme.scene.shape.Sphere;
public class TestRotateAboutPoint extends SimpleGame {
private Sphere s;
private Sphere moon1;
private Node pivotNode1;
private float [] eulerAngles;
private Quaternion rot = new Quaternion();
private boolean absolute = true;
public static void main(String[] args) {
TestRotateAboutPoint app = new TestRotateAboutPoint();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleUpdate() {
if (absolute) {
eulerAngles[1] += tpf*1;
if (eulerAngles[1] > FastMath.PI) {
eulerAngles[1] = -FastMath.PI;
}
// set new rotation values based on the three euler angles
pivotNode1.getLocalRotation().fromAngles(eulerAngles);
} else {
// the following two lines add a small rotation to the existing
rot.fromAngles(0, tpf*1, 0);
pivotNode1.getLocalRotation().multLocal(rot);
}
// print out euler angles
float [] x = pivotNode1.getLocalRotation().toAngles(null);
System.out.println("euler[0] " +x[0]);
System.out.println("euler[1] " +x[1]);
System.out.println("euler[0] " +x[2]);
}
protected void simpleInitGame() {
display.setTitle("jME - Rotation About a Point");
eulerAngles = new float [3];
eulerAngles[0] = 0;
eulerAngles[1] = 0;
eulerAngles[2] = 0;
//Planet
s = new Sphere("Planet", 25, 25, 25);
s.setModelBound(new BoundingSphere());
s.updateModelBound();
rootNode.attachChild(s);
//Moon
moon1 = new Sphere("Moon 1",25, 25, 10);
moon1.setModelBound(new BoundingSphere());
moon1.updateModelBound();
moon1.setLocalTranslation(40, 0, 0);
pivotNode1 = new Node("PivotNode 1");
pivotNode1.attachChild(moon1);
rootNode.attachChild(pivotNode1);
cam.getLocation().z = 100;
}
}
Sorry for the confusion. I interpreted your question as asking how to accumulate the rotation one axis at a time.
I first do an rotation in Y Axis then in X Axis and finally in Z Axis... Anyway to do it?
I will make a brief explanation just in case someone will be in the same situation. What I finally do is a simple multiplication of the matrix, in the order I want, so this is de code:
y.fromAngleNormalAxis(getAngleY(), new Vector3f(0.0f , 1.0f , 0.0f));
x.fromAngleNormalAxis(getAngleX(), new Vector3f(1.0f , 0.0f , 0.0f));
z.fromAngleNormalAxis(getAngleZ(), new Vector3f(0.0f , 0.0f , 1.0f));
aux = y.mult(x);
aux = aux.mult(z);
where x , y , z and aux are the matrix and getAngleA returns the A angle of the sensor.
Thanks a lot for your attempts.