- Home /
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
Your answer
Follow this Question
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