Comments and answers for "Invert quaternion rotation"
http://answers.unity.com/questions/1144912/invert-quaternion-rotation.html
The latest comments and answers for the question "Invert quaternion rotation"Comment by elder0010 on elder0010's answer
http://answers.unity.com/comments/1146079/view.html
it is working finally :) thank you!!Tue, 23 Feb 2016 08:44:41 GMTelder0010Comment by Eno-Khaon on Eno-Khaon's comment
http://answers.unity.com/comments/1145409/view.html
Ohh, wait... When you said roll and pitch were inverted, did you mean I had them swapped with each other, then?
If so, that changes it from
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.right) * Quaternion.AngleAxis(-v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
to
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.forward) * Quaternion.AngleAxis(-v.x, Vector3.right) * Quaternion.AngleAxis(-v.z, Vector3.up);
instead.
At any rate, the rotation axes (forward/right/up) can all be modified freely to try different results. The main thing to keep consistent are the inputs into the final rotation (v.y, v.x, v.z).Sun, 21 Feb 2016 19:34:44 GMTEno-KhaonComment by elder0010 on elder0010's comment
http://answers.unity.com/comments/1145400/view.html
Nope :(
Changing from
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.right) * Quaternion.AngleAxis(-v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
to
transform.rotation = Quaternion.AngleAxis(-v.y, Vector3.right) * Quaternion.AngleAxis(v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
has the only effect to change the sign of the inverted axes (ie: rolling on the right raises the object instead of lowering it)Sun, 21 Feb 2016 19:09:59 GMTelder0010Comment by Eno-Khaon on Eno-Khaon's comment
http://answers.unity.com/comments/1145390/view.html
For each translated axis at this point, it should be a reasonably simple conversion to get them lined up.
The key order of axes in the axis translation is established now (`rotation = yRot * xRot * zRot`), so what's left is to correct each output axis.
When you say that yaw is correct, but pitch and roll are not, that correlates with Vector3.up, Vector3.right and Vector3.forward respectively. Therefore, up is matched while right and forward are inverted.
So, let's simply try inverting those and see how it works out:
transform.rotation = Quaternion.AngleAxis(-v.y, Vector3.right) * Quaternion.AngleAxis(v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
Effectively, for any testing purposes, the input axes (Vector3 v) must remain in the correct order, but the output axes (Vector3.right/forward/up) can be in any order, positive or negative.
By that same logic,
Quaternion.AngleAxis(-v.z, Vector3.up)
// is identical to
Quaternion.AngleAxis(v.z, -Vector3.up)
It would theoretically make more sense to keep the inputs constant and change only the outputs, but I had kind've a one-track mind when I first put it together.Sun, 21 Feb 2016 18:34:05 GMTEno-KhaonComment by elder0010 on elder0010's comment
http://answers.unity.com/comments/1145255/view.html
You are absolutely right, i checked again and getting back to your version of the code i do not have weird rotations.
Anyway, i still have 2 swapped axes: the roll and pitch are inverted. yaw is working correctly. With vector3 approach the correct rotation is obtained by using (y,-z,-x)
Vector3 v = arduino.getVector3 ();
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(v.y, -v.z, -v.x), Time.deltaTime * arduino.getEasingValue());
My object is placed at 0,0,0 and my camera is placed just behind it, at 0.22,0.22,-1.36 if this can help!
Here is the code:
Quaternion q = arduino.getQuaternion ();
emptyObject.transform.rotation = Quaternion.Slerp(emptyObject.transform.rotation, q, Time.deltaTime * arduino.getEasingValue());
Vector3 v = emptyObject.transform.eulerAngles;
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.right) * Quaternion.AngleAxis(-v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);Sun, 21 Feb 2016 10:25:00 GMTelder0010Comment by Eno-Khaon on Eno-Khaon's comment
http://answers.unity.com/comments/1145120/view.html
Hmm... I think there may have been a miscommunication on something, based on this. In your original post, you mention that the correlating axes, when related to Unity's (x, y, z), are (y, -z, -x).
If you convert the basic axes (x, y, z) to rotational axes (for use with AngleAxis), that gives you (right, up, forward).
From there, they key to recreating rotations in Unity using Euler angles is to process the rotations in the same order that Unity does: Z, X, Y
In order to reproduce that with twisted axes, I applied them as `rotation = yRot * xRot * zRot`. This resulted in rotations matching the changes I actively made. Any other ordering resulted in the second object refusing to match rotation and twisting about in unusual ways.
In your latest example here, you've reordered the rotations into Z Y X order, which doesn't match Unity's own ordering of Euler Angle generation.
Additionally, your conversion, rather than (y, -z, -x) has turned into (-x, -y, -z).Sat, 20 Feb 2016 23:40:28 GMTEno-KhaonComment by elder0010 on elder0010's comment
http://answers.unity.com/comments/1145114/view.html
and this approach will not be affected by gymbal lock?Sat, 20 Feb 2016 23:22:26 GMTelder0010Comment by elder0010 on elder0010's comment
http://answers.unity.com/comments/1145105/view.html
Using your approach i don't need anymore to switch any of the xyz axis, i just need to negate the values! The rotation works but it gets screwed sometimes. for example, if the X value is > 330, it will get back to 290 and then up again over 330. This is caused by the gymbal lock. I have no problem if i work with quaternions of course.
here is the code:
Quaternion q = arduino.getQuaternion ();
emptyObject.transform.rotation = Quaternion.Slerp(emptyObject.transform.rotation, q, Time.deltaTime * arduino.getEasingValue());
Vector3 v = emptyObject.transform.eulerAngles;
transform.rotation = Quaternion.AngleAxis(-v.x, Vector3.right) * Quaternion.AngleAxis(-v.y, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up) ;Sat, 20 Feb 2016 22:44:42 GMTelder0010Comment by Eno-Khaon on Eno-Khaon's comment
http://answers.unity.com/comments/1145080/view.html
Hmm... what direction(s) is it facing when this happens? Or, rather, what is the orientation of the Arduino input vs. how it is reflected in Unity in this case?Sat, 20 Feb 2016 22:11:50 GMTEno-KhaonComment by elder0010 on elder0010's answer
http://answers.unity.com/comments/1145059/view.html
The idea works, but it's still suffering from gymbal lock issues, due to the Vector3 data!Sat, 20 Feb 2016 21:12:05 GMTelder0010Answer by Eno-Khaon
http://answers.unity.com/answers/1145034/view.html
I would suggest utilizing an extra empty object to convert your rotations accurately.
Namely, use your first example to rotate an empty object, to get proper orientation to prepare to convert to a new set of axes.
Quaternion q = arduino.getQuaternion ();
emptyObject.rotation = Quaternion.Slerp(emptyObject.rotation, q, Time.deltaTime * arduino.getEasingValue());
Then, you can break down each axis and convert them for use in your visible object. However, doing this requires special attention paid to the order of operations. According to Unity's [documentation on Euler Angles][1],
> The x, y, and z angles represent a
> rotation z degrees around the z axis,
> x degrees around the x axis, and y
> degrees around the y axis (in that
> order).
Applying this in your case, then, can be done like this:
Vector3 v = emptyObject.eulerAngles;
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.right) * Quaternion.AngleAxis(-v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
The angles are applied matching the order of Unity's application of axes, in the correct order, but are then applied to the relative axes to which they now correlate.
[1]: http://docs.unity3d.com/ScriptReference/Transform-eulerAngles.htmlSat, 20 Feb 2016 19:42:14 GMTEno-KhaonComment by Bunny83 on Bunny83's comment
http://answers.unity.com/comments/1145029/view.html
No, he means a quaternion can be expressed as two direction vectors, usually "forward" and "up". If you multiply Vector3.forward with your quaternion you get the rotated forward vector. Doing the same with Vector3.up will give you the up vector.
Now you should fix the vector representation probably by rotating and / or mirroring the vectors at certain axis. Finally you just have to use Quaternion.LookRotation to convert the forward and up vector back to a quaternion.Sat, 20 Feb 2016 19:21:18 GMTBunny83Comment by elder0010
http://answers.unity.com/comments/1144998/view.html
that's what i have tried to do as you can see in the code, but i experience gymbal lock! And yes, my arduino gives me a correct quaternion (not a converted vector3!)Sat, 20 Feb 2016 17:32:23 GMTelder0010Comment by Owen-Reynolds
http://answers.unity.com/comments/1144969/view.html
Maybe try turning the Quaternion into a Vector3, fixing that for the wrong axis and converting back to a Quat? That would lose information about local spin, but I don't think arduino gives you that anyway -- it's probably just giving you a local UP (or whatever) as a quaternion.
Or, this sounds like a solved problem somewhere in a math forum. Changing axis has got to be common.Sat, 20 Feb 2016 15:44:43 GMTOwen-Reynolds