- Home /
Difference between Transform.InverseTransformPoint(v) and Transform.worldToLocalMatrix * v
Basically, the following fragment
Vector3 vertexLocal = transform.worldToLocalMatrix * vertex;
Vector3 vertexLocalTest = transform.InverseTransformPoint(vertex);
if (vertexLocal != vertexLocalTest) {
Debug.LogError("I don't get it: " + vertexLocal + " != " + vertexLocalTest);
return;
}
Produces errors in console. It seems as if multiplication (vertexLocal) transforms the point not from world coordinates but from parent's coordinates. I assumed the two transformations were supposed to be identical. Aren't they?
Answer by runevision · Jan 06, 2011 at 10:08 AM
Don't use transform.worldToLocalMatrix * vertex
Use transform.worldToLocalMatrix.MultiplyPoint(vertex)
or transform.worldToLocalMatrix.MultiplyPoint3x4(vertex)
(more efficient)
Then you'll get identical results as expected.
Thanks.
Is it because my Vector3 got extended to Vector4 in some special way?
Point is, I was trying to come up with a way to transform many points from ancestor's coordinate system to the descendant's, and wanted to premultiply a copy of descendant's worldToLocal$$anonymous$$atrix with ancestor's "localToWorld$$anonymous$$atrix" when I discovered that operator * SEE$$anonymous$$S to do what I wanted. But before I rejoice I want to understand why and if I can rely on this effect.
Actually the operator version takes a Vector4 and uses the 4th component to multiply with the position. When supplying a Vector3 it gets converted to a Vector4 with the 4th component being 0, thus the position of the matrix gets ignored.
Thanks again. So that's just because the parent was translated, but not rotated, that it appeared to do what I needed.
Answer by apantev · Feb 01, 2015 at 06:18 PM
Since worldToLocalMatrix
is a 4x4 matrix and vertex
is only a Vector3 when the two are multiplied together vertex
is automatically converted to a Vector4 with a 4th component of 0.
So
transform.worldToLocalMatrix * vertex
Is the same as
transform.worldToLocalMatrix * new Vector4(vertex.x, vertex.y, vertex.z, 0)
But when that forth component is 0 the multiplication is ignoring the position of the matrix, which is why you see the wrong result.
As runevision has pointed out the following
transform.InverseTransformPoint(vertex)
Is the same as
transform.worldToLocalMatrix.MultiplyPoint3x4(vertex)
Which is the same as
transform.worldToLocalMatrix * new Vector4(vertex.x, vertex.y, vertex.z, 1)
I get that the first answer was accepted because it's correct and was there first.
But I actually think this answer is more complete as it explains in greater detail what is happening.
But it misses the fact that "$$anonymous$$ultiplyPoint3x4" is more efficient for pure linear transformations as the 4th row of the matrix is not needed. If you do a "$$anonymous$$atrix4x4 * Vector4" you have to do more calculations for the last row which are pretty pointless as it will always be (0,0,0,1) and doesn't contribute to the x, y and z components.
$$anonymous$$ultiplyPoint3x4 expects just a Vector3 and outputs a Vector3. It treats the 4x4 matrix like a 3x3 matrix and just adds the 4th column to the result. Therefore:
$$anonymous$$ultiplyPoint3x4
does 9 multiplications; 9 additions$$anonymous$$ultiplyPoint
does 12 multiplications; 1 division; 12 additions.the
* operator
does 16 multiplications; 12 additions
Note that "$$anonymous$$ultiplyPoint" does the homogeneous divide internally as it outputs a Vector3.