Beispiel #1
0
    private Vector3 toVoxelSpace(Vector3 worldSpace, ThreadSafeVoxelisation.GridSize size, float scale)
    {
        float side = size.side;

        Vector3 mid = new Vector3(size.x * 0.5f, size.y * 0.5f, size.z * 0.5f);

        return(new Vector3(worldSpace.x * size.x * scale, worldSpace.y * size.y * scale, worldSpace.z * size.z * scale) + mid);
    }
Beispiel #2
0
    private Vector3 toWorldSpace(Vector3 voxelSpace)
    {
        ThreadSafeVoxelisation.GridSize gridSize = grid.GetSize();
        float x = (voxelSpace.x - (gridSize.x * 0.5f)) * gridSize.side / 2;
        float y = (voxelSpace.y - (gridSize.y * 0.5f)) * gridSize.side / 2;
        float z = (voxelSpace.z - (gridSize.z * 0.5f)) * gridSize.side / 2;

        return(new Vector3(x, y, z));
    }
Beispiel #3
0
    private void findHitVoxel(Vector3 hitPoint)
    {
        ThreadSafeVoxelisation.GridSize gridSize = aabcGrid.GetSize();
        Vector3 center = aabcGrid.GetCenter();

        Vector3 difference = hitPoint - center;

        short xOff, yOff, zOff;

        xOff = (short)(difference.x / gridSize.side);
        yOff = (short)(difference.y / gridSize.side);
        zOff = (short)(difference.z / gridSize.side);

        hit.x = (short)(gridSize.x / 2 + xOff);
        hit.y = (short)(gridSize.y / 2 + yOff);
        hit.z = (short)(gridSize.z / 2 + zOff);
    }
Beispiel #4
0
    public Dictionary <short, MeshInfo> Split(MeshInfo mesh, KDTree tree, List <Vector3> voxels, short[,,] colourings, ThreadSafeVoxelisation.GridSize size)
    {
        Dictionary <short, Dictionary <string, int> > meshFoundIndices = new Dictionary <short, Dictionary <string, int> >();
        Dictionary <short, List <Vector3> >           meshVertices     = new Dictionary <short, List <Vector3> >();
        Dictionary <short, List <int> >     meshIndices = new Dictionary <short, List <int> >();
        Dictionary <short, List <Vector3> > meshEdges   = new Dictionary <short, List <Vector3> >();


        int[]     tris  = mesh.index;
        Vector3[] verts = mesh.verts;

        for (int i = 0; i < tris.Length; i += 3)
        {
            Vector3 v1 = verts[tris[i]];
            Vector3 v2 = verts[tris[i + 1]];
            Vector3 v3 = verts[tris[i + 2]];

            short c1 = nearestColour(toVoxelSpace(v1, size, 0.5f), tree, voxels, colourings);
            short c2 = nearestColour(toVoxelSpace(v2, size, 0.5f), tree, voxels, colourings);
            short c3 = nearestColour(toVoxelSpace(v3, size, 0.5f), tree, voxels, colourings);

            if (c1 == c2 && c1 == c3)
            {
                Dictionary <string, int> foundIndices;
                if (!(meshFoundIndices.TryGetValue(c1, out foundIndices)))
                {
                    foundIndices = new Dictionary <string, int>();
                    meshFoundIndices.Add(c1, foundIndices);
                }

                List <Vector3> vertices;
                if (!(meshVertices.TryGetValue(c1, out vertices)))
                {
                    vertices = new List <Vector3>();
                    meshVertices.Add(c1, vertices);
                }

                List <int> indices;
                if (!(meshIndices.TryGetValue(c1, out indices)))
                {
                    indices = new List <int>();
                    meshIndices.Add(c1, indices);
                }

                StoreVertex(v1, foundIndices, indices, vertices);
                StoreVertex(v2, foundIndices, indices, vertices);
                StoreVertex(v3, foundIndices, indices, vertices);
            }
            else
            {
                if (c1 == c2)
                {
                    List <Vector3> edges;
                    if (!(meshEdges.TryGetValue(c1, out edges)))
                    {
                        edges = new List <Vector3>();
                        meshEdges.Add(c1, edges);
                    }
                    edges.Add(v1);
                    edges.Add(v2);
                    edges.Add(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity));
                }
                if (c1 == c3)
                {
                    List <Vector3> edges;
                    if (!(meshEdges.TryGetValue(c1, out edges)))
                    {
                        edges = new List <Vector3>();
                        meshEdges.Add(c1, edges);
                    }
                    edges.Add(v1);
                    edges.Add(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity));
                    edges.Add(v3);
                }
                if (c2 == c3)
                {
                    List <Vector3> edges;
                    if (!(meshEdges.TryGetValue(c2, out edges)))
                    {
                        edges = new List <Vector3>();
                        meshEdges.Add(c2, edges);
                    }
                    edges.Add(new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity));
                    edges.Add(v2);
                    edges.Add(v3);
                }
            }
        }

        Dictionary <short, MeshInfo> output = new Dictionary <short, MeshInfo>();

        foreach (short s in meshFoundIndices.Keys)
        {
            List <Vector3> vertices;
            meshVertices.TryGetValue(s, out vertices);

            List <int> indices;
            meshIndices.TryGetValue(s, out indices);

            List <Vector3> edges;
            meshEdges.TryGetValue(s, out edges);

            Fragment c = new Fragment(s);

            c.vertices.AddRange(edges);

            output.Add(s, new MeshInfo(vertices.ToArray(), indices.ToArray(), c));
        }

        return(output);
    }
 public void SetSize(GridSize dimension)
 {
     SetSize((short)dimension.x, (short)dimension.y, (short)dimension.z, dimension.side);
 }
    //MarchTetrahedron performs the Marching Tetrahedrons algorithm on a single tetrahedron
    static void MarchTetrahedron(Vector3[] tetrahedronPosition, float[] tetrahedronValue, List <Vector3> vertList, List <int> indexList, ThreadSafeVoxelisation.Voxelization.AABCGrid grid, Dictionary <string, int> indices, KDTree surface, List <Vector3> parentVerts)
    {
        ThreadSafeVoxelisation.GridSize gridSize = grid.GetSize();

        int   i, j, vert, vert0, vert1, idx;
        int   flagIndex = 0, edgeFlags;
        float offset, invOffset;

        bool boundary = false;

        Vector3[] edgeVertex = new Vector3[6];

        //Find which vertices are inside of the surface and which are outside
        for (i = 0; i < 4; i++)
        {
            if (tetrahedronValue[i] == -999f)
            {
                boundary = true;
            }
            if (tetrahedronValue[i] <= target)
            {
                flagIndex |= 1 << i;
            }
        }

        //Find which edges are intersected by the surface
        edgeFlags = tetrahedronEdgeFlags[flagIndex];

        //If the tetrahedron 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 < 6; i++)
        {
            //if there is an intersection on this edge
            if ((edgeFlags & (1 << i)) != 0)
            {
                vert0           = tetrahedronEdgeConnection[i, 0];
                vert1           = tetrahedronEdgeConnection[i, 1];
                offset          = GetOffset(tetrahedronValue[vert0], tetrahedronValue[vert1]);
                invOffset       = 1.0f - offset;
                edgeVertex[i].x = ((invOffset * tetrahedronPosition[vert0].x + offset * tetrahedronPosition[vert1].x) - (gridSize.x * 0.5f)) * gridSize.side / 2.1f;
                edgeVertex[i].y = ((invOffset * tetrahedronPosition[vert0].y + offset * tetrahedronPosition[vert1].y) - (gridSize.y * 0.5f)) * gridSize.side / 2.1f;
                edgeVertex[i].z = ((invOffset * tetrahedronPosition[vert0].z + offset * tetrahedronPosition[vert1].z) - (gridSize.z * 0.5f)) * gridSize.side / 2.1f;
            }
        }

        Vector3[] oEdgeVertex = new Vector3[6];

        if (boundary)
        {
            for (int c = 0; c < edgeVertex.Length; c++)
            {
                oEdgeVertex[c] = edgeVertex[c];
                int index = surface.FindNearest(edgeVertex[c]);
                edgeVertex[c] = parentVerts[index];
            }
        }
        else
        {
            for (int c = 0; c < edgeVertex.Length; c++)
            {
                oEdgeVertex[c] = edgeVertex[c];
                Vector3 random = Random.insideUnitSphere;
                random       *= 1f / 4f;
                random.x      = (random.x) * gridSize.side / 2.1f;
                random.y      = (random.y) * gridSize.side / 2.1f;
                random.z      = (random.z) * gridSize.side / 2.1f;
                edgeVertex[c] = edgeVertex[c] + random;
            }
        }

        //Save the triangles that were found. There can be up to 2 per tetrahedron
        for (i = 0; i < 2; i++)
        {
            if (tetrahedronTriangles[flagIndex, 3 * i] < 0)
            {
                break;
            }

            for (j = 0; j < 3; j++)
            {
                idx  = vertList.Count;
                vert = tetrahedronTriangles[flagIndex, 3 * i + windingOrder[j]];

                Vector3 vertex = edgeVertex[vert];

                string points = oEdgeVertex[vert].x + "," + oEdgeVertex[vert].y + "," + oEdgeVertex[vert].z;

                int index = -1;

                bool found = indices.TryGetValue(points, out index);

                if (found)
                {
                    indexList.Add(index);
                }
                else
                {
                    indexList.Add(idx);
                    vertList.Add(edgeVertex[vert]);
                    indices.Add(points, idx);
                }
            }
        }
    }
    //MarchCube performs the Marching Cubes algorithm on a single cube
    static void MarchCube(Vector3 pos, float[] cube, List <Vector3> vertList, List <int> indexList, ThreadSafeVoxelisation.Voxelization.AABCGrid grid, Dictionary <string, int> indices, KDTree surface, List <Vector3> parentVerts)
    {
        int   i, j, vert, idx;
        int   flagIndex = 0;
        float offset    = 0.0f;

        ThreadSafeVoxelisation.GridSize gridSize = grid.GetSize();

        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 cube

        /*for (i = 0; i < 5; i++) {
         *  if (triangleConnectionTable[flagIndex, 3 * i] < 0) break;
         *
         *  for (j = 0; j < 3; j++) {
         *      idx = vertList.Count;
         *      vert = triangleConnectionTable[flagIndex, 3 * i + windingOrder[j]];
         *
         *      Vector3 vertex = edgeVertex[vert];
         *      string points = vertex.x + "" + vertex.y + "" + vertex.z;
         *      int index = -1;
         *
         *      bool found = indices.TryGetValue(points, out index);
         *
         *      if (found) {
         *          indexList.Add(index);
         *      } else {
         *          indexList.Add(idx);
         *          vertList.Add(edgeVertex[vert]);
         *          indices.Add(points, idx);
         *      }
         *  }
         *
         * }*/

        for (i = 0; i < 5; i++)
        {
            if (triangleConnectionTable[flagIndex, 3 * i] < 0)
            {
                break;
            }

            idx = vertList.Count;

            for (j = 0; j < 3; j++)
            {
                vert = triangleConnectionTable[flagIndex, 3 * i + j];
                indexList.Add(idx + windingOrder[j]);
                vertList.Add(edgeVertex[vert]);
            }
        }
    }