- Home /
Does CombineMeshes concatenate vertices, or concatenate references to vertices?
Hi guys, I am proceduraly building a spherized cube based on a number of edges on a corner.
However after all of the building/moving of vertices, my submeshes are flat. I know my function to modify a cube works, however when it is applied to the combined mesh of my generated sides it is invisible. The vertices via the log that they are spherized for World, and the triangle count is correct. Even when I delete the submeshes they appear to be correctly positioned...
I am attaching some code. It's pretty sloppy so far, but it seems fairly simple to understand. using UnityEngine; using System.Collections; using System.Collections.Generic;
public class Spherizer : MonoBehaviour {
public Transform[] CubeSides;
public Transform Side;
public Transform World;
public float radius = 5f; //IDE
public float units = 5; //IDE
public int smooth = 50; // 0-100 bigger = smoother
Vector3 cubeOrigin;
List<Vector3> vertices;
Transform newSide;
List<Vector2> uvs;
//public Transform newSide = new Transform();
Mesh mesh;
// Use this for initialization
void Start () {
cubeOrigin = transform.position;
//vertices = new Vector3[mesh.vertexCount];
MakeCube();
MakeSphere();
Debug.Log("Loaded");
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown ("space"))
Debug.Log(mesh.vertexCount);
}
public void MakeCube(){
//instantiate global variables
World = GameObject.FindGameObjectWithTag("World").transform;
CubeSides = new Transform[6];
vertices = new List<Vector3>();
uvs = new List<Vector2>();
//instantiate local variables
List<MeshFilter> meshFilters = new List<MeshFilter>();
List<Vector3> sideVertices = new List<Vector3>();
List<int> triangles = new List<int>();
//Create Sides of Cube
for (int thisSide = 0; thisSide < CubeSides.Length; thisSide++) {
newSide = (Transform)Instantiate(Side,cubeOrigin,Quaternion.identity);
newSide.parent = World;
newSide.name = ("Side "+(thisSide+1));
//Create Vertices of Side
for (int x = 0;x<=units;x++){
for (int z = 0;z<=units;z++){
sideVertices.Add(new Vector3(x-(units/2),units/2,z-(units/2)));
}
}
//Create Triangles for Side
for(int i = 0;i<(sideVertices.Count-(units+1));i++){
if ((i+1)%(units+1)!=0) {
triangles.Add(i);
triangles.Add(i+1);
triangles.Add(i+(int)(units+1f));
triangles.Add(i+1);
triangles.Add(i+(int)(units+1f)+1);
triangles.Add(i+(int)(units+1f));
}
}
//Create UVs for Side
for (int i = 0; i < sideVertices.Count; i++) {
uvs.Add (new Vector2(sideVertices[i].x,sideVertices[i].z));
}
CubeSides[thisSide] = newSide;
//Assign collections to Side
newSide.gameObject.GetComponent<MeshFilter>().sharedMesh = newSide.gameObject.GetComponent<MeshFilter>().mesh;
mesh = newSide.gameObject.GetComponent<MeshFilter>().sharedMesh;
mesh.vertices = sideVertices.ToArray();
mesh.triangles = triangles.ToArray();
mesh.uv = uvs.ToArray();
mesh.RecalculateNormals();
meshFilters.Insert(0,newSide.GetComponent<MeshFilter>());
//Clear variables
sideVertices = new List<Vector3>();
triangles = new List<int>();
uvs = new List<Vector2>();
}
//Rotate Sides into Position (Is there a more eloquent way to do this?)
CubeSides[1].Rotate(new Vector3(270,180,0));
CubeSides[2].Rotate(new Vector3(270,90,0));
CubeSides[3].Rotate(new Vector3(270,0,0));
CubeSides[4].Rotate(new Vector3(270,270,0));
CubeSides[5].Rotate(new Vector3(180,180,0));
//Concatenate Sides into Cube
/*foreach(Transform side in CubeSides){
MeshFilter filter = side.gameObject.GetComponent<MeshFilter>();
for(int i = 0;i<filter.mesh.vertices.Length;i++){
Vector3 vert = filter.mesh.vertices[i];
vert = filter.transform.TransformPoint(vert);
vertices.Add(vert);
}
}*/
mesh = World.gameObject.GetComponent<MeshFilter>().mesh;
//mesh.vertices = vertices.ToArray();
CombineInstance[] combine = new CombineInstance[meshFilters.Count];
Debug.Log(meshFilters.Count);
for (int h = 0;h < meshFilters.Count;h++) {
combine[h].mesh = meshFilters[h].mesh;
combine[h].transform = meshFilters[h].transform.localToWorldMatrix;
meshFilters[h].gameObject.SetActive(false);
}
mesh = new Mesh();
mesh.CombineMeshes(combine,true,true);
Debug.Log("Loaded Cube");
}
public void MakeSphere(){ // done
for (int i = 0; i<mesh.vertexCount;i++){
Vector3 vert = mesh.vertices[i];
//Debug.Log(i+1 +","+ vert);
float distance = (cubeOrigin-vert).magnitude;
Vector3 vect = cubeOrigin - vert;
vect = vect.normalized;
vect *= (distance - radius + Random.Range(-radius/smooth, radius/smooth));
vert += vect;
vertices.Add(vert);
//Debug.Log(i+1 +","+ vert);
}
mesh.vertices = vertices.ToArray();
for (int i = 0; i < mesh.vertices.Length; i++) {
Debug.Log(i+1 +","+ mesh.vertices[i]);
}
for (int i = 0; i < mesh.triangles.Length-2; i+=2) {
Debug.Log(mesh.triangles[i]+","+mesh.triangles[i+1]+","+mesh.triangles[i+2]);
}
vertices.Clear();
vertices.AddRange(mesh.vertices);
Debug.Log(vertices.Count);
uvs = new List<Vector2>(vertices.Count);
for (int i = 0; i < vertices.Count ; i++) {
uvs.Add(new Vector2(vertices[i].x, vertices[i].z));
//Debug.Log(vertices[i].x+","+ vertices[i].z);
}
mesh.uv = uvs.ToArray();
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mesh.Optimize();
World.gameObject.SetActive(true);
Debug.Log("uv count "+mesh.uv.Length);
Debug.Log("triangle count "+mesh.triangles.Length/3);
}
}
Ok, after further inspection, the mesh.uv collection is empty, I tried filling it, but it seems to be avoiding assignment...
Apparently not the issue, as it still does not show...
Im not sure why, but when I leave the sub$$anonymous$$eshes active and I select my World object, it shows the mesh/triangles of the combined submeshes. However I have changed the coords of the vertices of the World objects $$anonymous$$esh... What am I missing guys?
Oh, to test it as is, you can simply attach the script to an empty GameObject and create another tagged as "World" with a meshFilter/Renderer attached. Other than that it is all self building...
Also, Side is an empty prefab with no mesh and any old texture will do.
(Gotta assign it to the Spherizer script and the empty GameObject)
Can you explain what you are trying to do in this code:
//Create Vertices of Side
for (int x = 0;x<=units;x++){
for (int z = 0;z<=units;z++){
sideVertices.Add(new Vector3(x-(units/2),units/2,z-(units/2)));
}
}
//Create Triangles for Side
for(int i = 0;i<(sideVertices.Count-(units+1));i++){
if ((i+1)%(units+1)!=0) {
triangles.Add(i);
triangles.Add(i+1);
triangles.Add(i+(int)(units+1f));
triangles.Add(i+1);
triangles.Add(i+(int)(units+1f)+1);
triangles.Add(i+(int)(units+1f));
}
}
//Cr
I've just no idea what that's all about!
There should be a number of vertices and exactly the same number of triangles entries.
Answer by whydoidoit · Mar 18, 2013 at 08:42 AM
BTW in answer to your question, CombineMeshes does not combine vertices (vertices are often duplicated for a good reason, like having different normals, uv coordinates or colors). CombineMeshes copies together the various meshes and appends the vertices (with all their data) and triangles together - this reduces draw calls but preserves the mesh.
Answer by Cyber_Defect · Mar 18, 2013 at 09:50 PM
Excellent, so CombineMeshes is useless... and written poorly on the API.
I found a solution, i just built it all into the MakeCube() function and altered that bit of commented out code to spherize the sides instead of spherizing the cube.
Here is the changed section of code. Now to sew up some seams ;)
//Concatenate Sides into Cube
foreach(Transform side in CubeSides){
MeshFilter filter = side.gameObject.GetComponent<MeshFilter>();
for(int i = 0;i<filter.mesh.vertices.Length;i++){
Vector3 vert = filter.mesh.vertices[i];
float distance = (cubeOrigin-vert).magnitude;
Vector3 vect = cubeOrigin - vert;
vect = vect.normalized;
vect *= ((distance - radius) + Random.Range(-radius/smooth, radius/smooth));
vert += vect;
sideVertices.Add(vert);
}
filter.mesh.vertices = sideVertices.ToArray();
sideVertices.Clear();
}
Your answer
Follow this Question
Related Questions
Renderer on object disabled after level reload 1 Answer
Combine (skinned) submeshes causes increased vertcount(for each submesh the whole vertcount) 0 Answers
How to combine vertices while removing duplicates AND inheriting connections? 0 Answers
How do I set up an invisible Button? 1 Answer
Invisible effect? 3 Answers