/// <summary> /// Steps through all Tile objects in the level and generates a nave mesh from it. /// </summary> /// <param name="level"></param> public void CreateNavMesh(GameObject.GameObject level) { // The gets used over and over again throughout the life if this object. level.OnMessage(mGetMapInfoMsg); Int32 mapWidth = mGetMapInfoMsg.mInfo_Out.mMapWidth; Int32 mapHeight = mGetMapInfoMsg.mInfo_Out.mMapHeight; Int32 tileWidth = mGetMapInfoMsg.mInfo_Out.mTileWidth; Int32 tileHeight = mGetMapInfoMsg.mInfo_Out.mTileHeight; // Clusters get indexed based on their X, Y positions in the world. mClusters = new Cluster[mapWidth / mClusterSize, mapHeight / mClusterSize]; // Loop through Cluster by Cluster initializing them. for (Int32 y = 0; y < mClusters.GetLength(1); y++) { for (Int32 x = 0; x < mClusters.GetLength(0); x++) { Cluster temp = new Cluster(mClusterSize, tileWidth, tileHeight); mGetTileAtPositionMsg.mPosition_In.X = x * (tileWidth * mClusterSize); mGetTileAtPositionMsg.mPosition_In.Y = y * (tileHeight * mClusterSize); level.OnMessage(mGetTileAtPositionMsg); // The top left tile becomes a handy spot to start iterations over all Tile objects // in a Cluster. temp.pTopLeft = mGetTileAtPositionMsg.mTile_Out; // Link Left <-> Right if (x > 0) { temp.pNeighbouringClusters[(Int32)Cluster.AdjacentClusterDirections.Left] = mClusters[x - 1, y]; mClusters[x - 1, y].pNeighbouringClusters[(Int32)Cluster.AdjacentClusterDirections.Right] = temp; } // Link Up <-> Down if (y > 0) { temp.pNeighbouringClusters[(Int32)Cluster.AdjacentClusterDirections.Up] = mClusters[x, y - 1]; mClusters[x, y - 1].pNeighbouringClusters[(Int32)Cluster.AdjacentClusterDirections.Down] = temp; } // Only walk the top and left walls for each cluster. The neighbouring clusters will do the same // and as a result all walls will have been evaluated. WalkWall(temp, temp.pTopLeft, null, Level.Tile.AdjacentTileDir.RIGHT, Level.Tile.AdjacentTileDir.UP, Cluster.AdjacentClusterDirections.Up); WalkWall(temp, temp.pTopLeft, null, Level.Tile.AdjacentTileDir.DOWN, Level.Tile.AdjacentTileDir.LEFT, Cluster.AdjacentClusterDirections.Left); // Store the cluster in the array index relative to its position in the world. mClusters[x, y] = temp; } } // At this point all intra-connections have been made (cluster crossing connections), so now we need to // make all inter-connections (nodes linked inside of a cluster). We have to wait till now since the WallWalk // done above only does 2 sides at a time. for (Int32 y = 0; y < mClusters.GetLength(1); y++) { for (Int32 x = 0; x < mClusters.GetLength(0); x++) { Cluster temp = mClusters[x, y]; LinkClusterGraphNodes(temp); } } }