internal void DoClipping_Old(Vector3D localPosition, float farPlaneDistance, RequestCollector collector) { m_localPosition = localPosition; MyClipmap.ComputeLodViewBounds(m_clipmap.m_scaleGroup, m_lodIndex, out m_nearDistance, out m_farDistance); m_fitsInFrustum = (farPlaneDistance * 1.25f) > m_nearDistance; if (!m_fitsInFrustum) return; //var localFrustum = new BoundingFrustumD(CameraFrustumGetter().Matrix * m_parent.m_invWorldMatrix); var frustum = CameraFrustumGetter(); Vector3I min, max; Vector3I ignoreMin, ignoreMax; var minD = m_localPosition - m_farDistance; var maxD = m_localPosition + m_farDistance; MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref minD, out min); MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref maxD, out max); BoundingBoxI lodBox = new BoundingBoxI(Vector3I.Zero, m_lodSizeMinusOne); bool intersects = false; bool intersectsNear = false; m_localFarCameraBox = new BoundingBoxI(min, max); m_localNearCameraBox = new BoundingBoxI(min, max); if (lodBox.Intersects(m_localFarCameraBox)) { intersects = true; var intersection = lodBox.Intersect(m_localFarCameraBox); min = intersection.Min; max = intersection.Max; //Optimize only LOD2 and higher by two lods, because neighbour cells shares border cells if (m_lodIndex > 1) { float lowerFar, lowerNear; MyClipmap.ComputeLodViewBounds(m_clipmap.m_scaleGroup, m_lodIndex - 2, out lowerFar, out lowerNear); var minNear = m_localPosition - (lowerNear - MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex) / 2); var maxNear = m_localPosition + (lowerNear - MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex) / 2); MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref minNear, out ignoreMin); MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref maxNear, out ignoreMax); m_localNearCameraBox = new BoundingBoxI(ignoreMin, ignoreMax); if (lodBox.Intersects(m_localNearCameraBox)) intersectsNear = false; } } if (m_lastMin == min && m_lastMax == max && !m_clipmap.m_updateClipping) return; m_lastMin = min; m_lastMax = max; LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); // Moves cells which are still needed from one collection to another. // All that is left behind is unloaded as no longer needed. // Move everything in range to collection of next stored cells. MyUtils.Swap(ref m_storedCellData, ref m_clippedCells); m_storedCellData.Clear(); if (intersects) { float sizeInMetres = MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex); MyCellCoord cell = new MyCellCoord(m_lodIndex, ref min); for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out cell.CoordInLod)) { if (intersectsNear && m_localNearCameraBox.Contains(cell.CoordInLod) == ContainmentType.Contains) continue; //if (!WasAncestorCellLoaded(parentLod, ref cell)) // continue; Vector3D minAABB = Vector3D.Transform((Vector3D)(sizeInMetres * (cell.CoordInLod - 2)), m_clipmap.m_worldMatrix); Vector3D maxAABB = Vector3D.Transform((Vector3D)(sizeInMetres * (cell.CoordInLod + 2) + new Vector3(sizeInMetres)), m_clipmap.m_worldMatrix); if (frustum.Contains(new BoundingBoxD(minAABB, maxAABB)) == ContainmentType.Disjoint) continue; var cellId = cell.PackId64(); CellData data; if (m_clippedCells.TryGetValue(cellId, out data)) { m_clippedCells.Remove(cellId); } else { var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, cellId); data = CellsCache.Read(clipmapCellId); if (data == null) //cache miss { data = new CellData(); ClippingCacheMisses++; } else { //cache hit ClippingCacheHits++; //System.Diagnostics.Debug.Assert((!data.InScene && data.Cell != null) || data.Cell == null, "Not allowed cell state"); data.InScene = false; if (data.Cell != null) { m_nonEmptyCells[cellId] = data; } } } if (data.State == CellState.Invalid) { if (!TryAddCellRequest(collector, parentLod, cell, cellId, data)) continue; } m_storedCellData.Add(cellId, data); } } }
// Iterate over sector boxes in a range. private void ForEachSector(Vector3 localPosition, float range, SectorIteration iterator) { Vector3 sectorPosition; LocalPositionToSectorCube(localPosition, out sectorPosition); Vector3D referencePoint = localPosition; SectorScans.Hit(); Vector3 rangev = new Vector3(range); BoundingBox probe = new BoundingBox(sectorPosition - rangev, sectorPosition + rangev); BoundingBoxI inter = m_sectorBox.Intersect(probe); Vector3S min = new Vector3S(inter.Min); Vector3S max = new Vector3S(inter.Max); // Iterate over each face of the cube that is in the intersection. MyPlanetSectorId id = new MyPlanetSectorId(); // Front if (inter.Min.Z == m_sectorBox.Min.Z) { id.Direction = Vector3B.Backward; id.Position.Z = min.Z; for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++) { for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++) { iterator(this, ref id, ref referencePoint); } } } // Back if (inter.Max.Z == m_sectorBox.Max.Z) { id.Direction = Vector3B.Forward; id.Position.Z = max.Z; for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++) { for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++) { iterator(this, ref id, ref referencePoint); } } } // Right if (inter.Min.X == m_sectorBox.Min.X) { id.Direction = Vector3B.Right; id.Position.X = min.X; for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++) { for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++) { iterator(this, ref id, ref referencePoint); } } } // Left if (inter.Max.X == m_sectorBox.Max.X) { id.Direction = Vector3B.Left; id.Position.X = max.X; for (id.Position.Y = min.Y; id.Position.Y <= max.Y; id.Position.Y++) { for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++) { iterator(this, ref id, ref referencePoint); } } } // Up if (inter.Min.Y == m_sectorBox.Min.Y) { id.Direction = Vector3B.Up; id.Position.Y = min.Y; for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++) { for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++) { iterator(this, ref id, ref referencePoint); } } } // Down if (inter.Max.Y == m_sectorBox.Max.Y) { id.Direction = Vector3B.Down; id.Position.Y = max.Y; for (id.Position.X = min.X; id.Position.X <= max.X; id.Position.X++) { for (id.Position.Z = min.Z; id.Position.Z <= max.Z; id.Position.Z++) { iterator(this, ref id, ref referencePoint); } } } }
internal void DoClipping_Old(Vector3D localPosition, float farPlaneDistance, RequestCollector collector) { m_localPosition = localPosition; MyClipmap.ComputeLodViewBounds(m_clipmap.m_scaleGroup, m_lodIndex, out m_nearDistance, out m_farDistance); m_fitsInFrustum = (farPlaneDistance * 1.25f) > m_nearDistance; if (!m_fitsInFrustum) { return; } //var localFrustum = new BoundingFrustumD(CameraFrustumGetter().Matrix * m_parent.m_invWorldMatrix); var frustum = CameraFrustumGetter(); Vector3I min, max; Vector3I ignoreMin, ignoreMax; var minD = m_localPosition - m_farDistance; var maxD = m_localPosition + m_farDistance; MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref minD, out min); MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref maxD, out max); BoundingBoxI lodBox = new BoundingBoxI(Vector3I.Zero, m_lodSizeMinusOne); bool intersects = false; bool intersectsNear = false; m_localFarCameraBox = new BoundingBoxI(min, max); m_localNearCameraBox = new BoundingBoxI(min, max); if (lodBox.Intersects(m_localFarCameraBox)) { intersects = true; var intersection = lodBox.Intersect(m_localFarCameraBox); min = intersection.Min; max = intersection.Max; //Optimize only LOD2 and higher by two lods, because neighbour cells shares border cells if (m_lodIndex > 1) { float lowerFar, lowerNear; MyClipmap.ComputeLodViewBounds(m_clipmap.m_scaleGroup, m_lodIndex - 2, out lowerFar, out lowerNear); var minNear = m_localPosition - (lowerNear - MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex) / 2); var maxNear = m_localPosition + (lowerNear - MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex) / 2); MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref minNear, out ignoreMin); MyVoxelCoordSystems.LocalPositionToRenderCellCoord(m_lodIndex, ref maxNear, out ignoreMax); m_localNearCameraBox = new BoundingBoxI(ignoreMin, ignoreMax); if (lodBox.Intersects(m_localNearCameraBox)) { intersectsNear = false; } } } if (m_lastMin == min && m_lastMax == max && !m_clipmap.m_updateClipping) { return; } m_lastMin = min; m_lastMax = max; LodLevel parentLod, childLod; GetNearbyLodLevels(out parentLod, out childLod); // Moves cells which are still needed from one collection to another. // All that is left behind is unloaded as no longer needed. // Move everything in range to collection of next stored cells. MyUtils.Swap(ref m_storedCellData, ref m_clippedCells); m_storedCellData.Clear(); if (intersects) { float sizeInMetres = MyVoxelCoordSystems.RenderCellSizeInMeters(m_lodIndex); MyCellCoord cell = new MyCellCoord(m_lodIndex, ref min); for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out cell.CoordInLod)) { if (intersectsNear && m_localNearCameraBox.Contains(cell.CoordInLod) == ContainmentType.Contains) { continue; } //if (!WasAncestorCellLoaded(parentLod, ref cell)) // continue; Vector3D minAABB = Vector3D.Transform((Vector3D)(sizeInMetres * (cell.CoordInLod - 2)), m_clipmap.m_worldMatrix); Vector3D maxAABB = Vector3D.Transform((Vector3D)(sizeInMetres * (cell.CoordInLod + 2) + new Vector3(sizeInMetres)), m_clipmap.m_worldMatrix); if (frustum.Contains(new BoundingBoxD(minAABB, maxAABB)) == ContainmentType.Disjoint) { continue; } var cellId = cell.PackId64(); CellData data; if (m_clippedCells.TryGetValue(cellId, out data)) { m_clippedCells.Remove(cellId); } else { var clipmapCellId = MyCellCoord.GetClipmapCellHash(m_clipmap.Id, cellId); data = CellsCache.Read(clipmapCellId); if (data == null) //cache miss { data = new CellData(); ClippingCacheMisses++; } else { //cache hit ClippingCacheHits++; //System.Diagnostics.Debug.Assert((!data.InScene && data.Cell != null) || data.Cell == null, "Not allowed cell state"); data.InScene = false; if (data.Cell != null) { m_nonEmptyCells[cellId] = data; } } } if (data.State == CellState.Invalid) { if (!TryAddCellRequest(collector, parentLod, cell, cellId, data)) { continue; } } m_storedCellData.Add(cellId, data); } } }