/// <summary> /// Updates the sleeping state. Is called in <see cref="UpdateVelocity"/>. /// </summary> /// <param name="deltaTime">The time step.</param> private void UpdateSleeping(float deltaTime) { if (IsSleeping || !CanSleep) { return; } if (MotionType == MotionType.Dynamic) { if (LinearVelocity.LengthSquared() < Simulation.Settings.Sleeping.LinearVelocityThresholdSquared && AngularVelocity.LengthSquared() < Simulation.Settings.Sleeping.AngularVelocityThresholdSquared) { // Movement is below threshold. Increase counter. _noMovementTime += deltaTime; // Static bodies sleep immediately. Kinematic and dynamic bodies are handled here. // Dynamic bodies can only sleep if their whole island is sleeping. (Note: When the island // is processed the sleeping of the dynamic body is deferred if the island is awake.) if (_noMovementTime > Simulation.Settings.Sleeping.TimeThreshold) { IsSleeping = true; } } else { // Movement detected. _noMovementTime = 0; } } else { if (LinearVelocity.LengthSquared() < Numeric.EpsilonFSquared && AngularVelocity.LengthSquared() < Numeric.EpsilonFSquared) { // Kinematic bodies are set to sleep immediately! IsSleeping = true; _linearVelocity = Vector3.Zero; _angularVelocity = Vector3.Zero; _noMovementTime = float.PositiveInfinity; } else { // Movement detected. _noMovementTime = 0; } } }
public void UpdateDeactivation(float timeStep) { if ((ActivationState == ActivationState.IslandSleeping) || (ActivationState == ActivationState.DisableDeactivation)) { return; } if ((LinearVelocity.LengthSquared() < LinearSleepingThreshold * LinearSleepingThreshold) && (AngularVelocity.LengthSquared() < AngularSleepingThreshold * AngularSleepingThreshold)) { DeactivationTime += timeStep; } else { DeactivationTime = 0; ActivationState = ActivationState.Nothing; } }
/// <summary> /// Applies damping to reduce speeds /// </summary>= public void ApplyDamping(float dt) { float ne = GetKineticEnergy() * m_OneOverMass; float ld = (1.0f - m_LinearDamping); float ad = (1.0f - m_AngularDamping); if ((ne >= m_SleepEnergyThreshold || ne > m_LastKineticEnergy) || AngularVelocity.LengthSquared() > SleepAngularVelocityThreshold) { m_DeactivationTimer += dt; m_DeactivationTimer = m_DeactivationTimer < GLOBAL_DEACTIVATION_TIMER ? m_DeactivationTimer : GLOBAL_DEACTIVATION_TIMER; } else { m_DeactivationTimer -= dt; m_DeactivationTimer = m_DeactivationTimer < 0.0f ? 0.0f : m_DeactivationTimer; /* Do we really need this, when default AD is set? * //Extra damping * float d = m_DeactivationTimer / GLOBAL_DEACTIVATION_TIMER; * d = d < 0.01 ? 0.01f : d; * * //Damping * float d2 = d*d; * * ld = ld * d2; * ad = ad * d2;*/ } m_Velocity = m_Velocity * (float)Math.Pow(ld, dt); m_AngularVelocity = m_AngularVelocity * (float)Math.Pow(ad, dt); MinerWars.AppCode.Game.Utils.MyUtils.AssertIsValid(m_AngularVelocity); m_LastKineticEnergy = ne; if (m_AngularVelocity.LengthSquared() < (0.001f * 0.001f)) { m_AngularVelocity = Vector3.Zero; } if (m_Velocity.LengthSquared() < (0.02f * 0.02f)) { m_Velocity = Vector3.Zero; } }