Example #1
0
        /// <summary>
        /// Applies a brush to the terrain.
        /// </summary>
        /// <param name="type">The type/shape of the brush.</param>
        /// <param name="size">The size (radius) of the brush.</param>
        /// <param name="pos">The (real world) position to apply the brush.</param>
        /// <param name="val">Density to apply.</param>
        public static void applyBrush(BrushType type, int size, Vector3 pos, float val)
        {
            List<Node> changedNodes = new List<Node>();
            float nodeWidth = NodeManager.LODSize[0];
            Vector3 realPos = new Vector3();
            Vector3I point = new Vector3I((int)Math.Round(pos.x / nodeWidth),
                (int)Math.Round(pos.y / nodeWidth),
                (int)Math.Round(pos.z / nodeWidth));

            List<Vector3> points = getPoints(type, size, pos);
            for (int o = 0; o < points.Count; o++)
            {
                realPos = points[o];
                Node[] editNodes = NodeManager.searchNodeContainingDensity(realPos, 0);

                for (int i = 0; i < editNodes.Length; i++)
                {
                    Node editNode = editNodes[i];
                    if (editNode != null && editNode.LOD == 0)
                    {
                        if (!changedNodes.Contains(editNode))
                            changedNodes.Add(editNode);

                        if (type == BrushType.SPHERE)
                        {
                            float v = val;
                            float dist = Vector3.Distance(pos, realPos);

                            if (val > MeshFactory.isolevel)
                                v = 10f - ((dist / (float)size) * 5f);
                            if (val < MeshFactory.isolevel)
                                v = 10f + ((dist / (float)size) * 5f);

                        }

                        editNode.setDensityFromWorldPos(realPos, val);
                        editNode.setMaterialFromWorldPos(realPos, materialID);

                    }
                }
            }

            applyPaint(type, size + 1, pos, false);
            for (int i = 0; i < changedNodes.Count; i++)
                changedNodes[i].regenerateChunk();
        }
Example #2
0
        /// <summary>
        /// Returns the density value at the given coordinates.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public float get(Vector3I pos)
        {
            if (changeData != null)
                if (changeData.get(pos) > -99999f)
                    return changeData.get(pos);

            return get(pos.x, pos.y, pos.z);
        }
Example #3
0
 /// <summary>
 /// Subtracts another vectory's values from this
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Vector3I Subtract(Vector3I other)
 {
     return new Vector3I(x - other.x, y - other.y, z - other.z);
 }
Example #4
0
        /// <summary>
        /// Returns a list of points inside of a given brush type and size.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="size"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        private static List<Vector3> getPoints(BrushType type, int size, Vector3 pos)
        {
            float nodeWidth = NodeManager.LODSize[0];
            //这里是不是少了一个nodesize呢?先加上去看看
            //但是仍旧还是一样的呢
            Vector3I point = new Vector3I((int)Math.Round(pos.x / nodeWidth),
                (int)Math.Round(pos.y / nodeWidth),
                (int)Math.Round(pos.z / nodeWidth));

            List<Vector3> ret = new List<Vector3>();
            switch (type)
            {
                case BrushType.BOX:
                    for (int x = 0; x <= size; x++)
                    {
                        for (int y = 0; y <= size; y++)
                        {
                            for (int z = 0; z <= size; z++)
                            {
                                Vector3 realPos = new Vector3();
                                realPos.x = ((point.x + x) * nodeWidth);
                                realPos.y = ((point.y + y) * nodeWidth);
                                realPos.z = ((point.z + z) * nodeWidth);
                                //这里就类似*nodesize了,所以上面应该是不用加
                                ret.Add(realPos);
                            }
                        }
                    }
                    break;

                case BrushType.SPHERE:
                    for (int x = -size; x < size; x++)
                    {
                        for (int y = -size * 2; y < size; y++)
                        {
                            for (int z = -size; z < size; z++)
                            {
                                Vector3 realPos = new Vector3();
                                realPos.x = ((point.x + x) * nodeWidth);
                                realPos.y = ((point.y + y) * nodeWidth);
                                realPos.z = ((point.z + z) * nodeWidth);

                                if (Vector3.Distance(realPos, pos) < size * nodeWidth)
                                {
                                    ret.Add(realPos);
                                }
                            }
                        }
                    }
                    break;
            }
            string retStr = type+","+size+",";
            foreach(Vector3 v in ret){
              retStr+=v+",";
            }
            Debug.Log(retStr);
            return ret;
        }
Example #5
0
        /// <summary>
        /// Sets the view position, and checks if chunks need to be updated
        /// </summary>
        /// <param name="pos"></param>
        public static void setViewPosition(Vector3 pos)
        {
            for (int i = 0; i <= maxLOD; i++)
            {
                float nWidth = LODSize[i] * nodeSize;
                viewChunkPos[i].x = (int)(pos.x / nWidth);
                viewChunkPos[i].y = (int)(pos.y / nWidth);
                viewChunkPos[i].z = (int)(pos.z / nWidth);
            }

            float    sWidth = LODSize[0] * nodeSize * 0.5f;
            Vector3I newPos = new Vector3I((int)(pos.x / sWidth), (int)(pos.y / sWidth), (int)(pos.z / sWidth));

            if (!curTopNode.Equals(getTopNode(pos)))
            {
                float    nodeWidth = LODSize[maxLOD] * nodeSize;
                Vector3I diff      = getTopNode(pos).Subtract(curTopNode);
                curTopNode = getTopNode(pos);
                while (diff.x > 0)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[0, y, z].dispose();
                            topNodes[0, y, z] = topNodes[1, y, z];
                            topNodes[1, y, z] = topNodes[2, y, z];
                            topNodes[2, y, z] = new Node(null,
                                                         new Vector3((curTopNode.x * nodeWidth) + nodeWidth,
                                                                     (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                                     (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                         0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.x--;
                }

                while (diff.x < 0)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[2, y, z].dispose();
                            topNodes[2, y, z] = topNodes[1, y, z];
                            topNodes[1, y, z] = topNodes[0, y, z];
                            topNodes[0, y, z] = new Node(null,
                                                         new Vector3((curTopNode.x * nodeWidth) - nodeWidth,
                                                                     (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                                     (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                         0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.x++;
                }

                while (diff.y > 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, 0, z].dispose();
                            topNodes[x, 0, z] = topNodes[x, 1, z];
                            topNodes[x, 1, z] = topNodes[x, 2, z];
                            topNodes[x, 2, z] = new Node(null,
                                                         new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                                     (curTopNode.y * nodeWidth) + nodeWidth,
                                                                     (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                         0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.y--;
                }

                while (diff.y < 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, 2, z].dispose();
                            topNodes[x, 2, z] = topNodes[x, 1, z];
                            topNodes[x, 1, z] = topNodes[x, 0, z];
                            topNodes[x, 0, z] = new Node(null,
                                                         new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                                     (curTopNode.y * nodeWidth) - nodeWidth,
                                                                     (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                         0, maxLOD, Node.RenderType.FRONT);
                        }
                    }

                    diff.y++;
                }

                while (diff.z > 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int y = 0; y < 3; y++)
                        {
                            topNodes[x, y, 0].dispose();
                            topNodes[x, y, 0] = topNodes[x, y, 1];
                            topNodes[x, y, 1] = topNodes[x, y, 2];
                            topNodes[x, y, 2] = new Node(null,
                                                         new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                                     (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                                     (curTopNode.z * nodeWidth) + nodeWidth),
                                                         0, maxLOD, Node.RenderType.FRONT);
                        }
                    }

                    diff.z--;
                }

                while (diff.z < 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int y = 0; y < 3; y++)
                        {
                            topNodes[x, y, 2].dispose();
                            topNodes[x, y, 2] = topNodes[x, y, 1];
                            topNodes[x, y, 1] = topNodes[x, y, 0];
                            topNodes[x, y, 0] = new Node(null,
                                                         new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                                     (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                                     (curTopNode.z * nodeWidth) - nodeWidth),
                                                         0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.z++;
                }
            }

            if (curBottomNode.x != newPos.x || curBottomNode.y != newPos.y || curBottomNode.z != newPos.z)
            {
                Vector3 setPos = new Vector3(newPos.x * sWidth + (sWidth / 1f), newPos.y * sWidth + (sWidth / 1f), newPos.z * sWidth + (sWidth / 1f));
                for (int x = 0; x < 3; x++)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, y, z].viewPosChanged(setPos);
                        }
                    }
                }

                curBottomNode = newPos;
            }
        }
Example #6
0
 /// <summary>
 /// Calculates the normal.
 /// </summary>
 /// <param name="p"></param>
 private static Vector3 calculateDensityNormal(Vector3I p, DensityData densities, int lod)
 {
     Vector3 normal = new Vector3();
     normal.x = (densities.get(p.x + 1, p.y, p.z) - densities.get(p.x - 1, p.y, p.z)) / (NodeManager.LODSize[lod]);
     normal.y = (densities.get(p.x, p.y + 1, p.z) - densities.get(p.x, p.y - 1, p.z)) / (NodeManager.LODSize[lod]);
     normal.z = (densities.get(p.x, p.y, p.z + 1) - densities.get(p.x, p.y, p.z - 1)) / (NodeManager.LODSize[lod]);
     normal.Normalize();
     return normal;
 }
Example #7
0
        /// <summary>
        /// Applies 'paint' to the area around the brush.
        /// </summary>
        /// <param name="type">The type/shape of the brush.</param>
        /// <param name="size">The size (radius) of the brush.</param>
        /// <param name="pos">The (real world) position to apply the brush.</param>
        /// <param name="regen">Set to true to have the engine regen the chunk after painting.</param>
        public static void applyPaint(BrushType type, int size, Vector3 pos, bool regen)
        {
            List<Node> changedNodes = new List<Node>();
            float nodeWidth = NodeManager.LODSize[0];
            Vector3 realPos = new Vector3();
            Vector3I point = new Vector3I((int)Math.Round(pos.x / nodeWidth),
                (int)Math.Round(pos.y / nodeWidth),
                (int)Math.Round(pos.z / nodeWidth));

            List<Vector3> points = getPoints(type, size, pos);
            for (int o = 0; o < points.Count; o++)
            {
                realPos = points[o];
                Node[] editNodes = NodeManager.searchNodeContainingDensity(realPos, 0);

                for (int i = 0; i < editNodes.Length; i++)
                {
                    Node editNode = editNodes[i];
                    if (editNode != null && editNode.LOD == 0)
                    {
                        if (!changedNodes.Contains(editNode))
                            changedNodes.Add(editNode);

                        editNode.setMaterialFromWorldPos(realPos, materialID);

                    }
                }
            }

            if (regen)
                for (int i = 0; i < changedNodes.Count; i++)
                    changedNodes[i].regenerateChunk();
        }
Example #8
0
        /// <summary>
        /// Sets the view position, and checks if chunks need to be updated
        /// </summary>
        /// <param name="pos"></param>
        public static void setViewPosition(Vector3 pos)
        {
            for (int i = 0; i <= maxLOD; i++)
            {
                float nWidth = LODSize[i] * nodeSize;
                viewChunkPos[i].x = (int)(pos.x / nWidth);
                viewChunkPos[i].y = (int)(pos.y / nWidth);
                viewChunkPos[i].z = (int)(pos.z / nWidth);
            }

            float sWidth = LODSize[0] * nodeSize * 0.5f;
            Vector3I newPos = new Vector3I((int)(pos.x / sWidth), (int)(pos.y / sWidth), (int)(pos.z / sWidth));

            if (!curTopNode.Equals(getTopNode(pos)))
            {
                float nodeWidth = LODSize[maxLOD] * nodeSize;
                Vector3I diff = getTopNode(pos).Subtract(curTopNode);
                curTopNode = getTopNode(pos);
                while (diff.x > 0)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[0, y, z].dispose();
                            topNodes[0, y, z] = topNodes[1, y, z];
                            topNodes[1, y, z] = topNodes[2, y, z];
                            topNodes[2, y, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + nodeWidth,
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.x--;
                }

                while (diff.x < 0)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[2, y, z].dispose();
                            topNodes[2, y, z] = topNodes[1, y, z];
                            topNodes[1, y, z] = topNodes[0, y, z];
                            topNodes[0, y, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) - nodeWidth,
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.x++;
                }

                while (diff.y > 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, 0, z].dispose();
                            topNodes[x, 0, z] = topNodes[x, 1, z];
                            topNodes[x, 1, z] = topNodes[x, 2, z];
                            topNodes[x, 2, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) + nodeWidth,
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.y--;
                }

                while (diff.y < 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, 2, z].dispose();
                            topNodes[x, 2, z] = topNodes[x, 1, z];
                            topNodes[x, 1, z] = topNodes[x, 0, z];
                            topNodes[x, 0, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) - nodeWidth,
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }

                    diff.y++;
                }

                while (diff.z > 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int y = 0; y < 3; y++)
                        {
                            topNodes[x, y, 0].dispose();
                            topNodes[x, y, 0] = topNodes[x, y, 1];
                            topNodes[x, y, 1] = topNodes[x, y, 2];
                            topNodes[x, y, 2] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) + nodeWidth),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }

                    diff.z--;
                }

                while (diff.z < 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int y = 0; y < 3; y++)
                        {
                            topNodes[x, y, 2].dispose();
                            topNodes[x, y, 2] = topNodes[x, y, 1];
                            topNodes[x, y, 1] = topNodes[x, y, 0];
                            topNodes[x, y, 0] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) - nodeWidth),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.z++;
                }
            }

            if (curBottomNode.x != newPos.x || curBottomNode.y != newPos.y || curBottomNode.z != newPos.z)
            {
                Vector3 setPos = new Vector3(newPos.x * sWidth + (sWidth / 1f), newPos.y * sWidth + (sWidth / 1f), newPos.z * sWidth + (sWidth / 1f));
                for (int x = 0; x < 3; x++)
                    for (int y = 0; y < 3; y++)
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, y, z].viewPosChanged(setPos);
                        }

                curBottomNode = newPos;
            }
        }
Example #9
0
        /// <summary>
        /// Sets the density of a point, given a world pos.
        /// </summary>
        /// <param name="worldPos"></param>
        public void setDensityFromWorldPos(Vector3 worldPos, float val)
        {
            worldPos = worldPos - position;
            Vector3I arrayPos = new Vector3I((int)Math.Round(worldPos.x) / NodeManager.LODSize[LOD],
                                            (int)Math.Round(worldPos.y) / NodeManager.LODSize[LOD],
                                            (int)Math.Round(worldPos.z) / NodeManager.LODSize[LOD]);

            if (arrayPos.x < -1 || arrayPos.x > 17 ||
                arrayPos.y < -1 || arrayPos.y > 17 ||
                arrayPos.z < -1 || arrayPos.z > 17)
            {
                Debug.Log("Wrong node. " + arrayPos + ":" + worldPos + ":" + containsDensityPoint(worldPos).ToString());
                return;
            }

            densityChangeData.set(arrayPos.x, arrayPos.y, arrayPos.z, val);
            setPermanence(true);

            hasDensityChangeData = true;
            MeshFactory.requestSave(this);
        }
Example #10
0
 /// <summary>
 /// Returns a 3d integer vector position of the "top" (highest LOD) node that contains the given position.
 /// </summary>
 /// <param name="pos"></param>
 /// <returns></returns>
 public static Vector3I getTopNode(Vector3 pos)
 {
     Vector3I ret = new Vector3I();
     ret.x = (int)Mathf.Floor(pos.x / (LODSize[maxLOD] * nodeSize));
     ret.y = (int)Mathf.Floor(pos.y / (LODSize[maxLOD] * nodeSize));
     ret.z = (int)Mathf.Floor(pos.z / (LODSize[maxLOD] * nodeSize));
     //Debug.Log("getTopNode:"+LODSize[maxLOD]+","+NodeManager.LODSize[maxLOD]);
     //去掉了原来的NodeManager.反正也是在一个类里面
     return ret;
 }
Example #11
0
        /// <summary>
        /// Generates the triangles for a specific voxel
        /// </summary>
        /// <param name="node">The node that contains the voxel</param>
        /// <param name="pos">The voxel position (Not real position) [16,16,16]</param>
        /// <param name="triangleList">The list used to contain triangles made so far</param>
        /// <param name="densities">The array that contains density information</param>
        /// <param name="densityNormals">The array that contains density normals</param>
        private static void generateTriangles(Node node, Vector3I pos, List <Triangle> triangleList, List <int> submeshIDList, int[] subMeshTriCount, DensityData densities, Vector3[, ,] densityNormals)
        {
            float size = NodeManager.LODSize[node.LOD];

            float[] denses = new float[8];
            denses[0] = densities.get(pos.x, pos.y, pos.z + 1);
            denses[1] = densities.get(pos.x + 1, pos.y, pos.z + 1);
            denses[2] = densities.get(pos.x + 1, pos.y, pos.z);
            denses[3] = densities.get(pos.x, pos.y, pos.z);
            denses[4] = densities.get(pos.x, pos.y + 1, pos.z + 1);
            denses[5] = densities.get(pos.x + 1, pos.y + 1, pos.z + 1);
            denses[6] = densities.get(pos.x + 1, pos.y + 1, pos.z);
            denses[7] = densities.get(pos.x, pos.y + 1, pos.z);

            byte cubeIndex = 0;

            if (denses[0] < isolevel)
            {
                cubeIndex |= 1;
            }
            if (denses[1] < isolevel)
            {
                cubeIndex |= 2;
            }
            if (denses[2] < isolevel)
            {
                cubeIndex |= 4;
            }
            if (denses[3] < isolevel)
            {
                cubeIndex |= 8;
            }
            if (denses[4] < isolevel)
            {
                cubeIndex |= 16;
            }
            if (denses[5] < isolevel)
            {
                cubeIndex |= 32;
            }
            if (denses[6] < isolevel)
            {
                cubeIndex |= 64;
            }
            if (denses[7] < isolevel)
            {
                cubeIndex |= 128;
            }

            if (cubeIndex == 0 || cubeIndex == 255)
            {
                return;
            }

            Vector3 origin = new Vector3((size * (pos.x))
                                         , (size * (pos.y))
                                         , (size * (pos.z)));

            Vector3[] positions = new Vector3[8];
            positions[0] = new Vector3(origin.x, origin.y, origin.z + size);
            positions[1] = new Vector3(origin.x + size, origin.y, origin.z + size);
            positions[2] = new Vector3(origin.x + size, origin.y, origin.z);
            positions[3] = new Vector3(origin.x, origin.y, origin.z);
            positions[4] = new Vector3(origin.x, origin.y + size, origin.z + size);
            positions[5] = new Vector3(origin.x + size, origin.y + size, origin.z + size);
            positions[6] = new Vector3(origin.x + size, origin.y + size, origin.z);
            positions[7] = new Vector3(origin.x, origin.y + size, origin.z);

            Vector3[][] vertlist = new Vector3[12][];
            if (IsBitSet(edgeTable[cubeIndex], 1))
            {
                vertlist[0] = VertexInterp(isolevel, positions[0], positions[1], denses[0], denses[1], densityNormals[pos.x, pos.y, pos.z + 1], densityNormals[pos.x + 1, pos.y, pos.z + 1]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 2))
            {
                vertlist[1] = VertexInterp(isolevel, positions[1], positions[2], denses[1], denses[2], densityNormals[pos.x + 1, pos.y, pos.z + 1], densityNormals[pos.x + 1, pos.y, pos.z]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 4))
            {
                vertlist[2] = VertexInterp(isolevel, positions[2], positions[3], denses[2], denses[3], densityNormals[pos.x + 1, pos.y, pos.z], densityNormals[pos.x, pos.y, pos.z]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 8))
            {
                vertlist[3] = VertexInterp(isolevel, positions[3], positions[0], denses[3], denses[0], densityNormals[pos.x, pos.y, pos.z], densityNormals[pos.x, pos.y, pos.z + 1]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 16))
            {
                vertlist[4] = VertexInterp(isolevel, positions[4], positions[5], denses[4], denses[5], densityNormals[pos.x, pos.y + 1, pos.z + 1], densityNormals[pos.x + 1, pos.y + 1, pos.z + 1]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 32))
            {
                vertlist[5] = VertexInterp(isolevel, positions[5], positions[6], denses[5], denses[6], densityNormals[pos.x + 1, pos.y + 1, pos.z + 1], densityNormals[pos.x + 1, pos.y + 1, pos.z]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 64))
            {
                vertlist[6] = VertexInterp(isolevel, positions[6], positions[7], denses[6], denses[7], densityNormals[pos.x + 1, pos.y + 1, pos.z], densityNormals[pos.x, pos.y + 1, pos.z]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 128))
            {
                vertlist[7] = VertexInterp(isolevel, positions[7], positions[4], denses[7], denses[4], densityNormals[pos.x, pos.y + 1, pos.z], densityNormals[pos.x, pos.y + 1, pos.z + 1]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 256))
            {
                vertlist[8] = VertexInterp(isolevel, positions[0], positions[4], denses[0], denses[4], densityNormals[pos.x, pos.y, pos.z + 1], densityNormals[pos.x, pos.y + 1, pos.z + 1]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 512))
            {
                vertlist[9] = VertexInterp(isolevel, positions[1], positions[5], denses[1], denses[5], densityNormals[pos.x + 1, pos.y, pos.z + 1], densityNormals[pos.x + 1, pos.y + 1, pos.z + 1]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 1024))
            {
                vertlist[10] = VertexInterp(isolevel, positions[2], positions[6], denses[2], denses[6], densityNormals[pos.x + 1, pos.y, pos.z], densityNormals[pos.x + 1, pos.y + 1, pos.z]);
            }
            if (IsBitSet(edgeTable[cubeIndex], 2048))
            {
                vertlist[11] = VertexInterp(isolevel, positions[3], positions[7], denses[3], denses[7], densityNormals[pos.x, pos.y, pos.z], densityNormals[pos.x, pos.y + 1, pos.z]);
            }

            int submesh = densities.getMaterial(pos.x, pos.y, pos.z);

            for (int i = 0; triTable[cubeIndex][i] != -1; i += 3)
            {
                submeshIDList.Add(submesh);
                subMeshTriCount[submesh] = subMeshTriCount[submesh] + 1;
                triangleList.Add(new Triangle(vertlist[triTable[cubeIndex][i]][0], vertlist[triTable[cubeIndex][i + 1]][0], vertlist[triTable[cubeIndex][i + 2]][0],
                                              vertlist[triTable[cubeIndex][i]][1], vertlist[triTable[cubeIndex][i + 1]][1], vertlist[triTable[cubeIndex][i + 2]][1]));
            }
        }
Example #12
0
        /// <summary>
        /// Called when the viewpoint has changed.
        /// </summary>
        /// <param name="pos"></param>
        public void viewPosChanged(Vector3 pos)
        {
            //float sep = 10f;

            //float distance = ((center.x - pos.x) * (center.x - pos.x) +
            //(center.y - pos.y) * (center.y - pos.y) +
            //(center.z - pos.z) * (center.z - pos.z));

            //if (distance < (((float)NodeManager.LODRange[LOD]) * sep) * (((float)NodeManager.LODRange[LOD]) * sep))
            Vector3I viewPos = NodeManager.viewChunkPos[LOD];
            /*Debug.Log(viewPos+","+LOD);
            如前所述,viewChunkPos其实应该是摄像机当前位置在各个细节层次上的V3I坐标值
            这里根据LOD选择相应层次下面的对应V3I
            */
            int size = 1;
            /*chunkPos是center的position在当前LOD下面的v3i坐标
            下面的这个判定式就是说viewPos(摄像机位置V3I)是不是在当前chunk内部(中心+-1,这也是用V3I的好处)
            */
            if ((viewPos.x >= chunkPos.x - size && viewPos.x <= chunkPos.x + size)
                && (viewPos.y >= chunkPos.y - size && viewPos.y <= chunkPos.y + size)
                && (viewPos.z >= chunkPos.z - size && viewPos.z <= chunkPos.z + size))
            {
                if (isBottomLevel())
                    createSubNodes(RenderType.FRONT);

                for (int i = 0; i < 8; i++)
                {
                    if (subNodes[i] != null)
                        subNodes[i].viewPosChanged(pos);
                        //向下传递命令
                }
            }
            //else if (!permanent)
            else
            {
                size += 2;
                if (LOD < 3 && (viewPos.x < chunkPos.x - size || viewPos.x > chunkPos.x + size)
                    || (viewPos.y < chunkPos.y - size || viewPos.y > chunkPos.y + size)
                    || (viewPos.z < chunkPos.z - size || viewPos.z > chunkPos.z + size))
                {
                  /*Debug.Log(size+","+LOD+"viewPos:"+viewPos+","+chunkPos);
                  在lod低阶的时候,如果在一个半chunk以外,也就是包围当前chunk的chunks以外,那就不再subdivide的意思吧……*/
                    for (int i = 0; i < 8; i++)
                    {
                        if (subNodes[i] != null)
                        {
                            subNodes[i].dispose();
                            subNodes[i] = null;
                        }
                    }
                }
                else if (LOD >= 3)
                //在粗糙的层级,只要超出了当前chunk那就直接不再subdivide
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (subNodes[i] != null)
                        {
                            subNodes[i].dispose();
                            subNodes[i] = null;
                        }
                    }
                }
            }

            if (LOD == 0)
            {
                /*Debug.Log("LOD 0 situation");
                lod0的情况是经常会发生的*/
                float nodeSize = (float)NodeManager.LODSize[0] * (float)NodeManager.nodeSize;
                /*Debug.Log(nodeSize);
                仍旧是LODSize[0]是4,nodesize当然是16,这里nodesize是64*/
                //其实下面这里是函数里面第一次用到pos进行运算,前面那个引用pos只是向下传递接过来的参数。
                Vector3I viewChunk = new Vector3I((int)(pos.x / nodeSize),
                    (int)(pos.y / nodeSize),
                    (int)(pos.z / nodeSize));
                /*if(!viewChunk.Equals(NodeManager.viewChunkPos[0])){
                  Debug.Log(viewChunk+",NM.viewChunkPos: "+NodeManager.viewChunkPos[0]);
                }
                这两个真的不是一直都是相等的。好神奇。所以千万不要乱改。
                因为确实nodeSize就是nodemanager里面nWidth在lod=0的值,那就只可能是两处的pos不一定一样了。
                */
                Vector3I curChunk = new Vector3I((int)(position.x / nodeSize),
                    (int)(position.y / nodeSize),
                    (int)(position.z / nodeSize));

                if (curChunk.x >= viewChunk.x - 3 && curChunk.x <= viewChunk.x + 3 &&
                    curChunk.y >= viewChunk.y - 3 && curChunk.y <= viewChunk.y + 3 &&
                    curChunk.z >= viewChunk.z - 3 && curChunk.z <= viewChunk.z + 3)
                {
                    //curChunk,viewChunk,viewPos,chunkPos,这个家伙命名还真是随意啊
                    //collides是一个什么鬼,当前摄像机位置在curChunk三个单位(其实是各个轴6个单位)以内时:
                    collides = true;
                    if (chunk != null)
                    {
                        chunk.GetComponent<MeshCollider>().sharedMesh = chunk.GetComponent<MeshFilter>().sharedMesh;
                    }
                }
            }

            renderCheck();
        }
Example #13
0
        /// <summary>
        /// Sets the density of a point, given a world pos.
        /// </summary>
        /// <param name="worldPos"></param>
        public void setDensityFromWorldPos(Vector3 worldPos, float val)
        {
            worldPos = worldPos - position;
            Vector3I arrayPos = new Vector3I((int)(worldPos.x), (int)(worldPos.y), (int)(worldPos.z));

            if (arrayPos.x < -1 || arrayPos.x > 17 ||
                arrayPos.y < -1 || arrayPos.y > 17 ||
                arrayPos.z < -1 || arrayPos.z > 17)
            {
                //Debug.Log("Wrong node. " + arrayPos+", and worldPos is :"+worldPos);
                return;
            }

            densityChangeData.set(arrayPos.x, arrayPos.y, arrayPos.z, val);
            setPermanence(true);

            hasDensityChangeData = true;
            MeshFactory.requestSave(this);
        }
Example #14
0
        /// <summary>
        /// Sets the view position, and checks if chunks need to be updated
        /// </summary>
        /// <param name="pos"></param>
        public static void setViewPosition(Vector3 pos)
        {
            /*Debug.Log(pos+",cameraPos:"+QuixelEngine.getCameraPos());
            测试结果,这里的pos确实就是camera的位置
            所以应该每次camera位置更新以后这里就会被call
            然后计算出各个LOD下面camera的viewPosition(V3I形式)
            */
            for (int i = 0; i <= maxLOD; i++)
            {
                float nWidth = LODSize[i] * nodeSize;
                viewChunkPos[i].x = (int)(pos.x / nWidth);
                viewChunkPos[i].y = (int)(pos.y / nWidth);
                viewChunkPos[i].z = (int)(pos.z / nWidth);

            }

            float sWidth = LODSize[0] * nodeSize * 0.5f;
            //不知是谁设置的,但是这里的LODSize[0]已经是4了,毕竟init的时候debug就是这样,所以这里sWidth是32
            Vector3I newPos = new Vector3I((int)(pos.x / sWidth), (int)(pos.y / sWidth), (int)(pos.z / sWidth));
            //getTopNode不管character怎么掉都一直是0,-1,0.
            //不过如果一开始很高的话(大于0?)这个时侯会是0,0,0
            //然后curTopNode和getTopNode倒是一直都很一致
            //这是因为下面的这一大长段内容,如果curTop和Top不一样的话就马上进行调整
            //newPos是为了调整curBottomNode
            if (!curTopNode.Equals(getTopNode(pos)))
            {

                float nodeWidth = LODSize[maxLOD] * nodeSize;
                Vector3I diff = getTopNode(pos).Subtract(curTopNode);
                curTopNode = getTopNode(pos);
                while (diff.x > 0)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[0, y, z].dispose();
                            topNodes[0, y, z] = topNodes[1, y, z];
                            topNodes[1, y, z] = topNodes[2, y, z];
                            topNodes[2, y, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + nodeWidth,
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.x--;
                }

                while (diff.x < 0)
                {
                    for (int y = 0; y < 3; y++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[2, y, z].dispose();
                            topNodes[2, y, z] = topNodes[1, y, z];
                            topNodes[1, y, z] = topNodes[0, y, z];
                            topNodes[0, y, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) - nodeWidth,
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.x++;
                }

                while (diff.y > 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, 0, z].dispose();
                            topNodes[x, 0, z] = topNodes[x, 1, z];
                            topNodes[x, 1, z] = topNodes[x, 2, z];
                            topNodes[x, 2, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) + nodeWidth,
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.y--;
                }

                while (diff.y < 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, 2, z].dispose();
                            topNodes[x, 2, z] = topNodes[x, 1, z];
                            topNodes[x, 1, z] = topNodes[x, 0, z];
                            topNodes[x, 0, z] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) - nodeWidth,
                                                    (curTopNode.z * nodeWidth) + ((z - 1) * nodeWidth)),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }

                    diff.y++;
                }

                while (diff.z > 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int y = 0; y < 3; y++)
                        {
                            topNodes[x, y, 0].dispose();
                            topNodes[x, y, 0] = topNodes[x, y, 1];
                            topNodes[x, y, 1] = topNodes[x, y, 2];
                            topNodes[x, y, 2] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) + nodeWidth),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }

                    diff.z--;
                }

                while (diff.z < 0)
                {
                    for (int x = 0; x < 3; x++)
                    {
                        for (int y = 0; y < 3; y++)
                        {
                            topNodes[x, y, 2].dispose();
                            topNodes[x, y, 2] = topNodes[x, y, 1];
                            topNodes[x, y, 1] = topNodes[x, y, 0];
                            topNodes[x, y, 0] = new Node(null,
                                                new Vector3((curTopNode.x * nodeWidth) + ((x - 1) * nodeWidth),
                                                    (curTopNode.y * nodeWidth) + ((y - 1) * nodeWidth),
                                                    (curTopNode.z * nodeWidth) - nodeWidth),
                                                0, maxLOD, Node.RenderType.FRONT);
                        }
                    }
                    diff.z++;
                }
            }
            if (curBottomNode.x != newPos.x || curBottomNode.y != newPos.y || curBottomNode.z != newPos.z)
            {
                Vector3 setPos = new Vector3(newPos.x * sWidth + (sWidth / 1f), newPos.y * sWidth + (sWidth / 1f), newPos.z * sWidth + (sWidth / 1f));
                for (int x = 0; x < 3; x++){
                    for (int y = 0; y < 3; y++){
                        for (int z = 0; z < 3; z++)
                        {
                            topNodes[x, y, z].viewPosChanged(setPos);
                            //Debug.Log(setPos+",newpos:"+newPos+",curbuttom:"+curBottomNode);
                            /*
                            (32.0, -96.0, 32.0),newpos:(0,-4,0),curbuttom:(0,-3,0)>>(0,-4,0)

                            */
                        }}}

                curBottomNode = newPos;

            }
        }
Example #15
0
 /// <summary>
 /// Sets the density value at the given coordinates.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="z"></param>
 /// <returns></returns>
 public void set(Vector3I pos, float val)
 {
     set(pos.x, pos.y, pos.z, val);
 }
Example #16
0
        /// <summary>
        /// Sets the material of the voxel at the given world position.
        /// </summary>
        /// <param name="worldPos"></param>
        /// <param name="val"></param>
        public void setMaterialFromWorldPos(Vector3 worldPos, byte val)
        {
            worldPos = worldPos - position;
            Vector3I arrayPos = new Vector3I((int)Math.Round(worldPos.x) / NodeManager.LODSize[LOD],
                                            (int)Math.Round(worldPos.y) / NodeManager.LODSize[LOD],
                                            (int)Math.Round(worldPos.z) / NodeManager.LODSize[LOD]);

            if (arrayPos.x < -1 || arrayPos.x > 17 ||
                arrayPos.y < -1 || arrayPos.y > 17 ||
                arrayPos.z < -1 || arrayPos.z > 17)
            {
                Debug.Log("Wrong node. " + arrayPos);
                return;
            }

            bool change = (densityChangeData.getMaterial(arrayPos.x, arrayPos.y, arrayPos.z) != val);
            densityChangeData.setMaterial(arrayPos.x, arrayPos.y, arrayPos.z, val);

            if (change)
            {
                setPermanence(true);
                hasDensityChangeData = true;
                MeshFactory.requestSave(this);
            }
        }
Example #17
0
 /// <summary>
 /// Adds another vector's values to this
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Vector3I Add(Vector3I other)
 {
     return new Vector3I(x + other.x, y + other.y, z + other.z);
 }
Example #18
0
        /// <summary>
        /// Called when the viewpoint has changed.
        /// </summary>
        /// <param name="pos"></param>
        public void viewPosChanged(Vector3 pos)
        {
            //float sep = 10f;

            //float distance = ((center.x - pos.x) * (center.x - pos.x) +
            //(center.y - pos.y) * (center.y - pos.y) +
            //(center.z - pos.z) * (center.z - pos.z));

            //if (distance < (((float)NodeManager.LODRange[LOD]) * sep) * (((float)NodeManager.LODRange[LOD]) * sep))
            Vector3I viewPos = NodeManager.viewChunkPos[LOD];
            int size = 1;
            if ((viewPos.x >= chunkPos.x - size && viewPos.x <= chunkPos.x + size)
                && (viewPos.y >= chunkPos.y - size && viewPos.y <= chunkPos.y + size)
                && (viewPos.z >= chunkPos.z - size && viewPos.z <= chunkPos.z + size))
            {
                if (isBottomLevel())
                    createSubNodes(RenderType.FRONT);

                for (int i = 0; i < 8; i++)
                {
                    if (subNodes[i] != null)
                        subNodes[i].viewPosChanged(pos);
                }
            }
            //else if (!permanent)
            else
            {
                size += 2;
                if (LOD < 3 && (viewPos.x < chunkPos.x - size || viewPos.x > chunkPos.x + size)
                    || (viewPos.y < chunkPos.y - size || viewPos.y > chunkPos.y + size)
                    || (viewPos.z < chunkPos.z - size || viewPos.z > chunkPos.z + size))
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (subNodes[i] != null)
                        {
                            subNodes[i].dispose();
                            subNodes[i] = null;
                        }
                    }
                }
                else if (LOD >= 3)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (subNodes[i] != null)
                        {
                            subNodes[i].dispose();
                            subNodes[i] = null;
                        }
                    }
                }
            }

            if (LOD == 0)
            {
                float nodeSize = (float)NodeManager.LODSize[0] * (float)NodeManager.nodeSize;
                Vector3I viewChunk = new Vector3I((int)(pos.x / nodeSize),
                    (int)(pos.y / nodeSize),
                    (int)(pos.z / nodeSize));

                Vector3I curChunk = new Vector3I((int)(position.x / nodeSize),
                    (int)(position.y / nodeSize),
                    (int)(position.z / nodeSize));

                if (curChunk.x >= viewChunk.x - 3 && curChunk.x <= viewChunk.x + 3 &&
                    curChunk.y >= viewChunk.y - 3 && curChunk.y <= viewChunk.y + 3 &&
                    curChunk.z >= viewChunk.z - 3 && curChunk.z <= viewChunk.z + 3)
                {
                    collides = true;
                    if (chunk != null)
                    {
                        chunk.GetComponent<MeshCollider>().sharedMesh = chunk.GetComponent<MeshFilter>().sharedMesh;
                    }
                }
            }

            renderCheck();
        }
Example #19
0
        /// <summary>
        /// Returns a list of points inside of a given brush type and size.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="size"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        private static List<Vector3> getPoints(BrushType type, int size, Vector3 pos)
        {
            float nodeWidth = NodeManager.LODSize[0];
            Vector3I point = new Vector3I((int)Math.Round(pos.x / nodeWidth),
                (int)Math.Round(pos.y / nodeWidth),
                (int)Math.Round(pos.z / nodeWidth));

            List<Vector3> ret = new List<Vector3>();
            switch (type)
            {
                case BrushType.BOX:
                    for (int x = 0; x <= size; x++)
                    {
                        for (int y = 0; y <= size; y++)
                        {
                            for (int z = 0; z <= size; z++)
                            {
                                Vector3 realPos = new Vector3();
                                realPos.x = ((point.x + x) * nodeWidth);
                                realPos.y = ((point.y + y) * nodeWidth);
                                realPos.z = ((point.z + z) * nodeWidth);
                                ret.Add(realPos);
                            }
                        }
                    }
                    break;

                case BrushType.SPHERE:
                    for (int x = -size; x < size; x++)
                    {
                        for (int y = -size * 2; y < size; y++)
                        {
                            for (int z = -size; z < size; z++)
                            {
                                Vector3 realPos = new Vector3();
                                realPos.x = ((point.x + x) * nodeWidth);
                                realPos.y = ((point.y + y) * nodeWidth);
                                realPos.z = ((point.z + z) * nodeWidth);

                                if (Vector3.Distance(realPos, pos) < size * nodeWidth)
                                {
                                    ret.Add(realPos);
                                }
                            }
                        }
                    }
                    break;
            }

            return ret;
        }
Example #20
0
        /// <summary>
        /// Returns a 3d integer vector position of the "top" (highest LOD) node that contains the given position.
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public static Vector3I getTopNode(Vector3 pos)
        {
            Vector3I ret = new Vector3I();
            ret.x = (int)Mathf.Floor(pos.x / (NodeManager.LODSize[maxLOD] * nodeSize));
            ret.y = (int)Mathf.Floor(pos.y / (NodeManager.LODSize[maxLOD] * nodeSize));
            ret.z = (int)Mathf.Floor(pos.z / (NodeManager.LODSize[maxLOD] * nodeSize));

            return ret;
        }
Example #21
0
        /// <summary>
        /// Calculates a density value given a location
        /// </summary>
        /// <param name="node"></param>
        /// <param name="pos"></param>
        /// <returns></returns>
        private static VoxelData calculateDensity(Node node, Vector3I pos)
        {
            int nodeWidth = NodeManager.LODSize[node.LOD];
            Vector3 ws = new Vector3(node.position.x + (nodeWidth * pos.x),
                node.position.y + (nodeWidth * pos.y),
                node.position.z + (nodeWidth * pos.z));

            return terrainGenerator.calculateDensity(ws);
        }
Example #22
0
        /// <summary>
        /// Initializes the node manager.
        /// </summary>
        public static void init(string worldName)
        {
            NodeManager.worldName = worldName;
            float nSize = LODSize[maxLOD] * nodeSize;
            for (int x = -1; x < 2; x++)
            {
                for (int y = -1; y < 2; y++)
                {
                    for (int z = -1; z < 2; z++)
                    {
                        topNodes[x + 1, y + 1, z + 1] = new Node(null,
                            new Vector3(x * nSize,
                                y * nSize,
                                z * nSize),
                            0, maxLOD, Node.RenderType.FRONT);
                    }
                }
            }

            viewChunkPos = new Vector3I[maxLOD + 1];
            for (int i = 0; i <= maxLOD; i++)
                viewChunkPos[i] = new Vector3I();
        }
Example #23
0
        /// <summary>
        /// Generates the triangles for a specific voxel
        /// </summary>
        /// <param name="node">The node that contains the voxel</param>
        /// <param name="pos">The voxel position (Not real position) [16,16,16]</param>
        /// <param name="triangleList">The list used to contain triangles made so far</param>
        /// <param name="densities">The array that contains density information</param>
        /// <param name="densityNormals">The array that contains density normals</param>
        private static void generateTriangles(Node node, Vector3I pos, List<Triangle> triangleList, List<int> submeshIDList, int[] subMeshTriCount, DensityData densities, Vector3[, ,] densityNormals)
        {
            float size = NodeManager.LODSize[node.LOD];

            float[] denses = new float[8];
            denses[0] = densities.get(pos.x, pos.y, pos.z + 1);
            denses[1] = densities.get(pos.x + 1, pos.y, pos.z + 1);
            denses[2] = densities.get(pos.x + 1, pos.y, pos.z);
            denses[3] = densities.get(pos.x, pos.y, pos.z);
            denses[4] = densities.get(pos.x, pos.y + 1, pos.z + 1);
            denses[5] = densities.get(pos.x + 1, pos.y + 1, pos.z + 1);
            denses[6] = densities.get(pos.x + 1, pos.y + 1, pos.z);
            denses[7] = densities.get(pos.x, pos.y + 1, pos.z);

            byte cubeIndex = 0;

            if (denses[0] < isolevel)
                cubeIndex |= 1;
            if (denses[1] < isolevel)
                cubeIndex |= 2;
            if (denses[2] < isolevel)
                cubeIndex |= 4;
            if (denses[3] < isolevel)
                cubeIndex |= 8;
            if (denses[4] < isolevel)
                cubeIndex |= 16;
            if (denses[5] < isolevel)
                cubeIndex |= 32;
            if (denses[6] < isolevel)
                cubeIndex |= 64;
            if (denses[7] < isolevel)
                cubeIndex |= 128;

            if (cubeIndex == 0 || cubeIndex == 255)
                return;

            Vector3 origin = new Vector3((size * (pos.x))
                , (size * (pos.y))
                , (size * (pos.z)));

            Vector3[] positions = new Vector3[8];
            positions[0] = new Vector3(origin.x, origin.y, origin.z + size);
            positions[1] = new Vector3(origin.x + size, origin.y, origin.z + size);
            positions[2] = new Vector3(origin.x + size, origin.y, origin.z);
            positions[3] = new Vector3(origin.x, origin.y, origin.z);
            positions[4] = new Vector3(origin.x, origin.y + size, origin.z + size);
            positions[5] = new Vector3(origin.x + size, origin.y + size, origin.z + size);
            positions[6] = new Vector3(origin.x + size, origin.y + size, origin.z);
            positions[7] = new Vector3(origin.x, origin.y + size, origin.z);

            Vector3[][] vertlist = new Vector3[12][];
            if (IsBitSet(edgeTable[cubeIndex], 1))
                vertlist[0] = VertexInterp(isolevel, positions[0], positions[1], denses[0], denses[1], densityNormals[pos.x, pos.y, pos.z + 1], densityNormals[pos.x + 1, pos.y, pos.z + 1]);
            if (IsBitSet(edgeTable[cubeIndex], 2))
                vertlist[1] = VertexInterp(isolevel, positions[1], positions[2], denses[1], denses[2], densityNormals[pos.x + 1, pos.y, pos.z + 1], densityNormals[pos.x + 1, pos.y, pos.z]);
            if (IsBitSet(edgeTable[cubeIndex], 4))
                vertlist[2] = VertexInterp(isolevel, positions[2], positions[3], denses[2], denses[3], densityNormals[pos.x + 1, pos.y, pos.z], densityNormals[pos.x, pos.y, pos.z]);
            if (IsBitSet(edgeTable[cubeIndex], 8))
                vertlist[3] = VertexInterp(isolevel, positions[3], positions[0], denses[3], denses[0], densityNormals[pos.x, pos.y, pos.z], densityNormals[pos.x, pos.y, pos.z + 1]);
            if (IsBitSet(edgeTable[cubeIndex], 16))
                vertlist[4] = VertexInterp(isolevel, positions[4], positions[5], denses[4], denses[5], densityNormals[pos.x, pos.y + 1, pos.z + 1], densityNormals[pos.x + 1, pos.y + 1, pos.z + 1]);
            if (IsBitSet(edgeTable[cubeIndex], 32))
                vertlist[5] = VertexInterp(isolevel, positions[5], positions[6], denses[5], denses[6], densityNormals[pos.x + 1, pos.y + 1, pos.z + 1], densityNormals[pos.x + 1, pos.y + 1, pos.z]);
            if (IsBitSet(edgeTable[cubeIndex], 64))
                vertlist[6] = VertexInterp(isolevel, positions[6], positions[7], denses[6], denses[7], densityNormals[pos.x + 1, pos.y + 1, pos.z], densityNormals[pos.x, pos.y + 1, pos.z]);
            if (IsBitSet(edgeTable[cubeIndex], 128))
                vertlist[7] = VertexInterp(isolevel, positions[7], positions[4], denses[7], denses[4], densityNormals[pos.x, pos.y + 1, pos.z], densityNormals[pos.x, pos.y + 1, pos.z + 1]);
            if (IsBitSet(edgeTable[cubeIndex], 256))
                vertlist[8] = VertexInterp(isolevel, positions[0], positions[4], denses[0], denses[4], densityNormals[pos.x, pos.y, pos.z + 1], densityNormals[pos.x, pos.y + 1, pos.z + 1]);
            if (IsBitSet(edgeTable[cubeIndex], 512))
                vertlist[9] = VertexInterp(isolevel, positions[1], positions[5], denses[1], denses[5], densityNormals[pos.x + 1, pos.y, pos.z + 1], densityNormals[pos.x + 1, pos.y + 1, pos.z + 1]);
            if (IsBitSet(edgeTable[cubeIndex], 1024))
                vertlist[10] = VertexInterp(isolevel, positions[2], positions[6], denses[2], denses[6], densityNormals[pos.x + 1, pos.y, pos.z], densityNormals[pos.x + 1, pos.y + 1, pos.z]);
            if (IsBitSet(edgeTable[cubeIndex], 2048))
                vertlist[11] = VertexInterp(isolevel, positions[3], positions[7], denses[3], denses[7], densityNormals[pos.x, pos.y, pos.z], densityNormals[pos.x, pos.y + 1, pos.z]);

            int submesh = densities.getMaterial(pos.x, pos.y, pos.z);
            for (int i = 0; triTable[cubeIndex][i] != -1; i += 3)
            {
                submeshIDList.Add(submesh);
                subMeshTriCount[submesh] = subMeshTriCount[submesh] + 1;
                triangleList.Add(new Triangle(vertlist[triTable[cubeIndex][i]][0], vertlist[triTable[cubeIndex][i + 1]][0], vertlist[triTable[cubeIndex][i + 2]][0],
                    vertlist[triTable[cubeIndex][i]][1], vertlist[triTable[cubeIndex][i + 1]][1], vertlist[triTable[cubeIndex][i + 2]][1]));
            }
        }
Example #24
0
        /// <summary>
        /// Called when the viewpoint has changed.
        /// </summary>
        /// <param name="pos"></param>
        public void viewPosChanged(Vector3 pos)
        {
            //float sep = 10f;

            //float distance = ((center.x - pos.x) * (center.x - pos.x) +
            //(center.y - pos.y) * (center.y - pos.y) +
            //(center.z - pos.z) * (center.z - pos.z));

            //if (distance < (((float)NodeManager.LODRange[LOD]) * sep) * (((float)NodeManager.LODRange[LOD]) * sep))
            Vector3I viewPos = NodeManager.viewChunkPos[LOD];
            int      size    = 1;

            if ((viewPos.x >= chunkPos.x - size && viewPos.x <= chunkPos.x + size) &&
                (viewPos.y >= chunkPos.y - size && viewPos.y <= chunkPos.y + size) &&
                (viewPos.z >= chunkPos.z - size && viewPos.z <= chunkPos.z + size))
            {
                if (isBottomLevel())
                {
                    createSubNodes(RenderType.FRONT);
                }

                for (int i = 0; i < 8; i++)
                {
                    if (subNodes[i] != null)
                    {
                        subNodes[i].viewPosChanged(pos);
                    }
                }
            }
            //else if (!permanent)
            else
            {
                size += 2;
                if (LOD < 3 && (viewPos.x < chunkPos.x - size || viewPos.x > chunkPos.x + size) ||
                    (viewPos.y < chunkPos.y - size || viewPos.y > chunkPos.y + size) ||
                    (viewPos.z < chunkPos.z - size || viewPos.z > chunkPos.z + size))
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (subNodes[i] != null)
                        {
                            subNodes[i].dispose();
                            subNodes[i] = null;
                        }
                    }
                }
                else if (LOD >= 3)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        if (subNodes[i] != null)
                        {
                            subNodes[i].dispose();
                            subNodes[i] = null;
                        }
                    }
                }
            }

            if (LOD == 0)
            {
                float    nodeSize  = (float)NodeManager.LODSize[0] * (float)NodeManager.nodeSize;
                Vector3I viewChunk = new Vector3I((int)(pos.x / nodeSize),
                                                  (int)(pos.y / nodeSize),
                                                  (int)(pos.z / nodeSize));

                Vector3I curChunk = new Vector3I((int)(position.x / nodeSize),
                                                 (int)(position.y / nodeSize),
                                                 (int)(position.z / nodeSize));

                if (curChunk.x >= viewChunk.x - 3 && curChunk.x <= viewChunk.x + 3 &&
                    curChunk.y >= viewChunk.y - 3 && curChunk.y <= viewChunk.y + 3 &&
                    curChunk.z >= viewChunk.z - 3 && curChunk.z <= viewChunk.z + 3)
                {
                    collides = true;
                    if (chunk != null)
                    {
                        chunk.GetComponent <MeshCollider>().sharedMesh = chunk.GetComponent <MeshFilter>().sharedMesh;
                    }
                }
            }

            renderCheck();
        }