protected ColliderCollectorTerrainAbstract(NavMeshTemplateRecast template, Collider[] colliders)
        {
            this.template = template;

            foreach (var collider in colliders)
            {
                if (IsValid(collider))
                {
                    validColliders.Add(collider);
                }
            }
        }
        private static void ThreadWorker(object obj)
        {
            NavMeshTemplateRecast template = (NavMeshTemplateRecast)obj;

            try {
                template.Work();
            }
            catch (Exception e) {
                if (template.profiler != null)
                {
                    template.profiler.DebugLog(ProfilderLogMode.warning);
                }
                Debug.LogError(e);
                throw;
            }
        }
        private static IEnumerator TemplatePopulationLoop()
        {
            NavMeshTemplateRecast nm_t = null;

            while (true)
            {
                //if (_disconnectionQueue.Count > 0)
                //    Debug.Log("NavMeshTemplateRecast blocked by _disconnectionQueue.Count > 0");

                if (_acceptingWork == false | _activeThreads >= _settings.maxThreads | _disconnectionQueue.Count > 0)
                {
                    goto next;
                }

                lock (_navMeshTemplateQueue)
                    nm_t = _navMeshTemplateQueue.Count > 0 ? _navMeshTemplateQueue.Dequeue() : null;

                if (nm_t == null)
                {
                    goto next;
                }

                _activeCreationWorks++;
                nm_t.Populate();

                if (multithread)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWorker), nm_t);
                    _activeThreads++; //increasing thread count but it's not really a thread. it's whole operation until connection
                }
                else
                {
                    nm_t.Work();
                }

                //Debug.LogFormat("taken {0}, now active creation is {1}", "NavMeshTemplateRecast", _activeCreationWorks);
                goto next;

next:
                {
                    yield return(new WaitForEndOfFrame());

                    continue;
                }
            }
        }
        private static void QueueNavMeshTemplateToPopulation(XZPosInt pos, AgentProperties properties)
        {
            if (_acceptingWork == false)
            {
                return;
            }

            //Debug.Log("queue 1 " + pos);
            NavMeshTemplateRecast template = new NavMeshTemplateRecast(_chunkRange, pos, properties);

            Action <Graph> callBack = (Graph graph) => {
                //Debug.Log("callback 1 " + pos);
                QueueFinishGraphInMainThread(graph);
            };

            template.SetCallBack(callBack);
            _allTemplatesCreative[new GeneralXZData(pos, properties)] = template;

            lock (_navMeshTemplateQueue)
                _navMeshTemplateQueue.Enqueue(template);
        }
        public ColliderCollectorTerrainMeshAbstract(NavMeshTemplateRecast template, Collider[] colliders) : base(template, colliders)
        {
            List <Terrain> allTerrains = new List <Terrain>();

            for (int i = 0; i < validColliders.Count; i++)
            {
                allTerrains.Add(validColliders[i].GetComponent <Terrain>());
            }

            if (template.profiler != null)
            {
                template.profiler.AddLog("collecting terrain using fast collector. valid colliders:" + validColliders.Count);
            }

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

            float minSize = PathFinder.settings.terrainFastMinimalSize;

            foreach (var curTerrain in allTerrains)
            {
                TerrainColliderInfoMesh info = new TerrainColliderInfoMesh(curTerrain);

                if (template.profiler != null)
                {
                    template.profiler.AddLog("start collecting tree bounds");
                }

                info.treeData = GenerateTreeBounds(curTerrain);

                if (template.profiler != null)
                {
                    template.profiler.AddLog("end collecting tree bounds. collected bounds: " + info.treeData.Count);
                }

                TerrainData data     = curTerrain.terrainData;
                Vector3     position = curTerrain.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.halfFragmentOffset);
                VectorInt.Vector3Int terrainEndInt   = new VectorInt.Vector3Int((position + data.size) / voxelSize + template.halfFragmentOffset);

                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;

                SetTerrainSettings(info, curTerrain,
                                   startXClamp, startZClamp,
                                   endXClamp, endZClamp,
                                   terrainStartX, terrainStartZ,
                                   terrainSizeX, terrainSizeZ,
                                   position);


                terrainsInfo.Add(info);
            }
        }
Пример #6
0
 protected ColliderCollectorPrimitivesAbstract(NavMeshTemplateRecast template, Collider[] colliders) : base(template, colliders)
 {
     GenerateTemplates();
 }
Пример #7
0
        //main thread
        public ColliderCollectorTerrainUnityWay(NavMeshTemplateRecast template, Collider[] colliders) : base(template, colliders)
        {
            var   allTerrains  = (from collider in validColliders select collider.GetComponent <Terrain>());
            float fragmentSize = template.voxelSize;
            float halfFragment = fragmentSize * 0.5f;


            foreach (var curTerrain in allTerrains)
            {
                TerrainData          data            = curTerrain.terrainData;
                Vector3              position        = curTerrain.transform.position;
                VectorInt.Vector3Int terrainStartInt = new VectorInt.Vector3Int((position / fragmentSize) + template.halfFragmentOffset);
                VectorInt.Vector3Int terrainEndInt   = new VectorInt.Vector3Int((position + data.size) / fragmentSize + template.halfFragmentOffset);

                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;

                int offset = terrainStartInt.y;

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

                float[][] heightMap      = new float[template.lengthX_extra][];
                int[][]   passabilityMap = new int[template.lengthX_extra][]; //angle map

                for (int x = 0; x < template.lengthX_extra; x++)
                {
                    heightMap[x]      = new float[template.lengthZ_extra];
                    passabilityMap[x] = new int[template.lengthZ_extra];
                }

                //some cashed values
                int   startX_extra = template.startX_extra;
                int   startZ_extra = template.startZ_extra;
                float maxSlope     = template.maxSlope;

                //lets do bazzilion times Terrain.SampleHeight and TerrainData.GetSteepness!
                //it cant be done in thread cause terrain API is "threadsafe"!
                //actualy it can be done. but in order to do this we need to recreate this part of terrain mesh in thread but no. i dont want to do this. no.
                //maybe later


                for (int x = startXClamp; x < endXClamp; x++)
                {
                    for (int z = startZClamp; z < endZClamp; z++)
                    {
                        heightMap[x - startX_extra][z - startZ_extra]      = curTerrain.SampleHeight(new Vector3(x * fragmentSize + halfFragment, 0, z * fragmentSize + halfFragment)) + offset;
                        passabilityMap[x - startX_extra][z - startZ_extra] = data.GetSteepness((x - terrainStartX) / terrainSizeX, (z - terrainStartZ) / terrainSizeZ) < maxSlope ? (int)Passability.Walkable : (int)Passability.Slope;
                    }
                }

                TerrainColliderInfoPrecise info = new TerrainColliderInfoPrecise(curTerrain, heightMap, passabilityMap);

                if (template.profiler != null)
                {
                    template.profiler.AddLog("start collecting tree bounds");
                }

                info.treeData = GenerateTreeBounds(curTerrain);

                if (template.profiler != null)
                {
                    template.profiler.AddLog("end collecting tree bounds. collected bounds: " + info.treeData.Count);
                }

                SetTerrainSettings(info, curTerrain,
                                   startXClamp, startZClamp,
                                   endXClamp, endZClamp,
                                   terrainStartX, terrainStartZ,
                                   terrainSizeX, terrainSizeZ,
                                   position);

                _terrainsInfo.Add(info);
            }
        }
Пример #8
0
 //construtor are called in main thread but execute Collect(FragmentContainer) in own thread
 public ColliderCollectorPrimitivesCPU(NavMeshTemplateRecast template, Collider[] colliders) : base(template, colliders)
 {
 }
Пример #9
0
 public ColliderCollectorTerrainComputeShader(NavMeshTemplateRecast template, Collider[] colliders) : base(template, colliders)
 {
 }
 public TerrainCollectorAbstract(NavMeshTemplateRecast template, Collider[] colliders) : base(template, colliders)
 {
 }