/// <summary> /// Generates the mesh data /// </summary> public static void GenerateMeshData(MeshRequest request) { MeshData meshData = new MeshData(); request.meshData = meshData; //Check if the node requesting a generation has been disposed if (request == null || request.node.disposed) { meshData.triangleArray = new Vector3[0]; meshData.indexArray = new int[0][]; meshData.uvArray = new Vector2[0]; meshData.normalArray = new Vector3[0]; request.isDone = true; return; } DensityData densityArray = request.densities; Vector3[, ,] densityNormals = new Vector3[17, 17, 17]; List<Triangle> triangleList = new List<Triangle>(); List<int> subMeshIDList = new List<int>(); int[] subMeshTriCount = new int[QuixelEngine.materials.Length]; Node node = request.node; request.meshData = meshData; //Unoptimized generation densityNormals = new Vector3[18, 18, 18]; if (!request.hasDensities) { for (int x = -1; x < 18; x++) { for (int y = -1; y < 18; y++) { for (int z = -1; z < 18; z++) { VoxelData data = calculateDensity(node, new Vector3I(x, y, z)); densityArray.set(x, y, z, data.density); densityArray.setMaterial(x, y, z, data.material); } } } } for (int x = 0; x < 17; x++) { for (int y = 0; y < 17; y++) { for (int z = 0; z < 17; z++) { densityNormals[x, y, z] = calculateDensityNormal(new Vector3I(x, y, z), densityArray, node.LOD); } } } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { generateTriangles(node, new Vector3I(x, y, z), triangleList, subMeshIDList, subMeshTriCount, densityArray, densityNormals); } } } int ppos = 0; int li = 0; try { meshData.triangleArray = new Vector3[triangleList.Count * 3]; meshData.indexArray = new int[QuixelEngine.materials.Length][]; for (int i = 0; i < QuixelEngine.materials.Length; i++) meshData.indexArray[i] = new int[(subMeshTriCount[i] * 3) * 3]; meshData.uvArray = new Vector2[meshData.triangleArray.Length]; meshData.normalArray = new Vector3[meshData.triangleArray.Length]; int count = 0; int[] indCount = new int[QuixelEngine.materials.Length]; for (int i = 0; i < triangleList.Count; i++) { ppos = i; Triangle triangle = triangleList[i]; meshData.triangleArray[count + 2] = triangle.pointOne; meshData.triangleArray[count + 1] = triangle.pointTwo; meshData.triangleArray[count + 0] = triangle.pointThree; meshData.normalArray[count + 2] = triangle.nOne; meshData.normalArray[count + 1] = triangle.nTwo; meshData.normalArray[count + 0] = triangle.nThree; int ind = subMeshIDList[i]; li = subMeshIDList[i]; meshData.indexArray[ind][indCount[ind] + 0] = count + 0; meshData.indexArray[ind][indCount[ind] + 1] = count + 1; meshData.indexArray[ind][indCount[ind] + 2] = count + 2; meshData.uvArray[count + 0] = new Vector2(meshData.triangleArray[count + 0].x, meshData.triangleArray[count + 0].z); meshData.uvArray[count + 1] = new Vector2(meshData.triangleArray[count + 1].x, meshData.triangleArray[count + 1].z); meshData.uvArray[count + 2] = new Vector2(meshData.triangleArray[count + 2].x, meshData.triangleArray[count + 2].z); count += 3; indCount[subMeshIDList[i]] += 3; } } catch (Exception e) { StreamWriter sw = new StreamWriter("Error Log.txt"); sw.WriteLine(e.Message + "\r\n" + e.StackTrace); for (int i = 0; i < QuixelEngine.materials.Length; i++) sw.WriteLine(i + ": " + subMeshTriCount[i]); sw.WriteLine(ppos); sw.WriteLine(li); sw.Close(); } request.isDone = true; }
/// <summary> /// Called when a mesh has been generated /// </summary> /// <param name="mesh">Mesh data</param> public void setMesh(MeshData meshData) { densityData.setChangeData(densityChangeData); regenReq = false; if (regenFlag) { regenFlag = false; regenReq = true; MeshFactory.requestMesh(this); } hasMesh = true; if (meshData.indexArray.Length == 0) return; if (chunk == null) { chunk = ChunkPool.getChunk(); if (LOD > 2) chunk.transform.position = position - new Vector3(0f, (NodeManager.LODSize[LOD] / 2f), 0f); else chunk.transform.position = position; //chunk.GetComponent<MeshFilter>().mesh.subMeshCount = QuixelEngine.materials.Length; chunk.GetComponent<MeshRenderer>().materials = QuixelEngine.materials; } empty = false; Mesh mesh = new Mesh(); mesh.subMeshCount = QuixelEngine.materials.Length; mesh.vertices = meshData.triangleArray; for (int i = 0; i < QuixelEngine.materials.Length; i++) { if (meshData.indexArray[i].Length > 0) mesh.SetTriangles(meshData.indexArray[i], i); } //mesh.triangles = meshData.indexArray; mesh.uv = meshData.uvArray; mesh.normals = meshData.normalArray; //mesh.RecalculateBounds(); mesh.Optimize(); chunk.GetComponent<MeshFilter>().mesh = mesh; if (LOD == 0 && collides) chunk.GetComponent<MeshCollider>().sharedMesh = mesh; meshData.dispose(); renderCheck(); switch (renderType) { case RenderType.BACK: if (chunk != null) chunk.layer = 9; break; case RenderType.FRONT: if (chunk != null) chunk.layer = 8; break; } if (parent != null) parent.renderCheck(); }