/// <summary> /// Begins decelerating the <see cref="Target"/> based on any opposing drag forces. /// </summary> /// <returns>An Enumerator to manage the running state of the Coroutine.</returns> protected virtual IEnumerator BeginDeceleration() { while (!Velocity.ApproxEquals(Vector3.zero, NilVelocityTolerance) || !AngularVelocity.ApproxEquals(Vector3.zero, NilAngularVelocityTolerance)) { Velocity = Vector3.Slerp(Velocity, Vector3.zero, Drag * Time.deltaTime); AngularVelocity = Vector3.Slerp(AngularVelocity, Vector3.zero, AngularDrag * Time.deltaTime); Target.transform.localRotation *= Quaternion.Euler(AngularVelocity); Target.transform.localPosition += Velocity * Time.deltaTime; yield return(null); } decelerationRoutine = null; Velocity = Vector3.zero; AngularVelocity = Vector3.zero; }
/// <inheritdoc /> public virtual void Process() { if (!canProcess) { return; } if (!Velocity.ApproxEquals(Vector3.zero, NilVelocityTolerance) || !AngularVelocity.ApproxEquals(Vector3.zero, NilAngularVelocityTolerance)) { float deltaTime = Time.inFixedTimeStep ? Time.fixedDeltaTime : Time.deltaTime; Velocity = Vector3.Lerp(Velocity, Vector3.zero, Drag * deltaTime); AngularVelocity = Vector3.Lerp(AngularVelocity, Vector3.zero, AngularDrag * deltaTime); Target.transform.localRotation *= Quaternion.Euler(AngularVelocity); Target.transform.localPosition += Velocity * deltaTime; } else { Velocity = Vector3.zero; AngularVelocity = Vector3.zero; canProcess = false; } }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public void UpdateProperties(EntityProperties entprop) { bool changed = false; #region Updating Position if (entprop.ID != 0) { // we assign to the local variables so the normal set action does not happen if (_position != entprop.Position) { _position = entprop.Position; changed = true; } if (_orientation != entprop.Rotation) { _orientation = entprop.Rotation; changed = true; } if (_velocity != entprop.Velocity) { changed = true; _velocity = entprop.Velocity; } if (_acceleration != entprop.Acceleration) { _acceleration = entprop.Acceleration; changed = true; } if (_rotationalVelocity != entprop.RotationalVelocity) { changed = true; _rotationalVelocity = entprop.RotationalVelocity; } if (changed) { TriggerMovementUpdate(); } } #endregion #region Jump code if (_preJumping && Util.EnvironmentTickCountSubtract(_preJumpTime) > _scene.PreJumpTime) { //Time to jump _jumping = true; _preJumping = false; Velocity += _preJumpForce; _targetVelocityIsDecaying = false; TriggerMovementUpdate(); } if (_jumping && Util.EnvironmentTickCountSubtract(_preJumpTime) > _scene.PreJumpTime + 2000) { _jumping = false; _targetVelocity = Vector3.Zero; TriggerMovementUpdate(); } else if (_jumping && Util.EnvironmentTickCountSubtract(_preJumpTime) > _scene.PreJumpTime + 750) { _targetVelocityIsDecaying = false; TriggerMovementUpdate(); } else if (_jumping && Util.EnvironmentTickCountSubtract(_preJumpTime) > _scene.PreJumpTime + 500) { _targetVelocityIsDecaying = false; Velocity -= _preJumpForce / 100; //Cut down on going up TriggerMovementUpdate(); } #endregion #region Decaying velocity if (_targetVelocityIsDecaying) { _targetVelocity *= _scene.DelayingVelocityMultiplier; if (_targetVelocity.ApproxEquals(Vector3.Zero, 0.1f) || _velocity == Vector3.Zero) { _targetVelocity = Vector3.Zero; } } if (_targetVelocity != Vector3.Zero) { Velocity = new Vector3( _targetVelocity.X == 0 ? Velocity.X : (_targetVelocity.X * 0.25f) + (Velocity.X * 0.75f), _targetVelocity.Y == 0 ? Velocity.Y : (_targetVelocity.Y * 0.25f) + (Velocity.Y * 0.75f), _targetVelocity.Z == 0 ? Velocity.Z : (_targetVelocity.Z * 0.25f) + (Velocity.Z * 0.75f)); } else if (Velocity.X != 0 || Velocity.Y != 0 || Velocity.Z > 0) { Velocity *= _scene.DelayingVelocityMultiplier; } if (Velocity.ApproxEquals(Vector3.Zero, 0.3f)) { Velocity = Vector3.Zero; } #endregion }
/// <summary> /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. /// </summary> public void UpdatePositionAndVelocity() { if (Body == null) { return; } //int val = Environment.TickCount; CheckIfStandingOnObject(); //m_log.DebugFormat("time:{0}", Environment.TickCount - val); //IsColliding = Body.checkCollideWith(m_parent_scene.TerrainBody); tempTrans1.Dispose(); tempTrans1 = Body.getInterpolationWorldTransform(); tempVector1.Dispose(); tempVector1 = tempTrans1.getOrigin(); tempVector2.Dispose(); tempVector2 = Body.getInterpolationLinearVelocity(); // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! Vector3 vec = new Vector3(tempVector1.getX(), tempVector1.getY(), tempVector1.getZ()); // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) if (vec.X < -10.0f) { vec.X = 0.0f; } if (vec.Y < -10.0f) { vec.Y = 0.0f; } if (vec.X > m_parent_scene.m_region.RegionSizeX + 10.2f) { vec.X = m_parent_scene.m_region.RegionSizeX + 10.2f; } if (vec.Y > m_parent_scene.m_region.RegionSizeY + 10.2f) { vec.Y = m_parent_scene.m_region.RegionSizeY + 10.2f; } m_position.X = vec.X; m_position.Y = vec.Y; m_position.Z = vec.Z; // Did we move last? = zeroflag // This helps keep us from sliding all over if (m_zeroFlag) { m_velocity.X = 0.0f; m_velocity.Y = 0.0f; m_velocity.Z = 0.0f; // Did we send out the 'stopped' message? if (!m_lastUpdateSent) { m_lastUpdateSent = true; base.RequestPhysicsterseUpdate(); } //Tell any listeners that we've stopped base.TriggerMovementUpdate(); } else { m_lastUpdateSent = false; vec = new Vector3(tempVector2.getX(), tempVector2.getY(), tempVector2.getZ()); m_velocity.X = (vec.X); m_velocity.Y = (vec.Y); m_velocity.Z = (vec.Z); //m_log.Debug(m_target_velocity); if (m_velocity.Z < -6 && !m_hackSentFall) { m_hackSentFall = true; m_pidControllerActive = false; } else if (m_flying && !m_hackSentFly) { //m_hackSentFly = true; //base.SendCollisionUpdate(new CollisionEventUpdate()); } else { m_hackSentFly = false; m_hackSentFall = false; } const float VELOCITY_TOLERANCE = 0.001f; const float POSITION_TOLERANCE = 0.05f; //Check to see whether we need to trigger the significant movement method in the presence if (!RotationalVelocity.ApproxEquals(m_lastRotationalVelocity, VELOCITY_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !Position.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) { // Update the "last" values m_lastPosition = Position; m_lastRotationalVelocity = RotationalVelocity; m_lastVelocity = Velocity; base.RequestPhysicsterseUpdate(); base.TriggerSignificantMovement(); } //Tell any listeners about the new info base.TriggerMovementUpdate(); } if (Body != null) { if (Body.getFriction() < 0.9f) { Body.setFriction(0.9f); } } //if (Body != null) // Body.clearForces(); }