internal MyVoxelPhysicsBody(MyVoxelBase voxelMap, float phantomExtend, float predictionSize = 3.0f) : base(voxelMap, RigidBodyFlag.RBF_STATIC) { m_predictionSize = predictionSize; m_phantomExtend = phantomExtend; m_voxelMap = voxelMap; Vector3I storageSize = m_voxelMap.Size; Vector3I numCels = storageSize >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; m_cellsOffset = m_voxelMap.StorageMin >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; HkUniformGridShape shape; HkRigidBody lod1rb = null; if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { shape = new HkUniformGridShape( new HkUniformGridShapeArgs() { CellsCount = numCels, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES, }); shape.SetShapeRequestHandler(RequestShapeBlockingLod1); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.VoxelLod1CollisionLayer); shape.Base.RemoveReference(); lod1rb = RigidBody; RigidBody = null; } shape = new HkUniformGridShape( new HkUniformGridShapeArgs() { CellsCount = numCels, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES, }); shape.SetShapeRequestHandler(RequestShapeBlocking); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.VoxelCollisionLayer); shape.Base.RemoveReference(); if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { RigidBody2 = lod1rb; } if (ENABLE_AABB_PHANTOM) { m_aabbPhantom = new Havok.HkpAabbPhantom(new BoundingBox(Vector3.Zero, m_voxelMap.SizeInMetres), 0); m_aabbPhantom.CollidableAdded = AabbPhantom_CollidableAdded; m_aabbPhantom.CollidableRemoved = AabbPhantom_CollidableRemoved; } if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION) { Friction = 0.65f; } MaterialType = MyMaterialType.ROCK; }
internal MyVoxelPhysicsBody(MyVoxelMap voxelMap): base(voxelMap, RigidBodyFlag.RBF_STATIC) { m_voxelMap = voxelMap; Vector3I storageSize = m_voxelMap.Size; Vector3I numCels = storageSize >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; m_cellsOffset = m_voxelMap.StorageMin >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; HkUniformGridShape shape = new HkUniformGridShape( new HkUniformGridShapeArgs() { CellsCount = numCels, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES, }); shape.SetShapeRequestHandler(RequestShapeBlocking); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.StaticCollisionLayer); shape.Base.RemoveReference(); if (ENABLE_AABB_PHANTOM) { m_aabbPhantom = new Havok.HkpAabbPhantom(new BoundingBox(Vector3.Zero, m_voxelMap.SizeInMetres), 0); m_aabbPhantom.CollidableAdded = AabbPhantom_CollidableAdded; m_aabbPhantom.CollidableRemoved = AabbPhantom_CollidableRemoved; } if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION) Friction = 0.65f; MaterialType = Sandbox.Common.MyMaterialType.ROCK; }
private void SetEmptyShapes(int lod, ref HkUniformGridShape shape, int requiredCellsCount) { for (int i = 0; i < requiredCellsCount; i++) { Vector3I coordInLod = m_cellsToGenerateBuffer[i]; this.m_workTracker.Cancel(new MyCellCoord(lod, coordInLod)); shape.SetChild(coordInLod.X, coordInLod.Y, coordInLod.Z, (HkBvCompressedMeshShape)HkShape.Empty, HkReferencePolicy.TakeOwnership); } }
public bool GetShape(int lod, Vector3D localPos, out HkBvCompressedMeshShape mesh) { HkUniformGridShape shape = (HkUniformGridShape)this.GetRigidBody(lod).GetShape(); localPos += this.m_voxelMap.SizeInMetresHalf; Vector3I vectori = new Vector3I(localPos / ((double)(8f * (1 << (lod & 0x1f))))); return(shape.GetChild(vectori.X, vectori.Y, vectori.Z, out mesh)); }
public bool GetShape(int lod, out HkUniformGridShape gridShape) { HkRigidBody rigidBody = this.GetRigidBody(lod); if (rigidBody == null) { gridShape = new HkUniformGridShape(); return(false); } gridShape = (HkUniformGridShape)rigidBody.GetShape(); return(true); }
private void RefreshUniformGridShapeCell(ref HkUniformGridShape shape, ref Vector3I cellCoord) { var cell = m_voxelMap.Geometry.GetCell(MyLodTypeEnum.LOD0, ref cellCoord); if (cell == null || cell.VoxelTrianglesCount == 0) { shape.RemoveChild(cellCoord.X, cellCoord.Y, cellCoord.Z); } else { cell.SetShapeToCell(shape, ref cellCoord); } }
internal void OnTaskComplete(MyCellCoord coord, HkBvCompressedMeshShape childShape) { Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen."); if (RigidBody != null) { HkUniformGridShape shape = GetShape(coord.Lod); Debug.Assert(shape.Base.IsValid); shape.SetChild(coord.CoordInLod.X, coord.CoordInLod.Y, coord.CoordInLod.Z, childShape, HkReferencePolicy.None); //BoundingBoxD worldAabb; //MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(m_voxelMap.PositionLeftBottomCorner, ref coord, out worldAabb); //VRageRender.MyRenderProxy.DebugDrawAABB(worldAabb, Color.Green, 1f, 1f, true); m_needsShapeUpdate = true; } }
/// <param name="min">Inclusive min</param> /// <param name="max">Exclusive max</param> private void RefreshUniformGridShapeRange(HkUniformGridShape shape, Vector3I min, Vector3I max) { Vector3I cellCoord; Profiler.Begin("MyVoxelMap.RefreshUniformGridShapeRange() - loop"); for (cellCoord.X = min.X; cellCoord.X < max.X; cellCoord.X++) { for (cellCoord.Y = min.Y; cellCoord.Y < max.Y; cellCoord.Y++) { for (cellCoord.Z = min.Z; cellCoord.Z < max.Z; cellCoord.Z++) { RefreshUniformGridShapeCell(ref shape, ref cellCoord); } } } Profiler.End(); }
private HkShape GetUniformGridShape() { var geometry = m_voxelMap.Geometry; var cellsCount = geometry.CellsCount; HkUniformGridShape shape = new HkUniformGridShape( cellsCount.X, cellsCount.Y, cellsCount.Z, MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, HkReferencePolicy.None); RefreshUniformGridShapeRange(shape, Vector3I.Zero, cellsCount); if (shape.ShapeCount > 0) { return(shape); } else { return(HkShape.Empty); } }
internal void OnBatchTaskComplete(Dictionary <Vector3I, HkBvCompressedMeshShape> newShapes, int lod) { Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen."); if (RigidBody != null) { HkUniformGridShape shape = GetShape(lod); Debug.Assert(shape.Base.IsValid); foreach (var entry in newShapes) { var coord = entry.Key; var childShape = entry.Value; shape.SetChild(coord.X, coord.Y, coord.Z, childShape, HkReferencePolicy.None); } m_needsShapeUpdate = true; /*if (InvalidCells.Count != 0) * MyPrecalcComponent.PhysicsWithInvalidCells.Add(this);*/ } }
private void CheckAndDiscardShapes() { this.m_lastDiscardCheck++; if (((this.m_lastDiscardCheck > 0x12) && ((this.m_nearbyEntities.Count == 0) && (this.RigidBody != null))) && EnableShapeDiscard) { this.m_lastDiscardCheck = 0; HkUniformGridShape shape = (HkUniformGridShape)this.GetShape(); int hitsAndClear = shape.GetHitsAndClear(); if ((shape.ShapeCount > 0) && (hitsAndClear <= 0)) { shape.DiscardLargeData(); if (this.RigidBody2 != null) { shape = (HkUniformGridShape)this.RigidBody2.GetShape(); if (shape.GetHitsAndClear() <= 0) { shape.DiscardLargeData(); } } } } }
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(); } } }
public void SetShapeToCell(HkUniformGridShape shape, ref Vector3I cellCoord) { CreateMeshShape(); shape.SetChild(cellCoord.X, cellCoord.Y, cellCoord.Z, m_meshShape); }
private HkShape GetUniformGridShape() { var geometry = m_voxelMap.Geometry; var cellsCount = geometry.CellsCount; HkUniformGridShape shape = new HkUniformGridShape( cellsCount.X, cellsCount.Y, cellsCount.Z, MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, HkReferencePolicy.None); RefreshUniformGridShapeRange(shape, Vector3I.Zero, cellsCount); if (shape.ShapeCount > 0) { return shape; } else { return HkShape.Empty; } }
internal void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged, int lod) { MyPrecalcComponent.AssertUpdateThread(); // No physics there ever was so we don't care. if (!m_bodiesInitialized) { return; } if (m_queueInvalidation) { if (m_queuedRange.Max.X < 0) { m_queuedRange = new BoundingBoxI(minVoxelChanged, maxVoxelChanged); } else { var bb = new BoundingBoxI(minVoxelChanged, maxVoxelChanged); m_queuedRange.Include(ref bb); } return; } ProfilerShort.Begin("MyVoxelPhysicsBody.InvalidateRange"); minVoxelChanged -= MyPrecalcComponent.InvalidatedRangeInflate; maxVoxelChanged += MyPrecalcComponent.InvalidatedRangeInflate; m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged); m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged); Vector3I minCellChanged, maxCellChanged; MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out minCellChanged); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out maxCellChanged); Vector3I minCellChangedVoxelMap, maxCellChangedVoxelMap; minCellChangedVoxelMap = (minCellChanged - m_cellsOffset) >> lod; maxCellChangedVoxelMap = (maxCellChanged - m_cellsOffset) >> lod; var maxCell = m_voxelMap.Size - 1; MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxCell, out maxCell); maxCell >>= lod; Vector3I.Min(ref maxCellChangedVoxelMap, ref maxCell, out maxCellChangedVoxelMap); Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen."); var rb = GetRigidBody(lod); Debug.Assert(rb != null, "RigidBody in voxel physics is null! This must not happen."); if (rb != null) { HkUniformGridShape shape = (HkUniformGridShape)rb.GetShape(); Debug.Assert(shape.Base.IsValid); var tmpBuffer = m_cellsToGenerateBuffer; int invalidCount = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer); if (invalidCount > tmpBuffer.Length) { // Not storing this new buffer in static variable since this is just temporary and potentially large. // Static variable could be potentially the same as leak. tmpBuffer = new Vector3I[invalidCount]; int invalidCount2 = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer); Debug.Assert(invalidCount == invalidCount2); invalidCount = invalidCount2; } shape.InvalidateRangeImmediate(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap); Debug.Assert(invalidCount <= tmpBuffer.Length); for (int i = 0; i < invalidCount; i++) { InvalidCells.Add(tmpBuffer[i]); } if (RunningBatchTask == null && InvalidCells.Count != 0) { MyPrecalcComponent.PhysicsWithInvalidCells.Add(this); } } if (minCellChangedVoxelMap == Vector3I.Zero && maxCellChangedVoxelMap == maxCell) { m_workTracker.CancelAll(); } else { var cell = minCellChanged; for (var it = new Vector3I.RangeIterator(ref minCellChanged, ref maxCellChanged); it.IsValid(); it.GetNext(out cell)) { m_workTracker.Cancel(new MyCellCoord(lod, cell)); } } m_needsShapeUpdate = true; ProfilerShort.End(); m_voxelMap.RaisePhysicsChanged(); }
/// <param name="min">Inclusive min</param> /// <param name="max">Exclusive max</param> private void RefreshUniformGridShapeRange(HkUniformGridShape shape, Vector3I min, Vector3I max) { Vector3I cellCoord; Profiler.Begin("MyVoxelMap.RefreshUniformGridShapeRange() - loop"); for (cellCoord.X = min.X; cellCoord.X < max.X; cellCoord.X++) for (cellCoord.Y = min.Y; cellCoord.Y < max.Y; cellCoord.Y++) for (cellCoord.Z = min.Z; cellCoord.Z < max.Z; cellCoord.Z++) { RefreshUniformGridShapeCell(ref shape, ref cellCoord); } Profiler.End(); }
private void RefreshUniformGridShapeCell(ref HkUniformGridShape shape, ref Vector3I cellCoord) { var cell = m_voxelMap.Geometry.GetCell(MyLodTypeEnum.LOD0, ref cellCoord); if (cell == null || cell.VoxelTrianglesCount == 0) shape.RemoveChild(cellCoord.X, cellCoord.Y, cellCoord.Z); else cell.SetShapeToCell(shape, ref cellCoord); }
internal void InvalidateRange(Vector3I minVoxelChanged, Vector3I maxVoxelChanged, int lod) { MyPrecalcComponent.AssertUpdateThread(); // No physics there ever was so we don't care. if (!m_bodiesInitialized) { return; } if (m_queueInvalidation) { if (m_queuedRange.Max.X < 0) { m_queuedRange = new BoundingBoxI(minVoxelChanged, maxVoxelChanged); } else { var bb = new BoundingBoxI(minVoxelChanged, maxVoxelChanged); m_queuedRange.Include(ref bb); } return; } ProfilerShort.Begin("MyVoxelPhysicsBody.InvalidateRange"); minVoxelChanged -= 1; // MyPrecalcComponent.InvalidatedRangeInflate; maxVoxelChanged += 1; //MyPrecalcComponent.InvalidatedRangeInflate; m_voxelMap.Storage.ClampVoxelCoord(ref minVoxelChanged); m_voxelMap.Storage.ClampVoxelCoord(ref maxVoxelChanged); Vector3I minCellChanged, maxCellChanged; MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref minVoxelChanged, out minCellChanged); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxVoxelChanged, out maxCellChanged); Vector3I minCellChangedVoxelMap, maxCellChangedVoxelMap; minCellChangedVoxelMap = (minCellChanged - m_cellsOffset) >> lod; maxCellChangedVoxelMap = (maxCellChanged - m_cellsOffset) >> lod; var maxCell = m_voxelMap.Size - 1; MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref maxCell, out maxCell); maxCell >>= lod; Vector3I.Min(ref maxCellChangedVoxelMap, ref maxCell, out maxCellChangedVoxelMap); Debug.Assert(RigidBody != null, "RigidBody in voxel physics is null! This must not happen."); var rb = GetRigidBody(lod); Debug.Assert(rb != null, "RigidBody in voxel physics is null! This must not happen."); if (rb != null) { HkUniformGridShape shape = (HkUniformGridShape)rb.GetShape(); Debug.Assert(shape.Base.IsValid); var numCells = (maxCellChangedVoxelMap - minCellChangedVoxelMap + 1).Size; if (numCells >= m_cellsToGenerateBuffer.Length) { m_cellsToGenerateBuffer = new Vector3I[MathHelper.GetNearestBiggerPowerOfTwo(numCells)]; } var tmpBuffer = m_cellsToGenerateBuffer; int invalidCount = shape.InvalidateRange(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap, tmpBuffer); Debug.Assert(invalidCount <= tmpBuffer.Length); //if (numCells <= 8) //shape.InvalidateRangeImmediate(ref minCellChangedVoxelMap, ref maxCellChangedVoxelMap); Debug.Assert(invalidCount <= tmpBuffer.Length); for (int i = 0; i < invalidCount; i++) { InvalidCells[lod].Add(tmpBuffer[i]); } if (RunningBatchTask[lod] == null && InvalidCells[lod].Count != 0) { MyPrecalcComponent.PhysicsWithInvalidCells.Add(this); } } if (minCellChangedVoxelMap == Vector3I.Zero && maxCellChangedVoxelMap == maxCell) { m_workTracker.CancelAll(); } else { var cell = minCellChanged; for (var it = new Vector3I_RangeIterator(ref minCellChanged, ref maxCellChanged); it.IsValid(); it.GetNext(out cell)) { m_workTracker.Cancel(new MyCellCoord(lod, cell)); } } m_needsShapeUpdate = true; ProfilerShort.End(); m_voxelMap.RaisePhysicsChanged(); }
private void CreateRigidBodies() { if (Entity.MarkedForClose) { return; } ProfilerShort.Begin("MyVoxelPhysicsBody::CreateRigidBodies()"); try { if (m_bodiesInitialized) { Debug.Fail("Double rigid body intialization for voxel map!"); return; } Vector3I numCels = m_voxelMap.Size >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; HkUniformGridShape shape; HkRigidBody lod1rb = null; if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { shape = new HkUniformGridShape( new HkUniformGridShapeArgs { CellsCount = numCels >> 1, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES * 2, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES }); shape.SetShapeRequestHandler(RequestShapeBlockingLod1, QueryEmptyOrFull); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.CollisionLayers.VoxelLod1CollisionLayer); shape.Base.RemoveReference(); lod1rb = RigidBody; RigidBody = null; } shape = new HkUniformGridShape( new HkUniformGridShapeArgs { CellsCount = numCels, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES }); shape.SetShapeRequestHandler(RequestShapeBlocking, QueryEmptyOrFull); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.CollisionLayers.VoxelCollisionLayer); shape.Base.RemoveReference(); if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { RigidBody2 = lod1rb; } if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION) { Friction = 0.65f; } m_bodiesInitialized = true; // When doing the enable disable roundtrip we can mess up the ClusterTree because Activate() can end up calling this // if the phantom is immediatelly intersecting something. if (Enabled) { var matrix = GetRigidBodyMatrix(); RigidBody.SetWorldMatrix(matrix); m_world.AddRigidBody(RigidBody); if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { RigidBody2.SetWorldMatrix(matrix); m_world.AddRigidBody(RigidBody2); } } } finally { ProfilerShort.End(); } }
private void CreateRigidBodies() { if ((!base.Entity.MarkedForClose && (this.m_mesher != null)) && (base.m_world != null)) { try { if (!this.m_bodiesInitialized) { HkUniformGridShape shape; HkUniformGridShapeArgs args; HkMassProperties? nullable; Vector3I vectori = this.m_voxelMap.Size >> 3; HkRigidBody rigidBody = null; if (UseLod1VoxelPhysics) { args = new HkUniformGridShapeArgs { CellsCount = vectori >> 1, CellSize = 16f, CellOffset = 0.5f, CellExpand = 1f }; shape = new HkUniformGridShape(args); shape.SetShapeRequestHandler(new RequestShapeBatchBlockingDelegate(this.RequestShapeBlockingLod1)); nullable = null; this.CreateFromCollisionObject((HkShape)shape, -this.m_voxelMap.SizeInMetresHalf, this.m_voxelMap.WorldMatrix, nullable, 11); shape.Base.RemoveReference(); rigidBody = this.RigidBody; this.RigidBody = null; } args = new HkUniformGridShapeArgs { CellsCount = vectori, CellSize = 8f, CellOffset = 0.5f, CellExpand = 1f }; shape = new HkUniformGridShape(args); shape.SetShapeRequestHandler(new RequestShapeBatchBlockingDelegate(this.RequestShapeBlocking)); nullable = null; this.CreateFromCollisionObject((HkShape)shape, -this.m_voxelMap.SizeInMetresHalf, this.m_voxelMap.WorldMatrix, nullable, 0x1c); shape.Base.RemoveReference(); this.RigidBody.IsEnvironment = true; if (UseLod1VoxelPhysics) { this.RigidBody2 = rigidBody; } if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION) { this.Friction = 0.65f; } this.m_bodiesInitialized = true; if (this.Enabled) { Matrix rigidBodyMatrix = base.GetRigidBodyMatrix(); this.RigidBody.SetWorldMatrix(rigidBodyMatrix); base.m_world.AddRigidBody(this.RigidBody); if (UseLod1VoxelPhysics) { this.RigidBody2.SetWorldMatrix(rigidBodyMatrix); base.m_world.AddRigidBody(this.RigidBody2); } } } } finally { } } }
private void CreateRigidBodies() { if (Entity.MarkedForClose) return; ProfilerShort.Begin("MyVoxelPhysicsBody::CreateRigidBodies()"); try { if (m_bodiesInitialized) { Debug.Fail("Double rigid body intialization for voxel map!"); return; } Vector3I numCels = m_voxelMap.Size >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS; HkUniformGridShape shape; HkRigidBody lod1rb = null; if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { shape = new HkUniformGridShape( new HkUniformGridShapeArgs { CellsCount = numCels>>1, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES * 2, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES }); shape.SetShapeRequestHandler(RequestShapeBlockingLod1, QueryEmptyOrFull); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.CollisionLayers.VoxelLod1CollisionLayer); shape.Base.RemoveReference(); lod1rb = RigidBody; RigidBody = null; } shape = new HkUniformGridShape( new HkUniformGridShapeArgs { CellsCount = numCels, CellSize = MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, CellOffset = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF, CellExpand = MyVoxelConstants.VOXEL_SIZE_IN_METRES }); shape.SetShapeRequestHandler(RequestShapeBlocking, QueryEmptyOrFull); CreateFromCollisionObject(shape, -m_voxelMap.SizeInMetresHalf, m_voxelMap.WorldMatrix, collisionFilter: MyPhysics.CollisionLayers.VoxelCollisionLayer); shape.Base.RemoveReference(); if (MyFakes.USE_LOD1_VOXEL_PHYSICS) RigidBody2 = lod1rb; if (MyFakes.ENABLE_PHYSICS_HIGH_FRICTION) Friction = 0.65f; m_bodiesInitialized = true; // When doing the enable disable roundtrip we can mess up the ClusterTree because Activate() can end up calling this // if the phantom is immediatelly intersecting something. if (Enabled) { var matrix = GetRigidBodyMatrix(); RigidBody.SetWorldMatrix(matrix); m_world.AddRigidBody(RigidBody); if (MyFakes.USE_LOD1_VOXEL_PHYSICS) { RigidBody2.SetWorldMatrix(matrix); m_world.AddRigidBody(RigidBody2); } } } finally { ProfilerShort.End(); } }