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); }
void SetAngleToPhysics() { if (SafeConstraint != null) { HkLimitedHingeConstraintData.SetCurrentAngle(SafeConstraint, m_currentAngle); } }
private void SetConstraintPosition(MyAttachableTopBlockBase rotor, HkLimitedHingeConstraintData data) { 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, TopGrid.Physics); }
void SetSafeAngles(bool lowerIsFixed, float lowerLimit, float upperLimit) { // When out of limits get to limits if (m_currentAngle < lowerLimit) { ScaleUp(); } if (m_currentAngle > upperLimit) { ScaleDown(); } // Min must be smaller than max if (upperLimit < lowerLimit) { if (lowerIsFixed) { upperLimit = lowerLimit; } else { lowerLimit = upperLimit; } } if (lowerLimit < MIN_LOWER_LIMIT) { lowerLimit = float.NegativeInfinity; } if (upperLimit > MAX_UPPER_LIMIT) { upperLimit = float.PositiveInfinity; } m_minAngle.Value = lowerLimit; m_maxAngle.Value = upperLimit; m_limitsActive = false; TryActivateLimits(); if (SafeConstraint != null) { m_currentAngle = HkLimitedHingeConstraintData.GetCurrentAngle(SafeConstraint); } UpdateText(); RaisePropertiesChanged(); }
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); }
public static void SetInBodySpace(this HkLimitedHingeConstraintData data, Vector3 posA, Vector3 posB, Vector3 axisA, Vector3 axisB, Vector3 axisAPerp, Vector3 axisBPerp, MyPhysicsBody bodyA, MyPhysicsBody bodyB) { if (bodyA.IsWelded) { posA = Vector3.Transform(posA, bodyA.WeldInfo.Transform); axisA = Vector3.TransformNormal(axisA, bodyA.WeldInfo.Transform); axisAPerp = Vector3.TransformNormal(axisAPerp, bodyA.WeldInfo.Transform); } if (bodyB.IsWelded) { posB = Vector3.Transform(posB, bodyB.WeldInfo.Transform); axisB = Vector3.TransformNormal(axisB, bodyB.WeldInfo.Transform); axisBPerp = Vector3.TransformNormal(axisBPerp, bodyB.WeldInfo.Transform); } data.SetInBodySpaceInternal(ref posA, ref posB, ref axisA, ref axisB, ref axisAPerp, ref axisBPerp); }
protected override bool CreateConstraint(MyAttachableTopBlockBase rotor) { if (!base.CreateConstraint(rotor)) { return(false); } 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 = TopGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); SetConstraintPosition(rotor, data); 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(); return(true); }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (MyFakes.REPORT_INVALID_ROTORS) { //Debug.Assert(m_constraint != null, "Rotor constraint is not created although it should be!"); } if (CheckVelocities()) { return; } if (m_rotorGrid == null || SafeConstraint == null) { return; } if (SafeConstraint.RigidBodyA == SafeConstraint.RigidBodyB) //welded { SafeConstraint.Enabled = false; return; } var oldAngle = m_currentAngle; m_currentAngle = HkLimitedHingeConstraintData.GetCurrentAngle(SafeConstraint); if (oldAngle != m_currentAngle) { UpdateText(); } var data = (HkLimitedHingeConstraintData)m_constraint.ConstraintData; data.MaxFrictionTorque = BrakingTorque; TryActivateLimits(); if (!m_limitsActive) { data.DisableLimits(); } else if (!data.MinAngularLimit.IsEqual(m_minAngle) || !data.MaxAngularLimit.IsEqual(m_maxAngle)) { data.MinAngularLimit = m_minAngle; data.MaxAngularLimit = m_maxAngle; // Activate even when motor is stopped, so it fixes it's limits CubeGrid.Physics.RigidBody.Activate(); m_rotorGrid.Physics.RigidBody.Activate(); } if (m_limitsActive) { var handle = LimitReached; if (handle != null) { if (oldAngle > data.MinAngularLimit && m_currentAngle <= data.MinAngularLimit) { handle(false); } if (oldAngle < data.MaxAngularLimit && m_currentAngle >= data.MaxAngularLimit) { handle(true); } } } m_motor.MaxForce = Torque; m_motor.MinForce = -Torque; m_motor.VelocityTarget = TargetVelocity * Sync.RelativeSimulationRatio; bool motorRunning = IsWorking; if (data.MotorEnabled != motorRunning) { data.SetMotorEnabled(m_constraint, motorRunning); } if (motorRunning && m_rotorGrid != null && !m_motor.VelocityTarget.IsZero()) { CubeGrid.Physics.RigidBody.Activate(); m_rotorGrid.Physics.RigidBody.Activate(); } }
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 || rotor.CubeGrid == null || MarkedForClose || Closed || CubeGrid.MarkedForClose || CubeGrid.Closed || rotor.MarkedForClose || rotor.Closed || rotor.CubeGrid.MarkedForClose || rotor.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 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; }
protected override bool CreateConstraint(MyAttachableTopBlockBase rotor) { if (!base.CreateConstraint(rotor)) return false; 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 = TopGrid.Physics.RigidBody; var data = new HkLimitedHingeConstraintData(); m_motor = new HkVelocityConstraintMotor(1.0f, 1000000f); data.SetSolvingMethod(HkSolvingMethod.MethodStabilized); data.Motor = m_motor; data.DisableLimits(); SetConstraintPosition(rotor, data); 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(); return true; }
private void SetConstraintPosition(MyAttachableTopBlockBase rotor, HkLimitedHingeConstraintData data) { 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, TopGrid.Physics); }
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; }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (m_welded) { return; } if (TopGrid == null || SafeConstraint == null) { return; } if (SafeConstraint.RigidBodyA == SafeConstraint.RigidBodyB) //welded { SafeConstraint.Enabled = false; return; } var oldAngle = m_currentAngle; m_currentAngle = HkLimitedHingeConstraintData.GetCurrentAngle(SafeConstraint); if (oldAngle != m_currentAngle) { UpdateText(); } var data = (HkLimitedHingeConstraintData)m_constraint.ConstraintData; data.MaxFrictionTorque = BrakingTorque; TryActivateLimits(); if (!m_limitsActive) { data.DisableLimits(); } else if (!data.MinAngularLimit.IsEqual(m_minAngle) || !data.MaxAngularLimit.IsEqual(m_maxAngle)) { data.MinAngularLimit = m_minAngle; data.MaxAngularLimit = m_maxAngle; // Activate even when motor is stopped, so it fixes it's limits CubeGrid.Physics.RigidBody.Activate(); TopGrid.Physics.RigidBody.Activate(); } if (m_limitsActive) { var handle = LimitReached; if (handle != null) { if (oldAngle > data.MinAngularLimit && m_currentAngle <= data.MinAngularLimit) { handle(false); } if (oldAngle < data.MaxAngularLimit && m_currentAngle >= data.MaxAngularLimit) { handle(true); } } if (m_currentAngle > MathHelper.TwoPi) { ScaleDown(); } if (m_currentAngle < -MathHelper.TwoPi) { ScaleUp(); } } var effectiveTorque = Math.Min(Torque, TopGrid.Physics.Mass * TopGrid.Physics.Mass) * Sync.RelativeSimulationRatio; m_motor.MaxForce = effectiveTorque; m_motor.MinForce = -effectiveTorque; m_motor.VelocityTarget = TargetVelocity * Sync.RelativeSimulationRatio; bool motorRunning = IsWorking; if (data.MotorEnabled != motorRunning) { data.SetMotorEnabled(m_constraint, motorRunning); } if (motorRunning && TopGrid != null && !m_motor.VelocityTarget.IsZero()) { CubeGrid.Physics.RigidBody.Activate(); TopGrid.Physics.RigidBody.Activate(); } }
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; }