How to rotate a Node using Quaternions?

Hi, how do I rotate a Node 90 degrees counter clockwise in the x (horizontal) axis?



I’ve never really gotten a grasp around quaternions… Documentation would be awsome :slight_smile:



PS: By documentation I mean like code examples. If you just plain want to know about Quaternions there are lots of good stuff at Gamedev and such.

I’m probably missing the overall point of your question… but, if you wanted to create a Quaternion that is 90 counter clockwise (-90) degrees in the x axis, you’d do:


Quaternion q = new Quaternion();
q.fromAngles({-90, 0, 0});



or if you had a rotational matrix that contained your rotation

Quaternion q = new Quaternion();
q.fromRotationMatrix(rotMatrix);



If you want to smoothly rotate a node from 0 degrees to -90 degrees you'd use slerp.


Quaternion q1 = new Quaternion(); //start
Quaternion q2 = new Quaternion();
q2.fromAngles({-90,0,0});//end

//during update rotate a little bit based on time
node.setLocalRotation(q1.slerp(q1,q2,timeFactor));

1 Like

Thanks for the reply.



No, I have a Quaternion, and I want to rotate it instantly -90 degrees.

Then you’ll just want to use the fromAngles method on that quaternion.

Ah, ok, I see it takes a float[] as argument, so now I’m wondering how I would get the float[] it’s already rotated in?.. hrm…

Oh wait… I think I see what you are asking… if you can rotate a quaternion facing in some arbitrary direction a certain number of degrees…



In that case you have to switch back and forth between either the matrices or the angles.


  1. get the angles of your current orientation from the quat.
  2. rotate them a bit.
  3. set the angles of the quat.

missed your last post…



here’s code that rotates a node: (from KeyNodeRotateLeftAction)


//lockAxis is the axis we don't want affected, in FPS games, it's the Up axis.
incr.fromAxisAngle(lockAxis, speed * evt.getTime());
node.getLocalRotation().fromRotationMatrix(
incr.mult(node.getLocalRotation().toRotationMatrix(tempMa),
tempMb));
node.getLocalRotation().normalize();


As you might notice, we never directly deal with the quaternion besides the fromRotationMatrix, toRotationMatrix methods. We only work with Matrix3f objects (incr, tempMa, tempMb)

Ok, what should that lockAxis look like?

cam.getUp()…



but depending on what you are doing, you may not need the lockAxis at all.


incr.fromAxisAngle(node.getLocalRotation().getRotationColumn(1,
                    tempVa), speed * evt.getTime());



where tempVa is just a placeholder.

I'm afraid I may be overloading with information rather than just answering your question. Let me know if that is the case.

I can’t get it to work :frowning:



In case it makes this more clear, the reason why I want to do this is because I want a nice laser beam - built up by quads attached to a Node - to face the same direction as my weapon (which gives me the rotation in a Quaternion form).



To make the laser beam point in the same direction as the weapon firing it, I need to set it’s rotation to the weapons rotation -90 degrees (since the quads length are in the x axis).



Hehe, this was a rather strange explanation, but I hope you understand anyways.

This is what I do inside the beam constructor:

// rotation = the weapons rotation.

setLocalRotation(rotation);



Matrix3f incr = new Matrix3f();

Matrix3f tempMa = new Matrix3f();

Matrix3f tempMb = new Matrix3f();



float angle = -90*com.jme.math.FastMath.DEG_TO_RAD;



Vector3f tempVa = new Vector3f();



incr.fromAxisAngle(getLocalRotation().getRotationColumn(1, tempVa),

        angle);



//incr.fromAxisAngle(lockAxis, angle);

getLocalRotation().fromRotationMatrix(

incr.mult(getLocalRotation().toRotationMatrix(tempMa), tempMb));

getLocalRotation().normalize();





and this is the result I’m getting:

hmmm ok, I’ll have to do a little “thinking” on it, unfortunately, I need to get back to work for the moment. So, if someone else can help in the meantime… :slight_smile:



The screenshot looks great, btw. (besides the misoriented laser).



I’ll be back in a little bit to help all I can.

great thanks to your engagement mojomonk :slight_smile:

since the laser is being shot by your ship, can you use it’s rotation to orientate the laser?



laser.getLocalRotation().set(ship.getLocalRotation());

will the laser always shoot into the center of the screen? if so, you could probably use a shortcut involving converting known screen coords to world coords. Then using that point and the ships point, orient the laser quad.

No, the laser will shoot in the same direction as the weapon. The weapon is a node attached to the ship (atm. it has a local rotation of (0,0,0) so the world rotation is still the same as the ships).



However I’ve already tried sending the ships local rotation instead of the weapons world rotation, but with the same result…



/Per