- Home /
Matrix4x4.MultiplyVector: docs wrong?
The doc page for Matrix4x4.MultiplyVector
(https://docs.unity3d.com/ScriptReference/Matrix4x4.MultiplyVector.html) says, "This function is similar to MultiplyPoint; but it transforms directions and not positions. When transforming a direction, only the rotation part of the matrix is taken into account."
And yet, when I change the scale of the transform I use to get the Matrix4x4, the result of this function also changes.
So, it appears MultiplyVector actually takes BOTH rotation and scale into account, right? (If not, what am I misunderstanding? Why does changing the scale affect the result of this function?) This is what I would EXPECT, based on the function's name- but the doc's explicitly state otherwise.
Secondary question: Does this mean I should use Matrix4x4.rotation if I REALLY want to multiply a "direction" Vector3, and take ONLY rotation into account? (I don't see a true "multiplyDirection" function defined in the Matrix4x4 class.)
(If I get agreement in the answers, I'll submit feedback on the doc page, and would suggest you do the same.)
Quaternions are the simplest way to do pretty much anything. $$anonymous$$atrices are really only exposed for people who already know them. That's why the docs are rough. I mean, they should just say "in the usual way" or "4th column is zeroed out" or something a little more technical.
Are you using matrices for a special reason, or are you just trying to rotate a vector?
I was generating a bunch of TransformRelativeToAncestor extension functions and was trying to emulate the format for the various built-in Transform functions: TransformPoint, TransformVector, and TransformDirection. The only one that gave me wrong (or at least dissimilar) results when using matrices was my TransformDirectionRelativeToAncestor. (the matrix I use is just: ancenstorTransform.worldToLocal$$anonymous$$atrix * transform.localToWorld$$anonymous$$atrix
)
Answer by Bunny83 · Oct 05, 2018 at 11:03 PM
The "rotation part" of a 4x4 matrix does always include the scale as well. MultiplyVector just does a 3x3 matrix multiplication with the top 3x3 section of the 4x4 matrix.
For reference see my matrix crash course (on UnityAnswers)
The transformation matrix contains the combined the transformations that the Transform component represents. If you just want to apply the rotation of an object, use the Quaterion and not the matrix.
There are ways to extract just the rotation from a 4x4 matrix, however even a local matrix in Unity is only composed of translation, rotation and scale, a deeper nested local to world matrix may contain a shear operation as well (a shear would be produced by non uniform scaling and rotation). This makes it quite difficult to decompose a matrix into the seperate parts. In Unity it would make much more sense to just use the Quaternion.
Another alternative would be Transform.TransformDirection (if you don't need to be thread indepentent).
To answer your actual question, no, the docs are correct since it talks about the "rotation part" of the matrix which includes scale (and possible a shear). Though the docs could have mentioned explicitly that the scale affects the result, especially for those who are not familiar with matrices. Though most documentation pages are that short and could be more precise.
(Edit) Relevant detail from the comments: "So what actually is wrong in the documentation is the following sentence from the Transform.TransformDirection documentation:
"Transforms direction from local space to world space."
It does not transform a direction from local space to world space but just applies the wordspace rotation to a vector. If you only deal with uniform scales this is not really an issue since uniform scaling does not change the direction."
ps: Note that $$anonymous$$atrix4x4.rotation just
Attempts to get a rotation quaternion from this matrix
Since a matrix represents the combined result of several affine tranformations, extracting just the rotation may not be possible. Also keep in $$anonymous$$d that if the matrix contains a non uniform scaling the actual local space coordinate system will be squashed / stretched so the scale actually does affect the final direction of a vector. Ignoring the scale and just using the rotation it would not properly transform a direction from local space to world space.
"Ignoring the scale and just using the rotation it would not properly transform a direction from local space to world space" Can you explain this? I thought that is exactly what Transform.TransformDirection
does. That function's behavior is exactly what I was hoping to emulate, using a matrix.
Perhaps relevant? $$anonymous$$y use-case matrix is intended to transform relative to an ancestor's local-space, rather than world-space: e.g. ancenstorTransform.worldToLocal$$anonymous$$atrix * transform.localToWorld$$anonymous$$atrix
(I thought using it would be faster, and more consistent, than iterating the hierarchy for each transformation.)
Transform.TransformDirection only applies the rotation of the transform hierarchy. A coordinate space however could be transformed in various ways. In case your space is non uniformly scaled the same local space direction would actually point into a different world space direction.
The position of the small sphere is the result of TransformDirection(Vector3.one * 0.5f). The cube is located at the world origin. The cube is scaled "2, 1, 1" and you clearly see that the same vector in local space will actually end up at a different point in worldspace due to the scale only. A similar thing can be noticed when the object is sheared:
So what actually is wrong in the documentation is the following sentence from the Transform.TransformDirection documentation:
Transforms direction from local space to world space.
It does not transform a direction from local space to world space but just applies the wordspace rotation to a vector. If you only deal with uniform scales this is not really an issue since uniform scaling does not change the direction.
If you want to emulate what TransformDirection does, just use the quaternions of the transforms ins$$anonymous$$d of the localToWorld / worldToLocal matrix.
If you have some time i would recommend to watch some of the 3blue1brown videos on matrices and linear transformations
Your answer
Follow this Question
Related Questions
Physic Material Friction Combine Mode lack of documentation? 2 Answers
Generating (HTML) documentation for Unity Script (not C#) ? (like Doxygen) 1 Answer
Networking Destroy Player's RPC function uhm WHAT? 1 Answer
uGUI API Documentation 2 Answers
Current (5.3) Documentation (Manual and Scripting Reference) Download 2 Answers