private void ReadOctreeLeaf(Stream stream, ChunkHeader header, ref bool isOldFormat, MyStorageDataTypeEnum dataType, out UInt64 key, out MyMicroOctreeLeaf contentLeaf) { Debug.Assert( header.ChunkType == ChunkTypeEnum.ContentLeafOctree || header.ChunkType == ChunkTypeEnum.MaterialLeafOctree); MyCellCoord cellCoord = new MyCellCoord(); if (header.Version <= VERSION_OCTREE_LEAVES_32BIT_KEY) { UInt32 oldKey = stream.ReadUInt32(); cellCoord.SetUnpack(oldKey); key = cellCoord.PackId64(); header.Size -= sizeof(UInt32); isOldFormat = true; } else { Debug.Assert(header.Version == CURRENT_VERSION_OCTREE_LEAVES); key = stream.ReadUInt64(); cellCoord.SetUnpack(key); header.Size -= sizeof(UInt64); } contentLeaf = new MyMicroOctreeLeaf(dataType, LeafLodCount, cellCoord.CoordInLod << (cellCoord.Lod + LeafLodCount)); contentLeaf.ReadFrom(header, stream); }
internal void UpdateCellsInScene(float cameraDistance, Vector3D localPosition) { LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); MyCellCoord thisLodCell = new MyCellCoord(); foreach (var entry in m_nonEmptyCells) { var data = entry.Value; Debug.Assert(data.Cell != null, "Empty cell in m_nonEmptyCells!"); if (data.Cell != null) { thisLodCell.SetUnpack(entry.Key); if (ChildrenWereLoaded(childLod, ref thisLodCell) || (MyVoxelCoordSystems.RenderCellSizeShiftToLessDetailed(thisLodCell.Lod) == 1 && !AllSiblingsWereLoaded(ref thisLodCell)) || !ShouldBeThisLodVisible(cameraDistance) ) { RemoveFromScene(entry.Key, data); } else { AddToScene(entry.Key, data); } } } }
internal unsafe void DebugDraw(VRageRender.MyDebugDrawBatchAABB batch, Vector3 worldPos, MyVoxelDebugDrawMode mode) { switch (mode) { case MyVoxelDebugDrawMode.Content_MicroNodes: foreach (var entry in m_nodes) { Vector3I childOffset; BoundingBoxD bb; MyCellCoord cell = new MyCellCoord(); cell.SetUnpack(entry.Key); var data = entry.Value; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { if (data.HasChild(i) && cell.Lod != 0) { continue; } ComputeChildCoord(i, out childOffset); var childPos = (cell.CoordInLod << (cell.Lod + 1)) + (childOffset << cell.Lod); bb.Min = worldPos + childPos * MyVoxelConstants.VOXEL_SIZE_IN_METRES; bb.Max = bb.Min + MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << cell.Lod); batch.Add(ref bb); } } break; case MyVoxelDebugDrawMode.Content_MicroNodesScaled: foreach (var entry in m_nodes) { MyCellCoord cell = new MyCellCoord(); Vector3I childOffset; BoundingBoxD bb; cell.SetUnpack(entry.Key); var data = entry.Value; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { if (data.HasChild(i)) { continue; } ComputeChildCoord(i, out childOffset); float ratio = data.GetData(i) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT; if (ratio == 0f) { continue; } ratio = (float)Math.Pow((double)ratio * MyVoxelConstants.VOXEL_VOLUME_IN_METERS, 0.3333); var childPos = (cell.CoordInLod << (cell.Lod + 1)) + (childOffset << cell.Lod); var lodSize = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << cell.Lod); var center = worldPos + childPos * MyVoxelConstants.VOXEL_SIZE_IN_METRES + 0.5f * lodSize; bb.Min = center - 0.5f * ratio * lodSize; bb.Max = center + 0.5f * ratio * lodSize; batch.Add(ref bb); } } break; } }
private void RemoveExplored(ulong packedCoord) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(packedCoord); this.m_exploredCells.Remove(ref coord.CoordInLod); }
public void Submit() { ProfilerShort.Begin("RequestCollector.Submit"); MyCellCoord cell = default(MyCellCoord); int count = MaxRequestPerBatch; while (m_unsentRequests.Count > 0 && count > 0) { var request = m_unsentRequests.Dequeue(); m_sentRequests.Add(request.CellId); cell.SetUnpack(request.CellId); MyRenderProxy.RequireClipmapCell(m_clipmapId, cell, request.Data.GetPriority); request.Data.State = CellState.Pending; count--; } m_unsentRequests.Clear(); ProfilerShort.End(); }
public IMyHighLevelComponent GetComponent(MyHighLevelPrimitive primitive) { ulong num; Base6Directions.DirectionFlags flags; if (!this.m_navmeshComponents.GetComponentCell(primitive.Index, out num)) { return(null); } if (!this.m_navmeshComponents.GetComponentInfo(primitive.Index, num, out flags)) { return(null); } MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(num); foreach (Base6Directions.Direction direction in Base6Directions.EnumDirections) { Base6Directions.DirectionFlags directionFlag = Base6Directions.GetDirectionFlag(direction); if (!flags.HasFlag(directionFlag)) { Vector3I position = (Vector3I)(coord.CoordInLod + Base6Directions.GetIntVector(direction)); if (this.m_exploredCells.Contains(ref position)) { flags |= directionFlag; } } } return(new Component(primitive.Index, flags)); }
private static void DrawSparseOctrees(ref Matrix worldMatrix, Color color, MyVoxelDebugDrawMode mode, Dictionary <UInt64, IMyOctreeLeafNode> octree) { var camera = Sandbox.Game.World.MySector.MainCamera; if (camera == null) { return; } var targetPoint = camera.Position + camera.ForwardVector * 10; targetPoint = (Vector3)Vector3D.Transform(targetPoint, MatrixD.Invert(worldMatrix)); using (var batch = VRageRender.MyRenderProxy.DebugDrawBatchAABB(worldMatrix, color, true, true)) { MyCellCoord cell = new MyCellCoord(); foreach (var entry in octree) { var leaf = entry.Value as MyMicroOctreeLeaf; if (leaf != null) { cell.SetUnpack(entry.Key); Vector3D min = (cell.CoordInLod << LeafLodCount) * MyVoxelConstants.VOXEL_SIZE_IN_METRES; Vector3D max = min + LeafSizeInVoxels * MyVoxelConstants.VOXEL_SIZE_IN_METRES; if (targetPoint.IsInsideInclusive(ref min, ref max)) { leaf.DebugDraw(batch, min, mode); } } } } }
private void ReadProviderLeaf(Stream stream, ChunkHeader header, ref bool isOldFormat, HashSet <UInt64> outKeySet) { Debug.Assert( header.ChunkType == ChunkTypeEnum.MaterialLeafProvider || header.ChunkType == ChunkTypeEnum.ContentLeafProvider); UInt64 key; if (header.Version <= VERSION_OCTREE_LEAVES_32BIT_KEY) { UInt32 oldKey = stream.ReadUInt32(); MyCellCoord cell = new MyCellCoord(); cell.SetUnpack(oldKey); key = cell.PackId64(); header.Size -= sizeof(UInt32); isOldFormat = true; } else { Debug.Assert(header.Version == CURRENT_VERSION_OCTREE_LEAVES); key = stream.ReadUInt64(); header.Size -= sizeof(UInt64); } Debug.Assert(!outKeySet.Contains(key)); outKeySet.Add(key); Debug.Assert(header.Size == 0 || header.Version == 1, "All versions except 1 should have 0 size of provider leaf chunk."); stream.SkipBytes(header.Size); }
private static void DrawNodes(ref Matrix worldMatrix, Color color, Dictionary <UInt64, MyOctreeNode> octree) { using (var batch = MyRenderProxy.DebugDrawBatchAABB(worldMatrix, color, true, true)) { MyCellCoord cell = new MyCellCoord(); foreach (var entry in octree) { cell.SetUnpack(entry.Key); cell.Lod += LeafLodCount; var data = entry.Value; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { if (data.HasChild(i)) { continue; } Vector3I childOffset; ComputeChildCoord(i, out childOffset); var voxelPos = (cell.CoordInLod << (cell.Lod + 1)) + (childOffset << cell.Lod); var lodSize = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << cell.Lod); var center = voxelPos * MyVoxelConstants.VOXEL_SIZE_IN_METRES + 0.5f * lodSize; BoundingBoxD bb = new BoundingBoxD( center - 0.5f * lodSize, center + 0.5f * lodSize); batch.Add(ref bb); } } } }
public void DebugDraw() { if (MyFakes.DEBUG_DRAW_NAVMESH_EXPLORED_HL_CELLS) { foreach (var cell in m_exploredCells) { BoundingBoxD cellAABB; Vector3I cellCopy = cell; MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(m_mesh.VoxelMapReferencePosition, ref cellCopy, out cellAABB); VRageRender.MyRenderProxy.DebugDrawAABB(cellAABB, Color.Sienna, 1.0f, 1.0f, false); } } if (MyFakes.DEBUG_DRAW_NAVMESH_FRINGE_HL_CELLS) { foreach (var packedCoord in m_navmeshComponents.GetPresentCells()) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(packedCoord); Vector3I cellCoord = coord.CoordInLod; if (m_exploredCells.Contains(ref cellCoord)) { MyNavmeshComponents.CellInfo cellInfo = new MyNavmeshComponents.CellInfo(); if (m_navmeshComponents.TryGetCell(packedCoord, out cellInfo)) { for (int i = 0; i < cellInfo.ComponentNum; ++i) { int componentIndex = cellInfo.StartingIndex + i; var primitive = m_mesh.HighLevelGroup.GetPrimitive(componentIndex); foreach (var direction in Base6Directions.EnumDirections) { var dirFlag = Base6Directions.GetDirectionFlag(direction); if (cellInfo.ExploredDirections.HasFlag(dirFlag)) { continue; } if (m_exploredCells.Contains(cellCoord + Base6Directions.GetIntVector(direction))) { continue; } Vector3 dirVec = Base6Directions.GetVector(direction); VRageRender.MyRenderProxy.DebugDrawLine3D(primitive.WorldPosition, primitive.WorldPosition + dirVec * 3.0f, Color.Red, Color.Red, false); } } } } } } }
public void CheckConsistency() { if (DO_CONSISTENCY_CHECKS) { MyCellCoord coord = new MyCellCoord(); foreach (KeyValuePair <ulong, MyIntervalList> pair in this.m_triangleLists) { coord.SetUnpack(pair.Key); } } }
public void DebugDraw() { if (MyFakes.DEBUG_DRAW_NAVMESH_EXPLORED_HL_CELLS) { foreach (Vector3I vectori in this.m_exploredCells) { BoundingBoxD xd; MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(this.m_mesh.VoxelMapReferencePosition, ref vectori, out xd); MyRenderProxy.DebugDrawAABB(xd, Color.Sienna, 1f, 1f, false, false, false); } } if (MyFakes.DEBUG_DRAW_NAVMESH_FRINGE_HL_CELLS) { foreach (ulong num in this.m_navmeshComponents.GetPresentCells()) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(num); Vector3I coordInLod = coord.CoordInLod; if (this.m_exploredCells.Contains(ref coordInLod)) { MyNavmeshComponents.CellInfo cellInfo = new MyNavmeshComponents.CellInfo(); if (this.m_navmeshComponents.TryGetCell(num, out cellInfo)) { int num2 = 0; while (num2 < cellInfo.ComponentNum) { int index = cellInfo.StartingIndex + num2; MyHighLevelPrimitive primitive = this.m_mesh.HighLevelGroup.GetPrimitive(index); Base6Directions.Direction[] enumDirections = Base6Directions.EnumDirections; int num4 = 0; while (true) { if (num4 >= enumDirections.Length) { num2++; break; } Base6Directions.Direction dir = enumDirections[num4]; Base6Directions.DirectionFlags directionFlag = Base6Directions.GetDirectionFlag(dir); if (!cellInfo.ExploredDirections.HasFlag(directionFlag) && !this.m_exploredCells.Contains((Vector3I)(coordInLod + Base6Directions.GetIntVector(dir)))) { Vector3 vector = Base6Directions.GetVector(dir); MyRenderProxy.DebugDrawLine3D(primitive.WorldPosition, primitive.WorldPosition + (vector * 3f), Color.Red, Color.Red, false, false); } num4++; } } } } } } }
public void TryClearCell(ulong packedCoord) { if (m_triangleLists.ContainsKey(packedCoord)) { ClearCachedCell(packedCoord); } RemoveExplored(packedCoord); MyNavmeshComponents.CellInfo cellInfo; if (!m_navmeshComponents.TryGetCell(packedCoord, out cellInfo)) { return; } for (int i = 0; i < cellInfo.ComponentNum; ++i) { int componentIndex = cellInfo.StartingIndex + i; m_mesh.HighLevelGroup.RemovePrimitive(componentIndex); } foreach (var direction in Base6Directions.EnumDirections) { Base6Directions.DirectionFlags dirFlag = Base6Directions.GetDirectionFlag(direction); if (cellInfo.ExploredDirections.HasFlag(dirFlag)) { Vector3I dirVec = Base6Directions.GetIntVector(direction); MyCellCoord otherCoord = new MyCellCoord(); otherCoord.SetUnpack(packedCoord); Debug.Assert(otherCoord.Lod == MyVoxelNavigationMesh.NAVMESH_LOD); otherCoord.CoordInLod = otherCoord.CoordInLod + dirVec; MyNavmeshComponents.CellInfo otherCellInfo; if (m_navmeshComponents.TryGetCell(otherCoord.PackId64(), out otherCellInfo)) { Base6Directions.DirectionFlags flippedFlag = Base6Directions.GetDirectionFlag(Base6Directions.GetFlippedDirection(direction)); m_navmeshComponents.SetExplored(otherCoord.PackId64(), otherCellInfo.ExploredDirections & ~flippedFlag); } else { Debug.Assert(false, "Could not get the oposite explored cell!"); } } } m_navmeshComponents.ClearCell(packedCoord, ref cellInfo); }
public void MarkCellsOnPaths() { this.m_primitivesOnPath.Clear(); this.m_higherLevel.GetPrimitivesOnPath(ref this.m_primitivesOnPath); this.m_cellsOnWayCoords.Clear(); this.m_higherLevelHelper.GetCellsOfPrimitives(ref this.m_cellsOnWayCoords, ref this.m_primitivesOnPath); this.m_cellsOnWay.Clear(); foreach (ulong num in this.m_cellsOnWayCoords) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(num); Vector3I coordInLod = coord.CoordInLod; this.m_cellsOnWay.Add(coordInLod); } }
public void CheckConsistency() { if (!DO_CONSISTENCY_CHECKS) { return; } MyCellCoord cellCoord = new MyCellCoord(); foreach (var pair in m_triangleLists) { cellCoord.SetUnpack(pair.Key); Debug.Assert(m_exploredCells.Contains(ref cellCoord.CoordInLod), "Cell in triangle lists, but not explored!"); } }
private bool ProcessTriangleForHierarchy(MyNavigationTriangle triangle) { // The triangle parent can be wrong when we have multiple navmeshes connected via external edges if (triangle.Parent != m_mesh) { return(false); } // Previously unvisited triangle will be assigned the current relative component index if (triangle.ComponentIndex == -1) { m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center); m_tmpComponentTriangles.Add(triangle); triangle.ComponentIndex = m_currentComponentMarker; return(true); } else if (triangle.ComponentIndex == m_currentComponentMarker) { // We can safely ignore this triangle (it has already been processed); return(true); } else { ulong cellIndex; if (m_navmeshComponents.GetComponentCell(triangle.ComponentIndex, out cellIndex)) { MyCellCoord cellCoord = new MyCellCoord(); cellCoord.SetUnpack(cellIndex); Vector3I diff = cellCoord.CoordInLod - m_currentCell; if (diff.RectangularLength() != 1) { // CH: TODO: Connection of components over cell edges or vertices. I currently silently ignore that... return(false); } ConnectionInfo connection = new ConnectionInfo(); connection.Direction = Base6Directions.GetDirection(diff); connection.ComponentIndex = triangle.ComponentIndex; // Save connections to other components. There won't be so many, so we can keep them in a list instead of a HashSet if (!m_currentCellConnections[m_currentComponentRel].Contains(connection)) { m_currentCellConnections[m_currentComponentRel].Add(connection); } } } return(false); }
private static void DrawLeaves(ref Matrix worldMatrix, Color color, Dictionary <UInt64, IMyOctreeLeafNode> octree) { using (var batch = MyRenderProxy.DebugDrawBatchAABB(worldMatrix, color, true, true)) { MyCellCoord cell = new MyCellCoord(); foreach (var entry in octree) { cell.SetUnpack(entry.Key); cell.Lod += LeafLodCount; var data = entry.Value; var voxelPos = cell.CoordInLod << cell.Lod; var bb = new BoundingBoxD( voxelPos * MyVoxelConstants.VOXEL_SIZE_IN_METRES, (voxelPos + (1 << cell.Lod)) * MyVoxelConstants.VOXEL_SIZE_IN_METRES); batch.Add(ref bb); } } }
private static unsafe void ReadOctreeNodes(Stream stream, ChunkHeader header, ref bool isOldFormat, Dictionary <UInt64, MyOctreeNode> contentNodes) { switch (header.Version) { case VERSION_OCTREE_NODES_32BIT_KEY: { const int entrySize = sizeof(UInt32) + MyOctreeNode.SERIALIZED_SIZE; Debug.Assert((header.Size % entrySize) == 0); int nodesCount = header.Size / entrySize; MyOctreeNode node; MyCellCoord cell = new MyCellCoord(); for (int i = 0; i < nodesCount; i++) { cell.SetUnpack(stream.ReadUInt32()); node.ChildMask = stream.ReadByteNoAlloc(); stream.ReadNoAlloc(node.Data, 0, MyOctreeNode.CHILD_COUNT); contentNodes.Add(cell.PackId64(), node); } isOldFormat = true; } break; case CURRENT_VERSION_OCTREE_NODES: { const int entrySize = sizeof(UInt64) + MyOctreeNode.SERIALIZED_SIZE; Debug.Assert((header.Size % entrySize) == 0); int nodesCount = header.Size / entrySize; MyOctreeNode node; UInt64 key; for (int i = 0; i < nodesCount; i++) { key = stream.ReadUInt64(); node.ChildMask = stream.ReadByteNoAlloc(); stream.ReadNoAlloc(node.Data, 0, MyOctreeNode.CHILD_COUNT); contentNodes.Add(key, node); } } break; default: throw new InvalidBranchException(); } }
public IMyHighLevelComponent GetComponent(MyHighLevelPrimitive primitive) { ulong cellIndex; if (m_navmeshComponents.GetComponentCell(primitive.Index, out cellIndex)) { Base6Directions.DirectionFlags exploredDirections; if (m_navmeshComponents.GetComponentInfo(primitive.Index, cellIndex, out exploredDirections)) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(cellIndex); // Look at present unexplored cells around this cell. // Their direction can be marked as explored, because there was no geometry when they were being explored foreach (var direction in Base6Directions.EnumDirections) { var directionFlag = Base6Directions.GetDirectionFlag(direction); if (exploredDirections.HasFlag(directionFlag)) { continue; } Vector3I neighbor = coord.CoordInLod + Base6Directions.GetIntVector(direction); if (m_exploredCells.Contains(ref neighbor)) { exploredDirections |= directionFlag; } } return(new Component(primitive.Index, exploredDirections)); } else { return(null); } } else { return(null); } }
private static void DrawScaledNodes(ref Matrix worldMatrix, Color color, Dictionary <UInt64, MyOctreeNode> octree) { using (var batch = MyRenderProxy.DebugDrawBatchAABB(worldMatrix, color, true, true)) { MyCellCoord cell = new MyCellCoord(); foreach (var entry in octree) { cell.SetUnpack(entry.Key); cell.Lod += LeafLodCount; var data = entry.Value; for (int i = 0; i < MyOctreeNode.CHILD_COUNT; ++i) { if (data.HasChild(i) && cell.Lod != LeafLodCount) { continue; } Vector3I childOffset; ComputeChildCoord(i, out childOffset); float ratio = data.GetData(i) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT; if (ratio == 0f) { continue; } var voxelPos = (cell.CoordInLod << (cell.Lod + 1)) + (childOffset << cell.Lod); var lodSize = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << cell.Lod); var center = voxelPos * MyVoxelConstants.VOXEL_SIZE_IN_METRES + 0.5f * lodSize; ratio = (float)Math.Pow((double)ratio * MyVoxelConstants.VOXEL_VOLUME_IN_METERS, 0.3333); lodSize *= ratio; BoundingBoxD bb = new BoundingBoxD( center - 0.5f * lodSize, center + 0.5f * lodSize); batch.Add(ref bb); } } } }
private bool ProcessTriangleForHierarchy(MyNavigationTriangle triangle) { if (ReferenceEquals(triangle.Parent, this.m_mesh)) { ulong num; if (triangle.ComponentIndex == -1) { this.m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center); this.m_tmpComponentTriangles.Add(triangle); triangle.ComponentIndex = this.m_currentComponentMarker; return(true); } if (triangle.ComponentIndex == this.m_currentComponentMarker) { return(true); } if (this.m_navmeshComponents.GetComponentCell(triangle.ComponentIndex, out num)) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(num); Vector3I vec = coord.CoordInLod - this.m_currentCell; if (vec.RectangularLength() != 1) { return(false); } ConnectionInfo item = new ConnectionInfo { Direction = Base6Directions.GetDirection(vec), ComponentIndex = triangle.ComponentIndex }; if (!this.m_currentCellConnections[this.m_currentComponentRel].Contains(item)) { this.m_currentCellConnections[this.m_currentComponentRel].Add(item); } } } return(false); }
public unsafe void TryClearCell(ulong packedCoord) { MyNavmeshComponents.CellInfo info; if (this.m_triangleLists.ContainsKey(packedCoord)) { this.ClearCachedCell(packedCoord); } this.RemoveExplored(packedCoord); if (this.m_navmeshComponents.TryGetCell(packedCoord, out info)) { for (int i = 0; i < info.ComponentNum; i++) { int index = info.StartingIndex + i; this.m_mesh.HighLevelGroup.RemovePrimitive(index); } foreach (Base6Directions.Direction direction in Base6Directions.EnumDirections) { Base6Directions.DirectionFlags directionFlag = Base6Directions.GetDirectionFlag(direction); if (info.ExploredDirections.HasFlag(directionFlag)) { MyNavmeshComponents.CellInfo info2; Vector3I intVector = Base6Directions.GetIntVector(direction); MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(packedCoord); MyCellCoord *coordPtr1 = (MyCellCoord *)ref coord; coordPtr1->CoordInLod = (Vector3I)(coord.CoordInLod + intVector); if (this.m_navmeshComponents.TryGetCell(coord.PackId64(), out info2)) { Base6Directions.DirectionFlags flags2 = Base6Directions.GetDirectionFlag(Base6Directions.GetFlippedDirection(direction)); this.m_navmeshComponents.SetExplored(coord.PackId64(), info2.ExploredDirections & ((byte)~flags2)); } } } this.m_navmeshComponents.ClearCell(packedCoord, ref info); } }
public override unsafe void DebugDraw(ref Matrix drawMatrix) { if (MyFakes.DEBUG_DRAW_NAVMESH_PROCESSED_VOXEL_CELLS) { Vector3 vector = Vector3.TransformNormal(this.m_cellSize, (Matrix)drawMatrix); Vector3 vector2 = Vector3.Transform((Vector3)(this.m_voxelMap.PositionLeftBottomCorner - this.m_voxelMap.PositionComp.GetPosition()), (Matrix)drawMatrix); foreach (Vector3I vectori in this.m_processedCells) { BoundingBoxD xd; xd.Min = vector2 + (vector * (new Vector3(0.0625f) + vectori)); BoundingBoxD *xdPtr1 = (BoundingBoxD *)ref xd; xdPtr1->Max = xd.Min + vector; xd.Inflate((double)-0.20000000298023224); MyRenderProxy.DebugDrawAABB(xd, Color.Orange, 1f, 1f, false, false, false); MyRenderProxy.DebugDrawText3D(xd.Center, vectori.ToString(), Color.Orange, 0.5f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); } } if (MyFakes.DEBUG_DRAW_NAVMESH_CELLS_ON_PATHS) { Vector3 vector3 = Vector3.TransformNormal(this.m_cellSize, (Matrix)drawMatrix); Vector3 vector4 = Vector3.Transform((Vector3)(this.m_voxelMap.PositionLeftBottomCorner - this.m_voxelMap.PositionComp.GetPosition()), (Matrix)drawMatrix); MyCellCoord coord = new MyCellCoord(); foreach (ulong num in this.m_cellsOnWayCoords) { BoundingBoxD xd2; coord.SetUnpack(num); Vector3I coordInLod = coord.CoordInLod; xd2.Min = vector4 + (vector3 * (new Vector3(0.0625f) + coordInLod)); BoundingBoxD *xdPtr2 = (BoundingBoxD *)ref xd2; xdPtr2->Max = xd2.Min + vector3; xd2.Inflate((double)-0.30000001192092896); MyRenderProxy.DebugDrawAABB(xd2, Color.Green, 1f, 1f, false, false, false); } } if (MyFakes.DEBUG_DRAW_NAVMESH_PREPARED_VOXEL_CELLS) { Vector3 vector5 = Vector3.TransformNormal(this.m_cellSize, (Matrix)drawMatrix); Vector3 vector6 = Vector3.Transform((Vector3)(this.m_voxelMap.PositionLeftBottomCorner - this.m_voxelMap.PositionComp.GetPosition()), (Matrix)drawMatrix); float negativeInfinity = float.NegativeInfinity; Vector3I zero = Vector3I.Zero; int index = 0; while (true) { if (index >= this.m_toAdd.Count) { for (int i = 0; i < this.m_toAdd.Count; i++) { BoundingBoxD xd3; CellToAddHeapItem local1 = this.m_toAdd.GetItem(i); float num6 = local1.HeapKey; Vector3I position = local1.Position; xd3.Min = vector6 + (vector5 * (new Vector3(0.0625f) + position)); BoundingBoxD *xdPtr3 = (BoundingBoxD *)ref xd3; xdPtr3->Max = xd3.Min + vector5; xd3.Inflate((double)-0.10000000149011612); Color aqua = Color.Aqua; if (position.Equals(zero)) { aqua = Color.Red; } MyRenderProxy.DebugDrawAABB(xd3, aqua, 1f, 1f, false, false, false); string text = $"{num6.ToString("n2")}"; MyRenderProxy.DebugDrawText3D(xd3.Center, text, aqua, 0.7f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); } break; } CellToAddHeapItem item = this.m_toAdd.GetItem(index); float heapKey = item.HeapKey; if (heapKey > negativeInfinity) { negativeInfinity = heapKey; zero = item.Position; } index++; } } MyRenderProxy.DebugDrawSphere(this.m_debugPos1, 0.2f, Color.Red, 1f, false, false, true, false); MyRenderProxy.DebugDrawSphere(this.m_debugPos2, 0.2f, Color.Green, 1f, false, false, true, false); MyRenderProxy.DebugDrawSphere(this.m_debugPos3, 0.1f, Color.Red, 1f, false, false, true, false); MyRenderProxy.DebugDrawSphere(this.m_debugPos4, 0.1f, Color.Green, 1f, false, false, true, false); if (MyFakes.DEBUG_DRAW_VOXEL_CONNECTION_HELPER) { this.m_connectionHelper.DebugDraw(ref drawMatrix, base.Mesh); } if (MyFakes.DEBUG_DRAW_NAVMESH_CELL_BORDERS) { foreach (KeyValuePair <ulong, List <DebugDrawEdge> > pair in this.m_debugCellEdges) { foreach (DebugDrawEdge edge in pair.Value) { MyRenderProxy.DebugDrawLine3D(edge.V1, edge.V2, Color.Orange, Color.Orange, false, false); } } } else { this.m_debugCellEdges.Clear(); } if (MyFakes.DEBUG_DRAW_NAVMESH_HIERARCHY) { if (MyFakes.DEBUG_DRAW_NAVMESH_HIERARCHY_LITE) { this.m_higherLevel.DebugDraw(true); } else { this.m_higherLevel.DebugDraw(false); this.m_higherLevelHelper.DebugDraw(); } } if ((MyDebugDrawSettings.DEBUG_DRAW_NAVMESHES == MyWEMDebugDrawMode.LINES) && !(this.m_voxelMap is MyVoxelPhysics)) { int num7 = 0; MyWingedEdgeMesh.EdgeEnumerator edges = base.Mesh.GetEdges(null); Vector3D position = this.m_voxelMap.PositionComp.GetPosition(); while (edges.MoveNext()) { MyWingedEdgeMesh.Edge current = edges.Current; Vector3D vectord2 = base.Mesh.GetVertexPosition(current.Vertex2) + position; Vector3D point = ((base.Mesh.GetVertexPosition(edges.Current.Vertex1) + position) + vectord2) * 0.5; if (MyCestmirPathfindingShorts.Pathfinding.Obstacles.IsInObstacle(point)) { MyRenderProxy.DebugDrawSphere(point, 0.05f, Color.Red, 1f, false, false, true, false); } num7++; } } }
protected override void LoadInternal(int fileVersion, Stream stream, ref bool isOldFormat) { Debug.Assert(fileVersion == CURRENT_FILE_VERSION); ChunkHeader header = new ChunkHeader(); Dictionary <byte, MyVoxelMaterialDefinition> materialTable = null; HashSet <UInt64> materialLeaves = new HashSet <UInt64>(); HashSet <UInt64> contentLeaves = new HashSet <UInt64>(); while (header.ChunkType != ChunkTypeEnum.EndOfFile) { MyMicroOctreeLeaf contentLeaf; MyMicroOctreeLeaf materialLeaf; UInt64 key; header.ReadFrom(stream); Debug.Assert(Enum.IsDefined(typeof(ChunkTypeEnum), header.ChunkType)); switch (header.ChunkType) { case ChunkTypeEnum.StorageMetaData: ReadStorageMetaData(stream, header, ref isOldFormat); break; case ChunkTypeEnum.MaterialIndexTable: materialTable = ReadMaterialTable(stream, header, ref isOldFormat); break; case ChunkTypeEnum.MacroContentNodes: ReadOctreeNodes(stream, header, ref isOldFormat, m_contentNodes); break; case ChunkTypeEnum.MacroMaterialNodes: ReadOctreeNodes(stream, header, ref isOldFormat, m_materialNodes); break; case ChunkTypeEnum.ContentLeafProvider: ReadProviderLeaf(stream, header, ref isOldFormat, contentLeaves); break; case ChunkTypeEnum.ContentLeafOctree: ReadOctreeLeaf(stream, header, ref isOldFormat, MyStorageDataTypeEnum.Content, out key, out contentLeaf); m_contentLeaves.Add(key, contentLeaf); break; case ChunkTypeEnum.MaterialLeafProvider: ReadProviderLeaf(stream, header, ref isOldFormat, materialLeaves); break; case ChunkTypeEnum.MaterialLeafOctree: ReadOctreeLeaf(stream, header, ref isOldFormat, MyStorageDataTypeEnum.Material, out key, out materialLeaf); m_materialLeaves.Add(key, materialLeaf); break; case ChunkTypeEnum.DataProvider: ReadDataProvider(stream, header, ref isOldFormat, out m_dataProvider); break; case ChunkTypeEnum.EndOfFile: break; default: throw new InvalidBranchException(); } } { // At this point data provider should be loaded too, so have him create leaves MyCellCoord cell = new MyCellCoord(); foreach (var key in contentLeaves) { cell.SetUnpack(key); cell.Lod += LeafLodCount; m_contentLeaves.Add(key, new MyProviderLeaf(m_dataProvider, MyStorageDataTypeEnum.Content, ref cell)); } foreach (var key in materialLeaves) { cell.SetUnpack(key); cell.Lod += LeafLodCount; m_materialLeaves.Add(key, new MyProviderLeaf(m_dataProvider, MyStorageDataTypeEnum.Material, ref cell)); } } { // material reindexing when definitions change Debug.Assert(materialTable != null); bool needsReindexing = false; foreach (var entry in materialTable) { if (entry.Key != entry.Value.Index) { needsReindexing = true; } m_oldToNewIndexMap.Add(entry.Key, entry.Value.Index); } if (needsReindexing) { if (m_dataProvider != null) { m_dataProvider.ReindexMaterials(m_oldToNewIndexMap); } foreach (var entry in m_materialLeaves) { entry.Value.ReplaceValues(m_oldToNewIndexMap); } MySparseOctree.ReplaceValues(m_materialNodes, m_oldToNewIndexMap); } m_oldToNewIndexMap.Clear(); } }
internal unsafe void DebugDraw(IMyDebugDrawBatchAabb batch, Vector3 worldPos, MyVoxelDebugDrawMode mode) { Color?nullable; if (mode == MyVoxelDebugDrawMode.Content_MicroNodes) { foreach (KeyValuePair <uint, MyOctreeNode> pair in this.m_nodes) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(pair.Key); MyOctreeNode node = pair.Value; for (int i = 0; i < 8; i++) { if (!node.HasChild(i) || (coord.Lod == 0)) { Vector3I vectori; BoundingBoxD xd; this.ComputeChildCoord(i, out vectori); Vector3I vectori2 = (Vector3I)((coord.CoordInLod << (coord.Lod + 1)) + (vectori << coord.Lod)); xd.Min = worldPos + (vectori2 * 1f); BoundingBoxD *xdPtr1 = (BoundingBoxD *)ref xd; xdPtr1->Max = xd.Min + (1f * (1 << (coord.Lod & 0x1f))); if (node.GetData(i) != 0) { nullable = null; batch.Add(ref xd, nullable); } } } } return; } else if (mode != MyVoxelDebugDrawMode.Content_MicroNodesScaled) { return; } foreach (KeyValuePair <uint, MyOctreeNode> pair2 in this.m_nodes) { MyCellCoord coord2 = new MyCellCoord(); coord2.SetUnpack(pair2.Key); MyOctreeNode node2 = pair2.Value; for (int i = 0; i < 8; i++) { if (!node2.HasChild(i)) { Vector3I vectori3; this.ComputeChildCoord(i, out vectori3); float num3 = ((float)node2.GetData(i)) / 255f; if (num3 != 0f) { BoundingBoxD xd2; num3 = (float)Math.Pow(num3 * 1.0, 0.3333); Vector3I vectori4 = (Vector3I)((coord2.CoordInLod << (coord2.Lod + 1)) + (vectori3 << coord2.Lod)); float num4 = 1f * (1 << (coord2.Lod & 0x1f)); Vector3 vector = (worldPos + (vectori4 * 1f)) + (0.5f * num4); xd2.Min = vector - ((0.5f * num3) * num4); xd2.Max = vector + ((0.5f * num3) * num4); nullable = null; batch.Add(ref xd2, nullable); } } } } }
public void DebugDraw() { //if (m_lodIndex > 5) // return; // if (m_lodIndex == 1) // { // float sizeInMetres = MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex); // //var start = localFarCameraBox.Min; // //var end = localFarCameraBox.Max; // var start = m_localNearCameraBox.Min; // var end = m_localNearCameraBox.Max; // Vector3I coord = start; // Color nearColor = Color.Yellow; // Color farColor = Color.White; // var startF = m_localFarCameraBox.Min; // var endF = m_localFarCameraBox.Max; // Vector3I coordF = startF; //// for (var it = new Vector3I_RangeIterator(ref startF, ref endF); ////it.IsValid(); it.GetNext(out coordF)) //// { //// Vector3D min = Vector3D.Transform((Vector3D)(sizeInMetres * coordF), m_parent.m_worldMatrix); //// Vector3D max = Vector3D.Transform((Vector3D)(sizeInMetres * coordF + new Vector3(sizeInMetres)), m_parent.m_worldMatrix); //// BoundingBoxD aabb = new BoundingBoxD(min, max); //// MyRenderProxy.DebugDrawAABB(aabb, farColor, 1, 1, false); //// if (Vector3D.Distance(CameraFrustumGetter().Matrix.Translation, aabb.Center) < 200) //// MyRenderProxy.DebugDrawText3D(aabb.Center, coordF.ToString(), farColor, 0.5f, false); //// } // for (var it = new Vector3I_RangeIterator(ref start, ref end); //it.IsValid(); it.GetNext(out coord)) // { // Vector3D min = Vector3D.Transform((Vector3D)(sizeInMetres * coord), m_clipmap.m_worldMatrix); // Vector3D max = Vector3D.Transform((Vector3D)(sizeInMetres * coord + new Vector3(sizeInMetres)), m_clipmap.m_worldMatrix); // BoundingBoxD aabb = new BoundingBoxD(min, max); // MyRenderProxy.DebugDrawAABB(aabb, nearColor, 1, 1, false); // } // Vector3D center = Vector3D.Transform(m_localPosition, m_clipmap.m_worldMatrix); // MyRenderProxy.DebugDrawSphere(center, m_nearDistance, nearColor, 1, false); // MyRenderProxy.DebugDrawSphere(center, m_farDistance, farColor, 1, false); // } var camera = m_clipmap.LastCameraPosition; //if (m_lodIndex < 6) { float sizeInMetres = MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex); Color color = LOD_COLORS[m_lodIndex] + new Vector4(0.2f); foreach (var cell in m_storedCellData) { if (!cell.Value.InScene) { continue; } MyCellCoord cellStr = new MyCellCoord(); cellStr.SetUnpack(cell.Key); var coordF = cellStr.CoordInLod; Vector3D min = Vector3D.Transform((Vector3D)(sizeInMetres * coordF), m_clipmap.m_worldMatrix); Vector3D max = Vector3D.Transform((Vector3D)(sizeInMetres * coordF + new Vector3(sizeInMetres)), m_clipmap.m_worldMatrix); BoundingBoxD aabb = new BoundingBoxD(min, max); double distance = Vector3D.Distance(camera, aabb.Center); //if (distance < sizeInMetres * 4) MyRenderProxy.DebugDrawAABB(aabb, color, 1, 1, true); if (distance < sizeInMetres * 2) { MyRenderProxy.DebugDrawText3D(aabb.Center, String.Format("{0}:{1}", m_lodIndex, coordF.ToString()), color, 0.7f, false); } } if (m_storedCellData.Count > 0) { Vector3D center = Vector3D.Transform(m_localPosition, m_clipmap.m_worldMatrix); //MyRenderProxy.DebugDrawSphere(center, m_farDistance, color, 1, false); } } }