protected void assignMesh(GameObject meshObject, SubstanceCollection substances, Dictionary <int, int> vertices, List <int> triangles, byte[] MATS) { byte[] substanceArray = substances.getSubstances(); bool hasGrass = substanceArray.Length == 1 && control.voxelSubstances[substanceArray[0]].grassMaterial != null; int vertexCount = vertices.Count; if (hasGrass) { vertexCount *= 2; } Vector3[] verts = new Vector3[vertexCount]; Vector3[] norms = new Vector3[vertexCount]; Vector2[] uvs = new Vector2[vertexCount]; // create the vertex, normal, and uv arrays foreach (int index in vertices.Keys) { int i = vertices[index]; norms[i] = NORMS[index]; verts[i] = VERTS[index]; switch (substances.getSubstanceRelativeIndex(MATS[index])) { case 0: uvs[i] = Vector2.zero; break; case 1: uvs[i] = Vector2.right; break; case 2: uvs[i] = Vector2.up; break; } } if (hasGrass) { VoxelSubstance substance = control.voxelSubstances[substanceArray[0]]; for (int i = vertices.Count; i < vertexCount; ++i) { int index = i - vertices.Count; norms[i] = norms[index]; verts[i] = verts[index]; if (norms[i].y > substance.grassMinFlatness) { float factor = (norms[i].y - substance.grassMinFlatness + 0.1f) / (1 - substance.grassMinFlatness + 0.1f); verts[i].y += substance.grassHeight * factor; uvs[i] = new Vector2(0, 1 - factor); } else { uvs[i] = Vector2.up; } } } // apply the render materials to the renderer MeshRenderer rend = meshObject.GetComponent <MeshRenderer>(); PhysicMaterial phyMat = null; if (substanceArray.Length == 1) { Material[] materials = new Material[1]; if (hasGrass) { materials = new Material[2]; materials[1] = control.voxelSubstances[substanceArray[0]].grassMaterial; } materials[0] = control.voxelSubstances[substanceArray[0]].renderMaterial; materials[0].EnableKeyword("IS_BASE"); rend.sharedMaterials = materials; phyMat = control.voxelSubstances[substanceArray[0]].physicsMaterial; } else { Material[] materials = new Material[substanceArray.Length]; for (int i = 0; i < materials.Length; ++i) { Material material = new Material(control.voxelSubstances[substanceArray[i]].blendMaterial); material.renderQueue = i; if (!control.saveMeshes) { material.hideFlags = HideFlags.HideAndDontSave; } switch (i) { case 0: material.EnableKeyword("IS_BASE"); phyMat = control.voxelSubstances[substanceArray[i]].physicsMaterial; break; case 1: material.EnableKeyword("IS_X"); break; case 2: material.EnableKeyword("IS_Y"); break; } materials[i] = material; } rend.materials = materials; } Mesh m = meshObject.GetComponent <MeshFilter>().sharedMesh; m.Clear(); int[] triangleArray = triangles.ToArray(); // reduce mesh if (control.reduceMeshes) { HashSet <int> verticesRemoved = VoxelMeshReducer.reduce(ref verts, ref triangleArray, control.reductionAmount); norms = VoxelMeshReducer.removeEntries(norms, verticesRemoved); uvs = VoxelMeshReducer.removeEntries(uvs, verticesRemoved); } m.vertices = verts; m.normals = norms; m.uv = uvs; if (hasGrass) { m.subMeshCount = 2; int[] grassTriangles = new int[triangleArray.Length]; for (int i = 0; i < grassTriangles.Length; ++i) { grassTriangles[i] = triangleArray[i] + vertices.Count; } m.SetTriangles(grassTriangles, 1); } else { m.subMeshCount = 1; } m.SetTriangles(triangleArray, 0); m.RecalculateBounds(); m.Optimize(); rend.enabled = true; // add a collider for the mesh if (control.createColliders) { MeshCollider collider = meshObject.AddComponent <MeshCollider>(); collider.material = phyMat; if (hasGrass) { Mesh mesh = new Mesh(); Vector3[] colVerts = new Vector3[vertices.Count]; Vector3[] colNorms = new Vector3[vertices.Count]; Array.Copy(verts, colVerts, colVerts.Length); Array.Copy(norms, colNorms, colNorms.Length); mesh.vertices = colVerts; mesh.normals = colNorms; mesh.SetTriangles(triangles, 0); mesh.RecalculateBounds(); mesh.Optimize(); collider.sharedMesh = mesh; } else { collider.sharedMesh = m; } // collider.hideFlags = /*HideFlags.HideInInspector | */HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; } }
public void applyMesh(byte detailLevel, int x, int y, int z) { applied = true; if (TRIS.Length < 1 && (obs == null || obs.Length < 1)) { return; } // convert the vertexSubstances structure into a more directly usable format byte[] substanceToVertices = new byte[VERTS.Length]; foreach (int index in vertices.Keys) { if (vertexSubstances.ContainsKey(index)) { byte substance = vertexSubstances[index]; substanceToVertices[(int)vertices[index]] = substance; } } // build triangle and vertex lists for each mesh from the master triangle list Dictionary <SubstanceCollection, Dictionary <int, int> > substanceVertices = new Dictionary <SubstanceCollection, Dictionary <int, int> >(); Dictionary <SubstanceCollection, List <int> > substanceTriangles = new Dictionary <SubstanceCollection, List <int> >(); for (int i = 0; i < TRIS.Length; i += 3) { SubstanceCollection subs = new SubstanceCollection(); for (int j = 0; j < 3; ++j) { byte sub = substanceToVertices[TRIS[i + j]]; subs.add(sub); } if (!substanceTriangles.ContainsKey(subs)) { substanceTriangles[subs] = new List <int>(TRIS.Length / substanceToVertices.Length); substanceVertices[subs] = new Dictionary <int, int>(); } List <int> specificSubstanceTriangles = substanceTriangles[subs]; Dictionary <int, int> specificSubstanceVertexIndices = substanceVertices[subs]; for (int j = 0; j < 3; ++j) { int vertexIndex = TRIS[i + j]; if (!specificSubstanceVertexIndices.ContainsKey(vertexIndex)) { specificSubstanceVertexIndices[vertexIndex] = specificSubstanceVertexIndices.Count; } specificSubstanceTriangles.Add(specificSubstanceVertexIndices[vertexIndex]); } } // create and initialize the game objects which will have the mesh renderers and colliders attached to them removePolyCount(); GameObject[] oldObs = (obs == null)? new GameObject[0]: obs; obs = new GameObject[substanceTriangles.Count]; if (oldObs.Length > obs.Length) { Array.Copy(oldObs, obs, obs.Length); for (int i = obs.Length; i < oldObs.Length; ++i) { GameObject.DestroyImmediate(oldObs[i]); } } else { Array.Copy(oldObs, obs, oldObs.Length); for (int i = oldObs.Length; i < obs.Length; ++i) { obs[i] = createRendererGameObject(); } } foreach (GameObject ob in obs) { foreach (MeshCollider col in ob.GetComponents <MeshCollider>()) { GameObject.DestroyImmediate(col); } } // Assign vertex data to the game object meshes int obIndex = 0; foreach (SubstanceCollection substances in substanceTriangles.Keys) { assignMesh(obs[obIndex], substances, substanceVertices[substances], substanceTriangles[substances], substanceToVertices); ++obIndex; } // // refresh collider // if (control.createColliders) { // collider.enabled = false; // if (VoxelBlock.isRenderSize(size, control)) // collider.enabled = true; // } addPolyCount(); ((VoxelBlock)control.getHead().get(this.index)).clearSubRenderers(false, control); control.head.clearSuperRenderers(detailLevel, x, y, z, control); }