示例#1
0
 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);
                    }
                }
            }