コード例 #1
0
        //private static int getX(int index, int dimension) {
        //	return (y * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + x;
        //}

        //private static int getY(int index, int dimension) {
        //	return ((VERTEX_DIMENSION + x) * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + y;
        //}

        //private static int getZ(int index, int dimension) {
        //	return ((VERTEX_DIMENSION * 2 + x) * VERTEX_DIMENSION + y) * VERTEX_DIMENSION + z;
        //}

        //private static int getDimension(int index) {
        //	return index / (VERTEX_DIMENSION * VERTEX_DIMENSION * VERTEX_DIMENSION);
        //}

        private Voxel[, ,] createVoxelArray(VoxelUpdateInfo info)
        {
            setDimensions(info);
            Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION];

            for (byte y = (byte)(1 - yExtend); y < yDim; ++y)
            {
                for (byte z = (byte)(1 - zExtend); z < zDim; ++z)
                {
                    voxels[1 - xExtend, y, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - 1 + z).toVoxel();
                }
            }
            for (byte x = (byte)(2 - xExtend); x < xDim; ++x)
            {
                for (byte z = (byte)(1 - zExtend); z < zDim; ++z)
                {
                    voxels[x, 1 - yExtend, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + z).toVoxel();
                }
            }
            for (byte x = (byte)(2 - xExtend); x < xDim; ++x)
            {
                for (byte y = (byte)(2 - yExtend); y < yDim; ++y)
                {
                    voxels[x, y, 1 - zExtend] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - zExtend).toVoxel();
                }
            }

            return(voxels);
        }
コード例 #2
0
 public VoxelUpdateInfo(VoxelUpdateInfo super, byte xi, byte yi, byte zi)
     : this()
 {
     size = super.size / VoxelBlock.CHILD_DIMENSION;
     detailLevel = (byte)(super.detailLevel + 1);
     control = super.control;
     x = super.x * VoxelBlock.CHILD_DIMENSION + xi;
     y = super.y * VoxelBlock.CHILD_DIMENSION + yi;
     z = super.z * VoxelBlock.CHILD_DIMENSION + zi;
     for (byte xii = 0; xii < DIMENSION; ++xii) {
         for (byte yii = 0; yii < DIMENSION; ++yii) {
             for (byte zii = 0; zii < DIMENSION; ++zii) {
                 blocks[xii, yii, zii] = super.getSub(VoxelBlock.CHILD_COUNT_POWER, (byte)(xii + xi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(yii + yi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(zii + zi + VoxelBlock.CHILD_DIMENSION - 1));
                 renderers[xii, yii, zii] = super.renderers[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)];
                 if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old) {
                     renderers[xii, yii, zii] = super.blocks[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)].getRenderer(0, 0, 0, 0);
                     if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old)
                         renderers[xii, yii, zii] = blocks[xii, yii, zii].getRenderer(0, 0, 0, 0);
                     if (renderers[xii, yii, zii] != null && renderers[xii, yii, zii].old)
                         renderers[xii, yii, zii] = null;
                 }
             }
         }
     }
 }
コード例 #3
0
 public override void execute()
 {
     lock (control) {
         VoxelUpdateInfo info = control.getBaseUpdateInfo().getSubInfo(detailLevel, xOff, yOff, zOff);
         getRenderer().genMesh(info);
     }
 }
コード例 #4
0
 public VoxelUpdateInfo(VoxelUpdateInfo super, byte xi, byte yi, byte zi)
     : this()
 {
     size        = super.size / VoxelBlock.CHILD_DIMENSION;
     detailLevel = (byte)(super.detailLevel + 1);
     control     = super.control;
     x           = super.x * VoxelBlock.CHILD_DIMENSION + xi;
     y           = super.y * VoxelBlock.CHILD_DIMENSION + yi;
     z           = super.z * VoxelBlock.CHILD_DIMENSION + zi;
     for (byte xii = 0; xii < DIMENSION; ++xii)
     {
         for (byte yii = 0; yii < DIMENSION; ++yii)
         {
             for (byte zii = 0; zii < DIMENSION; ++zii)
             {
                 blocks[xii, yii, zii]    = super.getSub(VoxelBlock.CHILD_COUNT_POWER, (byte)(xii + xi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(yii + yi + VoxelBlock.CHILD_DIMENSION - 1), (byte)(zii + zi + VoxelBlock.CHILD_DIMENSION - 1));
                 renderers[xii, yii, zii] = super.renderers[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)];
                 if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old)
                 {
                     renderers[xii, yii, zii] = super.blocks[(int)((xii + xi + 1) * 0.5), (int)((yii + yi + 1) * 0.5), (int)((zii + zi + 1) * 0.5)].getRenderer(0, 0, 0, 0);
                     if (renderers[xii, yii, zii] == null || renderers[xii, yii, zii].old)
                     {
                         renderers[xii, yii, zii] = blocks[xii, yii, zii].getRenderer(0, 0, 0, 0);
                     }
                     if (renderers[xii, yii, zii] != null && renderers[xii, yii, zii].old)
                     {
                         renderers[xii, yii, zii] = null;
                     }
                 }
             }
         }
     }
 }
コード例 #5
0
        private void alignOtherEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            VoxelRenderer other = info.renderers[1, 1, 1];

            if (other == null)
            {
                if (info.blocks[1, 1, 1].GetType() == typeof(VoxelBlock))
                {
                    byte xStart = (byte)((VoxelBlock.CHILD_DIMENSION - 1) * (2 - x) / 2);
                    byte xEnd   = (byte)(1 + (VoxelBlock.CHILD_DIMENSION - 1) * (1 - x / 2));
                    byte yStart = (byte)((VoxelBlock.CHILD_DIMENSION - 1) * (2 - y) / 2);
                    byte yEnd   = (byte)(1 + (VoxelBlock.CHILD_DIMENSION - 1) * (1 - y / 2));
                    byte zStart = (byte)((VoxelBlock.CHILD_DIMENSION - 1) * (2 - z) / 2);
                    byte zEnd   = (byte)(1 + (VoxelBlock.CHILD_DIMENSION - 1) * (1 - z / 2));

                    for (byte xi = xStart; xi < xEnd; ++xi)
                    {
                        for (byte yi = yStart; yi < yEnd; ++yi)
                        {
                            for (byte zi = zStart; zi < zEnd; ++zi)
                            {
                                alignOtherEdge(new VoxelUpdateInfo(info, xi, yi, zi), x, y, z);
                            }
                        }
                    }
                }
                return;
            }
            other.addEdge(info, (byte)(2 - x), (byte)(2 - y), (byte)(2 - z));
        }
コード例 #6
0
ファイル: Modifier.cs プロジェクト: petra4372/OpenCircuit
        protected void traverse(VoxelUpdateInfo info, byte detailLevel)
        {
            int factor = 1 << (detailLevel - VoxelBlock.CHILD_COUNT_POWER);
            byte xiMin = (byte)Mathf.Max(min.x / factor - info.x * VoxelBlock.CHILD_DIMENSION, 0);
            byte xiMax = (byte)Mathf.Min((max.x + 3) / factor - info.x * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1);
            byte yiMin = (byte)Mathf.Max(min.y / factor - info.y * VoxelBlock.CHILD_DIMENSION, 0);
            byte yiMax = (byte)Mathf.Min((max.y + 3) / factor - info.y * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1);
            byte ziMin = (byte)Mathf.Max(min.z / factor - info.z * VoxelBlock.CHILD_DIMENSION, 0);
            byte ziMax = (byte)Mathf.Min((max.z + 3) / factor - info.z * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1);

            VoxelBlock block = (VoxelBlock)info.blocks[1, 1, 1];

            int scale = VoxelBlock.CHILD_DIMENSION << (VoxelBlock.CHILD_COUNT_POWER *(detailLevel));
            //			MonoBehaviour.print (scale);
            //			MonoBehaviour.print (detailLevel);

            uint minY = uint.MinValue;
            uint maxY = uint.MaxValue;
            foreach(VoxelMask mask in control.masks) {
                if (mask.active) {
                    if (mask.maskAbove) {
                        if (maxY > mask.yPosition)
                            maxY = mask.yPosition;
                    } else if (minY < mask.yPosition) {
                        minY = mask.yPosition;
                    }
                }
            }

            for (byte xi = xiMin; xi <= xiMax; ++xi) {
                for (byte yi = yiMin; yi <= yiMax; ++yi) {

                    if ((info.y +yi +1) *scale <= minY ||
                        (info.y +yi) *scale >= maxY) {
                        continue;
                    }

                    for (byte zi = ziMin; zi <= ziMax; ++zi) {
                        if (detailLevel <= VoxelBlock.CHILD_COUNT_POWER) {
                            block.children[xi, yi, zi] = modifyVoxel(block.children[xi, yi, zi], info.x * VoxelBlock.CHILD_DIMENSION + xi, info.y * VoxelBlock.CHILD_DIMENSION + yi, info.z * VoxelBlock.CHILD_DIMENSION + zi);
                        } else {
                            if (block.children[xi, yi, zi].GetType() == typeof(Voxel)) {
                                block.children[xi, yi, zi] = new VoxelBlock((Voxel)block.children[xi, yi, zi]);
                            }
                            traverse(new VoxelUpdateInfo(info, xi, yi, zi), (byte)(detailLevel - VoxelBlock.CHILD_COUNT_POWER));
                        }
                    }
                }
            }

            // TODO: this should check if completely contained, not if rendersize (for distant modifications) - FIXED?
            if (updateMesh && info != null && (VoxelBlock.isRenderSize(info.size, control) || VoxelBlock.isRenderLod(info.x, info.y, info.z, control.sizes[detailLevel], control))) {
                block.updateAll(info.x, info.y, info.z, info.detailLevel, control, true);
            }
        }
コード例 #7
0
        protected void traverse(VoxelUpdateInfo info, byte detailLevel)
        {
            int  factor = 1 << (detailLevel - VoxelBlock.CHILD_COUNT_POWER);
            byte xiMin  = (byte)Mathf.Max(minX / factor - info.x * VoxelBlock.CHILD_DIMENSION, 0f);
            byte xiMax  = (byte)Mathf.Min((maxX + 1) / factor - info.x * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1f);
            byte yiMin  = (byte)Mathf.Max(minY / factor - info.y * VoxelBlock.CHILD_DIMENSION, 0f);
            byte yiMax  = (byte)Mathf.Min((maxY + 1) / factor - info.y * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1f);
            byte ziMin  = (byte)Mathf.Max(minZ / factor - info.z * VoxelBlock.CHILD_DIMENSION, 0f);
            byte ziMax  = (byte)Mathf.Min((maxZ + 1) / factor - info.z * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1f);

            VoxelBlock block = (VoxelBlock)info.blocks[1, 1, 1];

            uint scale = (uint)(1 << (VoxelBlock.CHILD_COUNT_POWER * (detailLevel - 1)));

            for (byte yi = yiMin; yi <= yiMax; ++yi)
            {
                if ((info.y * VoxelBlock.CHILD_DIMENSION + yi) < maskMinY / scale ||
                    (info.y * VoxelBlock.CHILD_DIMENSION + yi) > maskMaxY / scale + 1)
                {
                    continue;
                }

                for (byte xi = xiMin; xi <= xiMax; ++xi)
                {
                    for (byte zi = ziMin; zi <= ziMax; ++zi)
                    {
                        if (detailLevel <= VoxelBlock.CHILD_COUNT_POWER)
                        {
                            block.children[xi, yi, zi] = modifyVoxel(block.children[xi, yi, zi], info.x * VoxelBlock.CHILD_DIMENSION + xi, info.y * VoxelBlock.CHILD_DIMENSION + yi, info.z * VoxelBlock.CHILD_DIMENSION + zi);
                        }
                        else
                        {
                            if (block.children[xi, yi, zi].GetType() == typeof(Voxel))
                            {
                                block.children[xi, yi, zi] = new VoxelBlock((Voxel)block.children[xi, yi, zi]);
                            }
                            traverse(new VoxelUpdateInfo(info, xi, yi, zi), (byte)(detailLevel - VoxelBlock.CHILD_COUNT_POWER));
                        }
                    }
                }
            }

            if (updateMesh && info != null && (VoxelBlock.isRenderSize(info.size, control) || VoxelBlock.isRenderLod(info.x, info.y, info.z, info.size, control)))
            {
                //block.clearSubRenderers(control);
                block.updateAll(info.x, info.y, info.z, info.detailLevel, control, true);
            }
        }
コード例 #8
0
		public void setFromSister(VoxelUpdateInfo sister, byte xi, byte yi, byte zi) {
			size = sister.size;
			detailLevel = sister.detailLevel;
			control = sister.control;
			x = sister.x + xi - 1;
			y = sister.y + yi - 1;
			z = sister.z + zi - 1;
			for (byte xii = (byte)(1 - (xi + 1) / 2); xii < DIMENSION - (xi / 2); ++xii) {
				for (byte yii = (byte)(1 - (yi + 1) / 2); yii < DIMENSION - (yi / 2); ++yii) {
					for (byte zii = (byte)(1 - (zi + 1) / 2); zii < DIMENSION - (zi / 2); ++zii) {
						blocks[xii, yii, zii] = sister.blocks[xii + xi - 1, yii + yi - 1, zii + zi - 1];
						renderers[xii, yii, zii] = sister.renderers[xii + xi - 1, yii + yi - 1, zii + zi - 1];
					}
				}
			}
		}
コード例 #9
0
 private void setDimensions(VoxelUpdateInfo info)
 {
     if (info.renderers[0, 1, 1] == null)
     {
         xExtend = 0;
     }
     else
     {
         xExtend = 1;
     }
     if (info.renderers[1, 0, 1] == null)
     {
         yExtend = 0;
     }
     else
     {
         yExtend = 1;
     }
     if (info.renderers[1, 1, 0] == null)
     {
         zExtend = 0;
     }
     else
     {
         zExtend = 1;
     }
     xDim = (byte)(VOXEL_DIMENSION + 1);
     yDim = (byte)(VOXEL_DIMENSION + 1);
     zDim = (byte)(VOXEL_DIMENSION + 1);
     if (info.renderers[2, 1, 1] != null && info.renderers[2, 1, 1].size > size * 1.1f)
     {
         ++xDim;
     }
     if (info.renderers[1, 2, 1] != null && info.renderers[1, 2, 1].size > size * 1.1f)
     {
         ++yDim;
     }
     if (info.renderers[1, 1, 2] != null && info.renderers[1, 1, 2].size > size * 1.1f)
     {
         ++zDim;
     }
 }
コード例 #10
0
 public void setFromSister(VoxelUpdateInfo sister, byte xi, byte yi, byte zi)
 {
     size        = sister.size;
     detailLevel = sister.detailLevel;
     control     = sister.control;
     x           = sister.x + xi - 1;
     y           = sister.y + yi - 1;
     z           = sister.z + zi - 1;
     for (byte xii = (byte)(1 - (xi + 1) / 2); xii < DIMENSION - (xi / 2); ++xii)
     {
         for (byte yii = (byte)(1 - (yi + 1) / 2); yii < DIMENSION - (yi / 2); ++yii)
         {
             for (byte zii = (byte)(1 - (zi + 1) / 2); zii < DIMENSION - (zi / 2); ++zii)
             {
                 blocks[xii, yii, zii]    = sister.blocks[xii + xi - 1, yii + yi - 1, zii + zi - 1];
                 renderers[xii, yii, zii] = sister.renderers[xii + xi - 1, yii + yi - 1, zii + zi - 1];
             }
         }
     }
 }
コード例 #11
0
ファイル: Modifier.cs プロジェクト: viviannimue/OpenCircuit
        protected void traverse(VoxelUpdateInfo info, byte detailLevel)
        {
            int factor = 1 << (detailLevel - VoxelBlock.CHILD_COUNT_POWER);
            byte xiMin = (byte)Mathf.Max(minX / factor - info.x * VoxelBlock.CHILD_DIMENSION, 0f);
            byte xiMax = (byte)Mathf.Min((maxX + 1) / factor - info.x * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1f);
            byte yiMin = (byte)Mathf.Max(minY / factor - info.y * VoxelBlock.CHILD_DIMENSION, 0f);
            byte yiMax = (byte)Mathf.Min((maxY + 1) / factor - info.y * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1f);
            byte ziMin = (byte)Mathf.Max(minZ / factor - info.z * VoxelBlock.CHILD_DIMENSION, 0f);
            byte ziMax = (byte)Mathf.Min((maxZ + 1) / factor - info.z * VoxelBlock.CHILD_DIMENSION, VoxelBlock.CHILD_DIMENSION - 1f);

            VoxelBlock block = (VoxelBlock)info.blocks[1, 1, 1];

            uint scale = (uint) (1 << (VoxelBlock.CHILD_COUNT_POWER *(detailLevel -1)));

            for (byte yi = yiMin; yi <= yiMax; ++yi) {

                if ((info.y *VoxelBlock.CHILD_DIMENSION +yi) < maskMinY /scale ||
                    (info.y *VoxelBlock.CHILD_DIMENSION +yi) > maskMaxY /scale +1) {
                    continue;
                }

                for (byte xi = xiMin; xi <= xiMax; ++xi) {
                    for (byte zi = ziMin; zi <= ziMax; ++zi) {
                        if (detailLevel <= VoxelBlock.CHILD_COUNT_POWER) {
                            block.children[xi, yi, zi] = modifyVoxel(block.children[xi, yi, zi], info.x * VoxelBlock.CHILD_DIMENSION + xi, info.y * VoxelBlock.CHILD_DIMENSION + yi, info.z * VoxelBlock.CHILD_DIMENSION + zi);
                        } else {
                            if (block.children[xi, yi, zi].GetType() == typeof(Voxel)) {
                                block.children[xi, yi, zi] = new VoxelBlock((Voxel)block.children[xi, yi, zi]);
                            }
                            traverse(new VoxelUpdateInfo(info, xi, yi, zi), (byte)(detailLevel - VoxelBlock.CHILD_COUNT_POWER));
                        }
                    }
                }
            }

            if (updateMesh && info != null && (VoxelBlock.isRenderSize(info.size, control) || VoxelBlock.isRenderLod(info.x, info.y, info.z, info.size, control))) {
                //block.clearSubRenderers(control);
                block.updateAll(info.x, info.y, info.z, info.detailLevel, control, true);
            }
        }
コード例 #12
0
        public void genMesh(VoxelUpdateInfo info)
        {
            if (control == null)
            {
                return;
            }

            size = info.size;

            Queue <int[]> triangleSet = new Queue <int[]>();

            vertices          = new Dictionary <int, object>();
            vertexSubstances  = new Dictionary <int, byte>();
            Voxel[, ,] voxels = createVoxelArray(info);
            MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, null);
            int totalTris = 0;

            for (byte x = (byte)(1 - xExtend), x1 = (byte)(x + 1); x1 < xDim; x = x1++)
            {
                for (byte y = (byte)(1 - yExtend), y1 = (byte)(y + 1); y1 < yDim; y = y1++)
                {
                    for (byte z = (byte)(1 - zExtend), z1 = (byte)(z + 1); z1 < zDim; z = z1++)
                    {
                        lock (control) {
                            VoxelHolder block = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION + x, VOXEL_DIMENSION + y, VOXEL_DIMENSION + z);
                            voxels[x1, y1, z1] = block.toVoxel();
                            int[] tris = MarchingCubes.lookupTriangles(x, y, z, x1, y1, z1);
                            if (tris == null)
                            {
                                continue;
                            }
                            triangleSet.Enqueue(tris);
                            totalTris += tris.Length;
                        }
                    }
                }
            }

            if (vertices.Count < 1)
            {
                applied = true;
                return;
            }


            List <int>     triangles     = new List <int>();
            List <Vector3> finalVertices = new List <Vector3>(vertices.Count);

            //List<byte> finalMats = new List<byte>(vertices.Count);
            while (triangleSet.Count > 0)
            {
                int[] triangleList = triangleSet.Dequeue();
                for (int i = 0; i < triangleList.Length; ++i)
                {
                    if (vertices[triangleList[i]].GetType() == typeof(Vector3))
                    {
                        finalVertices.Add((Vector3)vertices[triangleList[i]]);
                        //finalMats.Add(vertexSubstances[triangleList[i]]);
                        vertices[triangleList[i]] = finalVertices.Count - 1;
                    }
                    triangles.Add((int)vertices[triangleList[i]]);
                }
            }
            VERTS = finalVertices.ToArray();
            TRIS  = triangles.ToArray();
            //MATS = finalMats.ToArray();
            calcNorms();

            alignEdge(info, 0, 1, 1);
            alignEdge(info, 2, 1, 1);
            alignEdge(info, 1, 0, 1);
            alignEdge(info, 1, 2, 1);
            alignEdge(info, 1, 1, 0);
            alignEdge(info, 1, 1, 2);
            lock (control) {
                control.enqueueJob(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z));
            }
        }
コード例 #13
0
        private void alignOtherEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            VoxelRenderer other = info.renderers[1, 1, 1];
            if (other == null) {
                if (info.blocks[1, 1, 1].GetType() == typeof(VoxelBlock)) {

                    byte xStart = (byte)((VoxelBlock.CHILD_DIMENSION - 1) * (2 - x) / 2);
                    byte xEnd = (byte)(1 + (VoxelBlock.CHILD_DIMENSION - 1) * (1 - x / 2));
                    byte yStart = (byte)((VoxelBlock.CHILD_DIMENSION - 1) * (2 - y) / 2);
                    byte yEnd = (byte)(1 + (VoxelBlock.CHILD_DIMENSION - 1) * (1 - y / 2));
                    byte zStart = (byte)((VoxelBlock.CHILD_DIMENSION - 1) * (2 - z) / 2);
                    byte zEnd = (byte)(1 + (VoxelBlock.CHILD_DIMENSION - 1) * (1 - z / 2));

                    for (byte xi = xStart; xi < xEnd; ++xi) {
                        for (byte yi = yStart; yi < yEnd; ++yi) {
                            for (byte zi = zStart; zi < zEnd; ++zi) {
                                alignOtherEdge(new VoxelUpdateInfo(info, xi, yi, zi), x, y, z);
                            }
                        }
                    }
                }
                return;
            }
            other.addEdge(info, (byte)(2 - x), (byte)(2 - y), (byte)(2 - z));
        }
コード例 #14
0
        public void addEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            if (vertices == null)
            {
                return;
            }
            bool recalculate = false;

            Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION];
            if (x == 0 /* && xExtend == 0*/)
            {
                recalculate = true;
                xExtend     = 1;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        voxels[0, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            }
            else if (x == 2 /* && xDim < VERTEX_DIMENSION*/)
            {
                recalculate = true;
                xDim        = VERTEX_DIMENSION;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        voxels[VOXEL_DIMENSION + 1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[VOXEL_DIMENSION, yi, zi]     = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            }
            else if (y == 0 /* && yExtend == 0*/)
            {
                recalculate = true;
                yExtend     = 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        voxels[xi, 0, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[xi, 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            }
            else if (y == 2 /* && yDim < VERTEX_DIMENSION*/)
            {
                recalculate = true;
                yDim        = VERTEX_DIMENSION;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        voxels[xi, VOXEL_DIMENSION + 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[xi, VOXEL_DIMENSION, zi]     = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            }
            else if (z == 0 /* && zExtend == 0*/)
            {
                recalculate = true;
                zExtend     = 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                    {
                        voxels[xi, yi, 0] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - zExtend).toVoxel();
                        voxels[xi, yi, 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION).toVoxel();
                    }
                }
            }
            else if (z == 2 /* && zDim < VERTEX_DIMENSION*/)
            {
                recalculate = true;
                zDim        = VERTEX_DIMENSION;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                    {
                        voxels[xi, yi, VOXEL_DIMENSION + 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2).toVoxel();
                        voxels[xi, yi, VOXEL_DIMENSION]     = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2 - 1).toVoxel();
                    }
                }
            }

            if (recalculate)
            {
                Queue <int[]> triangleSet = new Queue <int[]>();
                MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, VERTS);

                byte xStart = (byte)(1 - xExtend + (VOXEL_DIMENSION + xExtend - 1) * (x / 2));
                byte xEnd   = (byte)(2 + (xDim - 2) * ((x + 1) / 2));
                byte yStart = (byte)(1 - yExtend + (VOXEL_DIMENSION + yExtend - 1) * (y / 2));
                byte yEnd   = (byte)(2 + (yDim - 2) * ((y + 1) / 2));
                byte zStart = (byte)(1 - zExtend + (VOXEL_DIMENSION + zExtend - 1) * (z / 2));
                byte zEnd   = (byte)(2 + (zDim - 2) * ((z + 1) / 2));

                for (byte xi = xStart, x1 = (byte)(xi + 1); x1 < xEnd; xi = x1++)
                {
                    for (byte yi = yStart, y1 = (byte)(yi + 1); y1 < yEnd; yi = y1++)
                    {
                        for (byte zi = zStart, z1 = (byte)(zi + 1); z1 < zEnd; zi = z1++)
                        {
                            int[] tris = MarchingCubes.lookupTriangles(xi, yi, zi, x1, y1, z1);
                            if (tris == null)
                            {
                                continue;
                            }
                            triangleSet.Enqueue(tris);
                        }
                    }
                }

                if (vertices.Count < 1)
                {
                    return;
                }


                List <int>     newTriangles = new List <int>(TRIS);
                List <Vector3> newVertices  = new List <Vector3>(VERTS);
                int            tri          = 0;
                while (triangleSet.Count > 0)
                {
                    int[] triangleList = triangleSet.Dequeue();
                    for (int i = 0; i < triangleList.Length; ++i)
                    {
                        if (vertices[triangleList[i]].GetType() == typeof(Vector3))
                        {
                            newVertices.Add((Vector3)vertices[triangleList[i]]);
                            vertices[triangleList[i]] = newVertices.Count - 1;
                        }
                        newTriangles.Add((int)vertices[triangleList[i]]);
                    }
                    tri += triangleList.Length;
                }

                Vector3[] finalNorms = new Vector3[newVertices.Count];
                Array.Copy(NORMS, finalNorms, NORMS.Length);
                int oldNormCount = NORMS.Length;

                VERTS = newVertices.ToArray();
                TRIS  = newTriangles.ToArray();
                calcNorms();
                Array.Copy(NORMS, oldNormCount, finalNorms, oldNormCount, finalNorms.Length - oldNormCount);
                NORMS = finalNorms;
            }

            alignEdge(info, x, y, z);
            control.enqueueJob(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z));
        }
コード例 #15
0
        public void removeEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            if (vertices == null)
            {
                return;
            }
            bool recalculate = false;

            if (x == 0 && xExtend == 1)
            {
                recalculate = true;
                xExtend     = 0;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        vertices.Remove(getX(0, yi, zi));
                        vertices.Remove(getY(0, yi, zi));
                        vertices.Remove(getZ(0, yi, zi));
                    }
                }
            }
            else if (x == 2 && xDim >= VERTEX_DIMENSION)
            {
                recalculate = true;
                xDim        = VERTEX_DIMENSION - 1;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        vertices.Remove(getX(xDim - 1, yi, zi));
                        vertices.Remove(getY(xDim, yi, zi));
                        vertices.Remove(getZ(xDim, yi, zi));
                    }
                }
            }
            else if (y == 0 && yExtend == 1)
            {
                recalculate = true;
                yExtend     = 0;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        vertices.Remove(getX(xi, 0, zi));
                        vertices.Remove(getY(xi, 0, zi));
                        vertices.Remove(getZ(xi, 0, zi));
                    }
                }
            }
            else if (y == 2 && yDim >= VERTEX_DIMENSION)
            {
                recalculate = true;
                yDim        = VERTEX_DIMENSION - 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi)
                    {
                        vertices.Remove(getX(xi, yDim, zi));
                        vertices.Remove(getY(xi, yDim - 1, zi));
                        vertices.Remove(getZ(xi, yDim, zi));
                    }
                }
            }
            else if (z == 0 && zExtend == 1)
            {
                recalculate = true;
                zExtend     = 0;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                    {
                        vertices.Remove(getX(xi, yi, 0));
                        vertices.Remove(getY(xi, yi, 0));
                        vertices.Remove(getZ(xi, yi, 0));
                    }
                }
            }
            else if (z == 2 && zDim >= VERTEX_DIMENSION)
            {
                recalculate = true;
                zDim        = VERTEX_DIMENSION - 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi)
                {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi)
                    {
                        vertices.Remove(getX(xi, yi, zDim));
                        vertices.Remove(getY(xi, yi, zDim));
                        vertices.Remove(getZ(xi, yi, zDim - 1));
                    }
                }
            }
            if (recalculate)
            {
                List <KeyValuePair <int, object> > vertexList = new List <KeyValuePair <int, object> >(vertices);
                int[]      oldTris  = TRIS;
                Vector3[]  oldVerts = VERTS;
                Vector3[]  oldNorms = NORMS;
                List <int> newTris  = new List <int>(TRIS.Length);
                Vector3[]  newVerts = new Vector3[vertexList.Count];
                Vector3[]  newNorms = new Vector3[newVerts.Length];

                object[] oldReverseIndices = new object[oldVerts.Length];


                int count = 0;
                foreach (KeyValuePair <int, object> pair in vertexList)
                {
                    int oldIndex = (int)pair.Value;
                    vertices[pair.Key]          = count;
                    newVerts[count]             = oldVerts[oldIndex];
                    newNorms[count]             = oldNorms[oldIndex];
                    oldReverseIndices[oldIndex] = pair.Key;
                    ++count;
                }

                int[] triangle = new int[3];
                for (int i = 0; i < oldTris.Length; i += 3)
                {
                    bool old = false;
                    for (int j = 0; j < 3; ++j)
                    {
                        object newIndex = oldReverseIndices[oldTris[i + j]];
                        if (newIndex == null)
                        {
                            old = true;
                            break;
                        }
                        triangle[j] = (int)vertices[(int)newIndex];
                    }
                    if (old)
                    {
                        continue;
                    }
                    newTris.AddRange(triangle);
                }

                VERTS = newVerts;
                NORMS = newNorms;
                TRIS  = newTris.ToArray();
                control.enqueueJob(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z));
            }
        }
コード例 #16
0
        //        ~VoxelRenderer() {
        //            clear();
        //        }
        public void genMesh(VoxelUpdateInfo info)
        {
            size = info.size;

            Queue<int[]> triangleSet = new Queue<int[]>();
            vertices = new Dictionary<int, object>();
            vertexSubstances = new Dictionary<int, byte>();
            Voxel[, ,] voxels = createVoxelArray(info);
            MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, null);
            int totalTris = 0;

            for (byte x = (byte)(1 - xExtend), x1 = (byte)(x + 1); x1 < xDim; x = x1++) {
                for (byte y = (byte)(1 - yExtend), y1 = (byte)(y + 1); y1 < yDim; y = y1++) {
                    for (byte z = (byte)(1 - zExtend), z1 = (byte)(z + 1); z1 < zDim; z = z1++) {
                        lock (control) {
                            VoxelHolder block = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION + x, VOXEL_DIMENSION + y, VOXEL_DIMENSION + z);
                            voxels[x1, y1, z1] = block.toVoxel();
                            int[] tris = MarchingCubes.lookupTriangles(x, y, z, x1, y1, z1);
                            if (tris == null) continue;
                            triangleSet.Enqueue(tris);
                            totalTris += tris.Length;
                        }
                    }
                }
            }

            if (vertices.Count < 1) {
                applied = true;
                return;
            }

            List<int> triangles = new List<int>();
            List<Vector3> finalVertices = new List<Vector3>(vertices.Count);
            //List<byte> finalMats = new List<byte>(vertices.Count);
            while (triangleSet.Count > 0) {
                int[] triangleList = triangleSet.Dequeue();
                for (int i = 0; i < triangleList.Length; ++i) {
                    if (vertices[triangleList[i]].GetType() == typeof(Vector3)) {
                        finalVertices.Add((Vector3)vertices[triangleList[i]]);
                        //finalMats.Add(vertexSubstances[triangleList[i]]);
                        vertices[triangleList[i]] = finalVertices.Count - 1;
                    }
                    triangles.Add((int)vertices[triangleList[i]]);
                }
            }
            VERTS = finalVertices.ToArray();
            TRIS = triangles.ToArray();
            //MATS = finalMats.ToArray();
            calcNorms();

            alignEdge(info, 0, 1, 1);
            alignEdge(info, 2, 1, 1);
            alignEdge(info, 1, 0, 1);
            alignEdge(info, 1, 2, 1);
            alignEdge(info, 1, 1, 0);
            alignEdge(info, 1, 1, 2);
            lock (control) {
                control.enqueueMeshApply(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z));
            }
        }
コード例 #17
0
        private void alignEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            if (info.renderers[x, y, z] == null || (x + y + z > 3 && info.renderers[x, y, z].size == size))
            {
                lock (control) {
                    VoxelUpdateInfo newInfo = new VoxelUpdateInfo(info.size, info.blocks[1, 1, 1], info.control);
                    newInfo.setFromSister(info, x, y, z);
                    alignOtherEdge(newInfo, x, y, z);
                }
                return;
            }
            lock (control) {
                info.renderers[x, y, z].removeEdge(info, (byte)(2 - x), (byte)(2 - y), (byte)(2 - z));
            }

            Vector3[]              newVerts   = VERTS;
            LinkedList <int>       myIndices  = new LinkedList <int>();
            LinkedList <Vector3[]> otherVerts = new LinkedList <Vector3[]>();

            Vector3[] newNorms = NORMS;

            lock (control) {
                if (x != 1)
                {
                    if (xDim < VERTEX_DIMENSION && x == 2)
                    {
                        return;
                    }
                    int otherXInd = 1 + (VERTEX_DIMENSION - 3) * (1 - x / 2);
                    int myXInd    = (VERTEX_DIMENSION - 1) * (x / 2);
                    for (int yi = 1 - yExtend; yi < yDim; ++yi)
                    {
                        for (int zi = 1 - zExtend; zi < zDim; ++zi)
                        {
                            addDualVertices(otherVerts, info.renderers[x, y, z], otherXInd, yi, zi, 0);
                            myIndices.AddFirst(getY(myXInd, yi, zi));
                            myIndices.AddFirst(getZ(myXInd, yi, zi));
                        }
                    }
                    addDualVertices(otherVerts, info.renderers[x, y + 1, z + 1], otherXInd, 0, 0, 0);
                    addDualVertices(otherVerts, info.renderers[x, y + 1, z - 1], otherXInd, 0, VERTEX_DIMENSION - 1, 0);
                    addDualVertices(otherVerts, info.renderers[x, y - 1, z + 1], otherXInd, VERTEX_DIMENSION - 1, 0, 0);
                    addDualVertices(otherVerts, info.renderers[x, y - 1, z - 1], otherXInd, VERTEX_DIMENSION - 1, VERTEX_DIMENSION - 1, 0);

                    for (int i = 0; i < VERTEX_DIMENSION; ++i)
                    {
                        addDualVertices(otherVerts, info.renderers[x, y, z + 1], otherXInd, i, 0, 0);
                        addDualVertices(otherVerts, info.renderers[x, y, z - 1], otherXInd, i, VERTEX_DIMENSION - 1, 0);
                        addDualVertices(otherVerts, info.renderers[x, y + 1, z], otherXInd, 0, i, 0);
                        addDualVertices(otherVerts, info.renderers[x, y - 1, z], otherXInd, VERTEX_DIMENSION - 1, i, 0);
                    }
                }
                else if (y != 1)
                {
                    if (yDim < VERTEX_DIMENSION && y == 2)
                    {
                        return;
                    }
                    int otherYInd = 1 + (VERTEX_DIMENSION - 3) * (1 - y / 2);
                    int myYInd    = (VERTEX_DIMENSION - 1) * (y / 2);
                    for (int xi = 1 - xExtend; xi < xDim; ++xi)
                    {
                        for (int zi = 1 - zExtend; zi < zDim; ++zi)
                        {
                            addDualVertices(otherVerts, info.renderers[x, y, z], xi, otherYInd, zi, 1);
                            myIndices.AddFirst(getX(xi, myYInd, zi));
                            myIndices.AddFirst(getZ(xi, myYInd, zi));
                        }
                    }
                    addDualVertices(otherVerts, info.renderers[x + 1, y, z + 1], 0, otherYInd, 0, 1);
                    addDualVertices(otherVerts, info.renderers[x + 1, y, z - 1], 0, otherYInd, VERTEX_DIMENSION - 1, 1);
                    addDualVertices(otherVerts, info.renderers[x - 1, y, z + 1], VERTEX_DIMENSION - 1, otherYInd, 0, 1);
                    addDualVertices(otherVerts, info.renderers[x - 1, y, z - 1], VERTEX_DIMENSION - 1, otherYInd, VERTEX_DIMENSION - 1, 1);

                    for (int i = 0; i < VERTEX_DIMENSION; ++i)
                    {
                        addDualVertices(otherVerts, info.renderers[x, y, z + 1], i, otherYInd, 0, 1);
                        addDualVertices(otherVerts, info.renderers[x, y, z - 1], i, otherYInd, VERTEX_DIMENSION - 1, 1);
                        addDualVertices(otherVerts, info.renderers[x + 1, y, z], 0, otherYInd, i, 1);
                        addDualVertices(otherVerts, info.renderers[x - 1, y, z], VERTEX_DIMENSION - 1, otherYInd, i, 1);
                    }
                }
                else if (z != 1)
                {
                    if (zDim < VERTEX_DIMENSION && z == 2)
                    {
                        return;
                    }
                    int otherZInd = 1 + (VERTEX_DIMENSION - 3) * (1 - z / 2);
                    int myZInd    = (VERTEX_DIMENSION - 1) * (z / 2);
                    for (int xi = 1 - xExtend; xi < xDim; ++xi)
                    {
                        for (int yi = 1 - yExtend; yi < yDim; ++yi)
                        {
                            addDualVertices(otherVerts, info.renderers[x, y, z], xi, yi, otherZInd, 2);
                            myIndices.AddFirst(getX(xi, yi, myZInd));
                            myIndices.AddFirst(getY(xi, yi, myZInd));
                        }
                    }
                    addDualVertices(otherVerts, info.renderers[x + 1, y + 1, z], 0, 0, otherZInd, 2);
                    addDualVertices(otherVerts, info.renderers[x + 1, y - 1, z], 0, VERTEX_DIMENSION - 1, otherZInd, 2);
                    addDualVertices(otherVerts, info.renderers[x - 1, y + 1, z], VERTEX_DIMENSION - 1, 0, otherZInd, 2);
                    addDualVertices(otherVerts, info.renderers[x - 1, y - 1, z], VERTEX_DIMENSION - 1, VERTEX_DIMENSION - 1, otherZInd, 2);

                    for (int i = 0; i < VERTEX_DIMENSION; ++i)
                    {
                        addDualVertices(otherVerts, info.renderers[x, y + 1, z], i, 0, otherZInd, 2);
                        addDualVertices(otherVerts, info.renderers[x, y - 1, z], i, VERTEX_DIMENSION - 1, otherZInd, 2);
                        addDualVertices(otherVerts, info.renderers[x + 1, y, z], 0, i, otherZInd, 2);
                        addDualVertices(otherVerts, info.renderers[x - 1, y, z], VERTEX_DIMENSION - 1, i, otherZInd, 2);
                    }
                }
            }

            lock (control) {
                foreach (int myIndex in myIndices)
                {
                    if (vertices.ContainsKey(myIndex))
                    {
                        Vector3[] vertex = getClosestVertex(newVerts[(int)vertices[myIndex]], otherVerts);
                        if (vertex == null || (newVerts[(int)vertices[myIndex]] - vertex[0]).sqrMagnitude > Mathf.Pow(size / 4, 2))
                        {
                            continue;
                        }
                        newVerts[(int)vertices[myIndex]] = vertex[0];
                        newNorms[(int)vertices[myIndex]] = vertex[1];
                    }
                }
            }

            VERTS = newVerts;
            NORMS = newNorms;
        }
コード例 #18
0
        public void removeEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            if (vertices == null) return;
            bool recalculate = false;
            if (x == 0 && xExtend == 1) {
                recalculate = true;
                xExtend = 0;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        vertices.Remove(getX(0, yi, zi));
                        vertices.Remove(getY(0, yi, zi));
                        vertices.Remove(getZ(0, yi, zi));
                    }
                }
            } else if (x == 2 && xDim >= VERTEX_DIMENSION) {
                recalculate = true;
                xDim = VERTEX_DIMENSION - 1;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        vertices.Remove(getX(xDim - 1, yi, zi));
                        vertices.Remove(getY(xDim, yi, zi));
                        vertices.Remove(getZ(xDim, yi, zi));
                    }
                }
            } else if (y == 0 && yExtend == 1) {
                recalculate = true;
                yExtend = 0;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        vertices.Remove(getX(xi, 0, zi));
                        vertices.Remove(getY(xi, 0, zi));
                        vertices.Remove(getZ(xi, 0, zi));
                    }
                }
            } else if (y == 2 && yDim >= VERTEX_DIMENSION) {
                recalculate = true;
                yDim = VERTEX_DIMENSION - 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        vertices.Remove(getX(xi, yDim, zi));
                        vertices.Remove(getY(xi, yDim - 1, zi));
                        vertices.Remove(getZ(xi, yDim, zi));
                    }
                }
            } else if (z == 0 && zExtend == 1) {
                recalculate = true;
                zExtend = 0;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                        vertices.Remove(getX(xi, yi, 0));
                        vertices.Remove(getY(xi, yi, 0));
                        vertices.Remove(getZ(xi, yi, 0));
                    }
                }
            } else if (z == 2 && zDim >= VERTEX_DIMENSION) {
                recalculate = true;
                zDim = VERTEX_DIMENSION - 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                        vertices.Remove(getX(xi, yi, zDim));
                        vertices.Remove(getY(xi, yi, zDim));
                        vertices.Remove(getZ(xi, yi, zDim - 1));
                    }
                }
            }
            if (recalculate) {
                List<KeyValuePair<int, object>> vertexList = new List<KeyValuePair<int, object>>(vertices);
                int[] oldTris = TRIS;
                Vector3[] oldVerts = VERTS;
                Vector3[] oldNorms = NORMS;
                List<int> newTris = new List<int>(TRIS.Length);
                Vector3[] newVerts = new Vector3[vertexList.Count];
                Vector3[] newNorms = new Vector3[newVerts.Length];

                object[] oldReverseIndices = new object[oldVerts.Length];

                int count = 0;
                foreach (KeyValuePair<int, object> pair in vertexList) {
                    int oldIndex = (int)pair.Value;
                    vertices[pair.Key] = count;
                    newVerts[count] = oldVerts[oldIndex];
                    newNorms[count] = oldNorms[oldIndex];
                    oldReverseIndices[oldIndex] = pair.Key;
                    ++count;
                }

                int[] triangle = new int[3];
                for (int i = 0; i < oldTris.Length; i += 3) {
                    bool old = false;
                    for (int j = 0; j < 3; ++j) {
                        object newIndex = oldReverseIndices[oldTris[i + j]];
                        if (newIndex == null) {
                            old = true;
                            break;
                        }
                        triangle[j] = (int)vertices[(int)newIndex];
                    }
                    if (old) continue;
                    newTris.AddRange(triangle);
                }

                VERTS = newVerts;
                NORMS = newNorms;
                TRIS = newTris.ToArray();
                control.enqueueMeshApply(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z));
            }
        }
コード例 #19
0
 private void setDimensions(VoxelUpdateInfo info)
 {
     if (info.renderers[0, 1, 1] == null)
         xExtend = 0;
     else
         xExtend = 1;
     if (info.renderers[1, 0, 1] == null)
         yExtend = 0;
     else
         yExtend = 1;
     if (info.renderers[1, 1, 0] == null)
         zExtend = 0;
     else
         zExtend = 1;
     xDim = (byte)(VOXEL_DIMENSION + 1);
     yDim = (byte)(VOXEL_DIMENSION + 1);
     zDim = (byte)(VOXEL_DIMENSION + 1);
     if (info.renderers[2, 1, 1] != null && info.renderers[2, 1, 1].size > size * 1.1f)
         ++xDim;
     if (info.renderers[1, 2, 1] != null && info.renderers[1, 2, 1].size > size * 1.1f)
         ++yDim;
     if (info.renderers[1, 1, 2] != null && info.renderers[1, 1, 2].size > size * 1.1f)
         ++zDim;
 }
コード例 #20
0
        public void addEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            if (vertices == null) return;
            bool recalculate = false;
            Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION];
            if (x == 0/* && xExtend == 0*/) {
                recalculate = true;
                xExtend = 1;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        voxels[0, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            } else if (x == 2/* && xDim < VERTEX_DIMENSION*/) {
                recalculate = true;
                xDim = VERTEX_DIMENSION;
                for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        voxels[VOXEL_DIMENSION + 1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[VOXEL_DIMENSION, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            } else if (y == 0/* && yExtend == 0*/) {
                recalculate = true;
                yExtend = 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        voxels[xi, 0, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[xi, 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            } else if (y == 2/* && yDim < VERTEX_DIMENSION*/) {
                recalculate = true;
                yDim = VERTEX_DIMENSION;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) {
                        voxels[xi, VOXEL_DIMENSION + 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + zi).toVoxel();
                        voxels[xi, VOXEL_DIMENSION, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + zi).toVoxel();
                    }
                }
            } else if (z == 0/* && zExtend == 0*/) {
                recalculate = true;
                zExtend = 1;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                        voxels[xi, yi, 0] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - zExtend).toVoxel();
                        voxels[xi, yi, 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION).toVoxel();
                    }
                }
            } else if (z == 2/* && zDim < VERTEX_DIMENSION*/) {
                recalculate = true;
                zDim = VERTEX_DIMENSION;
                for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) {
                    for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) {
                        voxels[xi, yi, VOXEL_DIMENSION + 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2).toVoxel();
                        voxels[xi, yi, VOXEL_DIMENSION] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2 - 1).toVoxel();
                    }
                }
            }

            if (recalculate) {

                Queue<int[]> triangleSet = new Queue<int[]>();
                MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, VERTS);

                byte xStart = (byte)(1 - xExtend + (VOXEL_DIMENSION + xExtend - 1) * (x / 2));
                byte xEnd = (byte)(2 + (xDim - 2) * ((x + 1) / 2));
                byte yStart = (byte)(1 - yExtend + (VOXEL_DIMENSION + yExtend - 1) * (y / 2));
                byte yEnd = (byte)(2 + (yDim - 2) * ((y + 1) / 2));
                byte zStart = (byte)(1 - zExtend + (VOXEL_DIMENSION + zExtend - 1) * (z / 2));
                byte zEnd = (byte)(2 + (zDim - 2) * ((z + 1) / 2));

                for (byte xi = xStart, x1 = (byte)(xi + 1); x1 < xEnd; xi = x1++) {
                    for (byte yi = yStart, y1 = (byte)(yi + 1); y1 < yEnd; yi = y1++) {
                        for (byte zi = zStart, z1 = (byte)(zi + 1); z1 < zEnd; zi = z1++) {
                            int[] tris = MarchingCubes.lookupTriangles(xi, yi, zi, x1, y1, z1);
                            if (tris == null) continue;
                            triangleSet.Enqueue(tris);
                        }
                    }
                }

                if (vertices.Count < 1) {
                    return;
                }

                List<int> newTriangles = new List<int>(TRIS);
                List<Vector3> newVertices = new List<Vector3>(VERTS);
                List<Vector3> newNorms = new List<Vector3>(NORMS);
                int tri = 0;
                while (triangleSet.Count > 0) {
                    int[] triangleList = triangleSet.Dequeue();
                    for (int i = 0; i < triangleList.Length; ++i) {
                        if (vertices[triangleList[i]].GetType() == typeof(Vector3)) {
                            newVertices.Add((Vector3)vertices[triangleList[i]]);
                            newNorms.Add(Vector3.zero);
                            vertices[triangleList[i]] = newVertices.Count - 1;
                        }
                        newTriangles.Add((int)vertices[triangleList[i]]);
                    }
                    tri += triangleList.Length;
                }

                Vector3[] finalNorms = new Vector3[newNorms.Count];
                Array.Copy(NORMS, finalNorms, NORMS.Length);
                int oldNormCount = NORMS.Length;

                VERTS = newVertices.ToArray();
                TRIS = newTriangles.ToArray();
                calcNorms();
                Array.Copy(NORMS, oldNormCount, finalNorms, oldNormCount, finalNorms.Length - oldNormCount);
                NORMS = finalNorms;
            }

            alignEdge(info, x, y, z);
            control.enqueueMeshApply(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z));
        }
コード例 #21
0
        //private static int getX(int index, int dimension) {
        //    return (y * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + x;
        //}
        //private static int getY(int index, int dimension) {
        //    return ((VERTEX_DIMENSION + x) * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + y;
        //}
        //private static int getZ(int index, int dimension) {
        //    return ((VERTEX_DIMENSION * 2 + x) * VERTEX_DIMENSION + y) * VERTEX_DIMENSION + z;
        //}
        //private static int getDimension(int index) {
        //    return index / (VERTEX_DIMENSION * VERTEX_DIMENSION * VERTEX_DIMENSION);
        //}
        private Voxel[, ,] createVoxelArray(VoxelUpdateInfo info)
        {
            setDimensions(info);
            Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION];

            for (byte y = (byte)(1 - yExtend); y < yDim; ++y) {
                for (byte z = (byte)(1 - zExtend); z < zDim; ++z) {
                    voxels[1 - xExtend, y, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - 1 + z).toVoxel();
                }
            }
            for (byte x = (byte)(2 - xExtend); x < xDim; ++x) {
                for (byte z = (byte)(1 - zExtend); z < zDim; ++z) {
                    voxels[x, 1 - yExtend, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + z).toVoxel();
                }
            }
            for (byte x = (byte)(2 - xExtend); x < xDim; ++x) {
                for (byte y = (byte)(2 - yExtend); y < yDim; ++y) {
                    voxels[x, y, 1 - zExtend] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - zExtend).toVoxel();
                }
            }

            return voxels;
        }
コード例 #22
0
        private void alignEdge(VoxelUpdateInfo info, byte x, byte y, byte z)
        {
            if (info.renderers[x, y, z] == null || (x + y + z > 3 && info.renderers[x, y, z].size == size)) {
                lock (control) {
                    VoxelUpdateInfo newInfo = new VoxelUpdateInfo(info.size, info.blocks[1, 1, 1], info.control);
                    newInfo.setFromSister(info, x, y, z);
                    alignOtherEdge(newInfo, x, y, z);
                }
                return;
            }
            lock (control) {
                info.renderers[x, y, z].removeEdge(info, (byte)(2 - x), (byte)(2 - y), (byte)(2 - z));
            }

            Vector3[] newVerts = VERTS;
            LinkedList<int> myIndices = new LinkedList<int>();
            LinkedList<Vector3[]> otherVerts = new LinkedList<Vector3[]>();

            Vector3[] newNorms = NORMS;

            lock (control) {
                if (x != 1) {
                    if (xDim < VERTEX_DIMENSION && x == 2) return;
                    int otherXInd = 1 + (VERTEX_DIMENSION - 3) * (1 - x / 2);
                    int myXInd = (VERTEX_DIMENSION - 1) * (x / 2);
                    for (int yi = 1 - yExtend; yi < yDim; ++yi) {
                        for (int zi = 1 - zExtend; zi < zDim; ++zi) {
                            addDualVertices(otherVerts, info.renderers[x, y, z], otherXInd, yi, zi, 0);
                            myIndices.AddFirst(getY(myXInd, yi, zi));
                            myIndices.AddFirst(getZ(myXInd, yi, zi));
                        }
                    }
                    addDualVertices(otherVerts, info.renderers[x, y + 1, z + 1], otherXInd, 0, 0, 0);
                    addDualVertices(otherVerts, info.renderers[x, y + 1, z - 1], otherXInd, 0, VERTEX_DIMENSION - 1, 0);
                    addDualVertices(otherVerts, info.renderers[x, y - 1, z + 1], otherXInd, VERTEX_DIMENSION - 1, 0, 0);
                    addDualVertices(otherVerts, info.renderers[x, y - 1, z - 1], otherXInd, VERTEX_DIMENSION - 1, VERTEX_DIMENSION - 1, 0);

                    for (int i = 0; i < VERTEX_DIMENSION; ++i) {
                        addDualVertices(otherVerts, info.renderers[x, y, z + 1], otherXInd, i, 0, 0);
                        addDualVertices(otherVerts, info.renderers[x, y, z - 1], otherXInd, i, VERTEX_DIMENSION - 1, 0);
                        addDualVertices(otherVerts, info.renderers[x, y + 1, z], otherXInd, 0, i, 0);
                        addDualVertices(otherVerts, info.renderers[x, y - 1, z], otherXInd, VERTEX_DIMENSION - 1, i, 0);
                    }
                } else if (y != 1) {
                    if (yDim < VERTEX_DIMENSION && y == 2) return;
                    int otherYInd = 1 + (VERTEX_DIMENSION - 3) * (1 - y / 2);
                    int myYInd = (VERTEX_DIMENSION - 1) * (y / 2);
                    for (int xi = 1 - xExtend; xi < xDim; ++xi) {
                        for (int zi = 1 - zExtend; zi < zDim; ++zi) {
                            addDualVertices(otherVerts, info.renderers[x, y, z], xi, otherYInd, zi, 1);
                            myIndices.AddFirst(getX(xi, myYInd, zi));
                            myIndices.AddFirst(getZ(xi, myYInd, zi));
                        }
                    }
                    addDualVertices(otherVerts, info.renderers[x + 1, y, z + 1], 0, otherYInd, 0, 1);
                    addDualVertices(otherVerts, info.renderers[x + 1, y, z - 1], 0, otherYInd, VERTEX_DIMENSION - 1, 1);
                    addDualVertices(otherVerts, info.renderers[x - 1, y, z + 1], VERTEX_DIMENSION - 1, otherYInd, 0, 1);
                    addDualVertices(otherVerts, info.renderers[x - 1, y, z - 1], VERTEX_DIMENSION - 1, otherYInd, VERTEX_DIMENSION - 1, 1);

                    for (int i = 0; i < VERTEX_DIMENSION; ++i) {
                        addDualVertices(otherVerts, info.renderers[x, y, z + 1], i, otherYInd, 0, 1);
                        addDualVertices(otherVerts, info.renderers[x, y, z - 1], i, otherYInd, VERTEX_DIMENSION - 1, 1);
                        addDualVertices(otherVerts, info.renderers[x + 1, y, z], 0, otherYInd, i, 1);
                        addDualVertices(otherVerts, info.renderers[x - 1, y, z], VERTEX_DIMENSION - 1, otherYInd, i, 1);
                    }
                } else if (z != 1) {
                    if (zDim < VERTEX_DIMENSION && z == 2) return;
                    int otherZInd = 1 + (VERTEX_DIMENSION - 3) * (1 - z / 2);
                    int myZInd = (VERTEX_DIMENSION - 1) * (z / 2);
                    for (int xi = 1 - xExtend; xi < xDim; ++xi) {
                        for (int yi = 1 - yExtend; yi < yDim; ++yi) {
                            addDualVertices(otherVerts, info.renderers[x, y, z], xi, yi, otherZInd, 2);
                            myIndices.AddFirst(getX(xi, yi, myZInd));
                            myIndices.AddFirst(getY(xi, yi, myZInd));
                        }
                    }
                    addDualVertices(otherVerts, info.renderers[x + 1, y + 1, z], 0, 0, otherZInd, 2);
                    addDualVertices(otherVerts, info.renderers[x + 1, y - 1, z], 0, VERTEX_DIMENSION - 1, otherZInd, 2);
                    addDualVertices(otherVerts, info.renderers[x - 1, y + 1, z], VERTEX_DIMENSION - 1, 0, otherZInd, 2);
                    addDualVertices(otherVerts, info.renderers[x - 1, y - 1, z], VERTEX_DIMENSION - 1, VERTEX_DIMENSION - 1, otherZInd, 2);

                    for (int i = 0; i < VERTEX_DIMENSION; ++i) {
                        addDualVertices(otherVerts, info.renderers[x, y + 1, z], i, 0, otherZInd, 2);
                        addDualVertices(otherVerts, info.renderers[x, y - 1, z], i, VERTEX_DIMENSION - 1, otherZInd, 2);
                        addDualVertices(otherVerts, info.renderers[x + 1, y, z], 0, i, otherZInd, 2);
                        addDualVertices(otherVerts, info.renderers[x - 1, y, z], VERTEX_DIMENSION - 1, i, otherZInd, 2);
                    }
                }
            }

            lock (control) {
                foreach (int myIndex in myIndices) {
                    if (vertices.ContainsKey(myIndex)) {
                        Vector3[] vertex = getClosestVertex(newVerts[(int)vertices[myIndex]], otherVerts);
                        if (vertex == null || (newVerts[(int)vertices[myIndex]] -vertex[0]).sqrMagnitude > Mathf.Pow(size /4, 2))
                            continue;
                        newVerts[(int)vertices[myIndex]] = vertex[0];
                        newNorms[(int)vertices[myIndex]] = vertex[1];
                    }
                }
            }

            VERTS = newVerts;
            NORMS = newNorms;
        }