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();
        }
        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();
            }
        }
Exemple #3
0
        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();
            }
        }