Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
8
Question by user132456789 · Oct 16, 2014 at 01:10 PM · quaterniondocumentation

Quaternion multiplication order

If I understand correctly multiplying two quaternions together is equivalent to applying the rotation of the first quaternion then the rotation of the second. In the Unity documentation it is stated :

Rotating by the product lhs * rhs is the same as applying the two rotations in sequence, rhs first and then rhs

The end of the sentence does not make sense for me. I would except either rhs first and then lhs or lhs first and then rhs. Can someone tell me which one of the two is correct ?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image chris-nolet · Jul 10, 2017 at 02:01 AM 0
Share

The documentation has been updated, and now reads: "Rotating by the product lhs * rhs is the same as applying the two rotations in sequence: lhs first and then rhs, relative to the reference frame resulting from lhs rotation." As Owen-Reynolds points out in his answer, below, it is left-to-right if you think of each transform being applied as a local rotation. If you want to think about applying transforms 'as if you're using the global rotation tool,' read it right-to-left ins$$anonymous$$d.

3 Replies

· Add your reply
  • Sort: 
avatar image
22

Answer by Owen-Reynolds · Oct 16, 2014 at 04:47 PM

Combining rotations (and using Quaternions) is one of those things where Unity just copies the way everyone else does it. So you can find better descriptions in general gaming-math sites.

The missing piece is local vs. global. If you have rotations A*B you can think of it as applying A as a global rotation to B. Or as applying B as a local rotation to A(*).

In other words, suppose R is the current rotation, and Ry is a small spin on Y, which you would like to apply. To apply it as if you're using the global rotation tool, use Ry*R. To apply the spin as if using the rotation tool set to local, use R*Ry.

In other, other words. A*B is B applied on local A, or global A applied to B, depending on how you want to think of it. Yes, it is very confusing until you settle on the "right" way to think of it for any particular problem.

Robot hand is a common example. To find the rotation of a hand bone, use globalRbotSpin localShoulderSpin localElbowSpin ... . All rotations are stored and applied locally.

(*) I always get the orders mixed up, and my Unity machine isn't here. It could be the other way -- left is local and right is global.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image user132456789 · Oct 17, 2014 at 07:32 AM 0
Share

Thanks. Nice explanation.

avatar image slippdouglas · Jul 16, 2016 at 01:35 AM 2
Share

Your logic of “applying A as a global rotation to B. Or as applying B as a local rotation to A” matches my own findings.  I believe you can remove the “I always get the orders mixed up” footnote.

avatar image Oliver-Bogdan · Jun 21, 2017 at 02:02 PM 0
Share

Great explanation, got to save this somewhere :)

avatar image chris-nolet · Jul 10, 2017 at 01:53 AM 0
Share

Can confirm: You have the order correct. (No need for the final paragraph/disclaimer.)

avatar image
2

Answer by winxalex · Nov 30, 2019 at 05:01 PM

SUPER SIMPLE: alt text alt text

  //Note: Rotation values in Inspector are in Local space
             //Let say Quaternion is something that contain information of how some 3D object is rotated
             //for simplicity we will use just rotation aroundY and let say we have one parent game object and one child
             //let parent is rotated 60 degree, and child is 30degree.
             //as parent is first element in the world and world is not rotated it has same global and local rotation represented by Quaternions
             //parentGO.transform.rotation==parentGO.transform.localRotation
             //child has 60degree rotation from parent and 30 itself so it has 90 degree global rotation, and 30 local as we said
             //childGO.transform.rotation.eulerAngles.y will be 90
             //childGO.transform.localRotation.eulerAngles.y will be 30
             //When we use multiply 2 Quaternions A * B, 
             **//Think Quaternions A * B as addition: of A+B=C, if A gives rotation of 60 and B of 30, A*B will give rotation of 90 degree
             //Think of A as global rotation (transform.rotation) or as quaternion value, delta offset  for B (delta + B)
             //Think of B as local rotation (transform.localRotation) or quaternion value,  delta offset  for A (A + delta)**
             //so to find out child global rotation
             // parentGO.transform.rotation * childGO.transform.localRotation; // 60+30=90 gives you quaternion that will rotate something 90degree
     
             // if Quaternon gives you rotation, inverse quaternion gives you minus rotation, ex. if A=60, Inverse(A)=-60
             //but what if we have child global rotation which is 90 in our case, and we want to find child local rotation
             //Quaternon.Inverse(childGO.transform.parent.rotation) * childGO.transform.rotation; // (-60 + 90 = 30)  
     
             //(delta + B)
             //so what if we want to rotate childGO locally for 10degree more, was 30, so plus 10 will be 40
             //childGO.transform.localRotation = Quaternion.AngleAxis(10, Vector3.up) * childGO.transform.localRotation; //(10+30)=40
     
             //(A + delta)
             //so what if we want to rotate childGO globally for 10degree more, was 90degree, will be 100 
             //childGO.transform.rotation = childGO.transform.rotation * Quaternion.AngleAxis(10, Vector3.up); //(90+10)=100



clipboard25.jpg (82.6 kB)
clipboard24.jpg (71.4 kB)
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Owen-Reynolds · Nov 30, 2019 at 09:15 PM 1
Share

You seem to always have both rotations around y. That's a degenerate, easy, case where the order doesn't matter. To see what the question is asking, take any other rotations -- like around y and x.

avatar image winxalex Owen-Reynolds · Apr 18, 2020 at 11:58 PM 0
Share

Quite degenerative when in your answer you also have Ry. which maybe mean rotation around y,x? Right?. Order of what? A * B not equal to B*A where A,B are Quats Good answer can be found here.

https://gamedev.stackexchange.com/questions/140579/euler-right-handed-to-quaternion-left-handed-conversion-in-unity

avatar image Owen-Reynolds winxalex · Apr 19, 2020 at 12:09 AM 0
Share

If you have both rotations around y, such as Ry1 and Ry2, then Ry1*Ry2 is just adding the y-rotations. It's a super-easy special case. In math. that's called a degenerate case. If only 1 is around y, it's as complex as all the rest.

avatar image
1

Answer by EricHFrazer · Apr 19, 2020 at 07:27 AM

I posted this earlier, then got so annoyed at the comments, I deleted it. I'm going to repost and try to be more concise... I'm going to get to the point first, then explain some things afterwards.

Suppose you have an object "O" and want to rotate it by a quaternion Q. You need to decide if you want it to rotate around the world axis, or the object's own local axis. (Most of the time I want it to rotate around its local axis)

 W: O.transform.rotation = Q * O.transform.rotation   <- this rotates around world axis
 L: O.transform.rotation = O.transform.rotation  * Q <- this rotates around its local axis

That's it. Those are the two forms you need to remember. The way I remember the order is because (as the docs say), when Unity runs across A mul B, the * operator override performs the A rotation first (LHS), then applies the B operation next (RHS). In my head I phrase it "gives it an extra spin at the end of everything". Iif you give it the extra spin before its normal spin, that's not going to happen "locally". That's a global (world) spin.

Another sort of non-obvious result of this is that if you have a cube at a distance from 0,0,0, and you want to rotate it in a giant circle around say the Y axis, like a planet, you can't do that by applying varying rotations on the transform, without that object having a parent, and even then you have to rotate the parent, not the object itself. If you were to try to rotate the object "around the world axis Y", it would simply spin in place around the up and down axis in the world. Not spin around 0,0,0's Y axis. Obvious to some, but not to everybody.


Somebody wrote me a private message and said, "you don't know what you're talking about wrt local rotations and parents. Nothing in Unity when it comes to setting rotations and positions matters with regards to if it has a parent or not". So polite. Well, it's true and it ain't true. Let me explain...


Put two identical objects into a scene. One of them has a parent, one of them does not. The one with a parent, the parent has some non-zero position and rotation offset. I set both the objects' world position and rotation to something interesting. I can do it via independently setting position and then rotation, or I could call SetPositionAndRotation. Both the objects end up in exactly the same world position and world rotation. So what's the difference? The difference is that under the hood, during the = assignment for both position and rotation, Unity peeks at where you want it to be, and calculates where it already is (by looking at the parent chain), and it calculates deltas, and sets the local component to whatever it needs to be in order to get the object to where it should be. This applies to position AND it applies to rotation. In fact, rotation is "a bit special". When you assign a world rotation to an object that has a parent, it will change both the local position and the local rotation to get the object to the exact spot you've told it to be at. I find this interesting...

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image EricHFrazer · Apr 19, 2020 at 07:34 AM 0
Share

the thing that is killing me personally, comprehension wise, is this: I have some stereo camera calibration rotation matrices. One for the L camera, one for the R. Both the rotation matrices are in LH coordinate systems... They tell the cameras which way to rotate compared to the headset, in order to have the images be perfect. Now, I run the images through some openCV software, which is RH-based, and deter$$anonymous$$e according to openCV, that the L camera needs to be rotated an extra $$anonymous$$atrix4x4, call it $$anonymous$$, in order to be correct. I need to figure out how to translate this RH-based OpenCV matrix's angles to angles Unity can understand. I don't know the best way to decompose the $$anonymous$$ matrix into rotation angles around X, Y, and Z, and in what order. And once I have those values, I'm not quite sure how to construct a quaternion out of them in order to get that applied to the L camera object in Unity. It's a real stumper. I think OpenCV calculates 4x4 $$anonymous$$atrixes with Rout = Rz Ry Rx. And Unity calculates Quaternions and its 4x4 matrices using Ry Rx Rz. (?)

avatar image Owen-Reynolds EricHFrazer · Apr 19, 2020 at 05:32 PM 0
Share

Try asking this as a separate Q. Possibly break it down, for example "convert euler zyx into Unity eulers". Forums also has a dedicated area for VR. "How to use VR software package X" seems fine for that.

avatar image Owen-Reynolds · Apr 19, 2020 at 05:38 PM 0
Share

You're assu$$anonymous$$g that we care about either the object's current rotation or a possible parent's. Often we don't -- we have 2 arbitrary rotations to combine. We often aren't even using the result to rotate a gameObject -- it's part of some other equation.

Your examples of "rotate an object" and "set child rotation" are just 2 of the many things we might use lhs*rhs to do.

avatar image remi07 · Jan 15, 2021 at 02:08 AM 0
Share

"that by applying varying rotations on the transform, without that object having a parent, and even then you have to rotate the parent, not the object itself. If you were to try to rotate the object "around the world axis Y", it would simply spin in place around the up and down axis in the world. Not spin around 0,0,0's Y axis."

I don't think I agree? Ie if an object is at transform.position away from 0,0,0. Say its walking at the surface of a planet. Then to make it spin along the Y axis (or Vector3.up) you just need to do

 newPosition = Quaternion.Euler(Vector3.up * angle) * transform.position;

You don't need a parent?

avatar image Owen-Reynolds remi07 · Jan 15, 2021 at 03:55 AM 0
Share

Sure, but now you're explicitly changing position, and bringing in a vector. I think the point was that by themselves, rotations are only around the gameObject's origin.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Printable version of the documentation? 1 Answer

MonoDevelop not showing description of methods etc. with autocomplete? 1 Answer

How to use GameDraw Extension and Is there a Documentation? 2 Answers

How to make tab in editor near the top? 1 Answer

Documentation: optimizing scripts - I think there's an error. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges