Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 coakleyonenow · Aug 21, 2021 at 02:25 PM · meshverticesnormalstrianglesdeformation

Why is my mesh peeling off when I try to deform it during runtime?

alt text

I'm trying to deform meshes on runtime by doing some sort of "pressing/smooshing" effect


However when i try to do so my mesh "peels" because of the mesh's seams


Also note that i need to use procedural generated meshes on runtime so i can't just go to maya and connect vertices


What's the trick behind deforming a mesh without "peeling" it?

seams.gif (488.9 kB)
Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · Aug 21, 2021 at 06:02 PM

Well, you have to keep track of duplicated vertices and always move them together. So you need the concept of "virtual" or "grouped" vertices. There are several ways how this could be achieved. The most straight forward solution is to just create a List of indices for every "logical" vertex. This of course requires quite a bit of extra memory, though relatively speaking that's not really an issue for most platforms except WebGL which is probably the most restricted platform nowadays when it comes to memory.


Another solution is to create a second array that contains the Lists but initialize that list with null. Only create a List when you have found two or more vertices. You would reference that list from each entry that belongs to that group. That way you can easily look up every connected vertex if there is any. This can also be efficiently implemented with a Dictionary since shared vertices are usually the minority so you don't need that many entries.


Searching for duplicates and grouping them is a quite expensive operation since it's O(n²) in nature as you have to compare every vertex position with every other vertex. For really large meshes this could be optimised with an octree. Though since you usually only need to construct this grouping once at the start it's probably not worth to worry about.


From a usability point of view (depending on what kind of operations you want to do), creating an actual wrapper classs for the mesh and a logical vertex is the neatest way to tackle the issue.

Something like this:

 public class MeshWrapper
 {
     public Mesh mesh;
     public List<Vertex> vertices = new List<Vertex>();
     private List<Vector3> m_Vertices = new List<Vector3>();
     private List<Vector3> m_Normals = new List<Vector3>();
     // implement whatever vertex attributes you also need, UV, tangents, colors, ....
     public List<int> triangles;
 
     public MeshWrapper(Mesh aMesh)
     {
         mesh = aMesh;
         mesh.GetVertices(m_Vertices);
         mesh.GetNormals(m_Normals);
         // ...
         triangles.AddRange(mesh.triangles);
         
         GenerateVertexGroups();
     }
     public void Apply()
     {
         mesh.SetVertices(m_Vertices);
         mesh.SetNormals(m_Normals);
         // ...
         mesh.triangles = triangles.ToArray();
     }
 
     void GenerateVertexGroups(float aMaxPositionError = 0.0001f)
     {
         vertices.Clear();
         float maxErrorSqr = aMaxPositionError * aMaxPositionError;
         for (int i = 0; i < m_Vertices.Count; i++)
         {
             var pos = m_Vertices[i];
             Vertex vertex = null;
             foreach(Vertex v in vertices)
             {
                 float diffSqr = (v.position - pos).sqrMagnitude;
                 if (diffSqr < maxErrorSqr)
                 {
                     vertex = v;
                     break;
                 }
             }
             if (vertex == null)
             {
                 vertex = new Vertex(this);
             }
             vertex.AddVertex(i);
             vertices.Add(vertex);
         }
     }
 
 
     public class Vertex
     {
         private List<int> m_Vertices = new List<int>();
         private MeshWrapper m_Mesh;
         public Vertex(MeshWrapper aMesh)
         {
             m_Mesh = aMesh;
         }
         public void AddVertex(int aVertexIndex)
         {
             if (!m_Vertices.Contains(aVertexIndex))
                 m_Vertices.Add(aVertexIndex);
         }
         public Vector3 position
         {
             get => m_Mesh.m_Vertices[m_Vertices[0]];
             set
             {
                 foreach(int vIndex in m_Vertices)
                     m_Mesh.m_Vertices[vIndex] = value;
             }
         }
         public Vector3 normal
         {
             get => m_Mesh.m_Normals[m_Vertices[0]];
             set
             {
                 foreach (int vIndex in m_Vertices)
                     m_Mesh.m_Normals[vIndex] = value;
             }
         }
         // Add other properties as you need
     }
 }
 

Keep in mind that a Mesh in unity can come in many different flavours. This currently assumes a single submesh and that the mesh is actually a triangle mesh. Unity now supports other topologies as well. Though imported meshes are usually most likely triangle meshes anyways.

I also did not implement all vertex attributes in the Vertex wrapper class. Feel free to add those you may need as well.


With this you can simply create a wrapper around your mesh instance and you get a list of Vertex instances. Those should be grouped already. So if two vertices have the same position (within a tiny error margin) they are actually grouped into the same Vertex instance. When you set one of the vertex properties, it will automatically take care of setting all the grouped vertices to the same value.


Once you're done editing or when you want to update the changes, you just have to call Apply.


Note that this approach doesn't let you add or remove vertices since that would of course break all the housekeeping. This solution is only for editing (transforming) an existing mesh.

Comment
Add comment · Show 4 · 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 coakleyonenow · Aug 21, 2021 at 07:37 PM 0
Share

Wow thanks for the detailed reply. I'll try to mess around with your code after I attempt some solutions I found. So the approach I have right now is: -for each vertex, see if there are other vertices sharing the same position; these vertices will be the ones you need to "connect" -group those overlapping vertices together (maybe a dictionary like you said or list depending if 3 or 4 vertices overlap) -for each group of overlapping vertices, give them the same normal which in theory allows them to move in the same direction which will prevent the "peeling"

is this approach im suggesting wrong or am i on the right track? (link to image to represent what im doing:

groupingverts.png (17.8 kB)
avatar image coakleyonenow · Aug 22, 2021 at 07:45 AM 0
Share

I now found a new problem where there's a vertex on the other side of my deformation that just shoots through 0,0,0 in world space as soon as I apply the deformation as shown in the gifs below: https://i.imgur.com/zm6gd2G.gif https://i.imgur.com/Cd67Mad.gif Why does this happen?

avatar image Bunny83 coakleyonenow · Aug 22, 2021 at 08:47 AM 0
Share

Vertices do not change magically themselfs. So there has to be a bug in your defor$$anonymous$$g code.

Since that single vertex moves towards the vertices you're actually defor$$anonymous$$g, my guess would be that you inluced that single vertex wrongly in your calculations. Maybe the vertex at index 0?

avatar image coakleyonenow Bunny83 · Aug 22, 2021 at 05:17 PM 0
Share

Yeah it's so weird because It's happening for only vertex 0 but I'm not quite sure why it keeps getting selected as you can see here (blue sphere is the vertex 0): https://i.imgur.com/gvcaR4f.gif

I'm still trying to look but I can't detect anything in my code that could cause this. Is it because I'm Raycasting so constantly that it picks up vertex 0?

Also, is there anything significant about vertex 0 other than being the first vertex of the mesh?

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

139 People are following this question.

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

Related Questions

Problem drawing a mesh with Graphics.DrawMeshNow 1 Answer

Holes in procedural mesh 0 Answers

How to make sure two meshes have the same vertex count 0 Answers

Why does the default Unity sphere have duplicate vertices? 1 Answer

contains two different ids for the same vertex 0 Answers


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