Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by daterre · Jul 30, 2012 at 08:33 AM · transformquaternionmeshfiltertransformpoint

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;
 }
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Jul 30, 2012 at 10:15 AM 0
Share

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.

avatar image daterre · Jul 30, 2012 at 08:39 PM 0
Share

Thanks, this was a problem as well, bunny83 addressed the more critical calculation problem

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

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.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image daterre · Jul 30, 2012 at 08:39 PM 0
Share

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.

avatar image whydoidoit · Jul 30, 2012 at 08:46 PM 0
Share

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.

avatar image Bunny83 · Jul 30, 2012 at 08:53 PM 0
Share

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" ;)

avatar image whydoidoit · Jul 30, 2012 at 08:55 PM 0
Share

Nice diagram :)

avatar image Bunny83 · Jul 30, 2012 at 09:00 PM 0
Share

@whydoidoit:
google is your friend ;) but i guess the comment is a bit lengthy now :D

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges