public MyMarchingCubesMesher() { // Cube Edges for (int i = 0; i < m_edges.Length; i++) { m_edges[i] = new MyEdge(); } // Temporary voxel values, serve as cache between precalc and voxel map - so we don't have to always access voxel maps but can look here for (int i = 0; i < m_temporaryVoxels.Length; i++) { m_temporaryVoxels[i] = new MyTemporaryVoxel(); } // Array of edges in the cell m_edgeVertexCalcCounter = 0; m_edgeVertex = new MyEdgeVertex[CELL_EDGES_SIZE][][][]; for (int x = 0; x < CELL_EDGES_SIZE; x++) { m_edgeVertex[x] = new MyEdgeVertex[CELL_EDGES_SIZE][][]; for (int y = 0; y < CELL_EDGES_SIZE; y++) { m_edgeVertex[x][y] = new MyEdgeVertex[CELL_EDGES_SIZE][]; for (int z = 0; z < CELL_EDGES_SIZE; z++) { m_edgeVertex[x][y][z] = new MyEdgeVertex[MyMarchingCubesConstants.CELL_EDGE_COUNT]; for (int w = 0; w < MyMarchingCubesConstants.CELL_EDGE_COUNT; w++) { m_edgeVertex[x][y][z][w] = new MyEdgeVertex(); m_edgeVertex[x][y][z][w].CalcCounter = 0; } } } } }
private void CreateTriangles(ref Vector3I coord0, int cubeIndex, ref Vector3I tempVoxelCoord0) { MyVoxelVertex tmpVertex = new MyVoxelVertex(); int g = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS; Vector3I edge = new Vector3I(coord0.X, coord0.Y, coord0.Z); for (int i = 0; MyMarchingCubesConstants.TriangleTable[cubeIndex, i] != -1; i += 3) { // Edge indexes inside the cube int edgeIndex0 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 0]; int edgeIndex1 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 1]; int edgeIndex2 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 2]; MyEdge edge0 = m_edges[edgeIndex0]; MyEdge edge1 = m_edges[edgeIndex1]; MyEdge edge2 = m_edges[edgeIndex2]; // Edge indexes inside the cell Vector4I edgeConversion0 = MyMarchingCubesConstants.EdgeConversion[edgeIndex0]; Vector4I edgeConversion1 = MyMarchingCubesConstants.EdgeConversion[edgeIndex1]; Vector4I edgeConversion2 = MyMarchingCubesConstants.EdgeConversion[edgeIndex2]; MyEdgeVertex edgeVertex0 = m_edgeVertex[edge.X + edgeConversion0.X][edge.Y + edgeConversion0.Y][edge.Z + edgeConversion0.Z][edgeConversion0.W]; MyEdgeVertex edgeVertex1 = m_edgeVertex[edge.X + edgeConversion1.X][edge.Y + edgeConversion1.Y][edge.Z + edgeConversion1.Z][edgeConversion1.W]; MyEdgeVertex edgeVertex2 = m_edgeVertex[edge.X + edgeConversion2.X][edge.Y + edgeConversion2.Y][edge.Z + edgeConversion2.Z][edgeConversion2.W]; MyVoxelVertex compressedVertex0 = new MyVoxelVertex(); compressedVertex0.Position = edge0.Position; MyVoxelVertex compressedVertex1 = new MyVoxelVertex(); compressedVertex1.Position = edge1.Position; MyVoxelVertex compressedVertex2 = new MyVoxelVertex(); compressedVertex2.Position = edge2.Position; // We want to skip all wrong triangles, those that have two vertex at almost the same location, etc. // We do it simply, by calculating triangle normal and then checking if this normal has length large enough if (IsWrongTriangle(ref compressedVertex0, ref compressedVertex1, ref compressedVertex2) == true) { continue; } // Vertex at edge 0 if (edgeVertex0.CalcCounter != m_edgeVertexCalcCounter) { // If vertex at edge0 wasn't calculated for this cell during this precalc, we need to add it // Short overflow check System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= ushort.MaxValue); edgeVertex0.CalcCounter = m_edgeVertexCalcCounter; edgeVertex0.VertexIndex = (ushort)m_resultVerticesCounter; tmpVertex.Position = edge0.Position; tmpVertex.Normal = edge0.Normal; tmpVertex.Ambient = edge0.Ambient; tmpVertex.Material = edge0.Material; tmpVertex.PositionMorph = edge0.Position; m_resultVertices[m_resultVerticesCounter] = tmpVertex; m_resultVerticesCounter++; } // Vertex at edge 1 if (edgeVertex1.CalcCounter != m_edgeVertexCalcCounter) { // If vertex at edge1 wasn't calculated for this cell during this precalc, we need to add it // Short overflow check System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= ushort.MaxValue); edgeVertex1.CalcCounter = m_edgeVertexCalcCounter; edgeVertex1.VertexIndex = (ushort)m_resultVerticesCounter; tmpVertex.Position = edge1.Position; tmpVertex.Normal = edge1.Normal; tmpVertex.Ambient = edge1.Ambient; tmpVertex.Material = edge1.Material; tmpVertex.PositionMorph = edge1.Position; m_resultVertices[m_resultVerticesCounter] = tmpVertex; m_resultVerticesCounter++; } // Vertex at edge 2 if (edgeVertex2.CalcCounter != m_edgeVertexCalcCounter) { // If vertex at edge2 wasn't calculated for this cell during this precalc, we need to add it // Short overflow check System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= ushort.MaxValue); edgeVertex2.CalcCounter = m_edgeVertexCalcCounter; edgeVertex2.VertexIndex = (ushort)m_resultVerticesCounter; tmpVertex.Position = edge2.Position; tmpVertex.Normal = edge2.Normal; tmpVertex.Ambient = edge2.Ambient; tmpVertex.Material = edge2.Material; tmpVertex.PositionMorph = edge2.Position; tmpVertex.Cell = coord0; ; m_resultVertices[m_resultVerticesCounter] = tmpVertex; m_resultVerticesCounter++; } // Triangle m_resultTriangles[m_resultTrianglesCounter].VertexIndex0 = edgeVertex0.VertexIndex; m_resultTriangles[m_resultTrianglesCounter].VertexIndex1 = edgeVertex1.VertexIndex; m_resultTriangles[m_resultTrianglesCounter].VertexIndex2 = edgeVertex2.VertexIndex; Debug.Assert(edgeVertex0.VertexIndex < m_resultVerticesCounter); Debug.Assert(edgeVertex1.VertexIndex < m_resultVerticesCounter); Debug.Assert(edgeVertex2.VertexIndex < m_resultVerticesCounter); m_resultTrianglesCounter++; } }