private void CreateSubpartsConstraint(MyEntitySubpart subpart) { m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_subpartsFixedData.SetInertiaStabilizationFactor(1); var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation); var matA = (Matrix)matAD; var matB = subpart.PositionComp.LocalMatrix; m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB); //Dont dispose the fixed data or we wont have access to them HkConstraintData constraintData = m_subpartsFixedData; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_subpartPhysics.RigidBody, constraintData); var info = CubeGrid.Physics.RigidBody.GetCollisionFilterInfo(); info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, HkGroupFilter.GetSystemGroupFromFilterInfo(info), 1, 1); m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info); CubeGrid.Physics.HavokWorld.RefreshCollisionFilterOnEntity(m_subpartPhysics.RigidBody); Debug.Assert(m_subpartsConstraint.RigidBodyA != null); m_subpartsConstraint.WantRuntime = true; }
private void InitSubpartsPhysics() { var subpart = m_subpart1; if (subpart == null || CubeGrid.Physics == null) { return; } m_subpartPhysics = new MyPhysicsBody(this, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT)); const float threshold = 0.11f; // Must be bigger than 2x convex radius HkCylinderShape shape = new HkCylinderShape(new Vector3(0, -2, 0), new Vector3(0, 2, 0), CubeGrid.GridSize / 2 - threshold, 0.05f); var mass = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(new Vector3(0, -2, 0), new Vector3(0, 2, 0), CubeGrid.GridSize / 2, 40.0f * CubeGrid.GridSize); mass.Mass = BlockDefinition.Mass; m_subpartPhysics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass); var info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1); m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info); shape.Base.RemoveReference(); if (m_subpartPhysics.RigidBody2 != null) { m_subpartPhysics.RigidBody2.Layer = MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer; } CubeGrid.OnHavokSystemIDChanged += CubeGrid_OnHavokSystemIDChanged; CreateSubpartsConstraint(subpart); m_posChanged = true; }
protected void CreateSubpartConstraint(VRage.Game.Entity.MyEntity subpart, out HkFixedConstraintData constraintData, out HkConstraint constraint) { constraintData = null; constraint = null; if (base.CubeGrid.Physics != null) { HkRigidBody rigidBody; uint info = HkGroupFilter.CalcFilterInfo(subpart.GetPhysicsBody().RigidBody.Layer, base.CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody.SetCollisionFilterInfo(info); subpart.Physics.Enabled = true; constraintData = new HkFixedConstraintData(); constraintData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); constraintData.SetInertiaStabilizationFactor(1f); if ((base.CubeGrid.Physics.RigidBody2 == null) || !base.CubeGrid.Physics.Flags.HasFlag(RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { rigidBody = base.CubeGrid.Physics.RigidBody; } else { rigidBody = base.CubeGrid.Physics.RigidBody2; } constraint = new HkConstraint(rigidBody, subpart.Physics.RigidBody, constraintData); constraint.WantRuntime = true; } }
internal void UpdateHavokCollisionSystemID(int HavokCollisionSystemID) { foreach (var subpart in m_subparts) { if (subpart != null && subpart.Physics != null) { if ((subpart.ModelCollision.HavokCollisionShapes != null) && (subpart.ModelCollision.HavokCollisionShapes.Length > 0)) { var info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody.SetCollisionFilterInfo(info); if (subpart.GetPhysicsBody().HavokWorld != null) { subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody); } if (subpart.Physics.RigidBody2 != null) { info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody2.SetCollisionFilterInfo(info); if (subpart.GetPhysicsBody().HavokWorld != null) { subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody2); } } /*if (this.CubeGrid.Physics != null && this.CubeGrid.GetPhysicsBody().HavokWorld != null) * { * this.CubeGrid.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(m_subpartDoor1.Physics.RigidBody); * this.CubeGrid.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(m_subpartDoor1.Physics.RigidBody2); * }*/ } } } }
void CubeGrid_OnHavokSystemIDChanged(int sysId) { if (CubeGrid.Physics != null && CubeGrid.Physics.RigidBody != null && m_subpartPhysics != null && m_subpartPhysics.RigidBody != null) { var info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, sysId, 1, 1); m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info); } }
protected override bool CreateConstraint(MyAttachableTopBlockBase rotor) { if (!base.CreateConstraint(rotor)) { return(false); } var rotorBody = TopGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.Restitution = 0.5f; CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody); if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); CubeGrid.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(rotorBody); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = (rotor as MyMotorRotor).DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(m_damping); data.SetSuspensionStrength(m_strenth); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint not added!"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint = null; return(false); } m_constraint.Enabled = true; return(true); }
protected static void SetupDoorSubpart(MyEntitySubpart subpart, int havokCollisionSystemID, bool refreshInPlace) { if (((subpart != null) && ((subpart.Physics != null) && (subpart.ModelCollision.HavokCollisionShapes != null))) && (subpart.ModelCollision.HavokCollisionShapes.Length != 0)) { uint info = HkGroupFilter.CalcFilterInfo(subpart.GetPhysicsBody().RigidBody.Layer, havokCollisionSystemID, 1, 1); subpart.Physics.RigidBody.SetCollisionFilterInfo(info); if ((subpart.GetPhysicsBody().HavokWorld != null) & refreshInPlace) { subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody); } } }
void CubeGrid_OnPhysicsChanged(MyEntity obj) { if (CubeGrid.Physics == null || m_topGrid == null || m_topGrid.Physics == null) { return; } var rotorBody = m_topGrid.Physics.RigidBody; if (rotorBody == null) { return; } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); }
internal void UpdateHavokCollisionSystemID(int HavokCollisionSystemID) { foreach (var subpart in m_subparts) { if (subpart != null && subpart.Physics != null) { if ((subpart.ModelCollision.HavokCollisionShapes != null) && (subpart.ModelCollision.HavokCollisionShapes.Length > 0)) { var info = HkGroupFilter.CalcFilterInfo(MyPhysics.KinematicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody.SetCollisionFilterInfo(info); info = HkGroupFilter.CalcFilterInfo(MyPhysics.DynamicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody2.SetCollisionFilterInfo(info); } } } }
internal void UpdateHavokCollisionSystemID(int HavokCollisionSystemID) { foreach (MyEntitySubpart subpart in this.m_subparts) { if (subpart == null) { continue; } if ((subpart.Physics != null) && ((subpart.ModelCollision.HavokCollisionShapes != null) && (subpart.ModelCollision.HavokCollisionShapes.Length != 0))) { uint info = HkGroupFilter.CalcFilterInfo(15, HavokCollisionSystemID, 1, 1); subpart.Physics.RigidBody.SetCollisionFilterInfo(info); if (subpart.GetPhysicsBody().HavokWorld != null) { subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody); } } } }
internal void DisableRagdollBodiesCollisions() { Debug.Assert(Ragdoll != null, "Ragdoll is null!"); if (MyFakes.ENABLE_RAGDOLL_DEBUG) { var world = HavokWorld; Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.StaticCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.VoxelCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DefaultCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterNetworkCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DebrisCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.GravityPhantomLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.VirtualMassLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.NoCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.ExplosionRaycastLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollisionLayerWithoutCharacter), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollideWithStaticLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollectorCollisionLayer), "Collision isn't disabled!"); Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.AmmoLayer), "Collision isn't disabled!"); } if (Ragdoll != null) { foreach (var body in Ragdoll.RigidBodies) { var info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.RagdollCollisionLayer, 0, 0, 0); //HavokWorld.DisableCollisionsBetween(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.RagdollCollisionLayer); //HavokWorld.DisableCollisionsBetween(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterCollisionLayer); body.SetCollisionFilterInfo(info); body.LinearVelocity = Vector3.Zero;// Character.Physics.LinearVelocity; body.AngularVelocity = Vector3.Zero; HavokWorld.RefreshCollisionFilterOnEntity(body); Debug.Assert(body.InWorld, "Body isn't in world!"); Debug.Assert(MyPhysics.CollisionLayers.RagdollCollisionLayer == HkGroupFilter.GetLayerFromFilterInfo(body.GetCollisionFilterInfo()), "Body is in wrong layer!"); } } }
/// <summary> /// Handles camera collisions with environment /// </summary> /// <param name="controlledEntity"></param> /// <param name="shakeActive"></param> /// <param name="headPosition"></param> /// <param name="headDirection"></param> /// <returns>False if no correct position was found</returns> private bool HandleIntersection(MyEntity controlledEntity, MyOrientedBoundingBoxD safeOBB, bool requireRaycast, bool shakeActive, Vector3D headPosition, Vector3 headDirection) { var line = new LineD(m_target, m_position); var safeOBBLine = new LineD(line.From, line.From + line.Direction * 2 * safeOBB.HalfExtent.Length()); Vector3D castStartSafe; { MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeOBB.Center, safeOBB.HalfExtent + 2 * CAMERA_RADIUS, safeOBB.Orientation); double?safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine); if (!safeIntersection.HasValue) { safeIntersection = safeOBB.HalfExtent.Length(); } double safeDistance = safeIntersection.Value; castStartSafe = line.From + line.Direction * safeDistance; } { double?unsafeIntersection = safeOBB.Intersects(ref safeOBBLine); if (!requireRaycast && unsafeIntersection.HasValue) { var castStartUnsafe = line.From + line.Direction * unsafeIntersection.Value; var castEndUnsafe = castStartSafe + line.Direction; // short raycast, not causing problems with asteroids generating geometry Physics.MyPhysics.CastRay(castStartUnsafe, castEndUnsafe, m_raycastList, MyPhysics.DefaultCollisionLayer); if (!IsRaycastOK(m_raycastList)) { return(false); } } } if (requireRaycast) { // short raycast, not causing problems with asteroids generating geometry Physics.MyPhysics.CastRay(line.From, castStartSafe + line.Direction, m_raycastList, MyPhysics.DefaultCollisionLayer); if (!IsRaycastOK(m_raycastList)) { return(false); } } HkShape shape = new HkSphereShape(CAMERA_RADIUS); try { // small shape, not causing problems with asteroids generating geometry Physics.MyPhysics.GetPenetrationsShape(shape, ref castStartSafe, ref Quaternion.Identity, m_rigidList, 15); if (m_rigidList.Count > 0) { bool sameGrid = false; if (MySession.ControlledEntity != null && m_rigidList[0] != null) { sameGrid = m_rigidList[0].UserObject == ((MyEntity)MySession.ControlledEntity).Physics; } if (sameGrid) { castStartSafe += line.Direction; } } var shapeCastLine = new LineD(castStartSafe, m_position); uint steps = 1; uint stepIdx = 0; if (shapeCastLine.Length > SHAPE_CAST_STEP) { steps = (uint)Math.Ceiling(shapeCastLine.Length / SHAPE_CAST_STEP); if (steps >= SHAPE_CAST_MAX_STEP_COUNT) { steps = SHAPE_CAST_MAX_STEP_COUNT - 1; } stepIdx = m_updateCount % steps; m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity; Vector3D step = shapeCastLine.Direction * (shapeCastLine.Length / steps); shapeCastLine = new LineD(castStartSafe + stepIdx * step, castStartSafe + (stepIdx + 1) * step); } if (false) { BoundingBoxD bbox = BoundingBoxD.CreateInvalid(); bbox.Include(new BoundingSphereD(shapeCastLine.From, CAMERA_RADIUS)); bbox.Include(new BoundingSphereD(shapeCastLine.To, CAMERA_RADIUS)); VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Color.Crimson, 1f, 1f, true); } var matrix = MatrixD.CreateTranslation(shapeCastLine.From); HkContactPointData?cpd; if (controlledEntity.Physics.CharacterProxy != null) { cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, controlledEntity.Physics.CharacterCollisionFilter, 0.0f); } else { cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, HkGroupFilter.CalcFilterInfo(MyPhysics.DefaultCollisionLayer, 0), 0.0f); } if (cpd.HasValue) { var point = shapeCastLine.From + shapeCastLine.Direction * shapeCastLine.Length * cpd.Value.DistanceFraction; m_lastShapeCastDistance[stepIdx] = (float)(castStartSafe - point).Length(); } else { m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity; } float?dist = null; for (int i = 0; i < steps; ++i) { if (m_lastShapeCastDistance[i] != float.PositiveInfinity) { dist = Math.Min(m_lastShapeCastDistance[i], dist ?? float.PositiveInfinity); } } if (dist.HasValue) { if (dist == 0.0f) { return(false); } else { m_positionSafe = castStartSafe + shapeCastLine.Direction * dist.Value; } } else { m_positionSafe = m_position; } return(true); } finally { shape.RemoveReference(); } }
protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); if (rotor is MyMotorRotor) { if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_topBlock = rotor; m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.Restitution = 0.5f; CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody); if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = (rotor as MyMotorRotor).DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(m_damping); data.SetSuspensionStrength(m_strenth); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint not added!"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint = null; return(false); } m_constraint.Enabled = true; m_topBlock.Attach(this); m_isAttached = true; PropagateFriction(m_friction); UpdateIsWorking(); if (m_updateBrakeNeeded) { UpdateBrake(); } if (m_updateFrictionNeeded) { FrictionChanged(); } if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); } return(true); } } return(false); }
public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true) { if (CubeGrid.Physics == null || SafeConstraint != null) { return(false); } Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && rotor != null) { m_rotorBlock = rotor; m_rotorBlockId = rotor.EntityId; if (updateSync) { SyncObject.AttachRotor(m_rotorBlock); } m_rotorGrid = m_rotorBlock.CubeGrid; var rotorBody = m_rotorGrid.Physics.RigidBody; rotorBody.MaxAngularVelocity = float.MaxValue; rotorBody.AngularDamping *= 4; if (MyFakes.WHEEL_SOFTNESS) { HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity); } var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1); rotorBody.SetCollisionFilterInfo(info); HkWheelConstraintData data = new HkWheelConstraintData(); var suspensionAx = PositionComp.LocalMatrix.Forward; var posA = DummyPosition + (suspensionAx * m_height); var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; //empirical values because who knows what havoc sees behind this //docs say one value should mean same effect for 2 ton or 200 ton vehicle //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity data.SetSuspensionDamping(Damping); data.SetSuspensionStrength(Strength); //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel); data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel); data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics); m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_rotorBlock.Attach(this); PropagateFriction(m_friction); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return(true); } return(false); }
private void ActivateJetpackRagdoll() { if (RagdollMapper == null || Character.Physics == null || Character.Physics.Ragdoll == null) { return; } if (!MyPerGameSettings.EnableRagdollModels) { return; } if (!MyPerGameSettings.EnableRagdollInJetpack) { return; } if (Character.Physics.HavokWorld == null) { return; } List <string> bodies = new List <string>(); string[] bodiesArray; if (Character.CurrentWeapon == null) { if (Character.Definition.RagdollPartialSimulations.TryGetValue("Jetpack", out bodiesArray)) { bodies.AddArray(bodiesArray); } else { // Fallback if missing definitions bodies.Add("Ragdoll_SE_rig_LUpperarm001"); bodies.Add("Ragdoll_SE_rig_LForearm001"); bodies.Add("Ragdoll_SE_rig_LPalm001"); bodies.Add("Ragdoll_SE_rig_RUpperarm001"); bodies.Add("Ragdoll_SE_rig_RForearm001"); bodies.Add("Ragdoll_SE_rig_RPalm001"); bodies.Add("Ragdoll_SE_rig_LThigh001"); bodies.Add("Ragdoll_SE_rig_LCalf001"); bodies.Add("Ragdoll_SE_rig_LFoot001"); bodies.Add("Ragdoll_SE_rig_RThigh001"); bodies.Add("Ragdoll_SE_rig_RCalf001"); bodies.Add("Ragdoll_SE_rig_RFoot001"); } } else { if (Character.Definition.RagdollPartialSimulations.TryGetValue("Jetpack_Weapon", out bodiesArray)) { bodies.AddArray(bodiesArray); } else { bodies.Add("Ragdoll_SE_rig_LThigh001"); bodies.Add("Ragdoll_SE_rig_LCalf001"); bodies.Add("Ragdoll_SE_rig_LFoot001"); bodies.Add("Ragdoll_SE_rig_RThigh001"); bodies.Add("Ragdoll_SE_rig_RCalf001"); bodies.Add("Ragdoll_SE_rig_RFoot001"); } } List <int> simulatedBodies = new List <int>(); foreach (var body in bodies) { simulatedBodies.Add(RagdollMapper.BodyIndex(body)); } if (!Character.Physics.IsRagdollModeActive) { Character.Physics.SwitchToRagdollMode(false); } if (Character.Physics.IsRagdollModeActive) { RagdollMapper.ActivatePartialSimulation(simulatedBodies); } // This is hack, ragdoll in jetpack sometimes can't settle and simulation is broken, if we find another way how to avoid that, this can be disabled if (!MyFakes.ENABLE_JETPACK_RAGDOLL_COLLISIONS) { foreach (var body in Character.Physics.Ragdoll.RigidBodies) { var info = HkGroupFilter.CalcFilterInfo(MyPhysics.RagdollCollisionLayer, 0, 0, 0); Character.Physics.HavokWorld.DisableCollisionsBetween(MyPhysics.RagdollCollisionLayer, MyPhysics.RagdollCollisionLayer); body.SetCollisionFilterInfo(info); body.LinearVelocity = Vector3.Zero; body.AngularVelocity = Vector3.Zero; } } RagdollMapper.ResetRagdoll(Character.WorldMatrix); }