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.

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

Thanks for the answer but I already know that :slight_smile:
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)

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.

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”.

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;

I know that :slight_smile:

I’m trying to modify MeshFilter.Mesh.vertice, not simple Vector3.
I would like to change mesh vertices, something like that :

Vector3[] tmpvertices = mesh1.GetComponent<MeshFiler>().Mesh.vertices;

// 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 )
     {
         tmpvertices[j] = mesh1transform.InverseTransformPoint(mesh2worldpoint);
     }
}

// Update mesh
mesh1.vertices = tmpvertices;
mesh1.RecalculateNormals();
mesh1.RecalculateBounds();

// Check if points are equals, if not, fix that mess !
if( Vector3.Distance(mesh1worldpoint, mesh2worldpoint) < Mathf.Epsilon )
{
tmpvertices[j] = mesh1transform.InverseTransformPoint(mesh2worldpoint);
}

According to your commentary the error may be there, you go in the function when the points are close enought ( ~ equals). You want the opposite, so I would change with “> Mathf.Epsilon.”

Yeah that’s my bad. I already fixed that bug, but I forgot to update the topic. I’m doing it right now.
According to another answer I had on the forum, I also tried that :

mesh1vertices[j] = mesh2vertices[j]
    
    ---------------------------------------------------------
    
    mesh2vertices[j] ----> (-0.02488029, -0.06023789, -0.025)
    mesh1transform.InverseTransformPoint(mesh2worldpoint) --> (-0.0248803, -0.06023791, -0.02499962)

As you can see, values are differents but the graphic result is exactly the same…

Ok I fixed my problem.
Thats was in another part of my program, nothing to deal with MeshFilter, etc… :confused:

Thanks a lot for helping.