/// <summary> /// Adds the file the be generation, if it wasn't generated before. /// </summary> /// <param name="obbCoord"></param> /// <returns>True if it was added to the list of the tiles to be generated</returns> private bool AddTileToGeneration(MyNavmeshOBBs.OBBCoords obbCoord) { if (!m_coordsAlreadyGenerated.Contains(obbCoord.Coords)) { return(m_obbCoordsToUpdate.Add(obbCoord)); } return(false); }
private unsafe void GenerateTile(MyNavmeshOBBs.OBBCoords obbCoord) { MyOrientedBoundingBoxD oBB = obbCoord.OBB; Vector3 pos = (Vector3)this.WorldPositionToLocalNavmeshPosition(oBB.Center, 0f); List <BoundingBoxD> boundingBoxes = new List <BoundingBoxD>(); MyNavigationInputMesh.WorldVerticesInfo info = this.m_navInputMesh.GetWorldVertices(this.m_border, this.Center, oBB, boundingBoxes, this.m_tmpTrackedVoxelMaps); this.m_groundCaptureAABBs = boundingBoxes; foreach (MyVoxelMap map in this.m_tmpTrackedVoxelMaps) { if (!this.m_trackedVoxelMaps.ContainsKey(map.EntityId)) { map.RangeChanged += new MyVoxelBase.StorageChanged(this.VoxelMapRangeChanged); this.m_trackedVoxelMaps.Add(map.EntityId, map); } } this.m_tmpTrackedVoxelMaps.Clear(); if (info.Triangles.Count <= 0) { this.m_newObbCoordsPolygons[obbCoord.Coords] = null; } else { Vector3 *vectorPtr; Vector3[] pinned vectorArray; int *numPtr2; int[] pinned numArray; if (((vectorArray = info.Vertices.GetInternalArray <Vector3>()) == null) || (vectorArray.Length == 0)) { vectorPtr = null; } else { vectorPtr = vectorArray; } float *vertices = (float *)vectorPtr; if (((numArray = info.Triangles.GetInternalArray <int>()) == null) || (numArray.Length == 0)) { numPtr2 = null; } else { numPtr2 = numArray; } this.m_rdWrapper.CreateNavmeshTile(pos, ref this.m_recastOptions, ref this.m_polygons, obbCoord.Coords.X, obbCoord.Coords.Y, 0, vertices, info.Vertices.Count, numPtr2, info.Triangles.Count / 3); numArray = null; vectorArray = null; this.GenerateDebugDrawPolygonNavmesh(this.Planet, this.m_polygons, this.m_navmeshOBBs.CenterOBB, obbCoord.Coords); this.GenerateDebugTileDataSize(pos, obbCoord.Coords.X, obbCoord.Coords.Y); if (this.m_polygons != null) { this.m_polygons.Clear(); this.m_updateDrawMesh = true; } } this.m_navmeshTileGenerationRunning = false; }
private void GenerateNextQueuedTile() { if (!this.m_navmeshTileGenerationRunning && this.TilesAreWaitingGeneration) { this.m_navmeshTileGenerationRunning = true; MyNavmeshOBBs.OBBCoords obb = this.m_obbCoordsToUpdate.First <MyNavmeshOBBs.OBBCoords>(); this.m_obbCoordsToUpdate.Remove(obb); this.m_coordsAlreadyGenerated.Add(obb.Coords); Parallel.Start(() => this.GenerateTile(obb)); } }
private bool TryGenerateNeighbourTiles(MyNavmeshOBBs.OBBCoords obbCoord, int radius = 1) { int num = 0; bool flag = false; int num2 = -radius; while (num2 <= radius) { int num1; if ((num2 == -radius) || (num2 == radius)) { num1 = 1; } else { num1 = 2 * radius; } int num3 = num1; int num4 = -radius; while (true) { Vector2I vectori; if (num4 > radius) { num2++; break; } vectori.X = obbCoord.Coords.X + num4; vectori.Y = obbCoord.Coords.Y + num2; MyNavmeshOBBs.OBBCoords?oBBCoord = this.m_navmeshOBBs.GetOBBCoord(vectori.X, vectori.Y); if (oBBCoord != null) { flag = true; if (this.AddTileToGeneration(oBBCoord.Value) && ((num + 1) >= 7)) { return(true); } } num4 += num3; } } if (num > 0) { return(true); } this.m_allTilesGenerated = !flag; return(!this.m_allTilesGenerated ? this.TryGenerateNeighbourTiles(obbCoord, radius + 1) : false); }
/// <summary> /// Generate tiles around the obbCoord. Each time, a bigger "circle" around it. /// </summary> /// <param name="obbCoord"></param> /// <param name="radius"></param> /// <returns></returns> private bool TryGenerateNeighbourTiles(MyNavmeshOBBs.OBBCoords obbCoord, int radius = 1) { int tilesAddedToGeneration = 0; bool validTiles = false; Vector2I newCoord; for (int i = -radius; i <= radius; i++) { // Get the neigbour tiles int jump = i == -radius || i == radius ? 1 : 2 * radius; for (int j = -radius; j <= radius; j += jump) { newCoord.X = obbCoord.Coords.X + j; newCoord.Y = obbCoord.Coords.Y + i; var surroundingOBBCoord = m_navmeshOBBs.GetOBBCoord(newCoord.X, newCoord.Y); if (surroundingOBBCoord.HasValue) { validTiles = true; if (AddTileToGeneration(surroundingOBBCoord.Value)) { tilesAddedToGeneration++; if (tilesAddedToGeneration >= MAX_TILES_TO_GENERATE) { return(true); } } } } } if (tilesAddedToGeneration > 0) { return(true); } m_allTilesGenerated = !validTiles; if (m_allTilesGenerated) { return(false); } else { return(TryGenerateNeighbourTiles(obbCoord, radius + 1)); } }
/// <summary> /// Generates a navmesh tile /// </summary> /// <param name="obbCoord"></param> private void GenerateTile(MyNavmeshOBBs.OBBCoords obbCoord) { ProfilerShort.Begin("LET THERE BE TILE!"); var obb = obbCoord.OBB; Vector3 localCenter = WorldPositionToLocalNavmeshPosition(obb.Center, 0); ProfilerShort.Begin("GetWorldVertices!!!"); List <BoundingBoxD> bbs = new List <BoundingBoxD>(); var worldVertices = m_navInputMesh.GetWorldVertices(m_border, Center, obb, bbs, m_tmpTrackedVoxelMaps); m_groundCaptureAABBs = bbs; foreach (var map in m_tmpTrackedVoxelMaps) { if (!m_trackedVoxelMaps.ContainsKey(map.EntityId)) { map.RangeChanged += VoxelMapRangeChanged; m_trackedVoxelMaps.Add(map.EntityId, map); } } m_tmpTrackedVoxelMaps.Clear(); ProfilerShort.End(); if (worldVertices.Triangles.Count > 0) { unsafe { fixed(Vector3 *vertices = worldVertices.Vertices.GetInternalArray()) { float *verticesPointer = (float *)vertices; fixed(int *trianglesPointer = worldVertices.Triangles.GetInternalArray()) { ProfilerShort.Begin("GrdWrapper.CreateNavmeshTile CALL"); m_rdWrapper.CreateNavmeshTile(localCenter, ref m_recastOptions, ref m_polygons, obbCoord.Coords.X, obbCoord.Coords.Y, 0, verticesPointer, worldVertices.Vertices.Count, trianglesPointer, worldVertices.Triangles.Count / 3); //Gets the triangles mesh that is sent to Recast //m_rdWrapper.DebugGetPolygonsFromInputTriangles(verticesPointer, worldVertices.Vertices.Count, trianglesPointer, worldVertices.Triangles.Count / 3, m_polygons); ProfilerShort.End(); } } } ProfilerShort.Begin("GenerateDebugDrawPolygonNavmesh"); GenerateDebugDrawPolygonNavmesh(Planet, m_polygons, m_navmeshOBBs.CenterOBB, obbCoord.Coords); ProfilerShort.End(); GenerateDebugTileDataSize(localCenter, obbCoord.Coords.X, obbCoord.Coords.Y); if (m_polygons != null) { m_polygons.Clear(); m_updateDrawMesh = true; } } else { m_newObbCoordsPolygons[obbCoord.Coords] = null; } m_navmeshTileGenerationRunning = false; ProfilerShort.End(); }
private bool AddTileToGeneration(MyNavmeshOBBs.OBBCoords obbCoord) => (!this.m_coordsAlreadyGenerated.Contains(obbCoord.Coords) && this.m_obbCoordsToUpdate.Add(obbCoord));