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); } }
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); } } }
public static void Start(Args args) { MyPrecalcJobPhysicsPrefetch work = m_instancePool.Allocate(); work.m_args = args; args.Tracker.Add(args.GeometryCell, work); MyPrecalcComponent.EnqueueBack(work); }
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); } }
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); } }
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(); }
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(); }
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); } } } } } }
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(); } } }
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(); }