public static void extract(oxelMap data, out List<Vector3f> vertices, out List<int> indizes, int lod,bool reuse)
        {
            vertices = new List<Vector3f>();
            indizes = new List<int>();

            int cellCnt = data.getSize();

            Cell[, ,] cells = new Cell[cellCnt, cellCnt, cellCnt];
            for (int xx = 0; xx < cellCnt; xx += lod)
                for (int yy = 0; yy < cellCnt; yy += lod)
                    for (int zz = 0; zz < cellCnt; zz += lod)
                    {
                        Cell c = new Cell(data, new Vector3i(xx, yy, zz));
                        cells[xx / lod, yy / lod, zz / lod] = c;
                        c.build(vertices, indizes, cells, lod, reuse);
                    }

            Console.WriteLine("VertexCount: " + vertices.Count + " TriCount: " + indizes.Count / 3);
        }
Beispiel #2
0
        public void build(List<Vector3f> vert, List<int> ind, Cell[, ,] cells,int lod,bool vertexReuseFlag = true)
        {
            byte[] density = new byte[8];
            for (int i = 0; i < density.Length; i++)
            {
                density[i] = data.getPoint(pos + VoxelConstants.cornerIndex[i] * lod);
            }

            rind = new int[4]{-1,-1,-1,-1};

            byte caseCode = getCaseCode(density);

            //Debug.Assert(((caseCode ^ ((density[7] >> 7) & 0xFF)) == 0) == (caseCode == 0x00 || caseCode == 0xFF), "Bit twidling trick failed");

            if ((caseCode ^ ((density[7] >> 7) & 0xFF)) == 0) //for this cases there is no triangulation
                return;

            byte regularCellClass = VoxelConstants.regularCellClass[caseCode];
            ushort[] vertexLocations = VoxelConstants.regularVertexData[caseCode];

            VoxelConstants.RegularCellData c = VoxelConstants.regularCellData[regularCellClass];
            long vertexCount = c.GetVertexCount();
            long triangleCount = c.GetTriangleCount();
            byte[] indexOffset = c.getIndizes(); //index offsets for current cell
            int[] mappedIndizes = new int[indexOffset.Length]; //array with real indizes for current cell

            for (int i = 0; i < vertexCount; i++)
            {
                byte edge = (byte)(vertexLocations[i] >> 8);
                byte reuseIndex = (byte)(edge & 0xF); //Vertex id which should be created or reused 1,2 or 3

                byte v1 = (byte)((vertexLocations[i]) & 0x0F); //Second Corner Index
                byte v0 = (byte)((vertexLocations[i] >> 4) & 0x0F); //First Corner Index

                byte d0 = density[v0];
                byte d1 = density[v1];

                long t = (d1 << 8) / (d1 - d0);

                if (t != 0 && t != 256 && t != -1 && t != -2 && t != 257 && t != 258)
                    Console.WriteLine(t);

                byte rDir = (byte)(edge >> 4); //the direction to go to reach a previous cell for reusing

                bool allowReuseOnCorners = false;

                if (!allowReuseOnCorners || (t & 0x00FF) != 0)
                {
                    if (v1 == 7)
                    {
                        Debug.Assert(v1 > v0, "Wrong corner order");

                        Vector3i iP0 = (pos + VoxelConstants.cornerIndex[v0] * lod) * voxelStep;
                        Vector3f P0 = new Vector3f(iP0.getX(), iP0.getY(), iP0.getZ());
                        Vector3i iP1 = (pos + VoxelConstants.cornerIndex[v1] * lod) * voxelStep;
                        Vector3f P1 = new Vector3f(iP1.getX(), iP1.getY(), iP1.getZ());

                        //EliminateLodPositionShift(lod, ref d0, ref d1, ref t, ref iP0, ref P0, ref iP1, ref P1);

                        Vector3f Q = InterpolateVoxelVector(t, P0, P1);
                        /*float fd0 = (float)d0;
                        float fd1 = (float)d1;

                        float inter = fd1/(fd1-fd0);

                        iP0 = VoxelConstants.cornerIndex[v0];
                        iP1 = VoxelConstants.cornerIndex[v1];
                        P0 = new Vector3(iP0.getX(),iP0.getY(),iP0.getZ());
                        P1 = new Vector3(iP1.getX(), iP1.getY(), iP1.getZ());
                        Vector3 Q = P0 * inter + P1 * (1 - inter);
                        Q += new Vector3(pos.getX(),pos.getY(),pos.getZ());*/

                        //Console.WriteLine(P0 + " " + P1 + " " + Q);

                        vert.Add(Q);
                        mapIndizes2Vertice(i, vert.Count-1, mappedIndizes, indexOffset);
                        rind[reuseIndex] = vert.Count - 1; //für reuse registrieren
                    }
                    else
                    {
                        Cell ccc = getReuseCell(cells, lod, rDir,pos);
                        Debug.Assert(ccc != null, "Cell for reuse is null");
                        int reI = ccc.rind[reuseIndex];
                        mapIndizes2Vertice(i, reI, mappedIndizes, indexOffset);
                    }
                }
                /* corner reuse is buggy */
                else if (t == 0)
                {
                    if (v1 == 7)
                    {
                        Vector3i v = (pos + VoxelConstants.cornerIndex[v1] * lod) * voxelStep;
                        Vector3f Q = new Vector3f(v.getX(), v.getY(), v.getZ());
                        vert.Add(Q);
                        mapIndizes2Vertice(i, vert.Count - 1, mappedIndizes, indexOffset);
                        rind[0] = vert.Count - 1;
                    }
                    else
                    {
                        rDir = v1;
                        rDir ^= (byte)7;
                        Cell ccc = getReuseCell(cells, lod, rDir, pos);
                        Debug.Assert(ccc != null, "Cell for reuse is null");
                        int reI = ccc.rind[0];
                        mapIndizes2Vertice(i, reI, mappedIndizes, indexOffset);
                    }
                }
                else
                {
                    rDir = v0;
                    rDir ^= (byte)7;
                    Cell ccc = getReuseCell(cells, lod, rDir, pos);
                    Debug.Assert(ccc != null, "Cell for reuse is null");
                    int reI = ccc.rind[0];

                    if (reI == -1)
                    {
                        //The vertex doesn't exist, create it
                        Vector3i v = (pos + VoxelConstants.cornerIndex[v0] * lod) * voxelStep;
                        Vector3f Q = new Vector3f(v.getX(), v.getY(), v.getZ());
                        vert.Add(Q);
                        mapIndizes2Vertice(i, vert.Count - 1, mappedIndizes, indexOffset);
                        rind[0] = vert.Count - 1;
                    }
                    else
                    {
                        mapIndizes2Vertice(i, reI, mappedIndizes, indexOffset);
                    }
                }
            }

            for (int i = 0; i < triangleCount; i++)
            {
                int i1 = mappedIndizes[i * 3 + 0];
                int i2 = mappedIndizes[i * 3 + 1];
                int i3 = mappedIndizes[i * 3 + 2];

                ind.Add(i1);
                ind.Add(i2);
                ind.Add(i3);
            }
        }
Beispiel #3
0
        private static Cell getReuseCell(Cell[, ,] cells, int lod, byte rDir,Vector3i pos)
        {
            int rx = rDir & 0x01;
            int rz = (rDir >> 1) & 0x01;
            int ry = (rDir >> 2) & 0x01;

            int dx = pos.getX() / lod - rx;
            int dy = pos.getY() / lod - ry;
            int dz = pos.getZ() / lod - rz;

            Cell ccc = cells[dx, dy, dz];
            return ccc;
        }