private void CreateConstraint(MyEntitySubpart subpart, ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (subpart != null) { bool flag = !Sync.IsServer; if (subpart.Physics == null) { HkShape[] havokCollisionShapes = subpart.ModelCollision.HavokCollisionShapes; if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0)) { MyPhysicsBody body = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { IsSubpart = true }; subpart.Physics = body; HkShape shape = havokCollisionShapes[0]; MyPositionComponentBase positionComp = subpart.PositionComp; Vector3 center = positionComp.LocalVolume.Center; HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(positionComp.LocalAABB.HalfExtents, 100f); int collisionFilter = base.CubeGrid.IsStatic ? 9 : 0x10; body.CreateFromCollisionObject(shape, center, positionComp.WorldMatrix, new HkMassProperties?(properties), collisionFilter); } } if (flag) { subpart.Physics.Enabled = true; } else { base.CreateSubpartConstraint(subpart, out constraintData, out constraint); base.CubeGrid.Physics.AddConstraint(constraint); constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One); } } }
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; if (m_rotorGrid.Physics == null) { return(false); } var rotorBody = m_rotorGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(ref posA, ref posB, ref axisA, ref axisB, ref axisAPerp, ref axisBPerp); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; SetAngleToPhysics(); m_rotorBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } m_isAttached = true; return(true); } return(false); }
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; if (Sync.IsServer) // Breakable only on server { constraintData = new HkBreakableConstraintData(m_subpartsFixedData) { Threshold = BreakOffTreshold }; } m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, constraintData); Debug.Assert(m_subpartsConstraint.RigidBodyA != null); m_subpartsConstraint.WantRuntime = true; }
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; }
internal void Detach() { if (m_constraint == null) { return; } Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) { m_topBlock.Detach(); } tmpTopGrid.OnPhysicsChanged -= CubeGrid_OnPhysicsChanged; m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); UpdateText(); }
private void CreateConstraint(MyCubeGrid other, MyShipMergeBlock block) { var data = new HkPrismaticConstraintData(); data.MaximumLinearLimit = 0; data.MinimumLinearLimit = 0; var posA = ConstraintPositionInGridSpace(); var posB = block.ConstraintPositionInGridSpace(); var axisA = PositionComp.LocalMatrix.GetDirectionVector(m_forward); var axisAPerp = PositionComp.LocalMatrix.GetDirectionVector(m_right); var axisB = -block.PositionComp.LocalMatrix.GetDirectionVector(m_forward); Base6Directions.Direction thisRightForOther = block.WorldMatrix.GetClosestDirection(WorldMatrix.GetDirectionVector(m_right)); Base6Directions.Direction otherRight = WorldMatrix.GetClosestDirection(block.WorldMatrix.GetDirectionVector(block.m_right)); var axisBPerp = block.PositionComp.LocalMatrix.GetDirectionVector(thisRightForOther); data.SetInBodySpace(posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, other.Physics); var data2 = new HkMalleableConstraintData(); data2.SetData(data); data.ClearHandle(); data = null; data2.Strength = 0.00001f; var constraint = new HkConstraint(CubeGrid.Physics.RigidBody, other.Physics.RigidBody, data2); AddConstraint(constraint); SetConstraint(block, constraint, otherRight); m_other.SetConstraint(this, constraint, thisRightForOther); }
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; } }
protected override bool Attach(MyAttachableTopBlockBase topBlock, bool updateGroup = true) { Debug.Assert(topBlock != null, "Top block cannot be null!"); if (CubeGrid == topBlock.CubeGrid) { return(false); } MyPistonTop pistonTop = topBlock as MyPistonTop; if (pistonTop != null && base.Attach(topBlock, updateGroup)) { Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!"); Debug.Assert(m_connectionState.Value.TopBlockId.HasValue && (m_connectionState.Value.TopBlockId.Value == 0 || m_connectionState.Value.TopBlockId.Value == topBlock.EntityId), "m_topBlockId must be set prior calling Attach!"); UpdateAnimation(); var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics); //Dont dispose the fixed data or we wont have access to them m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, topBlock.CubeGrid.Physics.RigidBody, m_fixedData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData = null; return(false); } m_constraint.Enabled = true; m_topBlock = topBlock; m_topGrid = topBlock.CubeGrid; topBlock.Attach(this); m_isAttached = true; if (updateGroup) { m_conveyorEndpoint.Attach(pistonTop.ConveyorEndpoint as MyAttachableConveyorEndpoint); } UpdateText(); return(true); } return(false); }
public void Attach(MyPistonTop topBlock) { if (CubeGrid == topBlock.CubeGrid) { return; } Debug.Assert(topBlock != null, "Top block cannot be null!"); Debug.Assert(m_constraint == null, "Contraint already attached, call detach first!"); Debug.Assert(m_topBlockId.Value == topBlock.EntityId, "m_topBlockId must be set prior calling Attach!"); UpdateAnimation(); if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled && topBlock.CubeGrid.Physics != null) { m_topBlock = topBlock; m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(matA, matB, CubeGrid.Physics, m_topGrid.Physics); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { Debug.Fail("Constraint was not added to world"); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_fixedData.Dispose(); m_fixedData = null; return; } m_constraint.Enabled = true; m_topBlock.Attach(this); m_topGrid.OnPhysicsChanged += CubeGrid_OnPhysicsChanged; OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); UpdateText(); } }
protected override void DisposeConstraint() { if (m_constraint != null) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; } }
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; 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(ref posB, ref posA, ref axisB, ref axisA, ref suspensionAx, ref suspensionAx); 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); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return(true); } return(false); }
private void Detach() { if (MyFakes.WELD_LANDING_GEARS) { if (CubeGrid.Physics == null || CubeGrid.Physics.WeldInfo.Parent == null) { return; } MyWeldingGroups.Static.BreakLink(EntityId, CubeGrid.Physics.WeldInfo.Parent.Entity as MyEntity, CubeGrid); //OnConstraintRemoved(GridLinkTypeEnum.LandingGear, m_attachedTo); if (m_attachedTo != null) { m_attachedTo.OnPhysicsChanged -= m_physicsChangedHandler; } this.OnPhysicsChanged -= m_physicsChangedHandler; LockMode = LandingGearMode.Unlocked; m_attachedTo = null; return; } if (m_constraint == null) { return; } this.OnPhysicsChanged -= m_physicsChangedHandler; var tmpAttachedEntity = m_attachedTo; Debug.Assert(m_attachedTo != null, "Attached entity is null"); if (m_attachedTo != null) { m_attachedTo.OnPhysicsChanged -= m_physicsChangedHandler; } m_attachedTo = null; if (!m_needsToRetryLock && !MarkedForClose) { StartSound(m_unlockSound); } CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; LockMode = LandingGearMode.Unlocked; OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpAttachedEntity); OnConstraintRemoved(GridLinkTypeEnum.NoContactDamage, tmpAttachedEntity); var handle = StateChanged; if (handle != null) { handle(false); } }
private void Detach() { if (CubeGrid.Physics == null || m_attachedTo == null) { return; } if (Sync.IsServer && m_attachedTo is MyCubeGrid) { (m_attachedTo as MyCubeGrid).OnGridSplit -= CubeGrid_OnGridSplit; } m_lockModeSync.Value = LandingGearMode.Unlocked; var attachedTo = m_attachedTo; if (m_attachedTo != null) { m_attachedTo.OnPhysicsChanged -= m_physicsChangedHandler; } this.OnPhysicsChanged -= m_physicsChangedHandler; m_attachedTo = null; m_attachedEntityId = null; if (m_converted) { CubeGrid.Physics.ConvertToDynamic(CubeGrid.GridSizeEnum == MyCubeSize.Large); m_converted = false; } if (MyFakes.WELD_LANDING_GEARS && MyWeldingGroups.Static.LinkExists(EntityId, CubeGrid, (MyEntity)m_attachedTo)) { MyWeldingGroups.Static.BreakLink(EntityId, CubeGrid, (MyEntity)attachedTo); } else { if (m_constraint != null) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; } OnConstraintRemoved(GridLinkTypeEnum.NoContactDamage, attachedTo); } OnConstraintRemoved(GridLinkTypeEnum.Physical, attachedTo); if (!m_needsToRetryLock && !MarkedForClose) { StartSound(m_unlockSound); } var handle = StateChanged; if (handle != null) { handle(false); } }
protected void RemoveConstraint() { Debug.Assert(InConstraint); m_constraint = null; m_other = null; CheckEmissivity(); NeedsUpdate &= ~MyEntityUpdateEnum.EACH_FRAME; }
protected void DisposeSubpartConstraint(ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (constraint != null) { base.CubeGrid.Physics.RemoveConstraint(constraint); constraint.Dispose(); constraint = null; constraintData = null; } }
private void DisposeSubpartsConstraint() { if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; m_subpartsFixedData = null; }
public void Attach(MyPistonTop topBlock, bool updateSync = false) { if (m_topBlock != null) { Detach(); } if (CubeGrid.Physics == null || SafeConstraint != null) { return; } UpdateAnimation(); Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && topBlock != null) { m_topBlock = topBlock; m_topBlockId = topBlock.EntityId; if (updateSync) { SyncObject.AttachTop(m_topBlock); } m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(ref matA, ref matB); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_topBlock.Attach(this); OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); } }
private void DisposeConstraints() { for (int i = 0; i < this.m_subpartConstraints.Count; i++) { HkConstraint constraint = this.m_subpartConstraints[i]; HkFixedConstraintData constraintData = this.m_subpartConstraintsData[i]; base.DisposeSubpartConstraint(ref constraint, ref constraintData); } this.m_subpartConstraints.Clear(); this.m_subpartConstraintsData.Clear(); }
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); }
private void DisposePhantomContraint(MyCubeGrid oldGrid = null) { if (this.m_phantomConstraint != null) { if (oldGrid == null) { oldGrid = base.CubeGrid; } oldGrid.Physics.RemoveConstraint(this.m_phantomConstraint); this.m_phantomConstraint.Dispose(); this.m_phantomConstraint = null; } }
protected void SetConstraint(MyShipMergeBlock otherBlock, HkConstraint constraint, Base6Directions.Direction otherRight) { Debug.Assert(m_constraint == null && m_other == null); if (m_constraint != null || m_other != null) { return; } m_constraint = constraint; m_other = otherBlock; m_otherRight = otherRight; CheckEmissivity(); NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; }
protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true) { if (rotor is MyMotorRotor && base.Attach(rotor, updateGroup)) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_connectionState.Value.TopBlockId == 0 || m_connectionState.Value.TopBlockId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); var rotorBody = m_topGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, m_topGrid.Physics); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if (!m_constraint.InWorld) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; return(false); } m_constraint.Enabled = true; SetAngleToPhysics(); m_topBlock.Attach(this); m_isAttached = true; UpdateText(); return(true); } return(false); }
private void DisposeSubpartsConstraint() { if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; if (Sync.IsServer) { // On server, contraint contains breakable data, fixed data must be disposed manually // On client, contraint contains fixed data, which are disposed with constraint m_subpartsFixedData.Dispose(); } m_subpartsFixedData = null; }
private void CreatePhantomConstraint() { if (this.m_phantomConstraint != null) { this.DisposePhantomContraint(null); } MyGridPhysics bodyA = base.CubeGrid.Physics; MyPhysicsBody physics = base.Physics; if (((bodyA != null) && (physics != null)) && physics.Enabled) { HkFixedConstraintData data = new HkFixedConstraintData(); data.SetInBodySpace(base.PositionComp.LocalMatrix, Matrix.CreateTranslation(-physics.Center), bodyA, physics); this.m_phantomConstraint = new HkConstraint(bodyA.RigidBody, physics.RigidBody, data); bodyA.AddConstraint(this.m_phantomConstraint); } }
private void CheckSubpartConstraint() { if (m_subpartsConstraint != null && (m_subpartsConstraint.RigidBodyA == null)) { if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; var breakableData = new HkBreakableConstraintData(m_subpartsFixedData); //Dont dispose the fixed data or we wont have access to them breakableData.Threshold = BreakOffTreshold; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_subpart1.Physics.RigidBody, breakableData); Debug.Assert(m_subpartsConstraint.RigidBodyA != null); m_subpartsConstraint.WantRuntime = true; } }
private void Detach() { if (CubeGrid.Physics == null || m_attachedTo == null) { return; } Debug.Assert(m_attachedTo != null, "Attached entity is null"); LockMode = LandingGearMode.Unlocked; var attachedTo = m_attachedTo; if (m_attachedTo != null) { m_attachedTo.OnPhysicsChanged -= m_physicsChangedHandler; } this.OnPhysicsChanged -= m_physicsChangedHandler; m_attachedTo = null; if (MyFakes.WELD_LANDING_GEARS && MyWeldingGroups.Static.LinkExists(EntityId, CubeGrid, (MyEntity)m_attachedTo)) { MyWeldingGroups.Static.BreakLink(EntityId, CubeGrid, (MyEntity)attachedTo); } else { if (m_constraint != null) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; } OnConstraintRemoved(GridLinkTypeEnum.NoContactDamage, attachedTo); } OnConstraintRemoved(GridLinkTypeEnum.Physical, attachedTo); if (!m_needsToRetryLock && !MarkedForClose) { StartSound(m_unlockSound); } var handle = StateChanged; if (handle != null) { handle(false); } }
public virtual bool Detach(bool updateGroup = true, bool reattach = true) { if (m_constraint == null) { return(false); } Debug.Assert(m_constraint != null); Debug.Assert(m_rotorGrid != null); Debug.Assert(m_rotorBlock != null); var tmpRotorGrid = m_rotorGrid; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_rotorGrid = null; if (m_rotorBlock != null) { m_rotorBlock.Detach(); } m_rotorBlock = null; // The following line is commented out on purpose! If you move the motor between grids (e.g. after splitting), // you have to remember the attached rotor somehow. This rotorBlockId is how it's remembered. //m_rotorBlockId = 0; if (updateGroup) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpRotorGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpRotorGrid); } if (reattach) { // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; } if (tmpRotorGrid != null) { tmpRotorGrid.OnPhysicsChanged -= cubeGrid_OnPhysicsChanged; } return(true); }
private void InitSubpartsPhysics() { var subpart = m_subpart1; if (subpart == null || CubeGrid.Physics == null) { return; } subpart.Physics = new MyPhysicsBody(subpart, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT)); HkCylinderShape shape = new HkCylinderShape(Vector3.Zero, new Vector3(0, 0, 2), CubeGrid.GridSize / 2); var mass = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(Vector3.Zero, Vector3.One, 1, 40.0f * CubeGrid.GridSize); subpart.Physics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass); shape.Base.RemoveReference(); subpart.Physics.RigidBody.Layer = CubeGrid.Physics.RigidBody.Layer; if (subpart.Physics.RigidBody2 != null) { subpart.Physics.RigidBody2.Layer = MyPhysics.KinematicDoubledCollisionLayer; } m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); float res; var x = m_subpartsFixedData.GetInertiaStabilizationFactor(out res); 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); var breakableData = new HkBreakableConstraintData(m_subpartsFixedData); //Dont dispose the fixed data or we wont have access to them breakableData.Threshold = BreakOffTreshold; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, breakableData); m_subpartsConstraint.WantRuntime = true; m_posChanged = true; }
internal void Detach(bool updateGroups = true) { if (m_constraint == null) { return; } Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; if (m_constraint.InWorld && (m_constraint.ConstraintData as HkBreakableConstraintData).getIsBroken(m_constraint)) { m_topBlockId = 0; } m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) { m_topBlock.Detach(); } m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; if (updateGroups) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); } // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids }
private void DisposeSubpartsPhysics() { if (m_subpartsConstraint != null) { m_subpartsFixedData.Dispose(); m_subpartsFixedData = null; if (m_subPartContraintInScene) { m_subPartContraintInScene = false; CubeGrid.Physics.RemoveConstraint(m_subpartsConstraint); } m_subpartsConstraint.Dispose(); m_subpartsConstraint = null; } if (m_subpart1 != null && m_subpart1.Physics != null) { m_subpart1.Physics.Enabled = false; m_subpart1.Physics.Close(); m_subpart1.Physics = null; } }
private void CreateConstraintNosync(MyShipConnector otherConnector, ref Vector3 posA, ref Vector3 posB, ref Vector3 axisA, ref Vector3 axisB) { var data = new HkHingeConstraintData(); data.SetInBodySpace(ref posA, ref posB, ref axisA, ref axisB); var data2 = new HkMalleableConstraintData(); data2.SetData(data); data.ClearHandle(); data = null; data2.Strength = 0.0003f; var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, otherConnector.CubeGrid.Physics.RigidBody, data2); this.Master = true; otherConnector.Master = false; SetConstraint(otherConnector, newConstraint); otherConnector.SetConstraint(this, newConstraint); AddConstraint(newConstraint); }
public void Attach(MyPistonTop topBlock, bool updateSync = false) { if (m_topBlock != null) Detach(); if (CubeGrid.Physics == null || SafeConstraint != null) return; UpdateAnimation(); Debug.Assert(SafeConstraint == null); if (CubeGrid.Physics.Enabled && topBlock != null) { m_topBlock = topBlock; m_topBlockId = topBlock.EntityId; if (updateSync) SyncObject.AttachTop(m_topBlock); m_topGrid = m_topBlock.CubeGrid; var rotorBody = m_topGrid.Physics.RigidBody; var matAD = MatrixD.CreateWorld(Vector3D.Transform(Vector3D.Transform(m_constraintBasePos, Subpart3.WorldMatrix), CubeGrid.PositionComp.WorldMatrixNormalizedInv), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up); var matBD = MatrixD.CreateWorld(m_topBlock.Position * m_topBlock.CubeGrid.GridSize, m_topBlock.PositionComp.LocalMatrix.Forward, m_topBlock.PositionComp.LocalMatrix.Up); var matA = (Matrix)matAD; var matB = (Matrix)matBD; m_fixedData = new HkFixedConstraintData(); m_fixedData.SetInertiaStabilizationFactor(10); m_fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); m_fixedData.SetInBodySpace(ref matA, ref matB); var breakData = new HkBreakableConstraintData(m_fixedData); //Dont dispose the fixed data or we wont have access to them breakData.Threshold = BreakOffTreshold; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = false; m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, breakData); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; m_topBlock.Attach(this); OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid); m_conveyorEndpoint.Attach(topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); } }
public void RemoveConstraint(HkConstraint constraint) { m_constraints.Remove(constraint); if (m_world != null) { constraint.OnRemovedFromWorld(); m_world.RemoveConstraint(constraint); } }
private void AddConstraint(HkConstraint newConstraint) { HasConstraint = true; CubeGrid.Physics.AddConstraint(newConstraint); }
private void ConnectInternal(ref Matrix thisMatrix, ref Matrix otherMatrix, MyShipConnector otherConnector, bool constructor) { Debug.Assert(!m_attachableConveyorEndpoint.AlreadyAttached()); if (m_attachableConveyorEndpoint.AlreadyAttached()) m_attachableConveyorEndpoint.DetachAll(); m_attachableConveyorEndpoint.Attach(otherConnector.m_attachableConveyorEndpoint); var data = new HkFixedConstraintData(); data.SetInWorldSpace(ref thisMatrix, ref otherMatrix, ref thisMatrix); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, otherConnector.CubeGrid.Physics.RigidBody, data); this.Connected = true; this.Master = true; otherConnector.Connected = true; otherConnector.Master = false; if (!constructor) { this.ChangeConstraint(otherConnector, newConstraint); otherConnector.ChangeConstraint(this, newConstraint); } else { this.SetConstraint(otherConnector, newConstraint); otherConnector.SetConstraint(this, newConstraint); } AddConstraint(newConstraint); if (CubeGrid != otherConnector.CubeGrid) { this.OnConstraintAdded(GridLinkTypeEnum.Logical, otherConnector.CubeGrid); this.OnConstraintAdded(GridLinkTypeEnum.Physical, otherConnector.CubeGrid); } }
public virtual bool Detach(bool updateGroup = true) { if (m_isWelding == false) { UnweldGroup(); } var tmpRotorGrid = m_rotorGrid; if (updateGroup) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpRotorGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpRotorGrid); } if (m_constraint == null) return false; Debug.Assert(m_constraint != null); Debug.Assert(m_rotorGrid != null); Debug.Assert(m_rotorBlock != null); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_rotorGrid = null; if (m_rotorBlock != null) m_rotorBlock.Detach(m_welded || m_isWelding); m_rotorBlock = null; UpdateText(); return true; }
public static bool IsConstraintValid(HkConstraint constraint) { if (constraint == null) return false; if (constraint.IsDisposed) return false; if (constraint.RigidBodyA == null | constraint.RigidBodyB == null) return false; if (!constraint.RigidBodyA.InWorld | !constraint.RigidBodyB.InWorld) return false; return true; }
private void Weld(Matrix? masterToSlave) { m_welding = true; m_welded = true; m_other.m_welded = true; Debug.Assert(IsMaster, "Only master can call connect"); if (masterToSlave == null) masterToSlave = WorldMatrix * MatrixD.Invert(m_other.WorldMatrix); if (m_constraint != null) { RemoveConstraint(m_other, m_constraint); m_constraint = null; m_other.m_constraint = null; } WeldInternal(); if (Sync.IsServer) { MatrixD masterToSlaveGrid = CubeGrid.WorldMatrix * MatrixD.Invert(m_other.WorldMatrix); m_connectionState.Value = new State() { IsMaster = true, OtherEntityId = m_other.EntityId, MasterToSlave = masterToSlave.Value, MasterToSlaveGrid = masterToSlaveGrid }; m_other.m_connectionState.Value = new State() { IsMaster = false, OtherEntityId = EntityId, MasterToSlave = masterToSlave.Value }; } m_other.m_other = this; m_welding = false; }
public void RemoveConstraint(HkConstraint constraint) { constraint.UserData = 0; if(IsWelded) { WeldInfo.Parent.RemoveConstraint(constraint); return; } m_constraints.Remove(constraint); if (HavokWorld != null) { constraint.OnRemovedFromWorld(); HavokWorld.RemoveConstraint(constraint); } }
public void AddConstraint(HkConstraint constraint) { if (IsWelded) { WeldInfo.Parent.AddConstraint(constraint); return; } if (HavokWorld == null || RigidBody == null) return; if (constraint.UserData == 0) constraint.UserData = (uint)(WeldedRigidBody == null ? RigidBody.GetGcRoot() : WeldedRigidBody.GetGcRoot()); Debug.Assert(!m_constraints.Contains(constraint), "Constraint added twice"); Debug.Assert(HavokWorld.RigidBodies.Contains(constraint.RigidBodyA), "Object must be in the world"); Debug.Assert(HavokWorld.RigidBodies.Contains(constraint.RigidBodyB), "Object must be in the world"); Debug.Assert(constraint.RigidBodyA.IsAddedToWorld); Debug.Assert(constraint.RigidBodyB.IsAddedToWorld); m_constraints.Add(constraint); HavokWorld.AddConstraint(constraint); if (constraint.InWorld) constraint.OnAddedToWorld(); else Debug.Fail("Constraint not added!"); }
public override bool Attach(MyMotorRotor rotor, bool updateGroup = true) { Debug.Assert(rotor != null, "Rotor cannot be null!"); Debug.Assert(m_constraint == null, "Already attached, call detach first!"); Debug.Assert(m_rotorBlockId.Value.OtherEntityId == 0 || m_rotorBlockId.Value.OtherEntityId == rotor.EntityId, "m_rotorBlockId must be set prior calling Attach"); if (rotor == null || MarkedForClose || Closed || rotor.MarkedForClose || rotor.Closed || CubeGrid.MarkedForClose || CubeGrid.Closed) { return false; } if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled) { m_rotorBlock = rotor; m_rotorGrid = m_rotorBlock.CubeGrid; if (m_rotorGrid.Physics == null) return false; if (CubeGrid.Physics.RigidBody == m_rotorGrid.Physics.RigidBody) { if (updateGroup && m_welded) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } m_isAttached = true; return true; } var rotorBody = m_rotorGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); var posA = DummyPosition; var posB = rotor.Position * rotor.CubeGrid.GridSize; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var axisBPerp = rotor.PositionComp.LocalMatrix.Forward; data.SetInBodySpace(posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, m_rotorGrid.Physics); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, rotorBody, data); m_constraint.WantRuntime = true; CubeGrid.Physics.AddConstraint(m_constraint); if(!m_constraint.InWorld) { CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; return false; } m_constraint.Enabled = true; SetAngleToPhysics(); m_rotorBlock.Attach(this); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); m_rotorGrid.OnPhysicsChanged += cubeGrid_OnPhysicsChanged; } m_isAttached = true; UpdateText(); 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; HkWheelConstraintData data = new HkWheelConstraintData(); var posA = DummyPosition; var posB = rotor.DummyPosLoc; var axisA = PositionComp.LocalMatrix.Up; var axisAPerp = PositionComp.LocalMatrix.Forward; var axisB = rotor.PositionComp.LocalMatrix.Up; var suspensionAx = PositionComp.LocalMatrix.Forward; //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); data.SetSuspensionMaxLimit(BlockDefinition.SuspensionLimit); data.SetSuspensionMinLimit(-BlockDefinition.SuspensionLimit); data.SetInBodySpace(ref posB, ref posA, ref axisB, ref axisA, ref suspensionAx, ref suspensionAx); 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); UpdateIsWorking(); if (updateGroup) { OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid); OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid); } return true; } return false; }
internal void Detach(bool updateGroups = true) { if (m_constraint == null) return; Debug.Assert(m_constraint != null); Debug.Assert(m_topGrid != null); Debug.Assert(m_topBlock != null); var tmpTopGrid = m_topGrid; if (m_constraint.InWorld && (m_constraint.ConstraintData as HkBreakableConstraintData).getIsBroken(m_constraint)) m_topBlockId = 0; m_fixedData.Dispose(); m_fixedData = null; CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; m_topGrid = null; if (m_topBlock != null) m_topBlock.Detach(); m_conveyorEndpoint.Detach(m_topBlock.ConveyorEndpoint as MyAttachableConveyorEndpoint); m_topBlock = null; if (updateGroups) { OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpTopGrid); OnConstraintRemoved(GridLinkTypeEnum.Logical, tmpTopGrid); } // Try to reattach, if the block will still live next frame. This fixes missing attachments when splitting grids }
private void UnsetConstraint() { Debug.Assert(InConstraint); m_other = null; m_constraint = null; UpdateEmissivity(); }
private void WeldInternal() { Debug.Assert(!m_attachableConveyorEndpoint.AlreadyAttached()); if (m_attachableConveyorEndpoint.AlreadyAttached()) m_attachableConveyorEndpoint.DetachAll(); m_attachableConveyorEndpoint.Attach(m_other.m_attachableConveyorEndpoint); if (m_constraint != null) { RemoveConstraint(m_other, m_constraint); m_constraint = null; m_other.m_constraint = null; } this.Connected = true; m_other.Connected = true; MyWeldingGroups.Static.CreateLink(EntityId, CubeGrid, m_other.CubeGrid); UpdateEmissivity(); m_other.UpdateEmissivity(); if (CubeGrid != m_other.CubeGrid) { this.OnConstraintAdded(GridLinkTypeEnum.Logical, m_other.CubeGrid); this.OnConstraintAdded(GridLinkTypeEnum.Physical, m_other.CubeGrid); } CubeGrid.OnPhysicsChanged += CubeGrid_OnPhysicsChanged; CubeGrid.GridSystems.ConveyorSystem.FlagForRecomputation(); m_other.CubeGrid.GridSystems.ConveyorSystem.FlagForRecomputation(); }
private void ChangeConstraint(MyShipConnector other, HkConstraint newConstraint) { Debug.Assert(InConstraint); m_other = other; m_constraint = newConstraint; UpdateEmissivity(); }
void CubeGrid_OnPhysicsChanged(MyEntity obj) { if (Sync.IsServer && m_welding == false && InConstraint && m_welded == false) { if (m_hasConstraint) { if (MyPhysicsBody.IsConstraintValid(m_constraint) == false && m_constraint.IsDisposed == false) { RemoveConstraint(m_other, m_constraint); this.m_constraint = null; m_other.m_constraint = null; m_hasConstraint = false; m_other.m_hasConstraint = false; if (m_connectionState.Value.MasterToSlave.HasValue == false && CubeGrid.Physics != null && m_other.CubeGrid.Physics != null) { var posA = ConstraintPositionInGridSpace(); var posB = m_other.ConstraintPositionInGridSpace(); var axisA = ConstraintAxisGridSpace(); var axisB = -m_other.ConstraintAxisGridSpace(); var data = new HkHingeConstraintData(); data.SetInBodySpace(posA, posB, axisA, axisB, CubeGrid.Physics, m_other.CubeGrid.Physics); var data2 = new HkMalleableConstraintData(); data2.SetData(data); data.ClearHandle(); data = null; data2.Strength = GetEffectiveStrength(m_other); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_other.CubeGrid.Physics.RigidBody, data2); this.SetConstraint(m_other, newConstraint); m_other.SetConstraint(this, newConstraint); AddConstraint(newConstraint); } } } } }
private void RemoveConstraint(MyShipConnector otherConnector, HkConstraint constraint) { if (this.HasConstraint) { CubeGrid.Physics.RemoveConstraint(constraint); HasConstraint = false; } else { otherConnector.CubeGrid.Physics.RemoveConstraint(constraint); otherConnector.HasConstraint = false; } constraint.Dispose(); }
private void AddConstraint(HkConstraint newConstraint) { m_hasConstraint = true; if(newConstraint.RigidBodyA != newConstraint.RigidBodyB) CubeGrid.Physics.AddConstraint(newConstraint); }
public void AddConstraint(HkConstraint constraint) { Debug.Assert(!m_constraints.Contains(constraint), "Constraint added twice"); Debug.Assert(m_world.RigidBodies.Contains(constraint.RigidBodyA), "Object must be in the world"); Debug.Assert(m_world.RigidBodies.Contains(constraint.RigidBodyB), "Object must be in the world"); Debug.Assert(constraint.RigidBodyA.IsAddedToWorld); Debug.Assert(constraint.RigidBodyB.IsAddedToWorld); m_constraints.Add(constraint); m_world.AddConstraint(constraint); constraint.OnAddedToWorld(); }
private void RemoveConstraint(MyShipConnector otherConnector, HkConstraint constraint) { if (this.m_hasConstraint) { if (CubeGrid.Physics != null) CubeGrid.Physics.RemoveConstraint(constraint); m_hasConstraint = false; } else { if (otherConnector.CubeGrid.Physics != null) otherConnector.CubeGrid.Physics.RemoveConstraint(constraint); otherConnector.m_hasConstraint = false; } constraint.Dispose(); }
private void CreateConstraint(MyCubeGrid other, MyShipMergeBlock block) { var data = new HkPrismaticConstraintData(); data.MaximumLinearLimit = 0; data.MinimumLinearLimit = 0; var posA = ConstraintPositionInGridSpace(); var posB = block.ConstraintPositionInGridSpace(); var axisA = PositionComp.LocalMatrix.GetDirectionVector(m_forward); var axisAPerp = PositionComp.LocalMatrix.GetDirectionVector(m_right); var axisB = -block.PositionComp.LocalMatrix.GetDirectionVector(m_forward); Base6Directions.Direction thisRightForOther = block.WorldMatrix.GetClosestDirection(WorldMatrix.GetDirectionVector(m_right)); Base6Directions.Direction otherRight = WorldMatrix.GetClosestDirection(block.WorldMatrix.GetDirectionVector(block.m_right)); var axisBPerp = block.PositionComp.LocalMatrix.GetDirectionVector(thisRightForOther); data.SetInBodySpace( posA, posB, axisA, axisB, axisAPerp, axisBPerp, CubeGrid.Physics, other.Physics); var data2 = new HkMalleableConstraintData(); data2.SetData(data); data.ClearHandle(); data = null; data2.Strength = 0.00001f; var constraint = new HkConstraint(CubeGrid.Physics.RigidBody, other.Physics.RigidBody, data2); AddConstraint(constraint); SetConstraint(block, constraint, otherRight); m_other.SetConstraint(this, constraint, thisRightForOther); }
private void CreateConstraintNosync(MyShipConnector otherConnector) { Debug.Assert(IsMaster, "Constraints should be created only master (entity with higher EntityId)"); var posA = ConstraintPositionInGridSpace(); var posB = otherConnector.ConstraintPositionInGridSpace(); var axisA = ConstraintAxisGridSpace(); var axisB = -otherConnector.ConstraintAxisGridSpace(); var data = new HkHingeConstraintData(); data.SetInBodySpace(posA, posB, axisA, axisB, CubeGrid.Physics, otherConnector.CubeGrid.Physics); var data2 = new HkMalleableConstraintData(); data2.SetData(data); data.ClearHandle(); data = null; data2.Strength = GetEffectiveStrength(otherConnector); var newConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, otherConnector.CubeGrid.Physics.RigidBody, data2); SetConstraint(otherConnector, newConstraint); otherConnector.SetConstraint(this, newConstraint); AddConstraint(newConstraint); }
protected void SetConstraint(MyShipMergeBlock otherBlock, HkConstraint constraint, Base6Directions.Direction otherRight) { Debug.Assert(m_constraint == null && m_other == null); if (m_constraint != null || m_other != null) return; m_constraint = constraint; m_other = otherBlock; m_otherRight = otherRight; CheckEmissivity(); NeedsUpdate |= MyEntityUpdateEnum.EACH_FRAME; }
private void SetConstraint(MyShipConnector other, HkConstraint newConstraint) { m_other = other; m_constraint = newConstraint; UpdateEmissivity(); }
private void Attach(HkRigidBody body, Vector3 gearSpacePivot, Matrix otherBodySpacePivot) { if (CubeGrid.Physics.Enabled) { var entity = body.GetEntity(); Debug.Assert(m_attachedTo == null, "Already attached"); Debug.Assert(entity != null, "Landing gear is attached to body which has no entity"); Debug.Assert(m_constraint == null); if (m_attachedTo != null || entity == null || m_constraint != null) return; body.Activate(); CubeGrid.Physics.RigidBody.Activate(); m_attachedTo = entity; if (entity != null) { entity.OnPhysicsChanged += m_physicsChangedHandler; } this.OnPhysicsChanged += m_physicsChangedHandler; Matrix gearLocalSpacePivot = Matrix.Identity; gearLocalSpacePivot.Translation = gearSpacePivot; var fixedData = new HkFixedConstraintData(); if (MyFakes.OVERRIDE_LANDING_GEAR_INERTIA) { fixedData.SetInertiaStabilizationFactor(MyFakes.LANDING_GEAR_INTERTIA); } else { fixedData.SetInertiaStabilizationFactor(1); } fixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); fixedData.SetInBodySpace(ref gearLocalSpacePivot, ref otherBodySpacePivot); HkConstraintData data = fixedData; if (MyFakes.LANDING_GEAR_BREAKABLE && BreakForce < MaxSolverImpulse) { var breakData = new HkBreakableConstraintData(fixedData); fixedData.Dispose(); breakData.Threshold = BreakForce; breakData.ReapplyVelocityOnBreak = true; breakData.RemoveFromWorldOnBrake = true; data = breakData; } if (!m_needsToRetryLock) StartSound(m_lockSound); m_constraint = new HkConstraint(CubeGrid.Physics.RigidBody, body, data); CubeGrid.Physics.AddConstraint(m_constraint); m_constraint.Enabled = true; LockMode = LandingGearMode.Locked; if (CanAutoLock) ResetAutolock(); OnConstraintAdded(GridLinkTypeEnum.Physical, entity); OnConstraintAdded(GridLinkTypeEnum.NoContactDamage, entity); var handle = StateChanged; if (handle != null) handle(true); } }
private void InitSubpartsPhysics() { var subpart = m_subpart1; if (subpart == null || CubeGrid.Physics == null) return; subpart.Physics = new MyPhysicsBody(subpart, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT)); HkCylinderShape shape = new HkCylinderShape(Vector3.Zero, new Vector3(0, 0, 2), CubeGrid.GridSize / 2); var mass = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(Vector3.Zero, Vector3.One, 1, 40.0f*CubeGrid.GridSize); subpart.Physics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass); shape.Base.RemoveReference(); subpart.Physics.RigidBody.Layer = CubeGrid.Physics.RigidBody.Layer; if (subpart.Physics.RigidBody2 != null) subpart.Physics.RigidBody2.Layer = MyPhysics.KinematicDoubledCollisionLayer; m_subpartsFixedData = new HkFixedConstraintData(); m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized); float res; var x = m_subpartsFixedData.GetInertiaStabilizationFactor(out res); 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); var breakableData = new HkBreakableConstraintData(m_subpartsFixedData); //Dont dispose the fixed data or we wont have access to them breakableData.Threshold = BreakOffTreshold; m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, subpart.Physics.RigidBody, breakableData); m_subpartsConstraint.WantRuntime = true; m_posChanged = true; }
private void Detach() { if (m_constraint == null) return; this.OnPhysicsChanged -= m_physicsChangedHandler; var tmpAttachedEntity = m_attachedTo; Debug.Assert(m_attachedTo != null, "Attached entity is null"); if (m_attachedTo != null) { m_attachedTo.OnPhysicsChanged -= m_physicsChangedHandler; } m_attachedTo = null; if (!m_needsToRetryLock && !MarkedForClose) StartSound(m_unlockSound); CubeGrid.Physics.RemoveConstraint(m_constraint); m_constraint.Dispose(); m_constraint = null; LockMode = LandingGearMode.Unlocked; OnConstraintRemoved(GridLinkTypeEnum.Physical, tmpAttachedEntity); OnConstraintRemoved(GridLinkTypeEnum.NoContactDamage, tmpAttachedEntity); var handle = StateChanged; if (handle != null) handle(false); }