internal void UpdateCellsInScene(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); thisLodCell.SetUnpack(entry.Key); if (ChildrenWereLoaded(childLod, ref thisLodCell) || (MyVoxelCoordSystems.RenderCellSizeShiftToLessDetailed(thisLodCell.Lod) == 1 && !AllSiblingsWereLoaded(ref thisLodCell))) { RemoveFromScene(entry.Key, data); } else { AddToScene(entry.Key, data); } } }
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(); }
internal void UpdateCellsInScene(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); thisLodCell.SetUnpack(entry.Key); if (ChildrenWereLoaded(childLod, ref thisLodCell) || !AllSiblingsWereLoaded(ref thisLodCell)) { RemoveFromScene(entry.Key, data); } else { AddToScene(entry.Key, data); //data.Cell.PixelDiscardEnabled = false; } } }
internal void KeepOrDiscardClippedCells(RequestCollector collector) { LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); MyCellCoord thisLodCell = new MyCellCoord(); foreach (var entry in m_clippedCells) { var data = entry.Value; bool needed = false; // too far, but less detailed data might be missing so we still check parent thisLodCell.SetUnpack(entry.Key); needed = !WasAncestorCellLoaded(parentLod, ref thisLodCell); if (needed) { if (data.State == CellState.Invalid) { if (!TryAddCellRequest(collector, parentLod, thisLodCell, entry.Key, data)) { continue; } } m_storedCellData.Add(entry.Key, data); } else { if (UseCache && data.State == CellState.Loaded) { var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, entry.Key); CellsCache.Write(clipmapCellId, data); Delete(entry.Key, data, false); } else { if (data.State == CellState.Pending) { collector.CancelRequest(entry.Key); } if (data.Cell != null) { Delete(entry.Key, data); } } if (!UseCache) { CellsCache.Reset(); } } } m_clippedCells.Clear(); }
internal void KeepOrDiscardClippedCells(RequestCollector collector) { LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); MyCellCoord thisLodCell = new MyCellCoord(); foreach (var entry in m_clippedCells) { var data = entry.Value; bool needed = false; // too far, but less detailed data might be missing so we still check parent thisLodCell.SetUnpack(entry.Key); needed = !WasAncestorCellLoaded(parentLod, ref thisLodCell); if (needed) { if (data.State == CellState.Invalid) { collector.AddRequest(entry.Key, data.WasLoaded); data.State = CellState.Pending; } m_storedCellData.Add(entry.Key, data); } else { if (data.State == CellState.Pending) { collector.CancelRequest(entry.Key); } if (data.Cell != null) { Delete(entry.Key, data); } } } m_clippedCells.Clear(); }
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(); } }
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); } } } }
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 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 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); } } }
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!"); } }
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); } } }
private void RemoveExplored(ulong packedCoord) { MyCellCoord coord = new MyCellCoord(); coord.SetUnpack(packedCoord); m_exploredCells.Remove(ref coord.CoordInLod); }
internal void KeepOrDiscardClippedCells(RequestCollector collector) { LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); MyCellCoord thisLodCell = new MyCellCoord(); foreach (var entry in m_clippedCells) { var data = entry.Value; bool needed = false; // too far, but less detailed data might be missing so we still check parent thisLodCell.SetUnpack(entry.Key); needed = !WasAncestorCellLoaded(parentLod, ref thisLodCell); if (needed) { if (data.State == CellState.Invalid) { if (!TryAddCellRequest(collector, parentLod, thisLodCell, entry.Key, data)) continue; } m_storedCellData.Add(entry.Key, data); } else { if (UseCache && data.State == CellState.Loaded) { var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, entry.Key); CellsCache.Write(clipmapCellId, data); Delete(entry.Key, data, false); } else { if (data.State == CellState.Pending) collector.CancelRequest(entry.Key); if (data.Cell != null) Delete(entry.Key, data); } if (!UseCache) { CellsCache.Reset(); } } } m_clippedCells.Clear(); }
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 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; } }
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); } } } }
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); } } }
internal void KeepOrDiscardClippedCells(RequestCollector collector) { LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); MyCellCoord thisLodCell = new MyCellCoord(); foreach (var entry in m_clippedCells) { var data = entry.Value; bool needed = false; // too far, but less detailed data might be missing so we still check parent thisLodCell.SetUnpack(entry.Key); needed = !WasAncestorCellLoaded(parentLod, ref thisLodCell); if (needed) { if (data.State == CellState.Invalid) { collector.AddRequest(entry.Key, data.WasLoaded); data.State = CellState.Pending; } m_storedCellData.Add(entry.Key, data); } else { if (data.State == CellState.Pending) collector.CancelRequest(entry.Key); if (data.Cell != null) Delete(entry.Key, data); } } m_clippedCells.Clear(); }
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; } if (triangle.ComponentIndex == -1) { m_navmeshComponents.AddComponentTriangle(triangle, triangle.Center); triangle.ComponentIndex = m_navmeshComponents.OpenComponentIndex; return true; } else if (triangle.ComponentIndex == m_navmeshComponents.OpenComponentIndex) { 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; }
internal void UpdateCellsInScene(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); thisLodCell.SetUnpack(entry.Key); if (NEW_VOXEL_CLIPPING) { var siblingsLoaded = AllSiblingsWereLoaded(ref thisLodCell); if (ChildrenWereLoaded(childLod, ref thisLodCell) && siblingsLoaded) { RemoveFromScene(entry.Key, data); } else { AddToScene(entry.Key, data); } } else { if (ChildrenWereLoaded(childLod, ref thisLodCell) || (MyVoxelCoordSystems.RenderCellSizeShiftToLessDetailed(thisLodCell.Lod) == 1 && !AllSiblingsWereLoaded(ref thisLodCell)) ) { RemoveFromScene(entry.Key, data); } else { AddToScene(entry.Key, data); } } } }
public void Submit() { ProfilerShort.Begin("RequestCollector.Submit"); MyCellCoord cell = default(MyCellCoord); foreach (var cellId in m_cancelRequests) { cell.SetUnpack(cellId); MyRenderProxy.CancelClipmapCell(m_clipmapId, cell); bool removed = m_sentRequests.Remove(cellId); Debug.Assert(removed); } foreach (var highPriorityRequest in m_unsentRequestsHigh) { cell.SetUnpack(highPriorityRequest); MyRenderProxy.RequireClipmapCell(m_clipmapId, cell, highPriority: true); } m_unsentRequestsHigh.Clear(); int addedCount = 0; for (int i = m_unsentRequestsLow.Length - 1; i >= 0; i--) { var unsent = m_unsentRequestsLow[i]; while (0 < unsent.Count && m_sentRequests.Count < m_maxRequests) { var cellId = unsent.FirstElement(); cell.SetUnpack(cellId); // Do Z-order style iteration of siblings that also need to // be requested. This ensures faster processing of cells and // shorter time when both lods are rendered. var baseCoord = (cell.CoordInLod >> 1) << 1; var offset = Vector3I.Zero; for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref Vector3I.One); it.IsValid(); it.GetNext(out offset)) { cell.CoordInLod = baseCoord + offset; cellId = cell.PackId64(); if (!unsent.Remove(cellId)) { continue; } Debug.Assert(!m_cancelRequests.Contains(cellId)); MyRenderProxy.RequireClipmapCell(m_clipmapId, cell, highPriority: false); bool added = m_sentRequests.Add(cellId); Debug.Assert(added); addedCount++; } } // When set reaches reasonably small size, stop freeing memory if (unsent.Count > 100) { unsent.TrimExcess(); } } m_cancelRequests.Clear(); ProfilerShort.End(); }
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); } } } } } } }