private void SetVelocityAndRequestTerseUpdate(float secondsSinceLastSync, OpenMetaverse.Vector3 vColl) { OpenMetaverse.Vector3 cforces = _cForcesAreLocal ? _cForces * _rotation : _cForces; cforces.Z = 0; OpenMetaverse.Vector3 oldVelocity = _velocity; _velocity = ApplyAirBrakes(_vGravity + _vForces + cforces + this.VTargetWithRunAndRamp + vColl); if (_velocity == OpenMetaverse.Vector3.Zero && oldVelocity != OpenMetaverse.Vector3.Zero) { _acceleration = OpenMetaverse.Vector3.Zero; RequestPhysicsTerseUpdate(); } else { OpenMetaverse.Vector3 velDiff = _velocity - oldVelocity; OpenMetaverse.Vector3 accel = velDiff / secondsSinceLastSync; if (!accel.ApproxEquals(_acceleration, ACCELERATION_COMPARISON_TOLERANCE)) { _acceleration = accel; RequestPhysicsTerseUpdate(); //m_log.DebugFormat("Avatar Terse Vel: {0} Accel: {1} Sync: {2}", _velocity, _acceleration, secondsSinceLastSync); //m_log.DebugFormat("Vel Breakdown: vGravity {0} vForces {1} vTarget {2} vColl {3}", _vGravity, _vForces, this.VTargetWithRun, vColl); } } }
public override void SyncWithPhysics(float timeStep, uint ticksSinceLastSimulate, uint frameNum) { if (_suspended) { // character is in the middle of a crossing. we do not simulate _lastSync = (uint)Environment.TickCount; return; } float secondsSinceLastSync = Math.Min(((uint)Environment.TickCount - _lastSync) * 0.001f, MAX_TIMESTEP); //m_log.DebugFormat("[CHAR]: secondsSinceLastSync: {0}", secondsSinceLastSync); //sometimes a single quantum doesnt show up here, and the calculation returns a zero if (secondsSinceLastSync < MIN_TIMESTEP * 2) { secondsSinceLastSync = MIN_TIMESTEP * 2; } AccumulateGravity(secondsSinceLastSync); DecayForces(secondsSinceLastSync); OpenMetaverse.Vector3 cforces = _cForcesAreLocal ? _cForces * _rotation : _cForces; cforces.Z = 0; OpenMetaverse.Vector3 vCombined = ApplyAirBrakes(_vGravity + _vForces + cforces + this.VTargetWithRunAndRamp) * secondsSinceLastSync; //m_log.DebugFormat("[CHAR]: vGrav: {0}, vForces: {1}, vTarget {2}", _vGravity, _vForces, this.VTargetWithRun); if (vCombined == OpenMetaverse.Vector3.Zero) { SetVelocityAndRequestTerseUpdate(secondsSinceLastSync, OpenMetaverse.Vector3.Zero); //ReportCollisionsFromLastFrame(frameNum); return; } OpenMetaverse.Vector3 lastPosition = _position; //PhysX.ControllerFlag flags = _controller.Move(PhysUtil.OmvVectorToPhysx(vCombined), TimeSpan.FromSeconds(secondsSinceLastSync), 0.001f, FILTERS); //_position = PhysUtil.PhysxVectorToOmv(_controller.Position); bool collidingDown = CalcPhysics(vCombined, secondsSinceLastSync, 0.001f); _lastSync = (uint)Environment.TickCount; //take into account any movement not accounted for by the other calculations //this is due to collision OpenMetaverse.Vector3 vColl = (_position - lastPosition) - vCombined; //m_log.InfoFormat("vColl {0} {1} PosDiff: {2} Expected: {3}", vColl, flags, _position - lastPosition, vCombined); //m_log.DebugFormat("[CHAR]: vColl: {0}", vColl); //bool collidingDown = (flags & PhysX.ControllerFlag.Down) != 0; //if (!collidingDown) _rideOnBehavior.AvatarNotStandingOnPrim(); //negative z in vcoll while colliding down is due to gravity/ground collision, dont report it float gravityPushback = Math.Abs(_vGravity.Z) * secondsSinceLastSync; if (collidingDown && vColl.Z > 0 && Math.Abs(vColl.Z - gravityPushback) < GRAVITY_PUSHBACK_DIFF_TOLERANCE) { vColl.Z = 0; } //m_log.DebugFormat("[CHAR]: vColl: {0} gravityPushback {1} collidingDown:{2}", vColl, gravityPushback, collidingDown); if (/*flags != 0*/ collidingDown) { _colliding = true; if (collidingDown) { _collidingGround = true; _flying = false; _vGravity = OpenMetaverse.Vector3.Zero; _vForces.Z = 0.0f; _vTarget.Z = 0.0f; } else { _collidingGround = false; //if we're colliding with anything but the ground, zero out other forces _vForces = OpenMetaverse.Vector3.Zero; } } else { _colliding = false; _collidingGround = false; } /* Redundant here, and I suspect never even did anything unless the agent tunneled through the terrain mesh in the PhysX implmentation... * if (frameNum % 3 == 0) * { * CheckAvatarNotBelowGround(); * } */ SetVelocityAndRequestTerseUpdate(secondsSinceLastSync, vColl); //ReportCollisionsFromLastFrame(frameNum); if (!_position.ApproxEquals(lastPosition, POSITION_COMPARISON_TOLERANCE)) { RequestPhysicsPositionUpdate(); } }