public void ChunkMemoryCopy(SimTerrain.TerrainChunk chunk)
 {
     Array.Copy(chunk.verticesAry, memoryFlag.verticeOldStart, verticesAry, memoryFlag.verticeNewStart, memoryFlag.verticeCount);
     Array.Copy(chunk.ColorsAry, memoryFlag.verticeOldStart, ColorsAry, memoryFlag.verticeNewStart, memoryFlag.verticeCount);
     Array.Copy(chunk.uvAry, memoryFlag.verticeOldStart, uvAry, memoryFlag.verticeNewStart, memoryFlag.verticeCount);
     Array.Copy(chunk.indicesAry, memoryFlag.indiceOldStart, indicesBuffer, memoryFlag.indiceNewStart, memoryFlag.indiceCount);
 }
Beispiel #2
0
        private void BrushDown(Vector3 point, TerrainBrush brush, TerrainChunk chunk)
        {
            float radius    = brush.Radius;
            float num       = brush.Strenght;
            float blurRange = brush.BlurRadius;
            float num3      = 1.0f - Mathf.Pow(brush.BlurPower, 4.0f);

            num3 = 1.0f - Mathf.Pow(1.0f - num3, 1.1f);
            float target = brush.Targetheight;

            target -= 1.0f;
            //Height
            Vector2 localPoint = new Vector2(point.x - transform.position.x, point.z - transform.position.z);

            localPoint.x = Mathf.RoundToInt((localPoint.x / chunk.groupInfo.worldSize.x) * (chunk.groupInfo.terrainWidth - 1));
            localPoint.y = Mathf.RoundToInt((localPoint.y / chunk.groupInfo.worldSize.y) * (chunk.groupInfo.terrainLength - 1));

            float   Minx        = Mathf.Max(0, localPoint.x - (radius + blurRange));
            float   Maxx        = Mathf.Min(chunk.groupInfo.terrainWidth - 1, localPoint.x + (radius + blurRange));
            float   MinY        = Mathf.Max(0, localPoint.y - (radius + blurRange));
            float   Maxy        = Mathf.Min(chunk.groupInfo.terrainLength - 1, localPoint.y + (radius + blurRange));
            Vector2 CenterPoint = new Vector2(Minx, MinY);
            float   localsqrDis = (radius + blurRange) * (radius + blurRange);

            for (int y = (int)MinY; y <= Maxy; ++y)
            {
                for (int x = (int)Minx; x <= Maxx; ++x)
                {
                    int heightflag    = chunk.groupInfo.GetHeightIndex(x, y);
                    int heightMinFlag = chunk.groupInfo.GetMinHeightIndex(x, y);
                    int targetFlag    = Mathf.FloorToInt(brush.Targetheight - 0.001f);

                    if (heightMinFlag < targetFlag)
                    {
                        if (heightflag > targetFlag)
                        {
                            chunk.groupInfo.SetCullFace(x, y, targetFlag);
                        }
                        continue;
                    }


                    float curValue = chunk.groupInfo.GetRealHeight(x, y);
                    CenterPoint.x = x;
                    CenterPoint.y = y;
                    float sqr = Vector2.SqrMagnitude(localPoint - CenterPoint);
                    if (sqr < localsqrDis)
                    {
                        float distancePower = GetDistancePower(Mathf.Sqrt(sqr), true, brush);
                        float newvalue      = Mathf.Lerp(curValue, target, num * distancePower);
                        newvalue = Mathf.Min(curValue, newvalue);
                        newvalue = Mathf.Max(target + 0.001f, newvalue);
                        chunk.groupInfo.SetValue(x, y, newvalue);
                        chunk.groupInfo.SetSurfaceValue(x, y, newvalue);
                        chunk.groupInfo.SetCullFace(x, y, newvalue);
                    }
                }
            }
        }
Beispiel #3
0
        public bool CastGroup(Ray ray, TerrainBrush brush, List <TerrainChunk> colliedChunks, out Vector3 HitPoint)
        {
            RaycastHit info     = default(RaycastHit);
            bool       Collided = false;

            HitPoint = Vector3.zero;

            List <TerrainChunk> CopyChunks = Chunks;
            int nChildCount = CopyChunks.Count;

            int nCopyChunkCount = CopyChunks.Count;

            for (int idx = 0; idx < nCopyChunkCount; ++idx)
            {
                TerrainChunk Curchunk = CopyChunks[idx];

                if (Curchunk.GetMeshCollider().Raycast(ray, out info, 1000))
                {
                    if (flag != null)
                    {
                        flag.transform.position = info.point;
                    }


                    Brush(info.point, Curchunk, brush);
//                         Brush(info.point + new Vector3(0.0f,0.0f,0.2f), Curchunk, brush);
//                         Brush(info.point + new Vector3(0.0f, 0.0f, -0.2f), Curchunk, brush);
//                         Brush(info.point + new Vector3(-0.2f, 0.0f, 0.0f), Curchunk, brush);
//                         Brush(info.point + new Vector3(0.2f, 0.0f, 0.0f), Curchunk, brush);

                    //return info.point;
                    HitPoint = info.point;
                    Collided = true;
                    break;
                }
            }
            float  brushLenght = (brush.Radius + brush.BlurRadius) + 2.0f;
            Circle brushCircle = new Circle(new Vector2(info.point.x, info.point.z), brushLenght);

            colliedChunks.Clear();
            if (Collided)
            {
                for (int idx = 0; idx < nCopyChunkCount; ++idx)
                {
                    if (Circle.ColliderRect(brushCircle, CopyChunks[idx]._boxRect))
                    {
                        colliedChunks.Add(CopyChunks[idx]);
                    }
                }
            }
            int nColliderChunks = colliedChunks.Count;

            for (int idx = 0; idx < nColliderChunks; ++idx)
            {
                colliedChunks[idx].BuildChunk();
            }
            return(Collided);
        }
Beispiel #4
0
        private void BrushRaise(Vector3 point, TerrainBrush brush, TerrainChunk chunk)
        {
            Vector3 localPoint   = point - transform.position;
            int     BrushSize    = (int)brush.Radius;
            float   BrushOcaptiy = brush.Targetheight;
            float   powValue     = brush.Strenght;

            int idx = Mathf.RoundToInt((localPoint.x / chunk.groupInfo.worldSize.x) * chunk.groupInfo.terrainWidth);
            int idy = Mathf.RoundToInt((localPoint.z / chunk.groupInfo.worldSize.y) * chunk.groupInfo.terrainLength);

            int minX = Mathf.Max(0, idx - BrushSize);
            int maxX = Mathf.Min(chunk.groupInfo.terrainWidth, idx + BrushSize);

            int minY = Mathf.Max(0, idy - BrushSize);
            int maxY = Mathf.Min(chunk.groupInfo.terrainLength, idy + BrushSize);

            Vector2 center      = new Vector2(idx, idy);
            Vector2 testPoint   = new Vector2(maxX, maxY);
            float   maxDistance = Vector2.Distance(center, testPoint);

            for (int y = minY; y <= maxY; ++y)
            {
                for (int x = minX; x <= maxX; ++x)
                {
                    float curValue = chunk.groupInfo.GetRealHeight(x, y);
                    testPoint.x = x;
                    testPoint.y = y;
                    float distance      = Vector2.Distance(center, testPoint);
                    float Distancevalue = (distance / maxDistance);
                    float num1          = Mathf.Pow(Distancevalue, powValue);
                    float num2          = (1.0F - num1);
                    if (num2 > 1.0f)
                    {
                        num2 = 1.0f;
                    }
                    if (num2 < 0.0f)
                    {
                        num2 = 0.0f;
                    }
                    float newvalue = BrushOcaptiy * num2;
                    newvalue = Mathf.Max(newvalue, curValue);

                    chunk.groupInfo.SetValue(x, y, newvalue);
                    chunk.groupInfo.SetSurfaceValue(x, y, newvalue);
                    if (chunk.groupInfo.GetValue(x, y) != chunk.groupInfo.GetSurfaceValue(x, y))
                    {
                        Debug.LogError("Set Value  Error");
                        chunk.groupInfo.SetValue(x, y, newvalue);
                        chunk.groupInfo.SetSurfaceValue(x, y, newvalue);
                    }
                }
            }
        }
Beispiel #5
0
        TerrainBox GetBox(int x, int y)
        {
            int ChunkX = Mathf.FloorToInt(x / 32.0f);
            int ChunkY = Mathf.FloorToInt(y / 32.0f);

            TerrainChunk chunk = Chunks[ChunkY * ChunkColumn + ChunkX];

            int BoxX = x % 32;
            int BoxY = y % 32;

            TerrainBox[] boxs = chunk.boxs;

            return(boxs[BoxY * 32 + BoxX]);
        }
Beispiel #6
0
        public bool Init(LayerTerrainColor color, LayerTerrainGroups.Chunk data, TerrainFile file, Material mat)
        {
            chunkData   = data;
            filedata    = file;
            ChunkColumn = (file.terrainWidth / data.ChunkWidth);
            //2 *2 or 3*3 4*4
            ChunkRow   = (file.terrainLength / data.ChunkLenght);
            ChunkCount = ChunkColumn * ChunkRow;
            //create Chunk
            Chunks.Capacity = ChunkCount;
            float WorldChunkSize = file.worldSize.x / ChunkColumn;



            for (int idy = 0; idy < ChunkRow; ++idy)
            {
                for (int idx = 0; idx < ChunkColumn; ++idx)
                {
                    GameObject Chunk = new GameObject(this.gameObject.name + "Chunk[" + idy.ToString() + ":" + idx.ToString() + "]");
                    Chunk.transform.parent = transform;
                    Chunk.tag   = "Terrain";
                    Chunk.layer = 8;
                    MeshFilter meshfilter = Chunk.AddComponent <MeshFilter>();
                    meshfilter.hideFlags = HideFlags.HideAndDontSave;
                    MeshRenderer render = Chunk.AddComponent <MeshRenderer>();
                    render.hideFlags = HideFlags.DontSave;

                    TerrainChunk terrainChunkItem = Chunk.AddComponent <TerrainChunk>();
                    terrainChunkItem.hideFlags = HideFlags.HideAndDontSave;

                    Vector2Int index = new Vector2Int();
                    index.x = idx;
                    index.y = idy;

                    Vector3 offset = new Vector3();
                    offset.x = WorldChunkSize * idx;
                    offset.z = WorldChunkSize * idy;
                    offset.y = 0.0f;

                    terrainChunkItem.Init(new Vector2Int(idx, idy), offset,
                                          new Vector2(WorldChunkSize, WorldChunkSize),
                                          file, color, data, mat);
                    Chunks.Add(terrainChunkItem);
                }
            }
            return(true);
        }
Beispiel #7
0
        public bool TouchInGround(Ray ray, out int layerIndex)
        {
            RaycastHit info;

            for (int idx = 0; idx < transform.childCount; ++idx)
            {
                TerrainChunk Curchunk = transform.GetChild(idx).GetComponent <TerrainChunk>();
                if (Curchunk == null)
                {
                    continue;
                }
                if (Curchunk.GetComponent <MeshCollider>().Raycast(ray, out info, 5000.0f))
                {
                    layerIndex = Mathf.RoundToInt(info.point.y / chunkData.LayerHeight) + 1;
                    return(true);
                }
            }
            layerIndex = 0;
            return(false);
        }
Beispiel #8
0
        public void Brush(Vector3 point, TerrainChunk chunk, TerrainBrush brush)
        {
            switch (brush.brushType)
            {
            case TerrainBrush.BrushType.BT_ADD:
            {
                BrushRaiseEx(point, brush, chunk);
            }
            break;

            case TerrainBrush.BrushType.BT_DOWN:
            {
                BrushDown(point, brush, chunk);
            }
            break;

            case TerrainBrush.BrushType.LOCK:
            {
                BrushRaiseEx(point, brush, chunk);
            }
            break;
            }
        }
    public void BuildMesh(SimTerrain.TerrainChunk chunk /*, List<SimTerrain.TerrainTriangle> triangles*/)
    {
        Mesh mesh = chunk.GetMeshFilter().sharedMesh;

        mesh.Clear();



        if (vertticeIndex > chunk.verticesAry.Length)
        {
            int newValue = Math.Min(65000, vertticeIndex + 10000);
            chunk.verticesAry = new Vector3[newValue];
            chunk.uvAry       = new Vector2[newValue];
            chunk.ColorsAry   = new Color32[newValue];
        }

        if (IndicesIndex > chunk.indicesAry.Length)
        {
            chunk.indicesAry = new int[IndicesIndex + 2000 * 3];
        }


        Array.Clear(chunk.indicesAry, 0, chunk.indicesAry.Length);
        Array.Copy(indicesBuffer, chunk.indicesAry, IndicesIndex);
        int copyCount = Math.Min(65000, vertticeIndex);

        Array.Copy(verticesAry, chunk.verticesAry, copyCount);
        Array.Copy(ColorsAry, chunk.ColorsAry, copyCount);
        Array.Copy(uvAry, chunk.uvAry, copyCount);


        mesh.vertices = chunk.verticesAry;
        mesh.uv       = chunk.uvAry;
        mesh.colors32 = chunk.ColorsAry;
        mesh.SetIndices(chunk.indicesAry, MeshTopology.Triangles, 0);
        mesh.RecalculateNormals();
    }
        /// <summary>
        /// 根据高度图,重建三角面
        /// </summary>
        public bool RebuildTriangle(TerrainChunk chunk, TerrainMeshPool pool, ref TerrainMeshPool.MemoryFlag flag, int index)
        {
            if (groupInfo != null)
            {
                int value0 = groupInfo.CopyData[chunkIndex.v0Index];
                int value1 = groupInfo.CopyData[chunkIndex.v1Index];
                int value2 = groupInfo.CopyData[chunkIndex.v2Index];

                int valueSurface0 = groupInfo.CopySurfaceData[chunkIndex.v0Index];
                int valueSurface1 = groupInfo.CopySurfaceData[chunkIndex.v1Index];
                int valueSurface2 = groupInfo.CopySurfaceData[chunkIndex.v2Index];

                bool hasShowSurface = false;

                if (value0 != valueSurface0)
                {
                    hasShowSurface = true;
                }

                if (value1 != valueSurface1)
                {
                    hasShowSurface = true;
                }

                if (value2 != valueSurface2)
                {
                    hasShowSurface = true;
                }

                if (value0 == v0value && value1 == v1value && value2 == v2value && hasShowSurface == false)
                {
                    if (pool.vertticeIndex != verticesStart)
                    {
                        int det        = pool.vertticeIndex - verticesStart;
                        int indexCount = indicesCount;
                        for (int idx = 0; idx < indexCount; ++idx)
                        {
                            chunk.indicesAry[IndicesStart + idx] = chunk.indicesAry[IndicesStart + idx] + det;
                        }
                    }

                    if (flag.flagOldPoint == false)
                    {
                        flag.verticeOldStart = verticesStart;
                        flag.indiceOldStart  = IndicesStart;
                        flag.flagOldPoint    = true;
                    }
                    flag.verticeCount += verticesCount;
                    flag.indiceCount  += indicesCount;

                    verticesStart       = pool.vertticeIndex;
                    IndicesStart        = pool.IndicesIndex;
                    pool.IndicesIndex  += indicesCount;
                    pool.vertticeIndex += verticesCount;
                    return(false);
                }
                else
                {
                    v0value = value0;
                    v1value = value1;
                    v2value = value2;
                }

                float maxValue = (float)ushort.MaxValue;
                _v0.y = (value0 / maxValue) * groupInfo.worldSize.z;
                _v1.y = (value1 / maxValue) * groupInfo.worldSize.z;
                _v2.y = (value2 / maxValue) * groupInfo.worldSize.z;

                groupInfo.CalculateHeightFlag(chunkIndex.v0Index);
                groupInfo.CalculateHeightFlag(chunkIndex.v1Index);
                groupInfo.CalculateHeightFlag(chunkIndex.v2Index);

                /*if (hasShowSurface)
                 * {
                 *  colorConfig.testSurface = true;
                 * }*/

                buildTriangle(pool, _v0, _v1, _v2);

                // buildTriangle(pool, _v0, _v1, _v2);

                if (hasShowSurface)
                {
                    int minSurfaceValue = Mathf.Min(valueSurface0, valueSurface1, valueSurface2);
                    _v0.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v1.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v2.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    buildTriangle(pool, _v0, _v1, _v2);
                }
                //colorConfig.testSurface = false;
                return(true);
            }
            return(false);
        }
        public bool RebuildTriangleEx(TerrainChunk chunk, TerrainMeshPool pool, ref TerrainMeshPool.MemoryFlag flag)
        {
            Vector3[] verticesAry = pool.verticesAry;
            Vector2[] uv0Ary      = pool.uvAry;
            Color32[] colorsAry   = pool.ColorsAry;
            int[]     indicesAry  = pool.indicesBuffer;

            float value0   = groupInfo.GetValue(chunkIndex.v0Index);
            float value1   = groupInfo.GetValue(chunkIndex.v1Index);
            float value2   = groupInfo.GetValue(chunkIndex.v2Index);
            float maxValue = (float)ushort.MaxValue;

            _v0.y = (value0 / maxValue) * groupInfo.worldSize.z;
            _v1.y = (value1 / maxValue) * groupInfo.worldSize.z;
            _v2.y = (value2 / maxValue) * groupInfo.worldSize.z;

            verticesStart = pool.vertticeIndex;
            verticesCount = 0;
            IndicesStart  = pool.IndicesIndex;
            indicesCount  = 0;



            verticesAry[verticesStart]     = (_v0);
            verticesAry[verticesStart + 1] = (_v1);
            verticesAry[verticesStart + 2] = (_v2);

            colorsAry[verticesStart + 0] = colorConfig.bottomColor;
            colorsAry[verticesStart + 1] = colorConfig.bottomColor;
            colorsAry[verticesStart + 2] = colorConfig.bottomColor;

            uv0Ary[verticesStart + 0] = (new Vector2(_v0.x / chunkConfig.uvReslution.x, _v0.z / chunkConfig.uvReslution.y));
            uv0Ary[verticesStart + 1] = (new Vector2(_v1.x / chunkConfig.uvReslution.x, _v1.z / chunkConfig.uvReslution.y));
            uv0Ary[verticesStart + 2] = (new Vector2(_v2.x / chunkConfig.uvReslution.x, _v2.z / chunkConfig.uvReslution.y));


            indicesAry[IndicesStart + 0] = verticesStart;
            indicesAry[IndicesStart + 1] = verticesStart + 1;
            indicesAry[IndicesStart + 2] = verticesStart + 2;

            verticesCount = 3;
            indicesCount  = 3;

            pool.vertticeIndex += 3;
            pool.IndicesIndex  += 3;
            return(true);

            /*
             * clear();
             * //TODO:
             * if (groupInfo != null)
             * {
             *
             *  float value0 = groupInfo.GetValue(chunkIndex.v0Index);
             *  float value1 = groupInfo.GetValue(chunkIndex.v1Index);
             *  float value2 = groupInfo.GetValue(chunkIndex.v2Index);
             *                  float maxValue  = (float)ushort.MaxValue;
             *                  _v0.y = (value0 / maxValue) * groupInfo.worldSize.z;
             *                  _v1.y = (value1 / maxValue) * groupInfo.worldSize.z;
             *                  _v2.y = (value2 / maxValue) * groupInfo.worldSize.z;
             *
             *  verticesAry[0] = (_v0);
             *  verticesAry[1] = (_v1);
             *  verticesAry[2] = (_v2);
             *
             *  colorsAry[0] = colorConfig.bottomColor;
             *  colorsAry[1] = colorConfig.bottomColor;
             *  colorsAry[2] = colorConfig.bottomColor;
             *
             *  uv0Ary[0] = (new Vector2(_v0.x / chunkConfig.uvReslution.x, _v0.z / chunkConfig.uvReslution.y));
             *  uv0Ary[1] = (new Vector2(_v1.x / chunkConfig.uvReslution.x, _v1.z / chunkConfig.uvReslution.y));
             *  uv0Ary[2] = (new Vector2(_v2.x / chunkConfig.uvReslution.x, _v2.z / chunkConfig.uvReslution.y));
             *
             *
             *  indexBuffer.Add(IndexBufferIndex + 0);
             *  indexBuffer.Add(IndexBufferIndex + 1);
             *  indexBuffer.Add(IndexBufferIndex + 2);
             *
             *
             *
             *  verticesCount = 3;
             *
             *
             *
             * return IndexBufferIndex + 3;
             * }
             *
             * return IndexBufferIndex;
             */
        }
Beispiel #12
0
        public bool RebuildTriangle(TerrainChunk chunk, TerrainMeshPool pool, ref TerrainMeshPool.MemoryFlag flag, int boxindex)
        {
            int value0 = groupInfo.CopyData[v0Index];
            int value1 = groupInfo.CopyData[v1Index];
            int value2 = groupInfo.CopyData[v2Index];
            int value3 = groupInfo.CopyData[v3Index];

            int valueSurface0 = groupInfo.CopySurfaceData[v0Index];
            int valueSurface1 = groupInfo.CopySurfaceData[v1Index];
            int valueSurface2 = groupInfo.CopySurfaceData[v2Index];
            int valueSurface3 = groupInfo.CopySurfaceData[v3Index];

            int valueCull0 = groupInfo.copyCullfaceData[v0Index];
            int valueCull1 = groupInfo.copyCullfaceData[v1Index];
            int valueCull2 = groupInfo.copyCullfaceData[v2Index];
            int valueCull3 = groupInfo.copyCullfaceData[v3Index];


            bool hasShowSurface = false;

            if (value0 != valueSurface0)
            {
                hasShowSurface = true;
            }

            if (value1 != valueSurface1)
            {
                hasShowSurface = true;
            }

            if (value2 != valueSurface2)
            {
                hasShowSurface = true;
            }

            if (value3 != valueSurface3)
            {
                hasShowSurface = true;
            }

            bool hasCullFace = false;

            if (value0 != valueCull0)
            {
                hasCullFace = true;
            }

            if (value1 != valueCull1)
            {
                hasCullFace = true;
            }

            if (value2 != valueCull2)
            {
                hasCullFace = true;
            }

            if (value3 != valueCull3)
            {
                hasCullFace = true;
            }


            if (value0 == v0value && value1 == v1value && value2 == v2value && value3 == v3value && hasShowSurface == false && hasCullFace == false)
            {
                if (pool.vertticeIndex != verticesStart)
                {
                    int det        = pool.vertticeIndex - verticesStart;
                    int indexCount = indicesCount;
                    for (int idx = 0; idx < indexCount; ++idx)
                    {
                        chunk.indicesAry[IndicesStart + idx] = chunk.indicesAry[IndicesStart + idx] + det;
                    }
                }
                if (flag.flagOldPoint == false)
                {
                    flag.verticeOldStart = verticesStart;
                    flag.indiceOldStart  = IndicesStart;
                    flag.flagOldPoint    = true;
                }
                flag.verticeCount += verticesCount;
                flag.indiceCount  += indicesCount;

                verticesStart       = pool.vertticeIndex;
                IndicesStart        = pool.IndicesIndex;
                pool.IndicesIndex  += indicesCount;
                pool.vertticeIndex += verticesCount;
                return(false);
            }
            else
            {
                v0value = value0;
                v1value = value1;
                v2value = value2;
                v3value = value3;
            }

            float maxValue = (float)ushort.MaxValue;

            _v0.y = (value0 / maxValue) * groupInfo.worldSize.z;
            _v1.y = (value1 / maxValue) * groupInfo.worldSize.z;
            _v2.y = (value2 / maxValue) * groupInfo.worldSize.z;
            _v3.y = (value3 / maxValue) * groupInfo.worldSize.z;

            if (hasCullFace)
            {
                valueCull0 = (int)((valueCull0 / maxValue) * groupInfo.worldSize.z);
                valueCull1 = (int)((valueCull1 / maxValue) * groupInfo.worldSize.z);
                valueCull2 = (int)((valueCull2 / maxValue) * groupInfo.worldSize.z);
                valueCull3 = (int)((valueCull3 / maxValue) * groupInfo.worldSize.z);
            }

            verticesStart = pool.vertticeIndex;
            verticesCount = 0;
            IndicesStart  = pool.IndicesIndex;
            indicesCount  = 0;
            //Debug.Log (chunk.name +  v0Index + ":" + v1Index + ":" + v2Index + ":" + v3Index);

            /*switch (TestCode)
             *          {
             *          case 1:
             *                  {
             *                          colorConfig.testSurface = true;
             *                          colorConfig.Red.r = 255;
             *                          colorConfig.Red.b = 0;
             *                          colorConfig.Red.g = 0;
             *                  }break;
             *     case 2:
             *                  {
             *                          colorConfig.testSurface = true;
             *                          colorConfig.Red.r = 0;
             *                          colorConfig.Red.b = 0;
             *                          colorConfig.Red.g = 255;
             *                  }
             *                  break;
             *
             *          }
             *
             */
            groupInfo.CalculateHeightFlag(v0Index);
            groupInfo.CalculateHeightFlag(v1Index);
            groupInfo.CalculateHeightFlag(v2Index);
            groupInfo.CalculateHeightFlag(v3Index);

            //colorConfig.testSurface = hasCullFace;


            if (Mathf.Max(_v0.y, _v2.y) > Mathf.Max(_v1.y, _v3.y))
            {
                int CullFaca = -1;
                if (hasCullFace)
                {
                    CullFaca = Mathf.Max(valueCull0, valueCull1, valueCull3);
                }

                buildTriangleLeft(pool, _v0, _v1, _v3, CullFaca);
                if (hasCullFace)
                {
                    CullFaca = Mathf.Max(valueCull2, valueCull1, valueCull3);
                }
                buildTriangleLeft(pool, _v3, _v1, _v2, CullFaca);

                if (hasShowSurface)
                {
                    int minSurfaceValue = Mathf.Min(valueSurface0, valueSurface1, valueSurface3);
                    _v0.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v1.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v3.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    buildTriangleLeft(pool, _v0, _v1, _v3);
                    minSurfaceValue = Mathf.Min(valueSurface2, valueSurface1, valueSurface3);
                    _v2.y           = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v1.y           = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v3.y           = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    buildTriangleLeft(pool, _v3, _v1, _v2);
                }
            }
            else
            {
                int CullFaca = -1;
                if (hasCullFace)
                {
                    CullFaca = Mathf.Max(valueCull0, valueCull1, valueCull2);
                }
                buildTriangleLeft(pool, _v0, _v1, _v2, CullFaca);
                if (hasCullFace)
                {
                    CullFaca = Mathf.Max(valueCull0, valueCull2, valueCull3);
                }

                buildTriangleLeft(pool, _v0, _v2, _v3, CullFaca);

                if (hasShowSurface)
                {
                    int minSurfaceValue = Mathf.Min(valueSurface0, valueSurface1, valueSurface2);
                    _v0.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v1.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v2.y = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    buildTriangleLeft(pool, _v0, _v1, _v2);

                    minSurfaceValue = Mathf.Min(valueSurface0, valueSurface2, valueSurface3);
                    _v0.y           = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v2.y           = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;
                    _v3.y           = (minSurfaceValue / maxValue) * groupInfo.worldSize.z;

                    buildTriangleLeft(pool, _v0, _v1, _v2);
                    buildTriangleLeft(pool, _v0, _v2, _v3);
                }
            }
            // colorConfig.testSurface = false;
            pool.vertticeIndex += verticesCount;
            pool.IndicesIndex  += indicesCount;

            return(true);
        }
Beispiel #13
0
        private void BrushRaiseEx(Vector3 point, TerrainBrush brush, TerrainChunk chunk)
        {
            #region v1.0

            /*
             *
             * Vector3 localPoint = point - transform.position;
             * Vector2 localIdx = new Vector2(localPoint.x, localPoint.z);
             *
             * localIdx.x = Mathf.RoundToInt((localIdx.x / chunk.groupInfo.worldSize.x) *
             *  chunk.groupInfo.terrainWidth);
             * localIdx.y = Mathf.RoundToInt((localIdx.y / chunk.groupInfo.worldSize.y) *
             * chunk.groupInfo.terrainLength);
             *
             * float radio = (float)brush.BrushRange;
             * float BrushOcaptiy = brush.BrushOpacity;
             * float cell = chunk.groupInfo.worldSize.x / (chunk.groupInfo.terrainWidth - 1);
             *
             *
             * float maxX = localPoint.x + (radio + 2.0f * cell);
             * float minX = localPoint.x - (radio + 2.0f * cell);
             * float maxY = localPoint.z + (radio + 2.0f * cell);
             * float minY = localPoint.z - (radio + 2.0f * cell);
             * int iMinx = Mathf.FloorToInt((minX / chunk.groupInfo.worldSize.x) *
             *  chunk.groupInfo.terrainWidth);
             *
             *
             * float fMaxX = (maxX / chunk.groupInfo.worldSize.x) * chunk.groupInfo.terrainWidth;
             * int iMaxx = Mathf.CeilToInt(fMaxX);
             * int iMiny = Mathf.FloorToInt((minY / chunk.groupInfo.worldSize.y) *
             *  chunk.groupInfo.terrainLength);
             * int iMaxy = Mathf.CeilToInt((maxY / chunk.groupInfo.worldSize.y) *
             *  chunk.groupInfo.terrainLength);
             *
             * Vector2 TestPoint = new Vector2();
             * for(int idy = iMiny; idy <= iMaxy; ++idy)
             * {
             *  for(int idx = iMinx; idx <= iMaxx; ++idx)
             *  {
             *      TestPoint.x = idx;
             *      TestPoint.y = idy;
             *      float distance = Vector2.Distance(TestPoint, localIdx);
             *      float weight =1.0f -  (distance / radio);
             *      if(weight < 0.0f)
             *      {
             *          weight = 0.0f;
             *      }
             *      if(weight > 1.0f)
             *      {
             *          weight = 1.0f;
             *      }
             *      weight = Mathf.Sin(weight * (Mathf.PI / 2.0f));
             *      float curValue = chunk.groupInfo.GetRealHeight(idx, idy);
             *      float newValue = (curValue * (1.0f - weight)) + BrushOcaptiy * weight;
             *      chunk.groupInfo.SetValue(idx, idy, newValue);
             *  }
             * }
             *
             */
            #endregion v1.0

            #region v1.1

            /*
             * Vector3 localPoint = point - transform.position;
             * int BrushSize = (int)brush.BrushRange;
             * float BrushOcaptiy = brush.Targetheight + 1.0f;
             * float powValue = brush.BrushPow;
             *
             * int idx = Mathf.RoundToInt((localPoint.x / chunk.groupInfo.worldSize.x) * chunk.groupInfo.terrainWidth);
             * int idy = Mathf.RoundToInt((localPoint.z / chunk.groupInfo.worldSize.y) * chunk.groupInfo.terrainLength);
             *
             * int minX = Mathf.Max(0, idx - BrushSize);
             * int maxX = Mathf.Min(chunk.groupInfo.terrainWidth, idx + BrushSize);
             *
             * int minY = Mathf.Max(0, idy - BrushSize);
             * int maxY = Mathf.Min(chunk.groupInfo.terrainLength, idy + BrushSize);
             *
             * Vector2 center = new Vector2(idx, idy);
             * Vector2 testPoint = new Vector2(maxX, maxY);
             * float maxDistance = Vector2.Distance(center, testPoint);
             * for (int y = minY; y <= maxY; ++y)
             * {
             *  for (int x = minX; x <= maxX; ++x)
             *  {
             *      float curValue = chunk.groupInfo.GetRealHeight(x, y);
             *      testPoint.x = x;
             *      testPoint.y = y;
             *      float distance = Vector2.Distance(center, testPoint);
             *      //if (distance > brush.BrushRange) continue;
             *      float Distancevalue = (distance / maxDistance);
             *      float num1 = Mathf.Pow(Distancevalue, powValue);
             *      float num2 = (1.0F - num1);
             *      if (num2 > 1.0f) num2 = 1.0f;
             *      if (num2 < 0.0f) num2 = 0.0f;
             *      float newvalue = BrushOcaptiy * num2;
             *
             *      if(newvalue > BrushOcaptiy - 1.0f)
             *      {
             *          newvalue = BrushOcaptiy - 1.0F;
             *      }
             *      newvalue = Mathf.Max(curValue, newvalue);
             *      chunk.groupInfo.SetValue(x, y, newvalue);
             *  }
             * }
             */
            #endregion v1.1

            float radius    = brush.Radius;
            float num       = brush.Strenght;
            float blurRange = brush.BlurRadius;
            float num3      = 1.0f - Mathf.Pow(brush.BlurPower, 4.0f);
            num3 = 1.0f - Mathf.Pow(1.0f - num3, 1.1f);

            //Height
            Vector2 localPoint = new Vector2(point.x - transform.position.x, point.z - transform.position.z);
            localPoint.x = Mathf.RoundToInt((localPoint.x / chunk.groupInfo.worldSize.x) * (chunk.groupInfo.terrainWidth - 1));
            localPoint.y = Mathf.RoundToInt((localPoint.y / chunk.groupInfo.worldSize.y) * (chunk.groupInfo.terrainLength - 1));

            float   Minx        = Mathf.Max(0, localPoint.x - (radius + blurRange));
            float   Maxx        = Mathf.Min(chunk.groupInfo.terrainWidth - 1, localPoint.x + (radius + blurRange));
            float   MinY        = Mathf.Max(0, localPoint.y - (radius + blurRange));
            float   Maxy        = Mathf.Min(chunk.groupInfo.terrainLength - 1, localPoint.y + (radius + blurRange));
            Vector2 CenterPoint = new Vector2(Minx, MinY);
            float   localsqrDis = (radius + blurRange) * (radius + blurRange);
            for (int y = (int)MinY; y <= Maxy; ++y)
            {
                for (int x = (int)Minx; x <= Maxx; ++x)
                {
                    //每个点的 高低的切面
                    int heightflag    = chunk.groupInfo.GetHeightIndex(x, y);
                    int heightMinFlag = chunk.groupInfo.GetMinHeightIndex(x, y);

                    //float curValue = chunk.groupInfo.GetRealHeight(x, y);
                    CenterPoint.x = x;
                    CenterPoint.y = y;
                    float sqr = Vector2.SqrMagnitude(localPoint - CenterPoint);
                    if (sqr < localsqrDis)
                    {
                        float distancePower = GetDistancePower(Mathf.Sqrt(sqr), true, brush);
                        int   targetFlag    = Mathf.FloorToInt(brush.Targetheight - 0.001f);

                        // float  curValue = chunk.groupInfo.GetRealHeight(x, y);

                        //做一次 Filter 整形,不需要重复整形。用Flag标志位表示

                        /* if (heightflag == heightMinFlag && heightMinFlag < targetFlag)
                         * {
                         *   if (chunk.groupInfo.GetFilterFlagValue(x, y) == false)
                         *   {
                         *
                         *       chunk.groupInfo.SetValue(x,y, heightMinFlag);
                         *       chunk.groupInfo.SetSurfaceValue(x, y, heightMinFlag);
                         *       chunk.groupInfo.SetFilterFlagValue(x, y, true);
                         *       //curValue = heightflag;
                         *   }
                         * }
                         */
                        float curValue = chunk.groupInfo.GetSurfaceRealValue(x, y);
                        float newvalue = Mathf.Lerp(curValue, brush.Targetheight, num * distancePower);

                        //防止拓扑面畸变,补面
                        if (heightflag > targetFlag)
                        {
                            if (heightMinFlag <= targetFlag)
                            {
                                float surfacevalue = Mathf.Max(chunk.groupInfo.GetSurfaceRealValue(x, y), brush.Targetheight - 0.5f);
                                chunk.groupInfo.SetSurfaceValue(x, y, surfacevalue);
                            }
                            continue;
                        }
                        if (heightMinFlag >= targetFlag)
                        {
                            continue;
                        }
                        chunk.groupInfo.SetCullFace(x, y, newvalue);
                        chunk.groupInfo.SetValue(x, y, newvalue);
                        chunk.groupInfo.SetSurfaceValue(x, y, newvalue);
                    }
                }
            }
        }