Example #1
0
        /// <summary>
        /// Builds the navigation graph for obstacle.
        /// If updateObstc is set to true cond., firstly, remove occuranse of obstacle in the graph.
        /// </summary>
        /// <param name="obstacleGOToUpdate">GameObject-obstacle, for which you want to update the graph.</param>
        /// <param name="cancToken">Cancellation token for controll to async handeling</param>
        /// <param name="entitiesTasksToParallelize">List, you want to put handelling task in (if you want)</param>
        /// <param name="updateObstc">Is obstc graph updating for, already was handeled once.</param>
        public void UpdateGraphForObstacle(GameObject obstacleGOToUpdate, CancellationToken cancToken, bool updateObstc = false)
        {
            MeshCollider meshColliderInst = obstacleGOToUpdate.GetComponent <MeshCollider>();
            MeshFilter   meshFilterInst   = obstacleGOToUpdate.GetComponent <MeshFilter>();
            Terrain      terrainInst      = obstacleGOToUpdate.GetComponent <Terrain>();

            if (updateObstc)
            {
                SpaceGraph.ReleaseCellsFromObstcID(obstacleGOToUpdate.transform.GetInstanceID());
            }
            MeshDataContainer mDCInst = new MeshDataContainer()
            {
                gameObjectName = obstacleGOToUpdate.name,
                transformData  = obstacleGOToUpdate.transform,
                instanceID     = obstacleGOToUpdate.transform.GetInstanceID(),
                CTInstance     = cancToken
            };

            if (meshColliderInst && meshColliderInst.sharedMesh)
            {
                mDCInst.triangles = meshColliderInst.sharedMesh.triangles;
                mDCInst.vertices  = meshColliderInst.sharedMesh.vertices;
                HandleEntity(mDCInst, EntityType.Mesh);
            }

            if (meshFilterInst && meshFilterInst.sharedMesh)
            {
                mDCInst.triangles = meshFilterInst.sharedMesh.triangles;
                mDCInst.vertices  = meshFilterInst.sharedMesh.vertices;
                HandleEntity(mDCInst, EntityType.Mesh);
            }

            if (terrainInst)
            {
                float[,] hmArr = terrainInst.terrainData.GetHeights(0, 0, terrainInst.terrainData.heightmapResolution,
                                                                    terrainInst.terrainData.heightmapResolution);
                TerrainDataContainer tDCInst = new TerrainDataContainer()
                {
                    gameObjectName = obstacleGOToUpdate.name,
                    maxH           = terrainInst.terrainData.size.y,
                    hMArray        = hmArr,
                    hMWidth        = terrainInst.terrainData.heightmapResolution,
                    xStart         = 1,
                    xEnd           = terrainInst.terrainData.heightmapResolution,
                    zStart         = 1,
                    zEnd           = terrainInst.terrainData.heightmapResolution,
                    hX             = terrainInst.terrainData.size.x,
                    hZ             = terrainInst.terrainData.size.z,
                    terrainPos     = terrainInst.GetPosition(),
                    hMapScaleX     = terrainInst.terrainData.heightmapScale.x,
                    hMapScaleZ     = terrainInst.terrainData.heightmapScale.z,
                    instanceID     = terrainInst.transform.GetInstanceID(),
                    CTInstance     = cancToken
                };
                HandleEntity(tDCInst, EntityType.Terrain);
            }
        }
Example #2
0
        /// <summary>
        /// Performs the distribution of obstacle handeling into several subtasks for their further asynchronous execution.
        /// </summary>
        /// <param name="entityData">MeshDataContainer or TerrainDataContainer, packed as object.</param>
        /// <param name="entityType">Represent type of the <paramref name="entityData" /> to provide correct unpack from object type.</param>
        /// <param name="entitiesTasksToParallelize">List in which subtasks puts.</param>
        void HandleEntity(object entityData, EntityType entityType)
        {
            if (entityType == EntityType.Mesh)
            {
                MeshDataContainer mDCInst = ((MeshDataContainer)entityData).Clone();
                int tripletsNum           = Mathf.CeilToInt(((float)mDCInst.triangles.Length / 3) / maxAliveAsyncTasksCount);
                if (tripletsNum == 0)
                {
                    tripletsNum = 1;
                }
                while (mDCInst.triangles.Length > 0)
                {
                    int   trisIntsNum  = Mathf.Min(mDCInst.triangles.Length, tripletsNum * 3);
                    int[] distrTrisArr = mDCInst.triangles.Take(trisIntsNum).ToArray();
                    mDCInst.triangles = mDCInst.triangles.Skip(trisIntsNum).ToArray();

                    MeshDataContainer newMDCInst = ((MeshDataContainer)entityData).Clone();
                    newMDCInst.triangles = distrTrisArr;
                    asyncTasksQueue.Enqueue(new object[] { TaskType.Handling, entityType, newMDCInst });
                }
            }
            else
            {
                int xDelta, n;
                int hMWidth = ((TerrainDataContainer)entityData).hMWidth;
                if (maxAliveAsyncTasksCount == 1)
                {
                    xDelta = hMWidth;
                    n      = 1;
                }
                else
                {
                    xDelta = Mathf.CeilToInt((float)hMWidth / maxAliveAsyncTasksCount / 16);
                    n      = Mathf.CeilToInt((float)hMWidth / xDelta);
                }
                for (var i = 0; i < n; ++i)
                {
                    TerrainDataContainer tDCInst = ((TerrainDataContainer)entityData).Clone();
                    tDCInst.xStart = i * xDelta + 1;
                    tDCInst.xEnd   = Mathf.Min(i * xDelta + xDelta + 1, hMWidth);
                    asyncTasksQueue.Enqueue(new object[] { TaskType.Handling, entityType, tDCInst });
                }
            }
        }
Example #3
0
            public TerrainDataContainer Clone()
            {
                TerrainDataContainer cloneInstance = new TerrainDataContainer
                {
                    maxH           = this.maxH,
                    hMArray        = this.hMArray,
                    xStart         = this.xStart,
                    xEnd           = this.xEnd,
                    zStart         = this.zStart,
                    zEnd           = this.zEnd,
                    hX             = this.hX,
                    hZ             = this.hZ,
                    hMWidth        = this.hMWidth,
                    terrainPos     = new Vector3(this.terrainPos.x, this.terrainPos.y, this.terrainPos.z),
                    hMapScaleX     = this.hMapScaleX,
                    hMapScaleZ     = this.hMapScaleZ,
                    instanceID     = this.instanceID,
                    CTInstance     = this.CTInstance,
                    gameObjectName = this.gameObjectName
                };


                return(cloneInstance);
            }
Example #4
0
        /// <summary>
        /// Perfoms handeling of the terrain. Must be running asyncronously.
        /// </summary>
        /// <param name="inpData">Terrain to handle data, packed from MeshDataContainer instance.</param>
        void AsyncTerrainMethod(object inpData)
        {
            if (agressiveUseMultithreading)
            {
                Interlocked.Increment(ref aliveHandelingTasksCount);
            }
            TerrainDataContainer tDCInst = (TerrainDataContainer)inpData;
            int curTaskId = uniqeHandlingTaskID;

            Interlocked.Increment(ref uniqeHandlingTaskID);
            AsyncTaskDataContainer aTDCInstance = new AsyncTaskDataContainer
            {
                gameObjectName = tDCInst.gameObjectName,
                threadName     = Thread.CurrentThread.Name,
                uniqeTaskID    = curTaskId,
                trisCount      = (tDCInst.xEnd - tDCInst.xStart) * (tDCInst.zEnd - tDCInst.zStart) * 2,
                verticesCount  = tDCInst.hMArray.Length
            };

            aliveTasksDict.TryAdd(curTaskId, aTDCInstance);
            try
            {
                CancellationToken localCancToken = (CancellationToken)tDCInst.CTInstance;
                Vector3           p0, p1, p2, p3;
                int     step = 1;
                int     hMWidth = tDCInst.hMWidth;
                Vector3 terrPos = tDCInst.terrainPos;
                float   hZ = tDCInst.hZ;
                float   hX = tDCInst.hX;
                float[,] hMArray = tDCInst.hMArray;
                float maxH = tDCInst.maxH;
                for (var x = tDCInst.xStart; x < tDCInst.xEnd; x += step)
                {
                    if (broadcastCancToken.IsCancellationRequested || localCancToken.IsCancellationRequested)
                    {
                        return;
                    }
                    for (var z = tDCInst.zStart; z < tDCInst.zEnd; z += step)
                    {
                        p0 = new Vector3(((float)(z - step) / hMWidth) * hZ + terrPos.x,
                                         (hMArray[x - step, z - step] * maxH) + terrPos.y,
                                         ((float)(x - step) / hMWidth) * hX + terrPos.z);
                        p1 = new Vector3(((float)(z - step) / hMWidth) * hZ + terrPos.x,
                                         (hMArray[x, z - step] * maxH) + terrPos.y, ((float)x / hMWidth) * hX + terrPos.z);
                        p2 = new Vector3(((float)z / hMWidth) * hZ + terrPos.x, (hMArray[x - step, z] * maxH) + terrPos.y,
                                         ((float)(x - step) / hMWidth) * hX + terrPos.z);
                        p3 = new Vector3(((float)z / hMWidth) * hZ + terrPos.x, (hMArray[x, z] * maxH) + terrPos.y,
                                         ((float)x / hMWidth) * hX + terrPos.z);
                        OccupyCellsForATriangle(p0, p1, p2, tDCInst.instanceID);
                        OccupyCellsForATriangle(p1, p2, p3, tDCInst.instanceID);
                    }
                }
                aliveTasksDict.TryRemove(curTaskId, out aTDCInstance);
                Interlocked.Decrement(ref aliveHandelingTasksCount);
                if (!isPrimaryProcessingCompleted && processedTrisCount >= totalTrisCount && aliveHandelingTasksCount == 0)
                {
                    NotifyRediness();
                }
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.Log(ex.Message + " " + ex.StackTrace);
            }
        }