Exemplo n.º 1
0
    /// <summary>
    /// 批量平滑操作
    /// </summary>
    public static void BatchSmooth(Vector3[] centers, float radius, float dev, int level = 1)
    {
        float differx     = terrainSize.x / (heightMapRes - 1) * level;
        float differz     = terrainSize.z / (heightMapRes - 1) * level;
        int   arrayLength = centers.Length;

        for (int i = 0; i < arrayLength; i++)
        {
            centers[i].x -= differx;
            centers[i].z -= differz;
        }
        Terrain[] terrains = new Terrain[arrayLength];

        HMArg[] args = new HMArg[arrayLength];
        LoomA.Initialize();
        for (int i = 0; i < arrayLength; i++)
        {
            terrains[i] = InitHMArg(centers[i], radius, out args[i]);
            BatchSmooth(terrains[i], args[i].heightMap, args[i].startMapIndex, dev, level);
            //BatchSmoothAsync(terrains[i], heightMaps[i], mapIndexs[i], dev, level);
        }
    }
Exemplo n.º 2
0
    /// <summary>
    /// 初始化地形高度图编辑所需要的参数
    /// 后四个参数需要在调用前定义
    /// 编辑高度时所需要用到的参数后期打算用一个结构体封装
    /// </summary>
    /// <param name="center">目标中心</param>
    /// <param name="radius">半径</param>
    /// <param name="mapIndex">起始修改点在高度图上的索引</param>
    /// <param name="heightMap">要修改的高度二维数组</param>
    /// <param name="mapRadius">修改半径对应的索引半径</param>
    /// <param name="limit">限制高度</param>
    /// <returns></returns>
    private static Terrain InitHMArg(Vector3 center, float radius, out HMArg arg)
    {
        Vector3 leftDown = new Vector3(center.x - radius, 0, center.z - radius);
        // 左下方Terrain
        Terrain centerTerrain   = Utility.SendRayDown(center, LayerMask.GetMask("Terrain")).collider?.GetComponent <Terrain>();
        Terrain leftDownTerrain = Utility.SendRayDown(leftDown, LayerMask.GetMask("Terrain")).collider?.GetComponent <Terrain>();

        arg = default(HMArg);
        if (leftDownTerrain != null)
        {
            // 获取相关参数
            arg.mapRadiusX     = (int)(heightMapRes / terrainSize.x * radius);
            arg.mapRadiusZ     = (int)(heightMapRes / terrainSize.z * radius);
            arg.mapRadiusX     = arg.mapRadiusX < 1 ? 1 : arg.mapRadiusX;
            arg.mapRadiusZ     = arg.mapRadiusZ < 1 ? 1 : arg.mapRadiusZ;
            arg.startMapIndex  = GetHeightmapIndex(leftDownTerrain, leftDown);
            arg.centerMapIndex = new Vector2Int(arg.startMapIndex.x + arg.mapRadiusX, arg.startMapIndex.y + arg.mapRadiusZ);
            arg.heightMap      = GetHeightMap(leftDownTerrain, arg.startMapIndex.x, arg.startMapIndex.y, 2 * arg.mapRadiusX, 2 * arg.mapRadiusZ);
            arg.limit          = 0 /*heightMap[mapRadius, mapRadius]*/;
            return(leftDownTerrain);
        }
        // 左下至少有一个方向没有Terrain,大多数情况下不会进入,如果删掉地图的左边界和下边界无法编辑,影响不大,其实我很想删掉,所以注释什么的就去TM的吧
        else if (centerTerrain != null)
        {
            // 获取相关参数
            arg.mapRadiusX = (int)(heightMapRes / terrainSize.x * radius);
            arg.mapRadiusZ = (int)(heightMapRes / terrainSize.z * radius);
            arg.mapRadiusX = arg.mapRadiusX < 1 ? 1 : arg.mapRadiusX;
            arg.mapRadiusZ = arg.mapRadiusZ < 1 ? 1 : arg.mapRadiusZ;

            arg.centerMapIndex = GetHeightmapIndex(centerTerrain, center);
            arg.startMapIndex  = new Vector2Int(arg.centerMapIndex.x - arg.mapRadiusX, arg.centerMapIndex.y - arg.mapRadiusZ);

            int width = 2 * arg.mapRadiusX, height = 2 * arg.mapRadiusZ;

            if (arg.startMapIndex.x < 0 && arg.startMapIndex.y < 0)
            {
                if (centerTerrain.Left() != null)
                {
                    height += arg.startMapIndex.y;
                    arg.startMapIndex.y  = 0;
                    arg.startMapIndex.x += heightMapRes;

                    centerTerrain = centerTerrain.Left();
                }
                else if (centerTerrain.Bottom() != null)
                {
                    width += arg.startMapIndex.x;
                    arg.startMapIndex.x  = 0;
                    arg.startMapIndex.y += heightMapRes;

                    centerTerrain = centerTerrain.Bottom();
                }
                else
                {
                    width += arg.startMapIndex.x;
                    arg.startMapIndex.x = 0;
                    height += arg.startMapIndex.y;
                    arg.startMapIndex.y = 0;
                }
            }
            else if (arg.startMapIndex.x < 0)
            {
                width += arg.startMapIndex.x;
                arg.startMapIndex.x = 0;
            }
            else if (arg.startMapIndex.y < 0)
            {
                height += arg.startMapIndex.y;
                arg.startMapIndex.y = 0;
            }

            arg.heightMap = GetHeightMap(centerTerrain, arg.startMapIndex.x, arg.startMapIndex.y, width, height);
            arg.limit     = 0 /*heightMap[mapRadius, mapRadius]*/;
        }
        return(centerTerrain);
    }