Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Muffty · Jan 01, 2019 at 07:58 PM · bug-perhapsprocedural meshmesh verticescombined mesh

Does CombineMesh always remove unused vertecies or not?

Hi all,

I wonder if this behavior is a bug or not: Using Mesh.CombineMesh, all vertices not used by triangles are dismissed (and the sum of vertices of the combined mesh may be lower than the sum of individual meshes). I found out that CombineMesh usually removes all unused vertices but I can create Meshes where it does not and I don't see a reason for that.

I have code to reproduce it (I am using 2018.2.14f1):

 using System.Collections.Generic;
 using UnityEngine;
 
 public class EmptyMeshCreator : MonoBehaviour
 {
     MeshFilter filter;
     MeshRenderer meshRenderer;
 
     private void Start()
     {
         filter = gameObject.GetComponent<MeshFilter>();
         meshRenderer = gameObject.GetComponent<MeshRenderer>();
         //Create(true, false);
         //Create(true, true);
         Create(false, true);
     }
 
     private void Create(bool startOpen, bool endOpen)
     {
         int count;
         Mesh mesh = CreateMesh(Vector3.zero, Vector3.right, out count, startOpen, endOpen);
         CombineInstance ci = new CombineInstance { mesh = mesh};
         CombineInstance[] cis = new CombineInstance[] { ci };
         Mesh combinedMesh = new Mesh();
         combinedMesh.CombineMeshes(cis, true, false);
         filter.sharedMesh = combinedMesh;
         Debug.Log(combinedMesh.vertexCount + " vs " + count);
     }
 
     public static Mesh CreateMesh(Vector3 startPoint, Vector3 endPoint, out int trueVertexCount, bool startOpen, bool endOpen)
     {
         Vector3 side = Vector3.forward * 0.2f;
         Vector3 startConnectionPointLeft = startPoint + side;
         Vector3 startConnectionPointRight = startPoint - side;
         Vector3 endConnectionPointLeft = endPoint + side;
         Vector3 endConnectionPointRight = endPoint - side;
 
         //Create World Positions:
         Vector3 levelHeight = new Vector3(0, 1, 0);
 
         Vector3 bottomStartLeft = startConnectionPointLeft;         //  0
         Vector3 bottomStartCenter = startPoint;                     //  1
         Vector3 bottomStartRight = startConnectionPointRight;       //  2
         Vector3 bottomEndLeft = endConnectionPointLeft;             //  3
         Vector3 bottomEndCenter = endPoint;                         //  4
         Vector3 bottomEndRight = endConnectionPointRight;           //  5
 
         Vector3 topStartLeft = bottomStartLeft + levelHeight;           //  6
         Vector3 topStartCenter = bottomStartCenter + levelHeight;       //  7
         Vector3 topStartRight = bottomStartRight + levelHeight;         //  8
         Vector3 topEndLeft = bottomEndLeft + levelHeight;               //  9
         Vector3 topEndCenter = bottomEndCenter + levelHeight;           //  10
         Vector3 topEndRight = bottomEndRight + levelHeight;             //  11
 
         //Create Mesh
         List<int> triangles = new List<int>();
         Vector3[] vertices = new Vector3[] {
                 bottomStartLeft , bottomStartCenter , bottomStartRight,         //Start
                 bottomEndLeft, bottomEndCenter, bottomEndRight,                 //End
                 topStartLeft, topStartCenter, topStartRight,                    //TopFront
                 topEndLeft, topEndCenter, topEndRight,                          //TopBack
                 bottomStartLeft, bottomEndLeft, topStartLeft, topEndLeft,       //Front
                 bottomStartRight, bottomEndRight, topStartRight, topEndRight};  //Back
 
         int unusedVertecies = 0;
         if (endOpen)
             unusedVertecies += 3;
         if (startOpen)
             unusedVertecies += 3;
 
         //1. End-Right
         if (!endOpen)
             AddGroundTopFace(triangles, 6, 5, 4);
         //2. End-Left
         if (!endOpen)
             AddGroundTopFace(triangles, 6, 4, 3);
         //3. Start-Right
         if (!startOpen)
             AddGroundTopFace(triangles, 6, 1, 2);
         //4. Start-Left
         if (!startOpen)
             AddGroundTopFace(triangles, 6, 0, 1);
         //5. Top-Right
         AddFace(triangles, 6, 7, 9, 10);
         //6. Top-Left
         AddFace(triangles, 7, 8, 10, 11);
         //7. Front
         AddFace(triangles, 16, 17, 18, 19);
         //8. Back
         AddFace(triangles, 13, 12, 15, 14);
 
         Mesh mesh = new Mesh
         {
             vertices = vertices,
             triangles = triangles.ToArray()
         };
         mesh.RecalculateNormals();
         mesh.RecalculateBounds();
 
 
         trueVertexCount = mesh.vertexCount - unusedVertecies;
 
         return mesh;
     }
 
     //Adds a face (two triangles) from groundA, groundB and topA, topB (which are ground+offset)
     private static void AddGroundTopFace(List<int> triangles, int topOffset, int groundA, int groundB)
     {
         int topA = groundA + topOffset;
         int topB = groundB + topOffset;
 
         AddFace(triangles, groundA, groundB, topA, topB);
     }
 
     private static void AddFace(List<int> triangles, int a, int b, int c, int d)
     {
         //Add Triangle 1
         triangles.Add(a);
         triangles.Add(c);
         triangles.Add(b);
 
         //Add Triangle 2
         triangles.Add(b);
         triangles.Add(c);
         triangles.Add(d);
     }
 
 }
 

Add it to a GameObject with MeshFilter and MeshRenderer. My output is: 20 vs 17 Hence. all 20 vertices are still present in the combined mesh, even though no. 3, 4 and 5 are never used. Using any other Create-Method call (there are two more given in a comment) the number of vertices is correctly reduced in the combined mesh.

If you want to visualize it better, here is a simple script to iterate through its vertices (attach to same game object):

 using UnityEngine;
 
 public class VertexView : MonoBehaviour {
 
     MeshFilter filter;
     public int vertex = 4;
 
     void Start () {
         filter = GetComponent<MeshFilter>();
     }
 
     private void OnDrawGizmos()
     {
         if (!filter || !filter.mesh)
             return;
         Gizmos.DrawSphere(filter.mesh.vertices[vertex], 0.1f);
     }
 }


So. Is this a bug or somehow a desired behavior?

Best, Tobi

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

0 Replies

· Add your reply
  • Sort: 

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

98 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

Related Questions

How to fill out a procedurally generated mesh with quads of varying sizes? 0 Answers

Circular Mesh UV interpolation for tileable texture 1 Answer

Mesh.colors doesn't work even though colors are passed correctly to the array 1 Answer

Create Mesh that encapsulates two different sized spheres (perhaps a distorted cylinder?) 1 Answer

Dynamically move vertices of a mesh 2 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