Exemplo n.º 1
0
        private void AddColliderTerrain(Collider collider, TerrainCollectorType terrainCollectionType)
        {
            Terrain terrain = collider.GetComponent <Terrain>();

            if (terrain == null | terrain.enabled == false)
            {
                return;
            }

            if (profiler != null)
            {
                profiler.AddLogFormat("collecting terrain {0}", terrain.gameObject.name);
            }

            TerrainColliderInfoMesh info = new TerrainColliderInfoMesh(terrain);

            info.trees = CollectTreeData(terrain);

            //general stuff
            float   voxelSize      = template.voxelSize;
            Bounds  offsetedBounds = template.chunkOffsetedBounds;
            Vector3 boundsMin      = offsetedBounds.min;
            Vector3 boundsMax      = offsetedBounds.max;

            float minSize = PathFinder.settings.terrainFastMinimalSize;

            //terrain stuff
            TerrainData data     = terrain.terrainData;
            Vector3     position = terrain.transform.position;
            Vector3     scale    = data.size;

            //height map
            int resolution = 1;

            int heightMapSizeX = data.heightmapWidth;
            int heightMapSizeZ = data.heightmapHeight;

            float hScaleX = scale.x / (heightMapSizeX - 1);
            float hScaleZ = scale.z / (heightMapSizeZ - 1);

            for (int i = 0; i < 4; i++)
            {
                if (minSize > hScaleX * resolution)
                {
                    resolution = (int)Mathf.Pow(2, i);
                }
                else
                {
                    break;
                }
            }

            int hTargetMinX = Mathf.Clamp(((Mathf.RoundToInt((boundsMin.x - position.x) / hScaleX) / resolution) - 1) * resolution, 0, heightMapSizeX);
            int hTargetMinZ = Mathf.Clamp(((Mathf.RoundToInt((boundsMin.z - position.z) / hScaleZ) / resolution) - 1) * resolution, 0, heightMapSizeX);

            int hTargetMaxX = Mathf.Clamp(((Mathf.RoundToInt((boundsMax.x - position.x) / hScaleX) / resolution) + 1) * resolution + 1, 0, heightMapSizeX);
            int hTargetMaxZ = Mathf.Clamp(((Mathf.RoundToInt((boundsMax.z - position.z) / hScaleZ) / resolution) + 1) * resolution + 1, 0, heightMapSizeX);

            int hSizeX = hTargetMaxX - hTargetMinX;
            int hSizeZ = hTargetMaxZ - hTargetMinZ;

            int hTargetSizeX = hSizeX / resolution + 1;
            int hTargetSizeZ = hSizeZ / resolution + 1;

            if (resolution == 1)
            {
                hTargetSizeX = hSizeX;
                hTargetSizeZ = hSizeZ;
            }


            info.heightMap    = data.GetHeights(hTargetMinX, hTargetMinZ, hSizeX, hSizeZ);
            info.heightMatrix = Matrix4x4.TRS(
                position + new Vector3(hScaleX * hTargetMinX, 0, hScaleZ * hTargetMinZ),
                Quaternion.identity,
                new Vector3(hScaleX * resolution, scale.y, hScaleZ * resolution));

            info.hSizeX     = hTargetSizeX;
            info.hSizeZ     = hTargetSizeZ;
            info.resolution = resolution;

            //rest
            VectorInt.Vector3Int terrainStartInt = new VectorInt.Vector3Int((position / voxelSize) + template.halfVoxelOffset);
            VectorInt.Vector3Int terrainEndInt   = new VectorInt.Vector3Int((position + data.size) / voxelSize + template.halfVoxelOffset);

            int startXClamp = Mathf.Clamp(terrainStartInt.x, template.startX_extra, template.endX_extra);
            int startZClamp = Mathf.Clamp(terrainStartInt.z, template.startZ_extra, template.endZ_extra);

            int endXClamp = Mathf.Clamp(terrainEndInt.x, template.startX_extra, template.endX_extra);
            int endZClamp = Mathf.Clamp(terrainEndInt.z, template.startZ_extra, template.endZ_extra);

            int terrainStartX = terrainStartInt.x;
            int terrainStartZ = terrainStartInt.z;

            float terrainSizeX = terrainEndInt.x - terrainStartX;
            float terrainSizeZ = terrainEndInt.z - terrainStartZ;

            var navmeshSettings = terrain.gameObject.GetComponent <TerrainNavmeshSettings>();

            if (navmeshSettings != null && navmeshSettings.isActiveAndEnabled && navmeshSettings.data.Any(x => x != 0))  //0 is default so if there is settings full of deffault areas then dont need that
            {
                Vector3 size = data.size;
                info.settings    = navmeshSettings;
                info.startXClamp = startXClamp;
                info.startZClamp = startZClamp;

                info.endXClamp = endXClamp;
                info.endZClamp = endZClamp;

                info.terrainStartX = terrainStartX;
                info.terrainStartZ = terrainStartZ;

                info.terrainSizeX = terrainSizeX;
                info.terrainSizeZ = terrainSizeZ;

                //all this values needed in 2 places. here to use data.GetAlphamaps in main thread and later in not main thread
                //so we just store it in terrain collider info
                info.alphaWidth  = data.alphamapWidth;
                info.alphaHeight = data.alphamapHeight;

                //normalized start and end
                //dont needed later
                float terNormStartX = Mathf.Clamp01((template.chunkData.realX - template.properties.radius - position.x) / size.x);
                float terNormStartZ = Mathf.Clamp01((template.chunkData.realZ - template.properties.radius - position.z) / size.z);

                float terNormEndX = Mathf.Clamp01((template.chunkData.realX + PathFinder.gridSize + template.properties.radius - position.x) / size.x);
                float terNormEndZ = Mathf.Clamp01((template.chunkData.realZ + PathFinder.gridSize + template.properties.radius - position.z) / size.z);

                //alpha map position of chunk
                info.alphaStartX = Mathf.RoundToInt(terNormStartX * info.alphaWidth);
                info.alphaStartZ = Mathf.RoundToInt(terNormStartZ * info.alphaHeight);

                //alpha map size of chunk
                //size needed only now
                info.alphaSizeX = Mathf.Min(Mathf.RoundToInt((terNormEndX - terNormStartX) * info.alphaWidth) + 1, info.alphaWidth - info.alphaStartX);
                info.alphaSizeZ = Mathf.Min(Mathf.RoundToInt((terNormEndZ - terNormStartZ) * info.alphaHeight) + 1, info.alphaHeight - info.alphaStartZ);

                info.alphaMap     = data.GetAlphamaps(info.alphaStartX, info.alphaStartZ, info.alphaSizeX, info.alphaSizeZ);
                info.possibleArea = (from areaID in navmeshSettings.data select PathFinder.GetArea(areaID)).ToArray(); //else if doCollectAreaInfo == false than later it became defaul area
            }

            switch (terrainCollectionType)
            {
            case TerrainCollectorType.CPU:
                terrainsInfoForCPU.Add(info);
                break;

            case TerrainCollectorType.ComputeShader:
                CollectTerrainOnGPU(info);
                break;
            }
        }
 public static void SetCurrentTerrainMethod(TerrainCollectorType type)
 {
     settings.terrainCollectionType = type;
 }