Beispiel #1
0
        // Called just before the simulation step. Update the vertical position for hoverness.
        private void Mover(float timeStep)
        {
            // Don't do hovering while the object is selected.
            if (!isActive)
            {
                return;
            }

            OMV.Vector3 origPosition = m_controllingPrim.RawPosition;     // DEBUG DEBUG (for printout below)

            // 'movePosition' is where we'd like the prim to be at this moment.
            OMV.Vector3 movePosition = m_controllingPrim.RawPosition + m_targetMotor.Step(timeStep);

            // If we are very close to our target, turn off the movement motor.
            if (m_targetMotor.ErrorIsZero())
            {
                m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
                                         m_controllingPrim.LocalID, movePosition, m_controllingPrim.RawPosition, m_controllingPrim.Mass);
                m_controllingPrim.ForcePosition = m_targetMotor.TargetValue;
            }
            else
            {
                m_controllingPrim.ForcePosition = movePosition;
            }
            m_physicsScene.DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", m_controllingPrim.LocalID, origPosition, movePosition);
        }
Beispiel #2
0
        // Called just before the simulation step. Update the vertical position for hoverness.
        private void Mover(float timeStep)
        {
            // Don't do movement while the object is selected.
            if (!isActive)
            {
                return;
            }

            // TODO: Decide if the step parameters should be changed depending on the avatar's
            //     state (flying, colliding, ...). There is code in ODE to do this.

            // COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
            //   specified for the avatar is the one that should be used. For falling, if the avatar
            //   is not flying and is not colliding then it is presumed to be falling and the Z
            //   component is not fooled with (thus allowing gravity to do its thing).
            // When the avatar is standing, though, the user has specified a velocity of zero and
            //   the avatar should be standing. But if the avatar is pushed by something in the world
            //   (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
            //   move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
            //   errors can creap in and the avatar will slowly float off in some direction.
            // So, the problem is that, when an avatar is standing, we cannot tell creaping error
            //   from real pushing.
            // The code below uses whether the collider is static or moving to decide whether to zero motion.

            m_velocityMotor.Step(timeStep);
            m_controllingPrim.IsStationary = false;

            // If we're not supposed to be moving, make sure things are zero.
            if (m_velocityMotor.ErrorIsZero() && m_velocityMotor.TargetValue == OMV.Vector3.Zero)
            {
                // The avatar shouldn't be moving
                m_velocityMotor.Zero();

                if (m_controllingPrim.IsColliding)
                {
                    // If we are colliding with a stationary object, presume we're standing and don't move around
                    if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.VolumeDetect)
                    {
                        m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotor",
                                                 m_controllingPrim.LocalID);
                        m_controllingPrim.IsStationary = true;
                        m_controllingPrim.ZeroMotion(true /* inTaintTime */);
                    }

                    // Standing has more friction on the ground
                    if (m_controllingPrim.Friction != BSParam.AvatarStandingFriction)
                    {
                        m_controllingPrim.Friction = BSParam.AvatarStandingFriction;
                        m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
                    }
                }
                else
                {
                    if (m_controllingPrim.Flying)
                    {
                        // Flying and not collising and velocity nearly zero.
                        m_controllingPrim.ZeroMotion(true /* inTaintTime */);
                    }
                }

                m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}",
                                         m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding);
            }
            else
            {
                // Supposed to be moving.
                OMV.Vector3 stepVelocity = m_velocityMotor.CurrentValue;

                if (m_controllingPrim.Friction != BSParam.AvatarFriction)
                {
                    // Probably starting up walking. Set friction to moving friction.
                    m_controllingPrim.Friction = BSParam.AvatarFriction;
                    m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
                }

                // If falling, we keep the world's downward vector no matter what the other axis specify.
                // The check for RawVelocity.Z < 0 makes jumping work (temporary upward force).
                if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
                {
                    if (m_controllingPrim.RawVelocity.Z < 0)
                    {
                        stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
                    }
                    // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
                    // no BSParam.AvatarJumpFrames supported in this Version :(
                }

                // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
                OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass;

                // Should we check for move force being small and forcing velocity to zero?

                // Add special movement force to allow avatars to walk up stepped surfaces.
                moveForce += WalkUpStairs();

                m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
                                         m_controllingPrim.LocalID, stepVelocity, m_controllingPrim.RawVelocity, m_controllingPrim.Mass,
                                         moveForce);
                m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, moveForce);
            }

            if (m_preJumpStart != 0 && Util.EnvironmentTickCountSubtract(m_preJumpStart) > 300)
            {
                m_controllingPrim.IsPreJumping = false;
                m_controllingPrim.IsJumping    = true;
                m_preJumpStart = 0;

                OMV.Vector3 target = m_jumpDirection;
                target.X *= 1.5f;
                target.Y *= 1.5f;
                target.Z *= 2.5f; //Scale so that we actually jump

                SetVelocityAndTargetInternal(m_controllingPrim.RawVelocity, target, false, 1);
                m_jumpStart = Util.EnvironmentTickCount();
            }
            if (!m_jumpFallState && m_jumpStart != 0 && Util.EnvironmentTickCountSubtract(m_jumpStart) > 500)
            {
                OMV.Vector3 newTarget = m_controllingPrim.RawVelocity;
                newTarget.X *= 1.5f; //Scale so that the jump looks correct
                newTarget.Y *= 1.5f;
                newTarget.Z *= -0.2f;
                SetVelocityAndTargetInternal(m_controllingPrim.RawVelocity, newTarget, false, 3);
                m_jumpFallState = true;
            }
            else if (m_jumpFallState && m_jumpStart != 0 && m_controllingPrim.IsColliding &&
                     Util.EnvironmentTickCountSubtract(m_jumpStart) > 1500 ||
                     (m_jumpStart != 0 && Util.EnvironmentTickCountSubtract(m_jumpStart) > 10000))    //Fallback
            {
                //Reset everything in case something went wrong
                m_disallowTargetVelocitySet    = false;
                m_jumpFallState                = false;
                m_controllingPrim.IsPreJumping = false;
                m_controllingPrim.IsJumping    = false;
                m_jumpStart    = 0;
                m_preJumpStart = 0;
            }
        }