- Home /
Transform coordinates to local space with quaternion
Hi,
I am trying to retrieve triangle vertex coordinates from a MeshFilter's mesh and and transform them so that the triangle is centered around (0,0,0) and the axis (0,1,0) - meaning it is lying on the x,z plane. The goal is to compare one triangle with another independently of their position/rotation, so that I can morph one into the other.
Well, I'm failing miserably, and would much appreciate any input on what I'm doing wrong! the following is the method that is supposed to return localized coordinates (if the localize parameter is true). The sourceTransform parameter is used to convert the positions to world coords.
Thanks for any help!
public GameObject MeshObject;
public TriangleMeshData GetTriangleMesh (int triangle, bool localize = false, Transform sourceTransform = null)
{
var filter = this.MeshObject.GetComponent<MeshFilter> ();
var data = new TriangleMeshData ();
Vector3[] verts = new Vector3[3];
verts [0] = (filter.sharedMesh.vertices [filter.sharedMesh.triangles [triangle]]);
verts [1] = (filter.sharedMesh.vertices [filter.sharedMesh.triangles [triangle + 1]]);
verts [2] = (filter.sharedMesh.vertices [filter.sharedMesh.triangles [triangle + 2]]);
if (sourceTransform != null)
for (int v = 0; v < 3; v++)
verts [v] = sourceTransform.TransformPoint (verts [v]);
data.Position = (verts [0] + verts [1] + verts [2]) / 3;
data.Normal = filter.sharedMesh.normals [filter.sharedMesh.triangles [triangle]];
if (sourceTransform != null)
data.Normal = sourceTransform.TransformDirection (data.Normal);
if (localize) {
Quaternion translation = Quaternion.FromToRotation (data.Normal, Vector3.up);
for (int v = 0; v < 3; v++) {
verts [v] -= data.Position;
verts [v] = translation * verts [v];
}
}
data.Vertices = verts;
return data;
}
public struct TriangleMeshData
{
public Vector3 Position;
public Vector3 Normal;
public Vector3[] Vertices;
}
Is triangle an ordinal or are you multiplying it by 3 before you call this? If not the it would appear you aren't getting the correct vertices.
Thanks, this was a problem as well, bunny83 addressed the more critical calculation problem
Answer by Bunny83 · Jul 30, 2012 at 11:15 AM
Well, it could be your vertex normal. Are you sure that your vertex normals equals your face normal? Usually they doesn't match the face normal unless the triangle is part of a flat surface like a cube. If you want to make sure the triangle is really flat, calculate the face normal. Just do this after you transformed your 3 verts into worldspace, the calculated normal will be automatically in worldspace ;):
// No guarantee that the normal is facing the right way :D
// Unity's left-handed-system is always confusing me.
data.Normal = Vector3.Cross(verts[1] - verts[0], verts[2] - verts[0]).normalized;
I guess the rest should be ok.
Don't forget if you use the worldspace coordinates the normal will be in world space. If you use the local space coordinated it will be in local space.
Didn't completely solve it, but finally I can get the two triangles to lie on the same plane. Thanks! Can you elaborate as to why a face normal is different then the vertex normal? I'd expect the face normal to point the same direction as it is facing.
Vertices can be shared by more than one face - unless all the other faces they are a part of lie in the same plane then the face normal cannot be the same as that of the vertices.
The only purpose of a vertex normal is for calculating lighting. The vertex normal should simulate the surface normal of the whole object at any point. The normal vector is interpolated in the shader between the given vertices. That way you can simulate a curved look. Flat-shaded objects on the other hand use the face normal for each triangle, so you have a hard edge between triangles.
Usually the normal at triangle edges point to the same direction so you don't see the edge due to shading
In the last image you can see the difference. If all normals of a triangle match their face normal, it would look like the right image. If the normals are smooth normals (probably shared vertices) it looks like the left image.
edit
I finally found a good visualization here. Just scroll down one third to "Normal Vectors" ;)
@whydoidoit:
google is your friend ;) but i guess the comment is a bit lengthy now :D
Your answer
Follow this Question
Related Questions
Get slerp to work just as LookAt(,Vector3.right) does 1 Answer
How to make Y-Axis face away from a position? 2 Answers
Write a C# script to record GameObject rotation? 4 Answers
Rotation not working 3 Answers
How to rotate on one axis while keeping the other axes open to be rotated by other scripts? 1 Answer