/// <summary> /// Clears the data /// </summary> public void UnloadData() { m_isManagerAlive = false; foreach (var map in m_trackedVoxelMaps) { map.Value.RangeChanged -= VoxelMapRangeChanged; } m_trackedVoxelMaps.Clear(); m_rdWrapper.Clear(); m_rdWrapper = null; m_navInputMesh.Clear(); m_navInputMesh = null; m_navmeshOBBs.Clear(); m_navmeshOBBs = null; m_obbCoordsToUpdate.Clear(); m_obbCoordsToUpdate = null; m_coordsAlreadyGenerated.Clear(); m_coordsAlreadyGenerated = null; m_obbCoordsPolygons.Clear(); m_obbCoordsPolygons = null; m_newObbCoordsPolygons.Clear(); m_newObbCoordsPolygons = null; m_polygons.Clear(); m_polygons = null; }
public void UnloadData() { this.m_isManagerAlive = false; foreach (KeyValuePair <long, MyVoxelMap> pair in this.m_trackedVoxelMaps) { pair.Value.RangeChanged -= new MyVoxelBase.StorageChanged(this.VoxelMapRangeChanged); } this.m_trackedVoxelMaps.Clear(); this.m_rdWrapper.Clear(); this.m_rdWrapper = null; this.m_navInputMesh.Clear(); this.m_navInputMesh = null; this.m_navmeshOBBs.Clear(); this.m_navmeshOBBs = null; this.m_obbCoordsToUpdate.Clear(); this.m_obbCoordsToUpdate = null; this.m_coordsAlreadyGenerated.Clear(); this.m_coordsAlreadyGenerated = null; this.m_obbCoordsPolygons.Clear(); this.m_obbCoordsPolygons = null; this.m_newObbCoordsPolygons.Clear(); this.m_newObbCoordsPolygons = null; this.m_polygons.Clear(); this.m_polygons = null; }
public MyNavmeshManager(MyRDPathfinding rdPathfinding, Vector3D center, Vector3D forwardDirection, int tileSize, int tileHeight, int tileLineCount, MyRecastOptions recastOptions) { Vector3 vector = new Vector3(ran.NextFloat(), ran.NextFloat(), ran.NextFloat()); vector -= Math.Min(vector.X, Math.Min(vector.Y, vector.Z)); vector /= Math.Max(vector.X, Math.Max(vector.Y, vector.Z)); this.m_debugColor = new Color(vector); this.m_tileSize = tileSize; this.m_tileHeight = tileHeight; this.m_tileLineCount = tileLineCount; this.Planet = this.GetPlanet(center); this.m_heightCoordTransformationIncrease = 0.5f; float cellSize = 0.2f; this.m_recastOptions = recastOptions; float num2 = (this.m_tileSize * 0.5f) + (this.m_tileSize * ((float)Math.Floor((double)(this.m_tileLineCount * 0.5f)))); float num3 = this.m_tileHeight * 0.5f; this.m_border = this.m_recastOptions.agentRadius + (3f * cellSize); float[] bMin = new float[] { -num2, -num3, -num2 }; float[] bMax = new float[] { num2, num3, num2 }; this.m_rdWrapper = new MyRDWrapper(); this.m_rdWrapper.Init(cellSize, (float)this.m_tileSize, bMin, bMax); Vector3D vectord = Vector3D.CalculatePerpendicularVector(-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center))); this.m_navmeshOBBs = new MyNavmeshOBBs(this.Planet, center, vectord, this.m_tileLineCount, this.m_tileSize, this.m_tileHeight); this.m_debugTileSize = new int?[this.m_tileLineCount][]; for (int i = 0; i < this.m_tileLineCount; i++) { this.m_debugTileSize[i] = new int?[this.m_tileLineCount]; } this.m_extendedBaseOBB = new MyOrientedBoundingBoxD(this.m_navmeshOBBs.BaseOBB.Center, new Vector3D(this.m_navmeshOBBs.BaseOBB.HalfExtent.X, (double)this.m_tileHeight, this.m_navmeshOBBs.BaseOBB.HalfExtent.Z), this.m_navmeshOBBs.BaseOBB.Orientation); this.m_navInputMesh = new MyNavigationInputMesh(rdPathfinding, this.Planet, center); }
public MyNavmeshManager(MyRDPathfinding rdPathfinding, Vector3D center, Vector3D forwardDirection, int tileSize, int tileHeight, int tileLineCount, MyRecastOptions recastOptions) { m_tileSize = tileSize; m_tileHeight = tileHeight; m_tileLineCount = tileLineCount; Planet = GetPlanet(center); m_heightCoordTransformationIncrease = 0.5f; float cellSize = RECAST_CELL_SIZE; m_recastOptions = recastOptions; float horizontalOrigin = (m_tileSize * 0.5f + m_tileSize * (float)Math.Floor(m_tileLineCount * 0.5f)); var verticalOrigin = m_tileHeight * 0.5f; m_border = m_recastOptions.agentRadius + 3 * cellSize; float[] bmin = new float[3] { -horizontalOrigin, -verticalOrigin, -horizontalOrigin }; float[] bmax = new float[3] { horizontalOrigin, verticalOrigin, horizontalOrigin }; m_rdWrapper = new MyRDWrapper(); m_rdWrapper.Init(cellSize, m_tileSize, bmin, bmax); Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); var direction = Vector3D.CalculatePerpendicularVector(gravityVector); m_navmeshOBBs = new MyNavmeshOBBs(Planet, center, direction, m_tileLineCount, m_tileSize, m_tileHeight); m_debugTileSize = new int?[m_tileLineCount][]; for (int i = 0; i < m_tileLineCount; i++) { m_debugTileSize[i] = new int?[m_tileLineCount]; } m_extendedBaseOBB = new MyOrientedBoundingBoxD(m_navmeshOBBs.BaseOBB.Center, new Vector3D(m_navmeshOBBs.BaseOBB.HalfExtent.X, m_tileHeight, m_navmeshOBBs.BaseOBB.HalfExtent.Z), m_navmeshOBBs.BaseOBB.Orientation); m_navInputMesh = new MyNavigationInputMesh(rdPathfinding, Planet, center); }
public void InitializeNavmesh(Vector3D center) { this.m_isNavmeshInitialized = true; float cellSize = 0.2f; this.m_singleTileSize = 20; this.m_tileLineCount = 50; this.m_singleTileHeight = 70; MyRecastOptions options1 = new MyRecastOptions(); options1.cellHeight = 0.2f; options1.agentHeight = 1.5f; options1.agentRadius = 0.5f; options1.agentMaxClimb = 0.5f; options1.agentMaxSlope = 50f; options1.regionMinSize = 1f; options1.regionMergeSize = 10f; options1.edgeMaxLen = 50f; options1.edgeMaxError = 3f; options1.vertsPerPoly = 6f; options1.detailSampleDist = 6f; options1.detailSampleMaxError = 1f; options1.partitionType = 1; this.m_recastOptions = options1; float num2 = (this.m_singleTileSize * 0.5f) + (this.m_singleTileSize * ((float)Math.Floor((double)(this.m_tileLineCount * 0.5f)))); float num3 = this.m_singleTileHeight * 0.5f; this.m_border = this.m_recastOptions.agentRadius + (3f * cellSize); float[] bMin = new float[] { -num2, -num3, -num2 }; float[] bMax = new float[] { num2, num3, num2 }; this.rdWrapper = new MyRDWrapper(); this.rdWrapper.Init(cellSize, (float)this.m_singleTileSize, bMin, bMax); Vector3D forwardDirection = Vector3D.CalculatePerpendicularVector(-Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(center))); this.UnloadData(); this.m_navmeshOBBs = new MyNavmeshOBBs(this.GetPlanet(center), center, forwardDirection, this.m_tileLineCount, this.m_singleTileSize, this.m_singleTileHeight); this.m_meshCenter = center; this.m_visualNavmesh.Clear(); }
//private NavmeshOBBs m_navmeshOBBs; #region NavmeshOBBs class /* // TODO: class should have a datastructure to encapsulate OBB with their coordinate and gravity vector /// <summary> /// Class that contains navmesh OBBs /// The middle of the matrix has 0,0 (x,y) coordinate, left is -x, bottom is -y /// ATTENTION -> the above is not true anymore -> search for the truth /// </summary> private class NavmeshOBBs { #region Fields private MyOrientedBoundingBox?[][] m_obbs; private float m_tileHalfSize, m_tileHalfHeight; Vector3D m_centerPoint; #endregion public int OBBsPerLine { get; private set; } #region Contructor // TODO: accept a rotation so we define what is front,back,left, right.... // or maybe notttttt public NavmeshOBBs(Vector3D centerPoint, int obbsPerLine, int tileSize, int tileHeight) { // There will always be an odd number of obbs in a line OBBsPerLine = obbsPerLine; if (OBBsPerLine % 2 == 0) OBBsPerLine += 1; m_tileHalfSize = tileSize * 0.5f; m_tileHalfHeight = tileHeight * 0.5f; m_centerPoint = centerPoint; m_obbs = new MyOrientedBoundingBox?[OBBsPerLine][]; for (int i = 0; i < OBBsPerLine; i++) m_obbs[i] = new MyOrientedBoundingBox?[OBBsPerLine]; Initialize(); } #endregion #region public Methods /// <summary> /// Return the OBB at the specific coordinate or null, if is out of bounds /// </summary> public MyOrientedBoundingBox? GetOBB(int coordX, int coordY) { if (coordX < 0 || coordX >= OBBsPerLine || coordY < 0 || coordY >= OBBsPerLine) return null; return m_obbs[coordY][coordX]; } public MyOrientedBoundingBox? GetOBB(Vector3D worldPosition) { // TODO: silly search needs to get smarter foreach (var obbLine in m_obbs) foreach(var obb in obbLine) { Vector3D diff = obb.Value.Center - worldPosition; if (Math.Abs(diff.X) <= obb.Value.HalfExtent.X && Math.Abs(diff.Y) <= obb.Value.HalfExtent.Y && Math.Abs(diff.Z) <= obb.Value.HalfExtent.Z) return obb; } return null; } /// <summary> /// TEMPORARY - Returns the coords for the OBB - remove this after creating a data structure to encapsulate... /// </summary> public bool GetCoords(MyOrientedBoundingBoxD obb, out int xCoord, out int yCoord) { xCoord = yCoord = -1; for (int i = 0; i < m_obbs.Length; i++) for (int j = 0; j < m_obbs[0].Length; j++) if (obb == m_obbs[i][j]) { xCoord = j; yCoord = i; return true; } return false; } /// <summary> /// Returns a list of OBBs intersected by a line /// </summary> public List<MyOrientedBoundingBoxD> GetIntersectedOBB(Line line) { //List<MyOrientedBoundingBoxD> intersectedOBBs = new List<MyOrientedBoundingBoxD>(); Dictionary<MyOrientedBoundingBox, float> intersectedOBBs = new Dictionary<MyOrientedBoundingBox, float>(); foreach (var obbLine in m_obbs) foreach (var obb in obbLine) if (obb.Value.Contains(ref line.From) || obb.Value.Contains(ref line.To) || obb.Value.Intersects(ref line).HasValue) //intersectedOBBs.Add(obb.Value); intersectedOBBs.Add(obb.Value, Vector3D.Distance(line.From, obb.Value.Center)); //if (intersectedOBBs.Count > 0) // ; return intersectedOBBs.OrderBy(d => d.Value).Select(kvp => kvp.Key).ToList(); } #endregion #region Private Methods private void Initialize() { /* MyOBBs corners * 00 - Upper Front Left <-- * 01 - Upper Back Left <-- * 02 - Lower Back Left * 03 - Lower Front Left * 04 - Upper Front Right <-- * 05 - Upper Back Right <-- * 06 - Lower Back Right * 07 - Lower Front Right */ /* // TODO: use GetOBBCorners int middleCoord = (OBBsPerLine - 1) / 2; MyOrientedBoundingBoxD obb = CreateOBB(m_centerPoint); m_obbs[middleCoord][middleCoord] = obb; Vector3[] corners = new Vector3[8]; obb.GetCorners(corners, 0); Vector3D offset = corners[4]; Vector3D newGravity = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(offset)); Vector3D newPoint = Vector3D.Transform(m_centerPoint - offset, Quaternion.CreateFromAxisAngle(newGravity, (float)(-90 * Math.PI / 180f))); Vector3D centerHorizontalDiff = newPoint - (m_centerPoint - offset); // // // For each point, calculate up and down points // Vector3D newCenter = m_centerPoint; Vector2I index = new Vector2I(middleCoord,middleCoord); for (int i = middleCoord; i >= 0; i--) { FillOBBLine(newCenter, index); newCenter -= centerHorizontalDiff; index += new Vector2I(-1,0); } newCenter = m_centerPoint; index.X = index.Y = middleCoord; for (int i = middleCoord + 1; i < OBBsPerLine; i++) { newCenter += centerHorizontalDiff; index += new Vector2I(1, 0); FillOBBLine(newCenter, index); } } private void FillOBBLine(Vector3D center, Vector2I currentIndex) { Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); Vector3D perpedicularVector = Vector3D.CalculatePerpendicularVector(gravityVector); MyOrientedBoundingBoxD obb = new MyOrientedBoundingBox(center, new Vector3(m_tileHalfSize, m_tileHalfHeight, m_tileHalfSize), Quaternion.CreateFromForwardUp(perpedicularVector, gravityVector)); if (m_obbs[currentIndex.Y][currentIndex.X] == null) m_obbs[currentIndex.Y][currentIndex.X] = obb; Vector3[] corners = new Vector3[8]; obb.GetCorners(corners, 0); Vector3D offset = corners[1]; Vector3D newGravity = -Vector3D.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(offset)); Vector3D newPoint = Vector3D.Transform(center - offset, Quaternion.CreateFromAxisAngle(newGravity, (float)(90 * Math.PI / 180f))); Vector3D centerVerticalDiff = newPoint - (center - offset); FillOBBSemiLine(center, centerVerticalDiff, currentIndex, new Vector2I(0, -1)); FillOBBSemiLine(center, -centerVerticalDiff, currentIndex, new Vector2I(0, 1)); } private void FillOBBSemiLine(Vector3D currentCenter, Vector3D diffVector, Vector2I currentIndex, Vector2I indexAddition) { if (currentIndex.X < 0 || currentIndex.X >= OBBsPerLine || currentIndex.Y < 0 || currentIndex.Y >= OBBsPerLine) return; if(m_obbs[currentIndex.Y][currentIndex.X] == null) m_obbs[currentIndex.Y][currentIndex.X] = CreateOBB(currentCenter); FillOBBSemiLine(currentCenter + diffVector, diffVector, currentIndex + indexAddition, indexAddition); } private MyOrientedBoundingBoxD CreateOBB(Vector3D center) { Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); Vector3D perpedicularVector = Vector3D.CalculatePerpendicularVector(gravityVector); return new MyOrientedBoundingBox(center, new Vector3(m_tileHalfSize, m_tileHalfHeight, m_tileHalfSize), Quaternion.CreateFromForwardUp(perpedicularVector, gravityVector)); } #endregion } */ #endregion public void InitializeNavmesh(Vector3D center) { m_isNavmeshInitialized = true; float cellSize = 0.2f; m_singleTileSize = 20; m_tileLineCount = 50; m_singleTileHeight = 70; //m_semiColumnCount = ((m_singleTileHeight / m_singleTileSize) - 1) / 2; m_recastOptions = new MyRecastOptions() { cellHeight = 0.2f, agentHeight = 1.5f, agentRadius = 0.5f, agentMaxClimb = 0.5f, agentMaxSlope = 50, regionMinSize = 1, regionMergeSize = 10, edgeMaxLen = 50, edgeMaxError = 3f, vertsPerPoly = 6, detailSampleDist = 6, detailSampleMaxError = 1, partitionType = 1 }; float horizontalOrigin = (m_singleTileSize * 0.5f + m_singleTileSize * (float)Math.Floor(m_tileLineCount * 0.5f)); var verticalOrigin = m_singleTileHeight * 0.5f; m_border = m_recastOptions.agentRadius + 3 * cellSize; float[] bmin = new float[3] { -horizontalOrigin, -verticalOrigin, -horizontalOrigin }; float[] bmax = new float[3] { horizontalOrigin, verticalOrigin, horizontalOrigin }; rdWrapper = new MyRDWrapper(); rdWrapper.Init(cellSize, m_singleTileSize, bmin, bmax); //Vector3D direction = MySession.Static.ControlledEntity.ControllerInfo.Controller.Player.Character.WorldMatrix.Forward; Vector3D gravityVector = -Vector3D.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(center)); var direction = Vector3D.CalculatePerpendicularVector(gravityVector); UnloadData(); m_navmeshOBBs = new MyNavmeshOBBs(GetPlanet(center), center, direction, m_tileLineCount, m_singleTileSize, m_singleTileHeight); // TODO: m_meshCenter is used for pathfinding position transformation -> probably use the center point of the OBB m_meshCenter = center; // To get the center point difference //var planet = GetPlanet(center); //int halfMaxSize = (int)(m_singleTileSize / 2f); //MyNavigationInputMesh.RefreshCache(); m_visualNavmesh.Clear(); }