Esempio n. 1
0
        public void Pitch(float angle)
        {
            Quaternion q = Quaternion.CreateFromAxisAngle(yAxis, angle);
            Matrix4    m = Matrix4.CreateFromQuaternion(q);

            Rotate(m);

            if (!xAxis.IsFinite() || !zAxis.IsFinite())
            {
                throw new Exception("Non-finite in CoordinateFrame.Pitch()");
            }
        }
Esempio n. 2
0
        public override void AddForce(bool inTaintTime, OMV.Vector3 force)
        {
            if (force.IsFinite())
            {
                OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
                // DetailLog("{0},BSCharacter.addForce,call,force={1},push={2},inTaint={3}", LocalID, addForce, pushforce, inTaintTime);

                PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
                {
                    // Bullet adds this central force to the total force for this tick
                    // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
                    if (PhysBody.HasPhysicalBody)
                    {
                        // Bullet adds this central force to the total force for this tick.
                        // Deep down in Bullet:
                        //      linearVelocity += totalForce / mass * timeStep;
                        PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
                        PhysScene.PE.Activate(PhysBody, true);
                    }
                    if (m_moveActor != null)
                    {
                        m_moveActor.SuppressStationayCheckUntilLowVelocity();
                    }
                });
            }
            else
            {
                m_log.WarnFormat("{0}: Got a NaN force applied to a character. LocalID={1}", LogHeader, LocalID);
                return;
            }
        }
Esempio n. 3
0
        // Internal version that, if initializing, doesn't do all the updating of the physics engine
        public void SetAvatarSize(OMV.Vector3 size, float feetOffset, bool initializing)
        {
            OMV.Vector3 newSize = size;
            if (newSize.IsFinite())
            {
                // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
                //     replace with the default values.
                if (newSize.X == 0f)
                {
                    newSize.X = BSParam.AvatarCapsuleDepth;
                }
                if (newSize.Y == 0f)
                {
                    newSize.Y = BSParam.AvatarCapsuleWidth;
                }

                if (newSize.X < 0.01f)
                {
                    newSize.X = 0.01f;
                }
                if (newSize.Y < 0.01f)
                {
                    newSize.Y = 0.01f;
                }
                if (newSize.Z < 0.01f)
                {
                    newSize.Z = BSParam.AvatarCapsuleHeight;
                }
            }
            else
            {
                newSize = new OMV.Vector3(BSParam.AvatarCapsuleDepth, BSParam.AvatarCapsuleWidth, BSParam.AvatarCapsuleHeight);
            }

            // This is how much the avatar size is changing. Positive means getting bigger.
            // The avatar altitude must be adjusted for this change.
            float heightChange = newSize.Z - Size.Z;

            _size = newSize;

            Scale = ComputeAvatarScale(Size);
            ComputeAvatarVolumeAndMass();
            DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
                      LocalID, _size, Scale, Density, _avatarVolume, RawMass);

            PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
            {
                if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
                {
                    PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
                    UpdatePhysicalMassProperties(RawMass, true);

                    // Adjust the avatar's position to account for the increase/decrease in size
                    ForcePosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, RawPosition.Z + heightChange / 2f);

                    // Make sure this change appears as a property update event
                    PhysScene.PE.PushUpdate(PhysBody);
                }
            });
        }
Esempio n. 4
0
        private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
        {
            if (force.IsFinite())
            {
                float magnitude = force.Length();
                if (magnitude > BSParam.MaxAddForceMagnitude)
                {
                    // Force has a limit
                    force = force / magnitude * BSParam.MaxAddForceMagnitude;
                }

                OMV.Vector3 addForce = force;
                // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);

                PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
                {
                    // Bullet adds this central force to the total force for this tick
                    // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
                    if (PhysBody.HasPhysicalBody)
                    {
                        PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
                    }
                });
            }
            else
            {
                m_log.WarnFormat("{0}: Got a NaN force applied to a character. LocalID={1}", LogHeader, LocalID);
                return;
            }
        }
Esempio n. 5
0
 public override void AddForce(OMV.Vector3 force, bool pushforce)
 {
     if (force.IsFinite())
     {
         _force.X += force.X;
         _force.Y += force.Y;
         _force.Z += force.Z;
         // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
         PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
         {
             DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
             BulletSimAPI.SetObjectForce2(BSBody.ptr, _force);
         });
     }
     else
     {
         m_log.ErrorFormat("{0}: Got a NaN force applied to a Character", LogHeader);
     }
     //m_lastUpdateSent = false;
 }
Esempio n. 6
0
        private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
        {
            if (force.IsFinite())
            {
                OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);

                PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
                {
                    // Bullet adds this central force to the total force for this tick
                    if (PhysBody.HasPhysicalBody)
                    {
                        PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
                    }
                });
            }
            else
            {
                MainConsole.Instance.WarnFormat("{0}: Got a NaN force applied to a character. LocalID={1}", LogHeader, LocalID);
                return;
            }
        }
        public override void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
        {
            if (force.IsFinite())
            {
                OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
                // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);

                PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
                {
                    // Bullet adds this central force to the total force for this tick
                    // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
                    if (PhysBody.HasPhysicalBody)
                    {
                        PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
                    }
                });
            }
            else
            {
                m_log.WarnFormat("{0}: Got a NaN force applied to a character. LocalID={1}", LogHeader, LocalID);
                return;
            }
        }
Esempio n. 8
0
        // Called just before the simulation step. Update the vertical position for hoverness.
        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)
                    // new  //if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect)
                    {
                        m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion",
                                                 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 colliding and velocity nearly zero.
                        m_controllingPrim.ZeroMotion(true /* inTaintTime */);
                    }
                    else
                    {
                        //We are falling but are not touching any keys make sure not falling too fast
                        if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
                        {
                            OMV.Vector3 slowingForce = new OMV.Vector3(0f, 0f, BSParam.AvatarTerminalVelocity - m_controllingPrim.RawVelocity.Z) * m_controllingPrim.Mass;
                            m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, slowingForce);
                        }
                    }
                }


                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;
                    }
                }

                // Colliding and not flying with an upward force. The avatar must be trying to jump.
                if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && stepVelocity.Z > 0)
                {
                    // We allow the upward force to happen for this many frames.
                    m_jumpFrames   = BSParam.AvatarJumpFrames;
                    m_jumpVelocity = stepVelocity.Z;
                }

                // The case where the avatar is not colliding and is not flying is special.
                // The avatar is either falling or jumping and the user can be applying force to the avatar
                //     (force in some direction or force up or down).
                // If the avatar has negative Z velocity and is not colliding, presume we're falling and keep the velocity.
                // If the user is trying to apply upward force but we're not colliding, assume the avatar
                //     is trying to jump and don't apply the upward force if not touching the ground any more.
                if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
                {
                    // If upward velocity is being applied, this must be a jump and only allow that to go on so long
                    if (m_jumpFrames > 0)
                    {
                        // Since not touching the ground, only apply upward force for so long.
                        m_jumpFrames--;
                        stepVelocity.Z = m_jumpVelocity;
                    }
                    else
                    {
                        // Since we're not affected by anything, the avatar must be falling and we do not want that to be too fast.
                        if (m_controllingPrim.RawVelocity.Z < BSParam.AvatarTerminalVelocity)
                        {
                            stepVelocity.Z = BSParam.AvatarTerminalVelocity;
                        }
                        else
                        {
                            stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
                        }
                    }
                    // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
                }

                //Alicia: Maintain minimum height when flying.
                // SL has a flying effect that keeps the avatar flying above the ground by some margin
                if (m_controllingPrim.Flying)
                {
                    float hover_height = m_physicsScene.TerrainManager.GetTerrainHeightAtXYZ(m_controllingPrim.RawPosition)
                                         + BSParam.AvatarFlyingGroundMargin;

                    if (m_controllingPrim.Position.Z < hover_height)
                    {
                        stepVelocity.Z += BSParam.AvatarFlyingGroundUpForce;
                    }
                }

                // '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);

                // i think this fix is working .. :-)
                if (moveForce.IsFinite())
                {
                    m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, moveForce);
                }
            }

            // a bit of jump processing...
            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;
            }
        }
Esempio n. 9
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_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", 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);
                }

                // '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);
                if (moveForce.IsFinite())
                {
                    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;
            }
        }