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(); }