private void March() { int x, y, z; for (int i = 0; i < metaballs.Count; i++) { z = (int)((metaballs[i].PosZ + 0.5f) * lattice.dimensionZ); x = (int)((metaballs[i].PosX + 0.5f) * lattice.dimensionX); y = (int)((metaballs[i].PosY + 0.5f) * lattice.dimensionY); while (z >= 0) { LatticeCube cube = lattice.GetCube(x, y, z); if (cube != null && cube.lastFrame < frameCount) { if (DoCube(cube)) { RecurseCube(cube); z = -1; } cube.lastFrame = frameCount; } else { z = -1; } } } }
private void GenerateEdge(LatticeCube cube, int edgeIndex, int pointIndex, int pointIndex2) { Vector3 vector; LatticeEdge edge = cube.edgeArray[edgeIndex]; if (edge.lastFrame < frameCount) { vector = lattice.PositionOnAxis(cube.pointArray[pointIndex], cube.pointArray[pointIndex2], edge.axis); edge.position = vector; edge.vertexIndex = vertexPointer; normals[vertexPointer] = CalculateNormal(vector); vertices[vertexPointer++] = vector; edge.lastFrame = frameCount; } }
public void GenerateLattice() { // calculate the amount of cubes, points and edges based on the dimensions int pointArrayAmount = ((dimensionX + 1) * (dimensionY + 1) * (dimensionZ + 1)); cubeArrayAmount = dimensionX * dimensionY * dimensionZ; int edgeArrayAmountTotal = (cubeArrayAmount * 3) + ((2 * dimensionX * dimensionY) + (2 * dimensionX * dimensionZ) + (2 * dimensionY * dimensionZ)) + dimensionX + dimensionY + dimensionZ; int edgeArrayAmountNow = edgeArrayAmountTotal + ((dimensionX * dimensionY) + (dimensionX * dimensionZ) + (dimensionY * dimensionZ)) * 2; cubeArray = new LatticeCube[cubeArrayAmount]; pointArray = new LatticePoint[pointArrayAmount]; edgeArray = new LatticeEdge[edgeArrayAmountNow]; // create all edges for (int i = 0; i < edgeArrayAmountNow; i++) { edgeArray[i] = new LatticeEdge(-1); } // create all points int pointIndex = 0; for (float i = 0; i <= dimensionX; i++) { for (float j = 0; j <= dimensionY; j++) { for (float k = 0; k <= dimensionZ; k++) { pointArray[pointIndex] = new LatticePoint((i / dimensionX) - 0.5f, (j / dimensionY) - 0.5f, (k / dimensionZ) - 0.5f, system); pointIndex++; } } } // create all cubes for (int i = 0; i < cubeArrayAmount; i++) { cubeArray[i] = new LatticeCube(); } LatticeCube cube; LatticeCube cube2; int cubeIndex = 0; int edgeIndex = 0; for (int i = 0; i < dimensionX; i++) { for (int j = 0; j < dimensionY; j++) { for (int k = 0; k < dimensionZ; k++) { cube = cubeArray[cubeIndex]; cubeIndex++; // set the position of the cube cube.posX = i; cube.posY = j; cube.posZ = k; // set the points of the cube LatticePoint[] points = cube.pointArray; points[0] = GetPoint(i, j, k); points[1] = GetPoint(i + 1, j, k); points[2] = GetPoint(i + 1, j + 1, k); points[3] = GetPoint(i, j + 1, k); points[4] = GetPoint(i, j, k + 1); points[5] = GetPoint(i + 1, j, k + 1); points[6] = GetPoint(i + 1, j + 1, k + 1); points[7] = GetPoint(i, j + 1, k + 1); LatticeEdge[] edges = cube.edgeArray; // set the axis of the edges edges[5] = edgeArray[edgeIndex++]; edges[5].axis = 1; edges[6] = edgeArray[edgeIndex++]; edges[6].axis = 0; edges[10] = edgeArray[edgeIndex++]; edges[10].axis = 2; // checks adjacent cubes and set their edges cube2 = GetCube(i + 1, j, k); if (cube2 != null) { cube2.edgeArray[11] = edges[10]; cube2.edgeArray[7] = edges[5]; } cube2 = GetCube(i, j + 1, k); if (cube2 != null) { cube2.edgeArray[4] = cube.edgeArray[6]; cube2.edgeArray[9] = cube.edgeArray[10]; } cube2 = GetCube(i, j + 1, k + 1); if (cube2 != null) { cube2.edgeArray[0] = cube.edgeArray[6]; } cube2 = GetCube(i + 1, j, k + 1); if (cube2 != null) { cube2.edgeArray[3] = cube.edgeArray[5]; } cube2 = GetCube(i + 1, j + 1, k); if (cube2 != null) { cube2.edgeArray[8] = cube.edgeArray[10]; } cube2 = GetCube(i, j, k + 1); if (cube2 != null) { cube2.edgeArray[1] = cube.edgeArray[5]; cube2.edgeArray[2] = cube.edgeArray[6]; } // set the remaining edges axis if (edges[0] == null) { edges[0] = edgeArray[edgeIndex++]; edges[0].axis = 0; } if (edges[1] == null) { edges[1] = edgeArray[edgeIndex++]; edges[1].axis = 1; } if (edges[2] == null) { edges[2] = edgeArray[edgeIndex++]; edges[2].axis = 0; } if (edges[3] == null) { edges[3] = edgeArray[edgeIndex++]; edges[3].axis = 1; } if (edges[4] == null) { edges[4] = edgeArray[edgeIndex++]; edges[4].axis = 0; } if (edges[7] == null) { edges[7] = edgeArray[edgeIndex++]; edges[7].axis = 1; } if (edges[8] == null) { edges[8] = edgeArray[edgeIndex++]; edges[8].axis = 2; } if (edges[9] == null) { edges[9] = edgeArray[edgeIndex++]; edges[9].axis = 2; } if (edges[11] == null) { edges[11] = edgeArray[edgeIndex++]; edges[11].axis = 2; } } } } }
private bool DoCube(LatticeCube cube) { int cubeIndex = 0; // check if the intensity of the point is over the treshhold if (cube.pointArray[0].CalculateIntensity() > isoLevel) { cubeIndex |= 1; } if (cube.pointArray[1].CalculateIntensity() > isoLevel) { cubeIndex |= 2; } if (cube.pointArray[2].CalculateIntensity() > isoLevel) { cubeIndex |= 4; } if (cube.pointArray[3].CalculateIntensity() > isoLevel) { cubeIndex |= 8; } if (cube.pointArray[4].CalculateIntensity() > isoLevel) { cubeIndex |= 16; } if (cube.pointArray[5].CalculateIntensity() > isoLevel) { cubeIndex |= 32; } if (cube.pointArray[6].CalculateIntensity() > isoLevel) { cubeIndex |= 64; } if (cube.pointArray[7].CalculateIntensity() > isoLevel) { cubeIndex |= 128; } int edgeIndex = edgeTable[cubeIndex]; if (edgeIndex != 0) { if ((edgeIndex & 1) > 0) { GenerateEdge(cube, 0, 0, 1); } if ((edgeIndex & 2) > 0) { GenerateEdge(cube, 1, 1, 2); } if ((edgeIndex & 4) > 0) { GenerateEdge(cube, 2, 2, 3); } if ((edgeIndex & 0x8) > 0) { GenerateEdge(cube, 3, 3, 0); } if ((edgeIndex & 0x10) > 0) { GenerateEdge(cube, 4, 4, 5); } if ((edgeIndex & 0x20) > 0) { GenerateEdge(cube, 5, 5, 6); } if ((edgeIndex & 0x40) > 0) { GenerateEdge(cube, 6, 6, 7); } if ((edgeIndex & 0x80) > 0) { GenerateEdge(cube, 7, 7, 4); } if ((edgeIndex & 0x100) > 0) { GenerateEdge(cube, 8, 0, 4); } if ((edgeIndex & 0x200) > 0) { GenerateEdge(cube, 9, 1, 5); } if ((edgeIndex & 0x400) > 0) { GenerateEdge(cube, 10, 2, 6); } if ((edgeIndex & 0x800) > 0) { GenerateEdge(cube, 11, 3, 7); } int temp; int triangleIndex = 0; while (triTable[cubeIndex, triangleIndex] != -1) { temp = cube.edgeArray[triTable[cubeIndex, triangleIndex + 2]].vertexIndex; triangles[trianglePointer++] = temp; temp = cube.edgeArray[triTable[cubeIndex, triangleIndex + 1]].vertexIndex; triangles[trianglePointer++] = temp; temp = cube.edgeArray[triTable[cubeIndex, triangleIndex]].vertexIndex; triangles[trianglePointer++] = temp; triangleIndex += 3; } return(true); } else { return(false); } }
private void RecurseCube(LatticeCube cube) { int x = cube.posX; int y = cube.posY; int z = cube.posZ; LatticeCube adjacent; adjacent = lattice.GetCube(x + 1, y, z); if (adjacent != null && adjacent.lastFrame < frameCount) { adjacent.lastFrame = frameCount; if (DoCube(adjacent)) { RecurseCube(adjacent); } } adjacent = lattice.GetCube(x - 1, y, z); if (adjacent != null && adjacent.lastFrame < frameCount) { adjacent.lastFrame = frameCount; if (DoCube(adjacent)) { RecurseCube(adjacent); } } adjacent = lattice.GetCube(x, y + 1, z); if (adjacent != null && adjacent.lastFrame < frameCount) { adjacent.lastFrame = frameCount; if (DoCube(adjacent)) { RecurseCube(adjacent); } } adjacent = lattice.GetCube(x, y - 1, z); if (adjacent != null && adjacent.lastFrame < frameCount) { adjacent.lastFrame = frameCount; if (DoCube(adjacent)) { RecurseCube(adjacent); } } adjacent = lattice.GetCube(x, y, z + 1); if (adjacent != null && adjacent.lastFrame < frameCount) { adjacent.lastFrame = frameCount; if (DoCube(adjacent)) { RecurseCube(adjacent); } } adjacent = lattice.GetCube(x, y, z - 1); if (adjacent != null && adjacent.lastFrame < frameCount) { adjacent.lastFrame = frameCount; if (DoCube(adjacent)) { RecurseCube(adjacent); } } }