예제 #1
0
        internal void GenerateAllShapes()
        {
            var min = Vector3I.Zero;

            Vector3I storageSize = m_voxelMap.Size;
            Vector3I max         = new Vector3I(0, 0, 0);

            max.X = storageSize.X >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            max.Y = storageSize.Y >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            max.Z = storageSize.Z >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;

            max += min;

            var args = new MyPrecalcJobPhysicsPrefetch.Args
            {
                GeometryCell  = new MyCellCoord(0, min),
                Storage       = m_voxelMap.Storage,
                TargetPhysics = this,
                Tracker       = m_workTracker,
            };

            for (var it = new Vector3I.RangeIterator(ref min, ref max);
                 it.IsValid();
                 it.GetNext(out args.GeometryCell.CoordInLod))
            {
                MyPrecalcJobPhysicsPrefetch.Start(args);
            }
        }
예제 #2
0
 internal void GenerateAllShapes()
 {
     if (this.m_mesher != null)
     {
         if (!this.m_bodiesInitialized)
         {
             this.CreateRigidBodies();
         }
         Vector3I zero = Vector3I.Zero;
         Vector3I size = this.m_voxelMap.Size;
         Vector3I end  = new Vector3I(0, 0, 0)
         {
             X = size.X >> 3,
             Y = size.Y >> 3,
             Z = size.Z >> 3
         };
         end = (Vector3I)(end + zero);
         MyPrecalcJobPhysicsPrefetch.Args args = new MyPrecalcJobPhysicsPrefetch.Args {
             GeometryCell  = new MyCellCoord(1, zero),
             Storage       = this.m_voxelMap.Storage,
             TargetPhysics = this,
             Tracker       = this.m_workTracker
         };
         Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref zero, ref end);
         while (iterator.IsValid())
         {
             MyPrecalcJobPhysicsPrefetch.Start(args);
             iterator.GetNext(out args.GeometryCell.CoordInLod);
         }
     }
 }
예제 #3
0
        public static void Start(Args args)
        {
            MyPrecalcJobPhysicsPrefetch work = m_instancePool.Allocate();

            work.m_args = args;
            args.Tracker.Add(args.GeometryCell, work);
            MyPrecalcComponent.EnqueueBack(work);
        }
예제 #4
0
 private void RequestShapeBatchBlockingInternal(HkShapeBatch info, bool lod1physics)
 {
     if (!MyPhysics.InsideSimulation && !ReferenceEquals(Thread.CurrentThread, MyUtils.MainThread))
     {
         MyLog.Default.Error("Invalid request shape Thread id: " + Thread.CurrentThread.ManagedThreadId.ToString() + " Stack trace: " + Environment.StackTrace, Array.Empty <object>());
     }
     if (!this.m_voxelMap.MarkedForClose)
     {
         if (!this.m_bodiesInitialized)
         {
             this.CreateRigidBodies();
         }
         this.m_needsShapeUpdate = true;
         int count = info.Count;
         if (((count > 0x4e20) || (Interlocked.Add(ref this.m_voxelQueriesInLastFrames, count) >= 0x2710)) && (Interlocked.Exchange(ref this.m_hasExtendedCache, 1) == 0))
         {
             HkUniformGridShape shape;
             Interlocked.Increment(ref ActiveVoxelPhysicsBodiesWithExtendedCache);
             if (this.GetShape(lod1physics ? 1 : 0, out shape))
             {
                 shape.EnableExtendedCache();
             }
         }
         Parallel.For(0, count, delegate(int i) {
             Vector3I vectori;
             info.GetInfo(i, out vectori);
             int lod = lod1physics ? 1 : 0;
             MyCellCoord geometryCellCoord = new MyCellCoord(lod, vectori);
             if (MyDebugDrawSettings.DEBUG_DRAW_REQUEST_SHAPE_BLOCKING)
             {
                 BoundingBoxD xd;
                 MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(this.m_voxelMap.PositionLeftBottomCorner, ref geometryCellCoord, out xd);
                 MyRenderProxy.DebugDrawAABB(xd, lod1physics ? Color.Yellow : Color.Red, 1f, 1f, false, false, false);
             }
             bool flag = false;
             HkBvCompressedMeshShape empty        = (HkBvCompressedMeshShape)HkShape.Empty;
             MyPrecalcJobPhysicsPrefetch prefetch = this.m_workTracker.Cancel(geometryCellCoord);
             if (((prefetch != null) && prefetch.ResultComplete) && (Interlocked.Exchange(ref prefetch.Taken, 1) == 0))
             {
                 flag  = true;
                 empty = prefetch.Result;
             }
             if (!flag)
             {
                 VrVoxelMesh mesh = this.CreateMesh(geometryCellCoord);
                 empty            = this.CreateShape(mesh, lod);
                 if (mesh != null)
                 {
                     mesh.Dispose();
                 }
             }
             info.SetResult(i, ref empty);
         }, 1, WorkPriority.VeryHigh, new WorkOptions?(Parallel.DefaultOptions.WithDebugInfo(MyProfiler.TaskType.Voxels, "RequestBatch")), true);
     }
 }
예제 #5
0
        private void StartPrecalcJobPhysicsIfNeeded(int lod, int i)
        {
            MyCellCoord id = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]);

            if (!this.m_workTracker.Exists(id))
            {
                MyPrecalcJobPhysicsPrefetch.Args args = new MyPrecalcJobPhysicsPrefetch.Args {
                    TargetPhysics = this,
                    Tracker       = this.m_workTracker,
                    GeometryCell  = id,
                    Storage       = this.m_voxelMap.Storage
                };
                MyPrecalcJobPhysicsPrefetch.Start(args);
            }
        }
예제 #6
0
        private void RequestShapeBlockingInternal(int x, int y, int z, out HkShape shape, out HkReferencePolicy refPolicy, bool lod1physics)
        {
            ProfilerShort.Begin("MyVoxelPhysicsBody.RequestShapeBlocking");

            if (!m_bodiesInitialized)
            {
                CreateRigidBodies();
            }

            int lod       = lod1physics ? 1 : 0;
            var cellCoord = new MyCellCoord(lod, new Vector3I(x, y, z));

            shape = HkShape.Empty;
            // shape must take ownership, otherwise shapes created here will leak, since I can't remove reference
            refPolicy = HkReferencePolicy.TakeOwnership;
            //MyPrecalcComponent.QueueJobCancel(m_workTracker, cellCoord);
            if (m_voxelMap.MarkedForClose)
            {
                ProfilerShort.End();
                return;
            }
            if (MyDebugDrawSettings.DEBUG_DRAW_REQUEST_SHAPE_BLOCKING)
            {
                BoundingBoxD aabb;
                MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(m_voxelMap.PositionLeftBottomCorner, ref cellCoord, out aabb);
                MyRenderProxy.DebugDrawAABB(aabb, lod1physics ? Color.Yellow : Color.Red, 1, 1, true);
            }
            ProfilerShort.Begin("Generating geometry");
            MyIsoMesh geometryData = CreateMesh(m_voxelMap.Storage, cellCoord);

            ProfilerShort.End();

            if (!MyIsoMesh.IsEmpty(geometryData))
            {
                ProfilerShort.Begin("Shape from geometry");
                shape = CreateShape(geometryData, true);
                shape.AddReference();
                var args = new MyPrecalcJobPhysicsPrefetch.Args()
                {
                    GeometryCell = cellCoord, TargetPhysics = this, Tracker = m_workTracker, SimpleShape = shape
                };
                MyPrecalcJobPhysicsPrefetch.Start(args);
                m_needsShapeUpdate = true;
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
예제 #7
0
        public void PrefetchShapeOnRay(ref LineD ray)
        {
            int      lod = UseLod1VoxelPhysics ? 1 : 0;
            Vector3D localStart;

            MyVoxelCoordSystems.WorldPositionToLocalPosition(m_voxelMap.PositionLeftBottomCorner, ref ray.From, out localStart);

            Vector3D localEnd;

            MyVoxelCoordSystems.WorldPositionToLocalPosition(m_voxelMap.PositionLeftBottomCorner, ref ray.To, out localEnd);

            var shape = GetShape(lod);

            Debug.Assert(shape.Base.IsValid);

            if (m_cellsToGenerateBuffer.Length < 64)
            {
                m_cellsToGenerateBuffer = new Vector3I[64];
            }

            int requiredCellsCount = shape.GetHitCellsInRange(localStart, localEnd, m_cellsToGenerateBuffer);

            if (requiredCellsCount == 0)
            {
                return;
            }

            ProfilerShort.Begin("Start Jobs");
            for (int i = 0; i < requiredCellsCount; ++i)
            {
                var cell = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]);
                if (m_workTracker.Exists(cell))
                {
                    continue;
                }

                MyPrecalcJobPhysicsPrefetch.Start(new MyPrecalcJobPhysicsPrefetch.Args
                {
                    TargetPhysics = this,
                    Tracker       = m_workTracker,
                    GeometryCell  = cell,
                    Storage       = m_voxelMap.Storage
                });
            }
            ProfilerShort.End();
        }
예제 #8
0
 public void PrefetchShapeOnRay(ref LineD ray)
 {
     if (this.m_mesher != null)
     {
         Vector3            vector;
         Vector3            vector2;
         HkUniformGridShape shape;
         int lod = UseLod1VoxelPhysics ? 1 : 0;
         MyVoxelCoordSystems.WorldPositionToLocalPosition(this.m_voxelMap.PositionLeftBottomCorner, ref ray.From, out vector);
         MyVoxelCoordSystems.WorldPositionToLocalPosition(this.m_voxelMap.PositionLeftBottomCorner, ref ray.To, out vector2);
         if (this.GetShape(lod, out shape))
         {
             if (m_cellsToGenerateBuffer.Length < 0x40)
             {
                 m_cellsToGenerateBuffer = new Vector3I[0x40];
             }
             int num2 = shape.GetHitCellsInRange(vector, vector2, m_cellsToGenerateBuffer);
             if (num2 != 0)
             {
                 for (int i = 0; i < num2; i++)
                 {
                     MyCellCoord id = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]);
                     if (!this.m_workTracker.Exists(id))
                     {
                         MyPrecalcJobPhysicsPrefetch.Args args = new MyPrecalcJobPhysicsPrefetch.Args {
                             TargetPhysics = this,
                             Tracker       = this.m_workTracker,
                             GeometryCell  = id,
                             Storage       = this.m_voxelMap.Storage
                         };
                         MyPrecalcJobPhysicsPrefetch.Start(args);
                     }
                 }
             }
         }
     }
 }
예제 #9
0
        internal void UpdateAfterSimulation10()
        {
            UpdateRigidBodyShape();

            // Apply prediction based on movement of nearby entities.
            foreach (var entity in m_nearbyEntities)
            {
                if (!(entity is MyCubeGrid)) //jn:TODO prediction for lod0
                {
                    continue;
                }

                if (entity.MarkedForClose)
                {
                    continue;
                }

                if (entity.Physics.LinearVelocity.Length() < 2f)
                {
                    continue;
                }

                var predictionOffset = ComputePredictionOffset(entity);
                var aabb             = entity.WorldAABB;
                aabb.Inflate(MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES * 3);
                aabb.Translate(predictionOffset);
                if (!aabb.Intersects(m_voxelMap.PositionComp.WorldAABB))
                {
                    continue;
                }
                Vector3I min, max;
                Vector3D localPositionMin, localPositionMax;

                MyVoxelCoordSystems.WorldPositionToLocalPosition(aabb.Min, m_voxelMap.PositionComp.WorldMatrix, m_voxelMap.PositionComp.WorldMatrixInvScaled, m_voxelMap.SizeInMetresHalf, out localPositionMin);
                MyVoxelCoordSystems.WorldPositionToLocalPosition(aabb.Max, m_voxelMap.PositionComp.WorldMatrix, m_voxelMap.PositionComp.WorldMatrixInvScaled, m_voxelMap.SizeInMetresHalf, out localPositionMax);


                MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref localPositionMin, out min);
                MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref localPositionMax, out max);
                m_voxelMap.Storage.ClampVoxelCoord(ref min);
                m_voxelMap.Storage.ClampVoxelCoord(ref max);
                MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref min, out min);
                MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref max, out max);
                {
                    var size = (max - min + 1).Size;
                    if (size >= m_cellsToGenerateBuffer.Length)
                    {
                        m_cellsToGenerateBuffer = new Vector3I[MathHelper.GetNearestBiggerPowerOfTwo(size)];
                    }
                }
                var shape = (HkUniformGridShape)GetShape();// RigidBody.GetShape();
                Debug.Assert(shape.Base.IsValid);
                int requiredCellsCount = shape.GetMissingCellsInRange(ref min, ref max, m_cellsToGenerateBuffer);

                for (int i = 0; i < requiredCellsCount; ++i)
                {
                    if (m_workTracker.Exists(m_cellsToGenerateBuffer[i]))
                    {
                        continue;
                    }

                    MyPrecalcJobPhysicsPrefetch.Start(new MyPrecalcJobPhysicsPrefetch.Args()
                    {
                        TargetPhysics = this,
                        Tracker       = m_workTracker,
                        GeometryCell  = new MyCellCoord(0, m_cellsToGenerateBuffer[i]),
                        Storage       = m_voxelMap.Storage,
                    });
                }
            }
            var voxelShape = (HkUniformGridShape)GetShape();

            if (m_nearbyEntities.Count == 0 && RigidBody != null && MyFakes.ENABLE_VOXEL_PHYSICS_SHAPE_DISCARDING && voxelShape.ShapeCount > 0)
            {
                // RigidBody.GetShape();
                Debug.Assert(voxelShape.Base.IsValid);
                voxelShape.DiscardLargeData();
                if (RigidBody2 != null)
                {
                    voxelShape = (HkUniformGridShape)RigidBody2.GetShape();
                    voxelShape.DiscardLargeData();
                }
            }
        }
예제 #10
0
        internal void UpdateAfterSimulation10()
        {
            ProfilerShort.Begin("Voxel Physics Prediction");
            UpdateRigidBodyShape();

            // Apply prediction based on movement of nearby entities.
            foreach (var entity in m_nearbyEntities)
            {
                Debug.Assert(m_bodiesInitialized, "Voxel map does not have physics!");

                bool lod0 = entity is MyCharacter;

                if (!lod0)
                {
                    var body = entity.Physics as MyPhysicsBody;

                    if (body != null && body.RigidBody != null &&
                        (body.RigidBody.Layer == MyPhysics.CollisionLayers.FloatingObjectCollisionLayer || body.RigidBody.Layer == MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer))
                    {
                        lod0 = true;
                    }
                }

                if (!(entity is MyCubeGrid) && !lod0)
                {
                    continue;
                }

                if (entity.MarkedForClose)
                {
                    continue;
                }

                if (entity.Physics == null || entity.Physics.LinearVelocity.Length() < 2f)
                {
                    continue;
                }

                BoundingBoxD aabb;
                GetPrediction(entity, out aabb);
                if (!aabb.Intersects(m_voxelMap.PositionComp.WorldAABB))
                {
                    continue;
                }

                int   lod     = lod0 ? 0 : 1;
                float lodSize = 1 << lod;

                Vector3I min, max;
                Vector3D localPositionMin, localPositionMax;

                aabb = aabb.Transform(m_voxelMap.PositionComp.WorldMatrixInvScaled);

                aabb.Translate(m_voxelMap.SizeInMetresHalf);

                localPositionMax = aabb.Max;
                localPositionMin = aabb.Min;



                MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref localPositionMin, out min);
                MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref localPositionMax, out max);
                m_voxelMap.Storage.ClampVoxelCoord(ref min);
                m_voxelMap.Storage.ClampVoxelCoord(ref max);
                MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref min, out min);
                MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref max, out max);
                min >>= lod;
                max >>= lod;

                {
                    var size = (max - min + 1).Size;
                    if (size >= m_cellsToGenerateBuffer.Length)
                    {
                        m_cellsToGenerateBuffer = new Vector3I[MathHelper.GetNearestBiggerPowerOfTwo(size)];
                    }
                }
                var shape = GetShape(lod);

                Debug.Assert(shape.Base.IsValid);
                int requiredCellsCount = shape.GetMissingCellsInRange(ref min, ref max, m_cellsToGenerateBuffer);

                if (requiredCellsCount == 0)
                {
                    continue;
                }

                var bb = new BoundingBox(min * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES * lodSize, (max + 1) * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES * lodSize);
                bb.Translate(m_voxelMap.StorageMin);
                ProfilerShort.Begin("Storage Intersect");
                if (requiredCellsCount > 0 && m_voxelMap.Storage.Intersect(ref bb, false) != ContainmentType.Intersects)
                {
                    ProfilerShort.BeginNextBlock("Set Empty Shapes");
                    for (int i = 0; i < requiredCellsCount; ++i)
                    {
                        var cell = m_cellsToGenerateBuffer[i];
                        m_workTracker.Cancel(new MyCellCoord(lod, cell));
                        shape.SetChild(cell.X, cell.Y, cell.Z, (HkBvCompressedMeshShape)HkShape.Empty, HkReferencePolicy.TakeOwnership);
                    }
                    ProfilerShort.End();
                    continue;
                }

                ProfilerShort.BeginNextBlock("Start Jobs");
                for (int i = 0; i < requiredCellsCount; ++i)
                {
                    if (m_workTracker.Exists(new MyCellCoord(lod, m_cellsToGenerateBuffer[i])))
                    {
                        continue;
                    }

                    MyPrecalcJobPhysicsPrefetch.Start(new MyPrecalcJobPhysicsPrefetch.Args
                    {
                        TargetPhysics = this,
                        Tracker       = m_workTracker,
                        GeometryCell  = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]),
                        Storage       = m_voxelMap.Storage
                    });
                }
                ProfilerShort.End();
            }

            if (m_bodiesInitialized)
            {
                CheckAndDiscardShapes();
            }
            ProfilerShort.End();
        }