Last active
January 18, 2023 06:44
-
-
Save GeorgiyRyaposov/e42397cd76a524573ba12ab762890d1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//To get the difference C between quaternions A and B you do this: | |
C = A * Quaternion.Inverse(B); | |
//To add the difference to D you do this: | |
D = C * D; | |
///////////////// | |
//World vs local | |
//An easy way to keep track of the order of operations for quaternions is to think of it in terms of world and local rotations. | |
//When multiplying a quaternion the world rotation is on the left, and the local rotation is on the right, like this: | |
finalRotation = worldRotation * localRotation; | |
//For example if you took the global rotation of an object and then multiplied it by the localRotation of a child of that object you | |
//would get the global rotation of that child object: | |
childRotation = parentTransform.rotation * childTransform.localRotation; | |
//You can also use this to add an offset to a rotation, for instance if you wanted to rotate an object around it’s local z axis | |
//you would just do something like this: | |
tranform.rotation = targetRotation * Quaternion.Euler(0, 0, 90); | |
//Of course this also applies to global rotations, if you want to rotate an object in global space you would just do this: | |
tranform.rotation = Quaternion.Euler(0, 0, 90) * transform.rotation; | |
/////////////// | |
//Adding and Subtracting | |
//To subtract one rotation from another you are going to need to get it’s inverse like so: | |
inverseRotation = Quaternion.Inverse(rotation); | |
//One of the main uses for this is getting the rotation between two rotations. | |
//For example if you wanted to know the Quaternion that would get you from rotationA to rotationB you would do something like this: | |
FromAtoB = Quaternion.Inverse(rotationA) * rotationB | |
//You would then get the rotation between them, this is most useful when you want to copy the offset of one thing to another thing | |
//For example maybe you want to make two levers mirror each other and refuse to use local rotations for whatever reason. | |
offset = Quaternion.Inverse(lever1BaseRotation) * lever1Rotation | |
lever2Rotation = lever2BaseRotation * offset | |
//Multiple rotations at once | |
//So maybe you’re completely insane and you want to do multiple rotations at once in the same equation, | |
//maybe you’re storing local rotations with an offset or something in a scriptable object for and auto hand poser or something. | |
//The trick is to always keep the order of operations. So if you did something like this to store rotation3: | |
rotation3Offset = Quaternion.Inverse(rotation1) * Quaternion.Inverse(rotation2) * rotation3 | |
//to get back to rotation3 you would need to do this: | |
rotation3 = rotation1 * rotation2 * rotation3Offset | |
//This can even work with predefined local offsets if you’re carful: | |
storedRotation = Quaternion.Inverse(parentRotation) * rotationToStore * Quaternion.Inverse(offset) | |
rotationToStore = parentRotation * storedRotation * offset | |
//Sorry if none of that made sense, but I hope it helps someone. If I’m just crazy please send help. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment