Пример #1
0
        //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);
            }
        }