public override void Collect(VolumeContainer container) { Area defaultArea = PathFinder.GetArea(0); Area clearArea = PathFinder.GetArea(1); for (int i = 0; i < _collectedTerrainUsingComputeShader.Count; i++) { TerrainInfoCSR info = _collectedTerrainUsingComputeShader[i]; TerrainColliderInfoMesh terrainInfo = info.colliderInfo; Volume terrainVolume; if (terrainInfo.alphaMap != null) { terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, terrainInfo.possibleArea); } else { terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, defaultArea); } terrainVolume.terrain = true; //var areaLibrary = PathFinder.settings.areaLibrary; info.voxelsTerrain.Read(terrainVolume); terrainVolume.SetVolumeMinimum(-1000f); SetTerrainArea(terrainVolume, terrainInfo, defaultArea); //apply terrain area info if it exist if (info.voxelsTrees != null) { //trees Volume treeVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, defaultArea); treeVolume.SetVolumeMinimum(-1000f); foreach (var treeVoxls in info.voxelsTrees) { if (treeVoxls != null) { treeVoxls.Read(treeVolume, clearArea); } } //connecting terrain and trees to single volume terrainVolume.Subtract(treeVolume); terrainVolume.ConnectToItself(); terrainVolume.Override(treeVolume); } else { terrainVolume.ConnectToItself(); } container.AddVolume(terrainVolume); } }
//in not main thread //read voxels to volume public override void Collect(VolumeContainer container) { if (templatesAfterComputeShader == null) { Debug.LogWarning("expecting to recive things from compute shader but list was null"); return; } for (int i = 0; i < templatesAfterComputeShader.Count; i++) { Volume curInfoVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, templatesAfterComputeShader[i].info.area); templatesAfterComputeShader[i].result.Read(curInfoVolume, templatesAfterComputeShader[i].info.area); container.AddVolume(curInfoVolume); } }
//not main thread public override void Collect(VolumeContainer container) { Area defaultArea = PathFinder.GetArea(0); foreach (var terrain in _terrainsInfo) { //terrain Volume terrainVolume; if (terrain.alphaMap != null) { terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, terrain.possibleArea); } else { terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, defaultArea); } terrainVolume.terrain = true; float[][] heightMap = terrain.heightMap; int[][] passabilityMap = terrain.passabilityMap; var areaLibrary = PathFinder.settings.areaLibrary; //apply terrain area info if it exist //SetTerrainArea(terrainVolume, terrain, defaultArea); if (terrain.alphaMap != null) { int[][] areaMap = ProcessAlphaMap(terrain); for (int x = 0; x < template.lengthX_extra; x++) { for (int z = 0; z < template.lengthZ_extra; z++) { terrainVolume.SetVoxel(x, z, heightMap[x][z], areaLibrary[areaMap[x][z]], passabilityMap[x][z]); if (areaMap[x][z] == 1) { terrainVolume.SetPassability(x, z, Passability.Unwalkable); } } } } else { for (int x = 0; x < template.lengthX_extra; x++) { for (int z = 0; z < template.lengthZ_extra; z++) { terrainVolume.SetVoxel(x, z, heightMap[x][z], defaultArea, passabilityMap[x][z]); } } } terrainVolume.SetVolumeMinimum(-1000f); //trees Volume treeVolume = base.CollectTrees(terrain); //connecting terrain and trees to single volume if (treeVolume != null) { terrainVolume.Subtract(treeVolume); terrainVolume.ConnectToItself(); terrainVolume.Override(treeVolume); } //sent terrain to container container.AddVolume(terrainVolume); //container.AddVolume(treeVolume); } }
//threaded public override void Collect(VolumeContainer container) { float maxSlopeCos = Mathf.Cos((float)((double)template.maxSlope * Math.PI / 180.0)); foreach (var colTemplate in templates) { Area area = colTemplate.area; Volume volume = new Volume(template.lengthX_extra, template.lengthZ_extra, area); Vector3[] templateVerts = colTemplate.verts; Vector3[] verts = new Vector3[templateVerts.Length]; Matrix4x4 matrix = colTemplate.matrix; for (int i = 0; i < templateVerts.Length; i++) { verts[i] = matrix.MultiplyPoint3x4(templateVerts[i]); } int[] tris = colTemplate.tris; for (int t = 0; t < colTemplate.tris.Length; t += 3) { Vector3 A = verts[tris[t]]; Vector3 B = verts[tris[t + 1]]; Vector3 C = verts[tris[t + 2]]; bool unwalkableBySlope = !CalculateWalk(A, B, C, maxSlopeCos); Passability currentPassability; if (area.id == 1)//id of clear Area all time { currentPassability = Passability.Unwalkable; } else if (unwalkableBySlope) { currentPassability = Passability.Slope; } else { currentPassability = Passability.Walkable; } #if UNITY_EDITOR if (currentPassability > Passability.Slope && Debuger_K.doDebug && Debuger_K.debugOnlyNavMesh == false) { Debuger_K.AddWalkablePolygon(template.gridPosX, template.gridPosZ, template.properties, A, B, C); } #endif base.RasterizeTriangle( volume, A, B, C, template.voxelSize, template.startX_extra, template.endX_extra, template.startZ_extra, template.endZ_extra, area, currentPassability); } container.AddVolume(volume); } }
//not main thread public override void Collect(VolumeContainer container) { Area defaultArea = PathFinder.GetArea(0); float maxSlopeCos = Mathf.Cos((float)((double)template.maxSlope * Math.PI / 180.0)); float voxelSize = template.voxelSize; Vector3 realChunkPos = template.realOffsetedPosition; float chunkPosX = realChunkPos.x; float chunkPosZ = realChunkPos.z; int offsetX = Mathf.RoundToInt(chunkPosX / voxelSize); int offsetZ = Mathf.RoundToInt(chunkPosZ / voxelSize); int sizeX = template.lengthX_extra; int sizeZ = template.lengthZ_extra; foreach (var terrain in terrainsInfo) { Volume terrainVolume; if (terrain.alphaMap != null) { terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, terrain.possibleArea); } else { terrainVolume = new Volume(template.lengthX_extra, template.lengthZ_extra, defaultArea); } terrainVolume.terrain = true; Vector3[] vrts; int[] trs; GetTerrainMesh(terrain, out vrts, out trs); //actual rasterization for (int i = 0; i < trs.Length; i += 3) { Vector3 A = vrts[trs[i]]; Vector3 B = vrts[trs[i + 1]]; Vector3 C = vrts[trs[i + 2]]; int passability = CalculateWalk(A, B, C, maxSlopeCos) ? 3 : 1;//if true then walkable else slope; int minX = Mathf.Clamp(Mathf.FloorToInt(SomeMath.Min(A.x, B.x, C.x) / voxelSize) - offsetX, 0, sizeX); int maxX = Mathf.Clamp(Mathf.CeilToInt(SomeMath.Max(A.x, B.x, C.x) / voxelSize) - offsetX, 0, sizeX); int minZ = Mathf.Clamp(Mathf.FloorToInt(SomeMath.Min(A.z, B.z, C.z) / voxelSize) - offsetZ, 0, sizeZ); int maxZ = Mathf.Clamp(Mathf.CeilToInt(SomeMath.Max(A.z, B.z, C.z) / voxelSize) - offsetZ, 0, sizeZ); for (int x = minX; x < maxX; x++) { for (int z = minZ; z < maxZ; z++) { float pointX = (x * voxelSize) + chunkPosX; float pointZ = (z * voxelSize) + chunkPosZ; if (SomeMath.LineSide(A.x, A.z, B.x, B.z, pointX, pointZ) <= 0.001 & SomeMath.LineSide(B.x, B.z, C.x, C.z, pointX, pointZ) <= 0.001 & SomeMath.LineSide(C.x, C.z, A.x, A.z, pointX, pointZ) <= 0.001) { terrainVolume.SetVoxelLight(x, z, SomeMath.CalculateHeight(A, B, C, pointX, pointZ), passability); } } } } //var areaLibrary = PathFinder.settings.areaLibrary; SetTerrainArea(terrainVolume, terrain, defaultArea); //apply terrain area info if it exist terrainVolume.SetVolumeMinimum(-1000f); //trees Volume treeVolume = base.CollectTrees(terrain); //connecting terrain and trees to single volume if (treeVolume != null) { terrainVolume.Subtract(treeVolume); terrainVolume.ConnectToItself(); terrainVolume.Override(treeVolume); } //sent terrain to container container.AddVolume(terrainVolume); } }