Example #1
0
        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 = (_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);
            _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)
            {
                _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;
            }

            if (frameNum % 3 == 0)
            {
                CheckAvatarNotBelowGround();
            }

            SetVelocityAndRequestTerseUpdate(secondsSinceLastSync, vColl);
            ReportCollisionsFromLastFrame(frameNum);

            if (!_position.ApproxEquals(lastPosition, POSITION_COMPARISON_TOLERANCE))
            {
                RequestPhysicsPositionUpdate();
            }
        }