- Home /
MeshFilter, World & Local Coordinates and InverseTransformPoint()
Hello, I've got a hell of an headache trying to debug that during 3 days.
So there is the problem : First of all, I'm working with unity script (C#). I've got 2 prefabs which contain a meshfilter. I'm trying to compare the vertices positions, vertex per vertex, between these two prefabs. Basically, I'm using gameObject.transform.GetComponent().mesh.vertices to get the vertices of each mesh. As these vertice are in local coordinates, I'm using gameObject.transform.TransformPoint() to put it in world space, and gameObject.transform.InverseTransformPoint() to put it back in local space. So there is my algorithm :
// Run through vertices
for(int j = 0; j < mesh1vertices.Count; j++)
{
Vector3 mesh1worldpoint = mesh1transform.TransformPoint(mesh1vertices[j]);
Vector3 mesh2worldpoint = mesh2transform.TransformPoint(mesh2vertices[j]);
// Check if points are equals, if not, fix that mess !
if( Vector3.Distance(mesh1worldpoint, mesh2worldpoint) > Mathf.Epsilon )
{
mesh1vertices[j] = mesh1transform.InverseTransformPoint(mesh2worldpoint);
}
}
// Update mesh
mesh1.vertices = mesh1vertices;
mesh1.RecalculateNormals();
mesh1.RecalculateBounds();
When I compared points in world coordinate, they're differents (not far from each other, but still different). But when I go back to local coordinates, mesh1transform.InverseTransformPoint(mesh2worldpoint) is exactly the same value than mesh1vertices[j] which means that InverseTransformPoint() has some crappy rounds or I just didn't get it.
If someone can give me a clue or a solution, it'll prevent me from killing myself..
Thanks a lot.
Answer by Cripple · Sep 04, 2012 at 09:58 PM
Vector x/y/z use float.
You should never compare float with == because it will often be false when you think it will be true because of a bad precision for floating var.
Instead you should compare the distance using Vector3.Distance( vec1, vec2) <= aValue
Answer by smoke · Sep 05, 2012 at 09:00 AM
Thanks for the answer but I already know that :) That's not my problem here. I've got troubles with InverseTransformPoint() which returns me exactly the same local coordinates for 2 differents Vector3 in world coordinates.
There is an example :
Vector3 A = new Vector3(-2.0f, -2.0f, 47.4f);
Vector3 B = new Vector3(-2.0f, -2.0f, 47.5f);
Debug.Log(mesh1transform.InverseTransformPoint(A));
Debug.Log(mesh1transform.InverseTransformPoint(B));
--------------------------------------------------------
Prints :
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
Answer by Cripple · Sep 05, 2012 at 09:09 AM
You can't use Debug.Log() to compare two vectors ... it only show you truncated values for x, y ,z.
Here is an example :
Vector3 vec1 = new Vector3(0.001f, 0.001f, 0.001f);
Vector3 vec2 = new Vector3(0.002f, 0.002f, 0.002f);
Debug.Log(vec1);
Debug.Log(vec2);
Debug.Log(vec1.x);
Debug.Log(vec2.x);
Prints :
(0.0, 0.0, 0.0)
(0.0, 0.0, 0.0)
0.001
0.002
According to this, your transformed vectors look equal in the Log, but actually they are not.
Answer by smoke · Sep 05, 2012 at 09:50 AM
Ok, good to know. Here is what I've got :
Vector3 A = new Vector3(-1.986626f, -1.998096f, 47.3696f);
Vector3 B = new Vector3(-1.990423f, -2.0f, 47.50004f);
Debug.Log(mesh1transform.InverseTransformPoint(A));
Debug.Log(mesh1transform.InverseTransformPoint(B));
--------------------------------------------------------
Prints :
(-0.02488029, 0.0, -0.025)
(-0.02488029, 0.0, 0.025)
So yeah they're different, but when I'm doing :
A = mesh1transform.InverseTransformPoint(B);
B = mesh1transform.InverseTransformPoint(B);
It didn't change anything on screen, I mean A isn't moving at all and I still see them "differents".
Answer by Cripple · Sep 05, 2012 at 06:35 PM
Of course when you change a vector nothing happens on screen. A vector is a struct and function return vector by copy not by reference.
If you want to apply the position of an object, you have to assign the new vector.
gameObject.transform.position = A;