internal unsafe void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged, int lod) { if (this.m_bodiesInitialized) { if (this.m_queueInvalidation) { if (this.m_queuedRange.Max.X < 0) { this.m_queuedRange = new BoundingBoxI(minVoxelChanged, maxVoxelChanged); } else { BoundingBoxI box = new BoundingBoxI(minVoxelChanged, maxVoxelChanged); this.m_queuedRange.Include(ref box); } } else { Vector3I vectori; Vector3I vectori2; minVoxelChanged -= 2; maxVoxelChanged = (Vector3I)(maxVoxelChanged + 1); this.m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged, 1); this.m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged, 1); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out vectori); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out vectori2); Vector3I minChanged = (vectori - this.m_cellsOffset) >> lod; Vector3I result = (vectori2 - this.m_cellsOffset) >> lod; Vector3I geometryCellCoord = this.m_voxelMap.Size - 1; Vector3I *vectoriPtr1 = (Vector3I *)ref geometryCellCoord; MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref (Vector3I) ref vectoriPtr1, out geometryCellCoord); geometryCellCoord = geometryCellCoord >> lod; Vector3I *vectoriPtr2 = (Vector3I *)ref result; Vector3I.Min(ref (Vector3I) ref vectoriPtr2, ref geometryCellCoord, out result); HkRigidBody rigidBody = this.GetRigidBody(lod); if ((minChanged == Vector3I.Zero) && (result == geometryCellCoord)) { this.m_workTracker.CancelAll(); } else { using (MyUtils.ReuseCollection <MyCellCoord>(ref m_toBeCancelledCache)) { BoundingBoxI xi2 = new BoundingBoxI(vectori, vectori2); foreach (KeyValuePair <MyCellCoord, MyPrecalcJobPhysicsPrefetch> pair in this.m_workTracker) { if (xi2.Contains(pair.Key.CoordInLod) != ContainmentType.Disjoint) { m_toBeCancelledCache.Add(pair.Key); } } foreach (MyCellCoord coord in m_toBeCancelledCache) { this.m_workTracker.CancelIfStarted(coord); } } } if (rigidBody != null) { HkUniformGridShape shape = (HkUniformGridShape)rigidBody.GetShape(); int size = ((result - minChanged) + 1).Size; if (size >= m_cellsToGenerateBuffer.Length) { m_cellsToGenerateBuffer = new Vector3I[MathHelper.GetNearestBiggerPowerOfTwo(size)]; } int num2 = shape.InvalidateRange(ref minChanged, ref result, m_cellsToGenerateBuffer); for (int i = 0; i < num2; i++) { this.StartPrecalcJobPhysicsIfNeeded(lod, i); } } this.m_voxelMap.RaisePhysicsChanged(); } } }
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); } } }