Exemplo n.º 1
0
 public void addCollider(uint localID, ContactPoint contact)
 {
     ContactPoint oldCol;
     if (!m_objCollisionList.TryGetValue(localID, out oldCol))
         m_objCollisionList.Add(localID, contact);
     else
     {
         if (oldCol.PenetrationDepth < contact.PenetrationDepth)
             m_objCollisionList[localID] = contact;
     }
 }
Exemplo n.º 2
0
 public void addCollider(uint localID, ContactPoint contact)
 {
     Cleared = false;
     /*ContactPoint oldCol;
     if(!m_objCollisionList.TryGetValue(localID, out oldCol))
     {
         */lock(m_objCollisionList)
             m_objCollisionList[localID] = contact;
     /*}
     else
     {
         if(oldCol.PenetrationDepth < contact.PenetrationDepth)
             lock(m_objCollisionList)
                 m_objCollisionList[localID] = contact;
     }*/
 }
Exemplo n.º 3
0
 public abstract void AddCollisionEvent (uint localID, ContactPoint contact);
Exemplo n.º 4
0
 public override void AddCollisionEvent (uint CollidedWith, ContactPoint contact)
 {
 }
Exemplo n.º 5
0
 private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
 {
     if (!p2.SubscribedEvents() && !p1.SubscribedEvents())
         return;
     FireCollisionEvent(p1, p2, contact);
     if (p1.SubscribedEvents())
         p1.AddCollisionEvent(p2.LocalID, contact);
     if (p2.SubscribedEvents())
         p2.AddCollisionEvent(p1.LocalID, contact);
 }
Exemplo n.º 6
0
        /// <summary>
        ///   This is our near callback.  A geometry is near a body
        /// </summary>
        /// <param name = "space">The space that contains the geoms.  Remember, spaces are also geoms</param>
        /// <param name = "g1">a geometry or space</param>
        /// <param name = "g2">another geometry or space</param>
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            //  no lock here!  It's invoked from within Simulate(), which is thread-locked

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero || g1 == g2)
                return;

            // Test if we're colliding a geom with a space.
            // If so we have to drill down into the space recursively

            if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
            {
                // Separating static prim geometry spaces.
                // We'll be calling near recursivly if one
                // of them is a space to find all of the
                // contact points in the space
                try
                {
                    d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (Exception e)
                {
                    MainConsole.Instance.WarnFormat("[PHYSICS]: SpaceCollide2 failed: {0} ", e);
                    return;
                }
                return;
            }
            IntPtr b1 = d.GeomGetBody(g1);
            IntPtr b2 = d.GeomGetBody(g2);

            int FindContactsTime = Util.EnvironmentTickCount();

            // Figure out how many contact points we have
            int count = 0;
            try
            {
                // Colliding Geom To Geom
                // This portion of the function 'was' blatantly ripped off from BoxStack.cs

                if (g1 == g2)
                    return; // Can't collide with yourself

                if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
                    return;

                count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray,
                                     d.ContactGeom.unmanagedSizeOf);
            }
            catch (Exception e)
            {
                MainConsole.Instance.WarnFormat("[PHYSICS]:  ode Collide failed: {0} ", e);
                return;
            }

            if (count == 0)
                return;

            PhysicsActor p1;
            PhysicsActor p2;

            if (!actor_name_map.TryGetValue(g1, out p1))
                p1 = PANull;

            if (!actor_name_map.TryGetValue(g2, out p2))
                p2 = PANull;
            /*
                        if (p1 is AuroraODEPrim && (p1 as AuroraODEPrim)._zeroFlag)
                            (p1 as AuroraODEPrim)._zeroFlag = false;
                        if (p2 is AuroraODEPrim && (p2 as AuroraODEPrim)._zeroFlag)
                            (p2 as AuroraODEPrim)._zeroFlag = false;
            */
            m_StatFindContactsTime = Util.EnvironmentTickCountSubtract(FindContactsTime);

            if (p1.CollisionScore >= float.MaxValue - count)
                p1.CollisionScore = 0;
            p1.CollisionScore += count;

            if (p2.CollisionScore >= float.MaxValue - count)
                p2.CollisionScore = 0;
            p2.CollisionScore += count;

            int ContactLoopTime = Util.EnvironmentTickCount();

            ContactPoint maxDepthContact = new ContactPoint();
            d.ContactGeom curContact = new d.ContactGeom();

            int NotSkipedCount = 0;

            #region Contact Loop

            IntPtr joint = IntPtr.Zero;

            for (int i = 0; i < count; i++)
            {
                if (curContact.depth > maxDepthContact.PenetrationDepth)
                {
                    maxDepthContact.PenetrationDepth = curContact.depth;
                    maxDepthContact.Position.X = curContact.pos.X;
                    maxDepthContact.Position.Y = curContact.pos.Y;
                    maxDepthContact.Position.Z = curContact.pos.Z;
                    maxDepthContact.Type = (ActorTypes) p1.PhysicsActorType;
                    maxDepthContact.SurfaceNormal.X = curContact.normal.X;
                    maxDepthContact.SurfaceNormal.Y = curContact.normal.Y;
                    maxDepthContact.SurfaceNormal.Z = curContact.normal.Z;
                }

                bool p2col = false;

                // We only need to test p2 for 'jump crouch purposes'
                if (p2 is AuroraODECharacter && p1.PhysicsActorType == (int) ActorTypes.Prim)
                {
                    // Testing if the collision is at the feet of the avatar
                    if ((p2.Position.Z - maxDepthContact.Position.Z) > (p2.Size.Z*0.6f))
                        p2col = true;
                }
                else
                    p2col = true;

                p2.IsColliding = p2col;

                // Logic for collision handling
                // Note, that if *all* contacts are skipped (VolumeDetect)
                // The prim still detects (and forwards) collision events but 
                // appears to be phantom for the world
                Boolean skipThisContact = false;

                if (p1 is PhysicsObject && ((PhysicsObject) p1).VolumeDetect)
                    skipThisContact = true; // No collision on volume detect prims

                if (p2 is PhysicsObject && ((PhysicsObject) p2).VolumeDetect)
                    skipThisContact = true; // No collision on volume detect prims

                if (!GetCurContactGeom(i, ref curContact))
                    break;

                if (curContact.depth < 0f)
                    skipThisContact = true;


                if (!skipThisContact &&
                    m_filterCollisions &&
                    checkDupe(curContact, p2.PhysicsActorType))
                    skipThisContact = true;


                if (!skipThisContact)
                {
                    NotSkipedCount++;

                    // If we're colliding against terrain
                    if (p1.PhysicsActorType == (int) ActorTypes.Ground)
                    {
                        if (p2.PhysicsActorType == (int) ActorTypes.Prim)
                        {
                            if (m_filterCollisions)
                                _perloopContact.Add(curContact);

                            ((AuroraODEPrim)p2).GetContactParam((ActorTypes)p2.PhysicsActorType, ref newGlobalcontact);

                            joint = CreateContacJoint(ref curContact);
                        }
                        //Can't collide against anything else, agents do their own ground checks
                    }
                    else if ((p1.PhysicsActorType == (int) ActorTypes.Agent) &&
                             (p2.PhysicsActorType == (int) ActorTypes.Agent))
                    {
                        GetContactParam(0.0f, AvatarContactBounce, ref newGlobalcontact);

                        if (m_filterCollisions)
                            _perloopContact.Add(curContact);

                        joint = CreateContacJoint(ref curContact);
                    }

                    else if (p1.PhysicsActorType == (int) ActorTypes.Prim)
                    {
                        if (p2.PhysicsActorType == (int) ActorTypes.Agent)
                        {
                            ((AuroraODEPrim) p1).GetContactParam((ActorTypes)p2.PhysicsActorType, ref newGlobalcontact);
                            if (m_filterCollisions)
                                _perloopContact.Add(curContact);

                            joint = CreateContacJoint(ref curContact);
                        }
                        else if (p2.PhysicsActorType == (int) ActorTypes.Prim)
                        {
                            if (m_filterCollisions)
                                _perloopContact.Add(curContact);

                            //Add restitution and friction changes
                            ((AuroraODEPrim) p1).GetContactParam((ActorTypes)p2.PhysicsActorType, ref newGlobalcontact);

                            joint = CreateContacJoint(ref curContact);
                        }
                    }

                    if (m_global_contactcount < m_currentmaxContactsbeforedeath && joint != IntPtr.Zero)
                        // stack collide!
                    {
                        d.JointAttach(joint, b1, b2);
                        m_global_contactcount++;
                        joint = IntPtr.Zero;
                    }
                }
            }

            #endregion

            m_StatContactLoopTime = Util.EnvironmentTickCountSubtract(ContactLoopTime);

            int CollisionAccountingTime = Util.EnvironmentTickCount();

            if (NotSkipedCount > 0)
            {
                if (count > geomContactPointsStartthrottle)
                {
                    // If there are more then 3 contact points, it's likely
                    // that we've got a pile of objects, so ...
                    // We don't want to send out hundreds of terse updates over and over again
                    // so lets throttle them and send them again after it's somewhat sorted out.
                    p2.ThrottleUpdates = true;
                }
            }
            collision_accounting_events(p1, p2, maxDepthContact);
            m_StatCollisionAccountingTime = Util.EnvironmentTickCountSubtract(CollisionAccountingTime);
        }
Exemplo n.º 7
0
 public void FireCollisionEvent (PhysicsActor actor, PhysicsActor collidedActor, ContactPoint contact)
 {
     if(OnCollisionEvent != null)
         OnCollisionEvent (actor, collidedActor, contact);
 }
Exemplo n.º 8
0
 public override void AddCollisionEvent(uint localID, ContactPoint contact)
 {
     args.addCollider(localID, contact);
 }
Exemplo n.º 9
0
        /// <summary>
        ///   Called from Simulate
        ///   This is the avatar's movement control + PID Controller
        /// </summary>
        /// <param name = "timeStep"></param>
        public void Move(float timeStep, ref List<AuroraODECharacter> defects)
        {
            //  no lock; for now it's only called from within Simulate()

            // If the PID Controller isn't active then we set our force
            // calculating base velocity to the current position

            if (Body == IntPtr.Zero)
                return;

            if (!m_shouldBePhysical)
                return;

            Vector3 vec = Vector3.Zero;
            d.Vector3 vel = d.BodyGetLinearVel(Body);
            d.Vector3 tempPos;
            d.BodyCopyPosition(Body, out tempPos);

            #region Flight Ceiling

            // rex, added height check

            if (m_pidControllerActive == false)
            {
                _zeroPosition = tempPos;
            }

            if (_parent_scene.m_useFlightCeilingHeight && tempPos.Z > _parent_scene.m_flightCeilingHeight)
            {
                tempPos.Z = _parent_scene.m_flightCeilingHeight;
                d.BodySetPosition(Body, tempPos.X, tempPos.Y, tempPos.Z);
                if (vel.Z > 0.0f)
                {
                    vel.Z = 0.0f;
                    d.BodySetLinearVel(Body, vel.X, vel.Y, vel.Z);
                }
                if (_target_velocity.Z > 0.0f)
                    _target_velocity.Z = 0.0f;
            }

            // endrex

            #endregion

            #region NonFinite Pos

            Vector3 localPos = new Vector3(tempPos.X, tempPos.Y, tempPos.Z);

            if (!IsFinite(localPos))
            {
                MainConsole.Instance.Warn("[PHYSICS]: Avatar Position is non-finite!");
                defects.Add(this);
                // _parent_scene.RemoveCharacter(this);

                // destroy avatar capsule and related ODE data

                if (Amotor != IntPtr.Zero)
                {
                    // Kill the Amotor
                    d.JointDestroy(Amotor);
                    Amotor = IntPtr.Zero;
                }

                //kill the Geometry
                _parent_scene.waitForSpaceUnlock(_parent_scene.space);

                if (Body != IntPtr.Zero)
                {
                    //kill the body
                    d.BodyDestroy(Body);

                    Body = IntPtr.Zero;
                }

                if (Shell != IntPtr.Zero)
                {
                    d.GeomDestroy(Shell);
                    Shell = IntPtr.Zero;
                }
                return;
            }

            #endregion

            #region Check for out of region

            if (Position.X < 0.25f || Position.Y < 0.25f ||
                Position.X > _parent_scene.Region.RegionSizeX - .25f ||
                Position.Y > _parent_scene.Region.RegionSizeY - .25f)
            {
                if (!CheckForRegionCrossing())
                {
                    Vector3 newPos = Position;
                    newPos.X = Util.Clip(Position.X, 0.75f, _parent_scene.Region.RegionSizeX - 0.75f);
                    newPos.Y = Util.Clip(Position.Y, 0.75f, _parent_scene.Region.RegionSizeY - 0.75f);
                    Position = newPos;
                    d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z);
                }
            }

            #endregion

            #region Movement Multiplier

            float movementmult = 1f;
            if (!m_alwaysRun)
                movementmult /= _parent_scene.avMovementDivisorWalk;
            else
                movementmult /= _parent_scene.avMovementDivisorRun;

            movementmult *= 10;
            movementmult *= SpeedModifier;
//            movementmult *= 1 / _parent_scene.TimeDilation;
            if (flying)
                movementmult *= _parent_scene.m_AvFlySpeed;

            #endregion

            #region Check for underground

            d.AABB aabb;
            d.GeomGetAABB(Shell, out aabb);
            float chrminZ = aabb.MinZ;

            Vector3 posch = localPos;

            float ftmp;

            if (flying)
            {
                ftmp = 0.75f*timeStep;
                posch.X += vel.X*ftmp;
                posch.Y += vel.Y*ftmp;
            }

            float groundHeight = _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y);

            if (chrminZ < groundHeight)
            {
                float depth = groundHeight - chrminZ;

                if (_target_velocity.Z < 0)
                    _target_velocity.Z = 0;

                if (!flying)
                {
                    if (vel.Z < -10f)
                        vel.Z = -10f;
                    vec.Z = -vel.Z*PID_D*1.5f + depth*PID_P*50.0f;
                }
                else
                {
                    vec.Z = depth*PID_P*50.0f;
                }

                if (depth < 0.12f)
                {
                    m_iscolliding = true;
                    m_colliderfilter = 2;
                    m_iscollidingGround = true;

                    ContactPoint point = new ContactPoint
                                             {
                                                 Type = ActorTypes.Ground,
                                                 PenetrationDepth = depth,
                                                 Position = {X = localPos.X, Y = localPos.Y, Z = chrminZ},
                                                 SurfaceNormal = new Vector3(0, 0, -1f)
                                             };

                    //0 is the ground localID
                    AddCollisionEvent(0, point);
                    vec.Z *= 0.5f;
                }
                else
                    m_iscollidingGround = false;
            }
            else
                m_iscollidingGround = false;
/*
            if(Flying && _target_velocity == Vector3.Zero &&
                Math.Abs(vel.Z) < 0.1)
                notMoving = true;
*/

            #endregion

            #region Movement

            #region Jump code

            if (IsJumping)
            {
//                if ((IsColliding) && m_preJumpCounter > _parent_scene.m_preJumpTime || m_preJumpCounter > 150)
                if ((IsColliding) && m_preJumpCounter > _parent_scene.m_preJumpTime || m_preJumpCounter > 150)
                {
                    m_isJumping = false;
                    m_preJumpCounter = 0;
                    _target_velocity.Z = 0;
                }
                else
                    m_preJumpCounter++;
            }

            else if (m_ispreJumping)
            {
                if (m_preJumpCounter == _parent_scene.m_preJumpTime)
                {
                    m_ispreJumping = false;
                    _target_velocity.X = m_preJumpForce.X*_parent_scene.m_preJumpForceMultiplierX;
                    _target_velocity.Y = m_preJumpForce.Y*_parent_scene.m_preJumpForceMultiplierY;
                    _target_velocity.Z = m_preJumpForce.Z*_parent_scene.m_preJumpForceMultiplierZ;

                    m_preJumpCounter = 0;
                    m_isJumping = true;
                }
                else
                {
                    m_preJumpCounter++;
                    TriggerMovementUpdate();
                    return;
                }
            }


            //This is for jumping on prims, since otherwise, you don't get off the ground sometimes
//            if (m_iscolliding && m_isJumping && _target_velocity.Z < 1 && !Flying)
//                _target_velocity.Z += m_preJumpForce.Z * _parent_scene.m_preJumpForceMultiplier;

            #endregion

            Vector3 gravForce = new Vector3();

            //  if velocity is zero, use position control; otherwise, velocity control
            if (_target_velocity == Vector3.Zero &&
                Math.Abs(vel.X) < 0.1 && Math.Abs(vel.Y) < 0.1 && Math.Abs(vel.Z) < 0.1 &&
                (this.m_iscolliding || this.flying || (this._zeroFlag && _wasZeroFlagFlying == flying)))
                //This is so that if we get moved by something else, it will update us in the client
            {
                m_isJumping = false;
                //  keep track of where we stopped.  No more slippin' & slidin'
                if (!_zeroFlag)
                {
                    _zeroFlag = true;
                    _wasZeroFlagFlying = flying;
                    _zeroPosition = tempPos;
                }

                if (m_pidControllerActive)
                {
                    // We only want to deactivate the PID Controller if we think we want to have our surrogate
                    // react to the physics scene by moving it's position.
                    // Avatar to Avatar collisions
                    // Prim to avatar collisions
                    // if target vel is zero why was it here ?
                    vec.X = -vel.X*PID_D + (_zeroPosition.X - tempPos.X)*PID_P;
                    vec.Y = -vel.Y*PID_D + (_zeroPosition.Y - tempPos.Y)*PID_P;
//                    if (!realFlying)
//                        vec.Z +=  - vel.Z * PID_D * 5;
//                    else
                    if (flying)
                        vec.Z += -vel.Z*PID_D*0.5f + (_zeroPosition.Z - tempPos.Z)*PID_P;

//                    _parent_scene.CalculateGravity(m_mass, tempPos, true, 0.15f, ref gravForce);
//                    vec += gravForce;
                }
            }
            else
            {
                m_pidControllerActive = true;
                _zeroFlag = false;

                if (m_iscolliding)
                {
                    if (!flying) //If there is a ground collision, it sets flying to false, so check against real flying
                    {
                        // We're standing or walking on something
                        if (_target_velocity.X != 0.0f)
                            vec.X += (_target_velocity.X * movementmult - vel.X) * PID_D * 2;
                        if (_target_velocity.Y != 0.0f)
                            vec.Y += (_target_velocity.Y * movementmult - vel.Y) * PID_D * 2;
                        if (_target_velocity.Z != 0.0f)
                            vec.Z += (_target_velocity.Z * movementmult - vel.Z) * PID_D;
                        /*// We're standing or walking on something
                        vec.X += (_target_velocity.X*movementmult - vel.X)*PID_D*2;
                        vec.Y += (_target_velocity.Y*movementmult - vel.Y)*PID_D*2;
                        if (_target_velocity.Z > 0.0f)
                            vec.Z += (_target_velocity.Z*movementmult - vel.Z)*PID_D;
                                // + (_zeroPosition.Z - tempPos.Z) * PID_P)) _zeropos maybe bad here*/
                    }
                    else
                    {
                        // We're flying and colliding with something
                        vec.X += (_target_velocity.X*movementmult - vel.X)*PID_D*0.5f;
                        vec.Y += (_target_velocity.Y*movementmult - vel.Y)*PID_D*0.5f;
                        //if(_target_velocity.Z > 0)
                        vec.Z += (_target_velocity.Z*movementmult - vel.Z)*PID_D*0.5f;
                    }
                }
                else
                {
                    if (flying)
                    {
                        // we're flying
                        vec.X += (_target_velocity.X * movementmult - vel.X) * PID_D * 0.75f;
                        vec.Y += (_target_velocity.Y * movementmult - vel.Y) * PID_D * 0.75f;
                    }
                    else
                    {
                        // we're not colliding and we're not flying so that means we're falling!
                        // m_iscolliding includes collisions with the ground.
                        vec.X += (_target_velocity.X - vel.X) * PID_D * 0.85f;
                        vec.Y += (_target_velocity.Y - vel.Y) * PID_D * 0.85f;
                    }
                }


                if (flying)
                {
                    #region Av gravity

                    if (_parent_scene.AllowAvGravity &&
                        tempPos.Z > _parent_scene.AvGravityHeight) //Should be stop avies from flying upwards
                    {
                        //Decay going up 
                        if (_target_velocity.Z > 0)
                        {
                            //How much should we force them down?
                            float Multiplier = (_parent_scene.AllowAvsToEscapeGravity ? .03f : .1f);
                            //How much should we force them down?
                            float fudgeHeight = (_parent_scene.AllowAvsToEscapeGravity ? 80 : 30);
                            //We add the 30 so that gravity is resonably strong once they pass the min height
                            Multiplier *= tempPos.Z + fudgeHeight - _parent_scene.AvGravityHeight;

                            //Limit these so that things don't go wrong
                            if (Multiplier < 1)
                                Multiplier = 1;

                            float maxpower = (_parent_scene.AllowAvsToEscapeGravity ? 1.5f : 3f);

                            if (Multiplier > maxpower)
                                Multiplier = maxpower;

                            _target_velocity.Z /= Multiplier;
                            vel.Z /= Multiplier;
                        }
                    }

                    #endregion

                    vec.Z = (_target_velocity.Z*movementmult - vel.Z)*PID_D*0.5f;
                    if (_parent_scene.AllowAvGravity && tempPos.Z > _parent_scene.AvGravityHeight)
                        //Add extra gravity
                        vec.Z += ((10*_parent_scene.gravityz)*Mass);
                }
            }

            if (realFlying)
            {
                #region Auto Fly Height

                //Added for auto fly height. Kitto Flora
                //Changed to only check if the avatar is flying around,

                // Revolution: If the avatar is going down, they are trying to land (probably), so don't push them up to make it harder
                //   Only if they are moving around sideways do we need to push them up
                if (_target_velocity.X != 0 || _target_velocity.Y != 0)
                {
                    Vector3 forwardVel = new Vector3(_target_velocity.X > 0 ? 2 : (_target_velocity.X < 0 ? -2 : 0),
                                                     _target_velocity.Y > 0 ? 2 : (_target_velocity.Y < 0 ? -2 : 0),
                                                     0);
                    float target_altitude = _parent_scene.GetTerrainHeightAtXY(tempPos.X, tempPos.Y) +
                                            MinimumGroundFlightOffset;

                    //We cheat a bit and do a bit lower than normal
                    if ((tempPos.Z - CAPSULE_LENGTH) < target_altitude ||
                        (tempPos.Z - CAPSULE_LENGTH) <
                        _parent_scene.GetTerrainHeightAtXY(tempPos.X + forwardVel.X, tempPos.Y + forwardVel.Y)
                        + MinimumGroundFlightOffset)
                        if (_target_velocity.Z < 0)
                            vec.Z += (target_altitude - tempPos.Z)*PID_P*0.5f; //Don't apply so much
                        else
                            vec.Z += (target_altitude - tempPos.Z)*PID_P*1.05f;
                }
                else
                {
                    //Straight up and down, only apply when they are very close to the ground
                    float target_altitude = _parent_scene.GetTerrainHeightAtXY(tempPos.X, tempPos.Y);

                    if ((tempPos.Z - CAPSULE_LENGTH + (MinimumGroundFlightOffset/1.5)) <
                        target_altitude + MinimumGroundFlightOffset)
                    {
                        if ((tempPos.Z - CAPSULE_LENGTH) < target_altitude + 1)
                        {
                            vec.Z += ((target_altitude + 4) - (tempPos.Z - CAPSULE_LENGTH))*PID_P;
                        }
                        else
                            vec.Z += ((target_altitude + MinimumGroundFlightOffset) - (tempPos.Z - CAPSULE_LENGTH))*
                                     PID_P*0.5f;
                    }
                }

                #endregion
            }

            #region Gravity

            if (!flying)
                _parent_scene.CalculateGravity(m_mass, tempPos, true, 1.0f, ref gravForce);
            else
                _parent_scene.CalculateGravity(m_mass, tempPos, false, 0.65f, ref gravForce);
                    //Allow point gravity and repulsors affect us a bit

            vec += gravForce;

            #endregion

            #region Under water physics

            if (_parent_scene.AllowUnderwaterPhysics && tempPos.X < _parent_scene.Region.RegionSizeX &&
                tempPos.Y < _parent_scene.Region.RegionSizeY)
            {
                //Position plus height to av's shoulder (aprox) is just above water
                if ((tempPos.Z + (CAPSULE_LENGTH/3) - .25f) < _parent_scene.GetWaterLevel(tempPos.X, tempPos.Y))
                {
                    if (StartingUnderWater)
                        ShouldBeWalking = Flying = false;
                    StartingUnderWater = false;
                    WasUnderWater = true;
                    Flying = true;
                    lastUnderwaterPush = 0;
                    if (ShouldBeWalking)
                    {
                        lastUnderwaterPush += (float) (_parent_scene.GetWaterLevel(tempPos.X, tempPos.Y) - tempPos.Z)*33 +
                                              3;
                        vec.Z += lastUnderwaterPush;
                    }
                    else
                    {
                        lastUnderwaterPush += 3500;
                        lastUnderwaterPush += (float) (_parent_scene.GetWaterLevel(tempPos.X, tempPos.Y) - tempPos.Z)*8;
                        vec.Z += lastUnderwaterPush;
                    }
                }
                else
                {
                    StartingUnderWater = true;
                    if (WasUnderWater)
                    {
                        WasUnderWater = false;
                        Flying = true;
                    }
                }
            }

            #endregion

            #endregion

            #region Apply the force

            if (IsFinite(vec))
            {
                if (vec.X < 100000000 && vec.Y < 10000000 && vec.Z < 10000000)
                    //Checks for crazy, going to NaN us values
                {
                    // round small values to zero. those possible are just errors
                    if (Math.Abs(vec.X) < 0.001)
                        vec.X = 0;
                    if (Math.Abs(vec.Y) < 0.001)
                        vec.Y = 0;
                    if (Math.Abs(vec.Z) < 0.001)
                        vec.Z = 0;

                    //ODE autodisables not moving prims, accept it and reenable when we need to
                    if (!d.BodyIsEnabled(Body))
                        d.BodyEnable(Body);

                    if (vec == Vector3.Zero) //if we arn't moving, STOP
                    {
                        if (m_lastForceApplied != -1)
                        {
                            m_lastForceApplied = -1;
                            d.BodySetLinearVel(Body, vec.X, vec.Y, vec.Z);
                        }
                    }
                    else
                    {
                        if (m_lastForceApplied < 5)
                            vec *= m_lastForceApplied / 5;
                        doForce(vec);
                        m_lastForceApplied++;
                    }

//                    if (!_zeroFlag && (!flying || m_iscolliding))
//                        AlignAvatarTiltWithCurrentDirectionOfMovement (vec, gravForce);

                    // the Amotor still lets avatar rotation to drift during colisions
                    // so force it back to identity

                    d.Quaternion qtmp;
                    qtmp.W = 1;
                    qtmp.X = 0;
                    qtmp.Y = 0;
                    qtmp.Z = 0;
                    d.BodySetQuaternion(Body, ref qtmp);
                    d.BodySetAngularVel(Body, 0, 0, 0);

                    //When falling, we keep going faster and faster, and eventually, the client blue screens (blue is all you see).
                    // The speed that does this is slightly higher than -30, so we cap it here so we never do that during falling.
                    if (vel.Z < -30)
                    {
                        vel.Z = -30;
                        d.BodySetLinearVel(Body, vel.X, vel.Y, vel.Z);
                    }

                    //Decay out the target velocity DON'T it forces tons of updates

                    _target_velocity *= _parent_scene.m_avDecayTime;
                    if (!_zeroFlag && _target_velocity.ApproxEquals (Vector3.Zero, _parent_scene.m_avStopDecaying))
                        _target_velocity = Vector3.Zero;

                }
                else
                {
                    //This is a safe guard from going NaN, but it isn't very smooth... which is ok
                    d.BodySetForce(Body, 0, 0, 0);
                    d.BodySetLinearVel(Body, 0, 0, 0);
                }
            }
            else
            {
                MainConsole.Instance.Warn("[PHYSICS]: Got a NaN force vector in Move()");
                MainConsole.Instance.Warn("[PHYSICS]: Avatar Position is non-finite!");
                defects.Add(this);
                //kill the Geometry
                _parent_scene.waitForSpaceUnlock(_parent_scene.space);

                if (Body != IntPtr.Zero)
                {
                    //kill the body
                    d.BodyDestroy(Body);

                    Body = IntPtr.Zero;
                }

                if (Shell != IntPtr.Zero)
                {
                    d.GeomDestroy(Shell);
                    Shell = IntPtr.Zero;
                }
            }

            #endregion
        }
Exemplo n.º 10
0
 public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
 {
     CollisionEventsThisFrame.addCollider(CollidedWith, contact);
 }