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; }