/* * public static Vector3[,,] CalculateNormals(float[,,] m_voxels) { * //float startTime = Time.realtimeSinceStartup; * * //This calculates the normal of each voxel. If you have a 3d array of data * //the normal is the derivitive of the x, y and z axis. * //Normally you need to flip the normal (*-1) but it is not needed in this case. * //If you dont call this function the normals that Unity generates for a mesh are used. * Vector3[,,] m_normals; * * int w = m_voxels.GetLength(0); * int h = m_voxels.GetLength(1); * int l = m_voxels.GetLength(2); * * m_normals = new Vector3[w,h,l]; * * for(int x = 2; x < w-2; x++) { * for(int y = 2; y < h-2; y++) { * for(int z = 2; z < l-2; z++) { * float dx = m_voxels[x+1,y,z] - m_voxels[x-1,y,z]; * float dy = m_voxels[x,y+1,z] - m_voxels[x,y-1,z]; * float dz = m_voxels[x,y,z+1] - m_voxels[x,y,z-1]; * * m_normals[x,y,z] = Vector3.Normalize(new Vector3(dx,dy,dz)); * } * } * } * return m_normals; * } */ //MarchCube performs the Marching Cubes algorithm on a single cube static void MarchCube(Vector3 pos, float[] cube, List <Vector3> vertList, List <int> indexList) { int i, j, vert, idx; int flagIndex = 0; float offset = 0.0f; Vector3[] edgeVertex = new Vector3[12]; //Find which vertices are inside of the surface and which are outside for (i = 0; i < 8; i++) { if (cube[i] <= target) { flagIndex |= 1 << i; } } //Find which edges are intersected by the surface int edgeFlags = cubeEdgeFlags[flagIndex]; //If the cube is entirely inside or outside of the surface, then there will be no intersections if (edgeFlags == 0) { return; } //Find the point of intersection of the surface with each edge for (i = 0; i < 12; i++) { //if there is an intersection on this edge if ((edgeFlags & (1 << i)) != 0) { offset = GetOffset(cube[edgeConnection[i, 0]], cube[edgeConnection[i, 1]]); edgeVertex[i].x = pos.x + (vertexOffset[edgeConnection[i, 0], 0] + offset * edgeDirection[i, 0]); edgeVertex[i].y = pos.y + (vertexOffset[edgeConnection[i, 0], 1] + offset * edgeDirection[i, 1]); edgeVertex[i].z = pos.z + (vertexOffset[edgeConnection[i, 0], 2] + offset * edgeDirection[i, 2]); } } //Save the triangles that were found. There can be up to five per cubes for (i = 0; i < 5; i++) { if (triangleConnectionTable[flagIndex, 3 * i] < 0) { break; } idx = vertList.Count; int usualIndex = idx; for (j = 0; j < 3; j++) { vert = triangleConnectionTable[flagIndex, 3 * i + j]; // index of the vertex in internal cube coordinates //int usualIndex = idx+windingOrder[j]; // index of the vertex in the vertexList, in the usual implementation int cullingIndex = 0; cullingIndex = vertexTree.AddVertex(edgeVertex[vert], usualIndex); if (usualIndex == cullingIndex) // The vertex was NOT already in the tree { indexList.Add(usualIndex); vertList.Add(edgeVertex[vert]); usualIndex++; } else // The vertex was already in the tree, its index is cullingIndex { indexList.Add(cullingIndex); } } } }