public override void RemoveAvatar(PhysicsActor actor)
 {
     BasicActor act = (BasicActor) actor;
     if (_actors.Contains(act))
     {
         _actors.Remove(act);
     }
 }
Beispiel #2
0
 public override void RemovePrim(PhysicsActor prim)
 {
     POSPrim p = (POSPrim) prim;
     if (_prims.Contains(p))
     {
         _prims.Remove(p);
     }
 }
Beispiel #3
0
 public override void RemoveAvatar(PhysicsActor character)
 {
     POSCharacter act = (POSCharacter) character;
     if (_characters.Contains(act))
     {
         _characters.Remove(act);
     }
 }
 /// <summary>
 /// Indicates that an actor has been updated by the engine.
 /// NOTE: This is an override method that is not needed.
 /// </summary>
 /// <param name="prim">The actor that was modified</param>
 public override void AddPhysicsActorTaint(PhysicsActor prim)
 {
     // Nothing to do here
 }
Beispiel #5
0
 public override void RemoveAvatar(PhysicsActor actor)
 {
     this.QueueCommand(new Commands.RemoveCharacterCmd((PhysxCharacter)actor));
 }
Beispiel #6
0
 public override void link(PhysicsActor obj) { return; }
Beispiel #7
0
 /// <summary>
 /// Remove an avatar.
 /// </summary>
 /// <param name="actor"></param>
 public abstract void RemoveAvatar(PhysicsActor actor);
        /// <summary>
        /// Apply physics to this part.
        /// </summary>
        /// <param name="rootObjectFlags"></param>
        /// <param name="m_physicalPrim"></param>
        public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool m_physicalPrim)
        {
            bool isPhysical = (((rootObjectFlags & (uint) PrimFlags.Physics) != 0) && m_physicalPrim);
            bool isPhantom = ((rootObjectFlags & (uint) PrimFlags.Phantom) != 0);

            if (IsJoint())
            {
                DoPhysicsPropertyUpdate(isPhysical, true);
            }
            else
            {
                // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored
                if (VolumeDetectActive)
                    isPhantom = false;

                // Added clarification..   since A rigid body is an object that you can kick around, etc.
                bool RigidBody = isPhysical && !isPhantom;

                // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
                // or flexible
                if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
                {
                    PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
                        Name,
                        Shape,
                        AbsolutePosition,
                        Scale,
                        RotationOffset,
                        RigidBody);

                    // Basic Physics returns null..  joy joy joy.
                    if (PhysActor != null)
                    {
                        PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
                        PhysActor.SOPDescription = this.Description;
                        PhysActor.LocalID = LocalId;
                        DoPhysicsPropertyUpdate(RigidBody, true);
                        PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
                    }
                }
            }
        }
Beispiel #9
0
        public void AttachToPhysicsShape(PhysicsActor shape, bool isChild)
        {
            PhysActor = shape;
            SetPhysActorRelationProperties();

            if (!isChild)
            {
                PhysActor.OnRequestTerseUpdate -= this.PhysicsRequestingTerseUpdate;
                PhysActor.OnRequestTerseUpdate += this.PhysicsRequestingTerseUpdate;
                PhysActor.OnComplexityError -= new PhysicsActor.ComplexityError(PhysActor_OnComplexityError);
                PhysActor.OnComplexityError += new PhysicsActor.ComplexityError(PhysActor_OnComplexityError);
                PhysActor.OnPhysicsRequestingOBB -= PhysActor_OnPhysicsRequestingOBB;
                PhysActor.OnPhysicsRequestingOBB += PhysActor_OnPhysicsRequestingOBB;
            }

            PhysActor.OnNeedsPersistence -= new PhysicsActor.RequestPersistence(PhysActor_OnNeedsPersistence);
            PhysActor.OnNeedsPersistence += new PhysicsActor.RequestPersistence(PhysActor_OnNeedsPersistence);
            PhysActor.OnPositionUpdate -= new PositionUpdate(PhysActor_OnPositionUpdate);
            PhysActor.OnPositionUpdate += new PositionUpdate(PhysActor_OnPositionUpdate);

            this.CheckForScriptCollisionEventsAndSubscribe();
        }
Beispiel #10
0
 public abstract void link(PhysicsActor obj);
Beispiel #11
0
        public void GetMesh(ODEPhysRepData repData)
        {
            PhysicsActor actor = repData.actor;

            PrimitiveBaseShape pbs = repData.pbs;

            repData.mesh   = null;
            repData.hasOBB = false;

            if (!needsMeshing(repData))
            {
                repData.meshState = MeshState.noNeed;
                return;
            }

            if (repData.meshState == MeshState.MeshFailed)
            {
                return;
            }

            if (pbs.SculptEntry)
            {
                if (repData.meshState == MeshState.AssetFailed)
                {
                    if (pbs.SculptTexture == repData.assetID)
                    {
                        return;
                    }
                }
            }

            repData.meshState = MeshState.noNeed;

            IMesh   mesh      = null;
            Vector3 size      = repData.size;
            byte    shapetype = repData.shapetype;

            bool convex;
            int  clod = (int)LevelOfDetail.High;

            if (shapetype == 0)
            {
                convex = false;
            }
            else
            {
                convex = true;
                if (pbs.SculptType != (byte)SculptType.Mesh)
                {
                    clod = (int)LevelOfDetail.Low;
                }
            }

            mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true);

            if (mesh == null)
            {
                if (pbs.SculptEntry)
                {
                    if (pbs.SculptTexture == UUID.Zero)
                    {
                        return;
                    }

                    repData.assetID = pbs.SculptTexture;

                    if (pbs.SculptData == null || pbs.SculptData.Length == 0)
                    {
                        repData.meshState = MeshState.needAsset;
                        return;
                    }
                }
            }

            repData.mesh           = mesh;
            repData.pbs.SculptData = Utils.EmptyBytes;

            if (mesh == null)
            {
                if (pbs.SculptEntry)
                {
                    repData.meshState = MeshState.AssetFailed;
                }
                else
                {
                    repData.meshState = MeshState.MeshFailed;
                }

                return;
            }

            repData.meshState = MeshState.AssetOK;

            return;
        }
Beispiel #12
0
        // see if we need a mesh and if so if we have a cached one
        // called with a new repData
        public void CheckMesh(ODEPhysRepData repData)
        {
            PhysicsActor       actor = repData.actor;
            PrimitiveBaseShape pbs   = repData.pbs;

            if (!needsMeshing(repData))
            {
                repData.meshState = MeshState.noNeed;
                repData.hasOBB    = false;
                return;
            }

            IMesh mesh = null;

            Vector3 size = repData.size;

            int  clod      = (int)LevelOfDetail.High;
            byte shapetype = repData.shapetype;
            bool convex    = shapetype == 2;

            mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);

            if (mesh == null)
            {
                if (pbs.SculptEntry)
                {
                    if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero)
                    {
                        repData.assetID   = pbs.SculptTexture;
                        repData.meshState = MeshState.needAsset;
                    }
                    else
                    {
                        repData.meshState = MeshState.MeshFailed;
                    }

                    return;
                }
                else
                {
                    repData.meshState = MeshState.needMesh;
                    mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true);
                    if (mesh == null)
                    {
                        repData.meshState = MeshState.MeshFailed;
                        return;
                    }
                }
            }

            repData.meshState = MeshState.AssetOK;
            repData.mesh      = mesh;
            repData.OBB       = mesh.GetOBB();
            repData.OBBOffset = mesh.GetCentroid();
            repData.hasOBB    = true;

            if (pbs.SculptEntry)
            {
                repData.assetID = pbs.SculptTexture;
            }

            pbs.SculptData = Utils.EmptyBytes;
            return;
        }
Beispiel #13
0
        public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            bool pushAllowed = false;

            bool pusheeIsAvatar = false;
            UUID targetID       = UUID.Zero;

            if (!UUID.TryParse(target, out targetID))
            {
                return;
            }

            IScenePresence    pusheeav  = null;
            Vector3           PusheePos = Vector3.Zero;
            ISceneChildEntity pusheeob  = null;

            IScenePresence avatar = World.GetScenePresence(targetID);

            if (avatar != null)
            {
                pusheeIsAvatar = true;

                // Pushee is in GodMode this pushing object isn't owned by them
                if (avatar.GodLevel > 0 && m_host.OwnerID != targetID)
                {
                    return;
                }

                pusheeav = avatar;

                // Find pushee position
                // Pushee Linked?
                if (pusheeav.ParentID != UUID.Zero)
                {
                    ISceneChildEntity parentobj = World.GetSceneObjectPart(pusheeav.ParentID);
                    PusheePos = parentobj != null ? parentobj.AbsolutePosition : pusheeav.AbsolutePosition;
                }
                else
                {
                    PusheePos = pusheeav.AbsolutePosition;
                }
            }

            if (!pusheeIsAvatar)
            {
                // not an avatar so push is not affected by parcel flags
                pusheeob = World.GetSceneObjectPart(UUID.Parse(target));

                // We can't find object
                if (pusheeob == null)
                {
                    return;
                }

                // Object not pushable.  Not an attachment and has no physics component
                if (!pusheeob.IsAttachment && pusheeob.PhysActor == null)
                {
                    return;
                }

                PusheePos   = pusheeob.AbsolutePosition;
                pushAllowed = true;
            }
            else
            {
                IParcelManagementModule parcelManagement = World.RequestModuleInterface <IParcelManagementModule>();
                if (World.RegionInfo.RegionSettings.RestrictPushing)
                {
                    pushAllowed = m_host.OwnerID == targetID ||
                                  m_host.ParentEntity.Scene.Permissions.IsGod(m_host.OwnerID);
                }
                else
                {
                    if (parcelManagement != null)
                    {
                        ILandObject targetlandObj = parcelManagement.GetLandObject(PusheePos.X, PusheePos.Y);
                        if (targetlandObj == null)
                        {
                            // We didn't find the parcel but region isn't push restricted so assume it's ok
                            pushAllowed = true;
                        }
                        else
                        {
                            // Parcel push restriction
                            pushAllowed = (targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) !=
                                          (uint)ParcelFlags.RestrictPushObject ||
                                          m_host.ParentEntity.Scene.Permissions.CanPushObject(m_host.OwnerID,
                                                                                              targetlandObj);
                        }
                    }
                }
            }

            if (pushAllowed)
            {
                float distance      = (PusheePos - m_host.AbsolutePosition).Length();
                float distance_term = distance * distance * distance; // Script Energy
                float pusher_mass   = m_host.GetMass();

                const float PUSH_ATTENUATION_DISTANCE = 17f;
                const float PUSH_ATTENUATION_SCALE    = 5f;
                float       distance_attenuation      = 1f;
                if (distance > PUSH_ATTENUATION_DISTANCE)
                {
                    float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE;
                    distance_attenuation = 1f / normalized_units;
                }

                Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z);
                {
                    float impulse_length = applied_linear_impulse.Length();

                    float desired_energy = impulse_length * pusher_mass;
                    if (desired_energy > 0f)
                    {
                        desired_energy += distance_term;
                    }

                    float scaling_factor = 1f;
                    scaling_factor         *= distance_attenuation;
                    applied_linear_impulse *= scaling_factor;
                }
                if (pusheeIsAvatar)
                {
                    if (pusheeav != null)
                    {
                        PhysicsActor pa = pusheeav.PhysicsActor;

                        if (pa != null)
                        {
                            if (local != 0)
                            {
                                applied_linear_impulse *= m_host.GetWorldRotation();
                            }
                            //Put a limit on it...
                            int MaxPush = (int)pusheeav.PhysicsActor.Mass * 25;

                            if (applied_linear_impulse.X > 0 &&
                                Math.Abs(applied_linear_impulse.X) > MaxPush)
                            {
                                applied_linear_impulse.X = MaxPush;
                            }
                            if (applied_linear_impulse.X < 0 &&
                                Math.Abs(applied_linear_impulse.X) > MaxPush)
                            {
                                applied_linear_impulse.X = -MaxPush;
                            }

                            if (applied_linear_impulse.Y > 0 &&
                                Math.Abs(applied_linear_impulse.X) > MaxPush)
                            {
                                applied_linear_impulse.Y = MaxPush;
                            }
                            if (applied_linear_impulse.Y < 0 &&
                                Math.Abs(applied_linear_impulse.Y) > MaxPush)
                            {
                                applied_linear_impulse.Y = -MaxPush;
                            }

                            if (applied_linear_impulse.Z > 0 &&
                                Math.Abs(applied_linear_impulse.X) > MaxPush)
                            {
                                applied_linear_impulse.Z = MaxPush;
                            }
                            if (applied_linear_impulse.Z < 0 &&
                                Math.Abs(applied_linear_impulse.Z) > MaxPush)
                            {
                                applied_linear_impulse.Z = -MaxPush;
                            }

                            pa.AddForce(applied_linear_impulse, true);
                        }
                    }
                }
                else
                {
                    if (pusheeob.PhysActor != null)
                    {
                        pusheeob.ApplyImpulse(applied_linear_impulse, local != 0);
                    }
                }
            }
        }
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        private string DetermineMovementAnimation()
        {
            const int FALL_DELAY    = 800;
            const int PREJUMP_DELAY = 200;
            const int JUMP_PERIOD   = 800;

            #region Inputs

            if (m_scenePresence.IsInTransit)
            {
                return(CurrentMovementAnimation);
            }

            if (m_scenePresence.SitGround)
            {
                currentControlState = motionControlStates.sitted;
                return("SITGROUND");
            }
            if (m_scenePresence.ParentID != 0 || m_scenePresence.ParentUUID != UUID.Zero)
            {
                currentControlState = motionControlStates.sitted;
                return("SIT");
            }

            AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
            PhysicsActor actor = m_scenePresence.PhysicsActor;

            const AgentManager.ControlFlags ANYXYMASK = (
                AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS |
                AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG |
                AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS |
                AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG
                );

            // Check control flags

            /* not in use
             *          bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0);
             *          bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0);
             *          bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0);
             *          bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0);
             */
            bool heldTurnLeft  = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
            bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
            //            bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS)) != 0);
            // excluded nudge up so it doesn't trigger jump state
            bool heldUp   = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0);
            bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0);
            //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
            //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;

            bool heldOnXY = ((controlFlags & ANYXYMASK) != 0);
            if (heldOnXY || heldUp || heldDown)
            {
                heldTurnLeft  = false;
                heldTurnRight = false;
            }

            #endregion Inputs

            // no physics actor case
            if (actor == null)
            {
                // well what to do?

                currentControlState = motionControlStates.onsurface;
                if (heldOnXY)
                {
                    return("WALK");
                }

                return("STAND");
            }

            #region Flying

            bool isColliding = actor.IsColliding;

            if (actor.Flying)
            {
                m_animTickFall = 0;
                m_animTickJump = 0;
                m_jumping      = false;
                Falling        = false;

                currentControlState = motionControlStates.flying;

                if (heldOnXY)
                {
                    return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
                }
                else if (heldUp)
                {
                    return("HOVER_UP");
                }
                else if (heldDown)
                {
                    if (isColliding)
                    {
                        actor.Flying        = false;
                        currentControlState = motionControlStates.landing;
                        m_animTickLand      = Environment.TickCount;
                        return("LAND");
                    }
                    else
                    {
                        return("HOVER_DOWN");
                    }
                }
                else
                {
                    return("HOVER");
                }
            }
            else
            {
                if (isColliding && currentControlState == motionControlStates.flying)
                {
                    currentControlState = motionControlStates.landing;
                    m_animTickLand      = Environment.TickCount;
                    return("LAND");
                }
            }

            #endregion Flying

            #region Falling/Floating/Landing

            if (!isColliding && currentControlState != motionControlStates.jumping)
            {
                float fallVelocity = actor.Velocity.Z;

                // if stable on Hover assume falling
                if (actor.PIDHoverActive && fallVelocity < 0.05f)
                {
                    Falling             = true;
                    currentControlState = motionControlStates.falling;
                    m_lastFallVelocity  = fallVelocity;
                    return("FALLDOWN");
                }

                if (fallVelocity < -2.5f)
                {
                    Falling = true;
                }

                if (m_animTickFall == 0 || (fallVelocity >= -0.5f))
                {
                    m_animTickFall = Environment.TickCount;
                }
                else
                {
                    int fallElapsed = (Environment.TickCount - m_animTickFall);
                    if ((fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f))
                    {
                        currentControlState = motionControlStates.falling;
                        m_lastFallVelocity  = fallVelocity;
                        // Falling long enough to trigger the animation
                        return("FALLDOWN");
                    }
                }

                // Check if the user has stopped walking just now
                if (CurrentMovementAnimation == "WALK" && !heldOnXY && !heldDown && !heldUp)
                {
                    return("STAND");
                }

                return(CurrentMovementAnimation);
            }

            m_animTickFall = 0;

            #endregion Falling/Floating/Landing

            #region Jumping     // section added for jumping...

            if (isColliding && heldUp && currentControlState != motionControlStates.jumping && !actor.PIDHoverActive)
            {
                // Start jumping, prejump
                currentControlState = motionControlStates.jumping;
                m_jumping           = true;
                Falling             = false;
                m_animTickJump      = Environment.TickCount;
                return("PREJUMP");
            }

            if (currentControlState == motionControlStates.jumping)
            {
                int jumptime = Environment.TickCount - m_animTickJump;
                if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
                {
                    // end jumping
                    m_jumping           = false;
                    Falling             = false;
                    actor.Selected      = false; // borrowed for jumping flag
                    m_animTickLand      = Environment.TickCount;
                    currentControlState = motionControlStates.landing;
                    return("LAND");
                }
                else if (jumptime > JUMP_PERIOD)
                {
                    // jump down
                    return("JUMP");
                }
                else if (jumptime > PREJUMP_DELAY)
                {
                    // jump up
                    m_jumping = true;
                    return("JUMP");
                }
                return(CurrentMovementAnimation);
            }

            #endregion Jumping

            #region Ground Movement

            if (currentControlState == motionControlStates.falling)
            {
                Falling             = false;
                currentControlState = motionControlStates.landing;
                m_animTickLand      = Environment.TickCount;
                // TODO: SOFT_LAND support
                float fallVsq = m_lastFallVelocity * m_lastFallVelocity;
                if (fallVsq > 300f) // aprox 20*h
                {
                    return("STANDUP");
                }
                else if (fallVsq > 160f)
                {
                    return("SOFT_LAND");
                }
                else
                {
                    return("LAND");
                }
            }


            if (currentControlState == motionControlStates.landing)
            {
                Falling = false;
                int landElapsed = Environment.TickCount - m_animTickLand;
                int limit       = 1000;
                if (CurrentMovementAnimation == "LAND")
                {
                    limit = 350;
                }
                // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client

                if ((m_animTickLand != 0) && (landElapsed <= limit))
                {
                    return(CurrentMovementAnimation);
                }
                else
                {
                    currentControlState = motionControlStates.onsurface;
                    m_animTickLand      = 0;
                    return("STAND");
                }
            }

            // next section moved outside paren. and realigned for jumping

            if (heldOnXY)
            {
                currentControlState = motionControlStates.onsurface;
                Falling             = false;
                // Walking / crouchwalking / running
                if (heldDown)
                {
                    return("CROUCHWALK");
                }
                // We need to prevent these animations if the user tries to make their avatar walk or run whilst
                // specifying AGENT_CONTROL_STOP (pressing down space on viewers).
                else if (!m_scenePresence.AgentControlStopActive)
                {
                    if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }
                    else
                    {
                        return("WALK");
                    }
                }
            }
            else
            {
                currentControlState = motionControlStates.onsurface;
                Falling             = false;
                // Not walking
                if (heldDown)
                {
                    return("CROUCH");
                }
                else if (heldTurnLeft)
                {
                    return("TURNLEFT");
                }
                else if (heldTurnRight)
                {
                    return("TURNRIGHT");
                }
                else
                {
                    return("STAND");
                }
            }
            #endregion Ground Movement

            return(CurrentMovementAnimation);
        }
Beispiel #15
0
        private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
        {
            ScenePresence presence = m_scene.GetScenePresence(client.AgentId);

            if (presence != null)
            {
                // If this is an update for our own avatar give it the highest priority
                if (presence == entity)
                {
                    return(0.0);
                }

                // Use group position for child prims
                Vector3 entityPos = entity.AbsolutePosition;
                if (entity is SceneObjectPart)
                {
                    entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
                }
                else
                {
                    entityPos = entity.AbsolutePosition;
                }

                if (!presence.IsChildAgent)
                {
                    if (entity is ScenePresence)
                    {
                        return(1.0);
                    }

                    // Root agent. Use distance from camera and a priority decrease for objects behind us
                    Vector3 camPosition = presence.CameraPosition;
                    Vector3 camAtAxis   = presence.CameraAtAxis;

                    // Distance
                    double priority = Vector3.DistanceSquared(camPosition, entityPos);

                    // Plane equation
                    float d = -Vector3.Dot(camPosition, camAtAxis);
                    float p = Vector3.Dot(camAtAxis, entityPos) + d;
                    if (p < 0.0f)
                    {
                        priority *= 2.0;
                    }

                    if (entity is SceneObjectPart)
                    {
                        PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
                        if (physActor == null || !physActor.IsPhysical)
                        {
                            priority += 100;
                        }

                        if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
                        {
                            priority = 1.0;
                        }
                    }
                    return(priority);
                }
                else
                {
                    // Child agent. Use the normal distance method
                    Vector3 presencePos = presence.AbsolutePosition;

                    return(Vector3.DistanceSquared(presencePos, entityPos));
                }
            }

            return(double.NaN);
        }
Beispiel #16
0
        private double GetPriorityByBestAvatarResponsiveness(IScenePresence presence, IEntity entity)
        {
            // If this is an update for our own avatar give it the highest priority
            if (presence.UUID == entity.UUID)
            {
                return(0.0);
            }
            if (entity == null)
            {
                return(double.NaN);
            }
            if (entity is IScenePresence)
            {
                return(1.0);
            }

            // Use group position for child prims
            Vector3 entityPos = entity.AbsolutePosition;

            if (!presence.IsChildAgent)
            {
                // Root agent. Use distance from camera and a priority decrease for objects behind us
                Vector3 camPosition = presence.CameraPosition;
                Vector3 camAtAxis   = presence.CameraAtAxis;

                // Distance
                double priority = Vector3.DistanceSquared(camPosition, entityPos);

                // Plane equation
                float d = -Vector3.Dot(camPosition, camAtAxis);
                float p = Vector3.Dot(camAtAxis, entityPos) + d;
                if (p < 0.0f)
                {
                    priority *= 2.0;
                }

                //Add distance again to really emphasize it
                priority += Vector3.DistanceSquared(presence.AbsolutePosition, entityPos);

                if ((Vector3.Distance(presence.AbsolutePosition, entityPos) / 2) > presence.DrawDistance)
                {
                    //Outside of draw distance!
                    priority *= 2;
                }

                SceneObjectPart rootPart = null;
                if (entity is SceneObjectPart)
                {
                    if (((SceneObjectPart)entity).ParentGroup != null &&
                        ((SceneObjectPart)entity).ParentGroup.RootPart != null)
                    {
                        rootPart = ((SceneObjectPart)entity).ParentGroup.RootPart;
                    }
                }
                if (entity is SceneObjectGroup)
                {
                    if (((SceneObjectGroup)entity).RootPart != null)
                    {
                        rootPart = ((SceneObjectGroup)entity).RootPart;
                    }
                }

                if (rootPart != null)
                {
                    PhysicsActor physActor = rootPart.PhysActor;

                    // Objects avatars are sitting on should be prioritized more
                    if (presence.ParentID == rootPart.UUID)
                    {
                        //Objects that are physical get more priority.
                        if (physActor != null && physActor.IsPhysical)
                        {
                            return(0.0);
                        }
                        else
                        {
                            return(1.2);
                        }
                    }

                    if (physActor == null || physActor.IsPhysical)
                    {
                        priority /= 2; //Emphasize physical objs
                    }
                    //Factor in the size of objects as well, big ones are MUCH more important than small ones
                    float size = rootPart.ParentGroup.GroupScale().Length();
                    //Cap size at 200 so that it doesn't completely overwhelm other objects
                    if (size > 200)
                    {
                        size = 200;
                    }

                    //Do it dynamically as well so that larger prims get smaller quicker
                    priority /= size > 40 ? (size / 35) : (size > 20 ? (size / 17) : 1);

                    if (rootPart.IsAttachment)
                    {
                        //Attachments are always high!
                        priority = 0.5;
                    }
                }
                //Closest first!
                return(priority);
            }
            else
            {
                // Child agent. Use the normal distance method
                Vector3 presencePos = presence.AbsolutePosition;

                return(Vector3.DistanceSquared(presencePos, entityPos));
            }
        }
Beispiel #17
0
 public override void delink()
 {
     m_taintparent = null;
 }
Beispiel #18
0
        public override void SetTerrain(bool[] heightMap)
        {
            if (m_terrainShape != null)
            {
                DeleteTerrain();
            }

            m_terrainShape = AddPrim(
                "__TERRAIN__",
                new Vector3(Constants.RegionSize / 2, Constants.RegionSize / 2, Constants.RegionSize / 2),
                new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize),
                Quaternion.Identity,
                voxmesher.ToMesh(heightMap),
                PrimitiveBaseShape.Default,
                false);
            //float AabbCenterX = Constants.RegionSize/2f;
            //float AabbCenterY = Constants.RegionSize/2f;

            //float AabbCenterZ = 0f;

            /*
             * float temphfmin, temphfmax;
             *
             * temphfmin = hfmin;
             * temphfmax = hfmax;
             *
             * if (temphfmin < 0)
             * {
             *  temphfmax = 0 - temphfmin;
             *  temphfmin = 0 - temphfmin;
             * }
             * else if (temphfmin > 0)
             * {
             *  temphfmax = temphfmax + (0 - temphfmin);
             *  //temphfmin = temphfmin + (0 - temphfmin);
             * }
             * AabbCenterZ = temphfmax/2f;
             *
             * if (m_terrainPosition == null)
             * {
             *  m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);
             * }
             * else
             * {
             *  try
             *  {
             *      m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ);
             *  }
             *  catch (ObjectDisposedException)
             *  {
             *      m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ);
             *  }
             * }
             */
            if (m_terrainMotionState != null)
            {
                m_terrainMotionState.Dispose();
                m_terrainMotionState = null;
            }
            m_terrainTransform   = new btTransform(QuatIdentity, m_terrainPosition);
            m_terrainMotionState = new btDefaultMotionState(m_terrainTransform);
        }
Beispiel #19
0
 public override void RemovePrim(PhysicsActor prim)
 {
     if (prim is BulletXPrim)
     {
         lock (BulletXLock)
         {
             try
             {
                 ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody);
             }
             catch (Exception ex)
             {
                 BulletXMessage(is_ex_message + ex.Message, true);
                 ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
                 AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
             }
             _prims.Remove(((BulletXPrim) prim).RigidBody);
         }
         GC.Collect();
     }
 }
Beispiel #20
0
 internal void remCollisionEventReporting(PhysicsActor bulletDotNETCharacter)
 {
     //TODO: FIXME:
 }
Beispiel #21
0
 private void RemoveFromPhysicalScene(PhysicsActor physActor)
 {
     if (IsRootPart())
     {
         m_parentGroup.Scene.PhysicsScene.RemovePrim(physActor);
         m_parentGroup.ForEachPart((SceneObjectPart part) =>
         {
             part.PhysActor = null;
         }
         );
     }
 }
 public override void DeletePrim(PhysicsActor prim)
 {
 }
 public override void RemoveAvatar(PhysicsActor actor)
 {
 }
        public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
        {
            int ret = -1;

            if (!Enabled)
            {
                return(ret);
            }

            // The part that is requesting the change.
            SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);

            if (requestingPart != null)
            {
                // The change is always made to the root of a linkset.
                SceneObjectGroup containingGroup = requestingPart.ParentGroup;
                SceneObjectPart  rootPart        = containingGroup.RootPart;

                if (rootPart != null)
                {
                    PhysicsActor rootPhysActor = rootPart.PhysActor;
                    if (rootPhysActor != null)
                    {
                        if (rootPhysActor.IsPhysical)
                        {
                            // Change a physical linkset by making non-physical, waiting for one heartbeat so all
                            //    the prim and linkset state is updated, changing the type and making the
                            //    linkset physical again.
                            containingGroup.ScriptSetPhysicsStatus(false);
                            Thread.Sleep(150); // longer than one heartbeat tick

                            // A kludge for the moment.
                            // Since compound linksets move the children but don't generate position updates to the
                            //     simulator, it is possible for compound linkset children to have out-of-sync simulator
                            //     and physical positions. The following causes the simulator to push the real child positions
                            //     down into the physics engine to get everything synced.
                            containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition);
                            containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation);

                            object[] parms2 = { rootPhysActor, null, linksetType };
                            ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2));
                            Thread.Sleep(150); // longer than one heartbeat tick

                            containingGroup.ScriptSetPhysicsStatus(true);
                        }
                        else
                        {
                            // Non-physical linksets don't have a physical instantiation so there is no state to
                            //    worry about being updated.
                            object[] parms2 = { rootPhysActor, null, linksetType };
                            ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2));
                        }
                    }
                    else
                    {
                        m_log.WarnFormat("{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
                                         LogHeader, rootPart.Name, hostID);
                    }
                }
                else
                {
                    m_log.WarnFormat("{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
                                     LogHeader, requestingPart.Name, hostID);
                }
            }
            else
            {
                m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
            }
            return(ret);
        }
Beispiel #25
0
 public virtual void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor)
 { return; }
        private bool GetRootPhysActor(UUID hostID, out SceneObjectGroup containingGroup, out SceneObjectPart rootPart, out PhysicsActor rootPhysActor)
        {
            bool ret = false;

            rootPhysActor   = null;
            containingGroup = null;
            rootPart        = null;

            SceneObjectPart requestingPart;

            requestingPart = BaseScene.GetSceneObjectPart(hostID);
            if (requestingPart != null)
            {
                // The type is is always on the root of a linkset.
                containingGroup = requestingPart.ParentGroup;
                if (containingGroup != null && !containingGroup.IsDeleted)
                {
                    rootPart = containingGroup.RootPart;
                    if (rootPart != null)
                    {
                        rootPhysActor = rootPart.PhysActor;
                        if (rootPhysActor != null)
                        {
                            ret = true;
                        }
                        else
                        {
                            m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
                                             LogHeader, rootPart.Name, hostID);
                        }
                    }
                    else
                    {
                        m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not exist. RequestingPartName={1}, hostID={2}",
                                         LogHeader, requestingPart.Name, hostID);
                    }
                }
                else
                {
                    m_log.WarnFormat("{0} GetRootAndChildPhysActors: Containing group missing or deleted. hostID={1}", LogHeader, hostID);
                }
            }
            else
            {
                m_log.WarnFormat("{0} GetRootAndChildPhysActors: cannot find script object in scene. hostID={1}", LogHeader, hostID);
            }

            return(ret);
        }
Beispiel #27
0
    public override void RemovePrim(PhysicsActor prim)
    {
        if (!m_initialized) return;

        BSPhysObject bsprim = prim as BSPhysObject;
        if (bsprim != null)
        {
            DetailLog("{0},RemovePrim,call", bsprim.LocalID);
            // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
            try
            {
                lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
            }
            catch (Exception e)
            {
                m_log.ErrorFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e);
            }
            bsprim.Destroy();
            // bsprim.dispose();
        }
        else
        {
            m_log.ErrorFormat("{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader);
        }
    }
        // Find the root and child PhysActors based on the linkNum.
        // Return 'true' if both are found and returned.
        private bool GetRootAndChildPhysActors(UUID hostID, int linkNum, out PhysicsActor rootPhysActor, out PhysicsActor childPhysActor)
        {
            bool ret = false;

            rootPhysActor  = null;
            childPhysActor = null;

            SceneObjectGroup containingGroup;
            SceneObjectPart  rootPart;

            if (GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor))
            {
                SceneObjectPart linkPart = containingGroup.GetLinkNumPart(linkNum);
                if (linkPart != null)
                {
                    childPhysActor = linkPart.PhysActor;
                    if (childPhysActor != null)
                    {
                        ret = true;
                    }
                    else
                    {
                        m_log.WarnFormat("{0} GetRootAndChildPhysActors: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}",
                                         LogHeader, rootPart.Name, hostID, linkNum);
                    }
                }
                else
                {
                    m_log.WarnFormat("{0} GetRootAndChildPhysActors: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}",
                                     LogHeader, rootPart.Name, hostID, linkNum);
                }
            }
            else
            {
                m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
                                 LogHeader, rootPart.Name, hostID);
            }

            return(ret);
        }
Beispiel #29
0
 public override void AddPhysicsActorTaint(PhysicsActor prim)
 {
     //throw new NotSupportedException("AddPhysicsActorTaint must be called with a taint type");
 }
Beispiel #30
0
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        private string DetermineMovementAnimation()
        {
            const float FALL_DELAY    = 800f;
            const float PREJUMP_DELAY = 200f;
            const float JUMP_PERIOD   = 800f;

            #region Inputs

            AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
            PhysicsActor actor = m_scenePresence.PhysicsActor;

            // Create forward and left vectors from the current avatar rotation
            Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
            Vector3 fwd       = Vector3.Transform(Vector3.UnitX, rotMatrix);
            Vector3 left      = Vector3.Transform(Vector3.UnitY, rotMatrix);

            // Check control flags
            bool heldForward   = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS);
            bool heldBack      = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
            bool heldLeft      = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
            bool heldRight     = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG);
            bool heldTurnLeft  = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
            bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
            bool heldUp        = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
            bool heldDown      = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
            //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
            //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
            if (heldForward || heldBack || heldLeft || heldRight || heldUp || heldDown)
            {
                heldTurnLeft  = false;
                heldTurnRight = false;
            }

            // Direction in which the avatar is trying to move
            Vector3 move = Vector3.Zero;
            if (heldForward)
            {
                move.X += fwd.X; move.Y += fwd.Y;
            }
            if (heldBack)
            {
                move.X -= fwd.X; move.Y -= fwd.Y;
            }
            if (heldLeft)
            {
                move.X += left.X; move.Y += left.Y;
            }
            if (heldRight)
            {
                move.X -= left.X; move.Y -= left.Y;
            }
            if (heldUp)
            {
                move.Z += 1;
            }
            if (heldDown)
            {
                move.Z -= 1;
            }

            // Is the avatar trying to move?
//            bool moving = (move != Vector3.Zero);
            #endregion Inputs

            #region Flying

            if (actor != null && actor.Flying)
            {
                m_animTickFall = 0;
                m_animTickJump = 0;
                m_jumping      = false;
                Falling        = false;
                m_jumpVelocity = 0f;
                actor.Selected = false;
                m_fallHeight   = actor.Position.Z;  // save latest flying height

                if (move.X != 0f || move.Y != 0f)
                {
                    return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
                }
                else if (move.Z > 0f)
                {
                    return("HOVER_UP");
                }
                else if (move.Z < 0f)
                {
                    if (actor != null && actor.IsColliding)
                    {
                        return("LAND");
                    }
                    else
                    {
                        return("HOVER_DOWN");
                    }
                }
                else
                {
                    return("HOVER");
                }
            }

            #endregion Flying

            #region Falling/Floating/Landing

            if ((actor == null || !actor.IsColliding) && !m_jumping)
            {
                float fallElapsed  = (float)(Environment.TickCount - m_animTickFall);
                float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

                if (!m_jumping && (fallVelocity < -3.0f))
                {
                    Falling = true;
                }

                if (m_animTickFall == 0 || (fallVelocity >= 0.0f))
                {
                    // not falling yet, or going up
                    // reset start of fall time
                    m_animTickFall = Environment.TickCount;
                }
                else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying))
                {
                    // Falling long enough to trigger the animation
                    return("FALLDOWN");
                }

                // Check if the user has stopped walking just now
                if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero))
                {
                    return("STAND");
                }

                return(CurrentMovementAnimation);
            }

            #endregion Falling/Floating/Landing


            #region Jumping     // section added for jumping...

            int jumptime;
            jumptime = Environment.TickCount - m_animTickJump;

            if ((move.Z > 0f) && (!m_jumping))
            {
                // Start jumping, prejump
                m_animTickFall = 0;
                m_jumping      = true;
                Falling        = false;
                actor.Selected = true;      // borrowed for jumping flag
                m_animTickJump = Environment.TickCount;
                m_jumpVelocity = 0.35f;
                return("PREJUMP");
            }

            if (m_jumping)
            {
                if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
                {
                    // end jumping
                    m_jumping      = false;
                    Falling        = false;
                    actor.Selected = false;      // borrowed for jumping flag
                    m_jumpVelocity = 0f;
                    m_animTickFall = Environment.TickCount;
                    return("LAND");
                }
                else if (jumptime > JUMP_PERIOD)
                {
                    // jump down
                    m_jumpVelocity = 0f;
                    return("JUMP");
                }
                else if (jumptime > PREJUMP_DELAY)
                {
                    // jump up
                    m_jumping      = true;
                    m_jumpVelocity = 10f;
                    return("JUMP");
                }
            }

            #endregion Jumping

            #region Ground Movement

            if (CurrentMovementAnimation == "FALLDOWN")
            {
                Falling        = false;
                m_animTickFall = Environment.TickCount;
                // TODO: SOFT_LAND support
                float fallHeight = m_fallHeight - actor.Position.Z;
                if (fallHeight > 15.0f)
                {
                    return("STANDUP");
                }
                else if (fallHeight > 8.0f)
                {
                    return("SOFT_LAND");
                }
                else
                {
                    return("LAND");
                }
            }
            else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP"))
            {
                int landElapsed = Environment.TickCount - m_animTickFall;
                int limit       = 1000;
                if (CurrentMovementAnimation == "LAND")
                {
                    limit = 350;
                }
                // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client

                if ((m_animTickFall != 0) && (landElapsed <= limit))
                {
                    return(CurrentMovementAnimation);
                }
                else
                {
                    m_fallHeight = actor.Position.Z;    // save latest flying height
                    return("STAND");
                }
            }

            // next section moved outside paren. and realigned for jumping
            if (move.X != 0f || move.Y != 0f)
            {
                m_fallHeight = actor.Position.Z;    // save latest flying height
                Falling      = false;
                // Walking / crouchwalking / running
                if (move.Z < 0f)
                {
                    return("CROUCHWALK");
                }
                // We need to prevent these animations if the user tries to make their avatar walk or run whilst
                // specifying AGENT_CONTROL_STOP (pressing down space on viewers).
                else if (!m_scenePresence.AgentControlStopActive)
                {
                    if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }
                    else
                    {
                        return("WALK");
                    }
                }
            }
            else if (!m_jumping)
            {
                Falling = false;
                // Not walking
                if (move.Z < 0)
                {
                    return("CROUCH");
                }
                else if (heldTurnLeft)
                {
                    return("TURNLEFT");
                }
                else if (heldTurnRight)
                {
                    return("TURNRIGHT");
                }
                else
                {
                    return("STAND");
                }
            }
            #endregion Ground Movement

            Falling = false;

            return(CurrentMovementAnimation);
        }
Beispiel #31
0
 public override void AddPhysicsActorTaint(PhysicsActor prim)
 {
 }
Beispiel #32
0
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        public string GetMovementAnimation()
        {
            const float FALL_DELAY    = 0.33f;
            const float PREJUMP_DELAY = 0.25f;

            #region Inputs
            if (m_scenePresence.SitGround)
            {
                return("SIT_GROUND_CONSTRAINED");
            }
            AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
            PhysicsActor actor = m_scenePresence.PhysicsActor;

            // Create forward and left vectors from the current avatar rotation
            Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
            Vector3 fwd       = Vector3.Transform(Vector3.UnitX, rotMatrix);
            Vector3 left      = Vector3.Transform(Vector3.UnitY, rotMatrix);

            // Check control flags
            bool heldForward =
                (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS));
            bool heldBack  = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
            bool heldLeft  = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
            bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
            //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
            //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
            bool heldUp   = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
            bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
            //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
            //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;

            // Direction in which the avatar is trying to move
            Vector3 move = Vector3.Zero;
            if (heldForward)
            {
                move.X += fwd.X; move.Y += fwd.Y;
            }
            if (heldBack)
            {
                move.X -= fwd.X; move.Y -= fwd.Y;
            }
            if (heldLeft)
            {
                move.X += left.X; move.Y += left.Y;
            }
            if (heldRight)
            {
                move.X -= left.X; move.Y -= left.Y;
            }
            if (heldUp)
            {
                move.Z += 1;
            }
            if (heldDown)
            {
                move.Z -= 1;
            }

            // Is the avatar trying to move?
//            bool moving = (move != Vector3.Zero);
            bool jumping = m_animTickJump != 0;

            #endregion Inputs

            #region Flying

            if (actor != null && actor.Flying)
            {
                m_animTickFall = 0;
                m_animTickJump = 0;

                if (move.X != 0f || move.Y != 0f)
                {
                    return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
                }
                else if (move.Z > 0f)
                {
                    return("HOVER_UP");
                }
                else if (move.Z < 0f)
                {
                    if (actor != null && actor.IsColliding)
                    {
                        return("LAND");
                    }
                    else
                    {
                        return("HOVER_DOWN");
                    }
                }
                else
                {
                    return("HOVER");
                }
            }

            #endregion Flying

            #region Falling/Floating/Landing

            if (actor == null || !actor.IsColliding)
            {
                float fallElapsed  = (float)(Environment.TickCount - m_animTickFall) / 1000f;
                float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

                if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
                {
                    // Just started falling
                    m_animTickFall = Environment.TickCount;
                }
                else if (!jumping && fallElapsed > FALL_DELAY)
                {
                    // Falling long enough to trigger the animation
                    return("FALLDOWN");
                }
                else if (m_animTickJump == -1)
                {
                    m_animTickJump = 0;
                    return("STAND");
                }

                return(m_movementAnimation);
            }

            #endregion Falling/Floating/Landing

            #region Ground Movement

            if (m_movementAnimation == "FALLDOWN")
            {
                m_animTickFall = Environment.TickCount;

                // TODO: SOFT_LAND support
                return("LAND");
            }
            else if (m_movementAnimation == "LAND")
            {
                float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
                if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY))
                {
                    return("LAND");
                }
            }

            m_animTickFall = 0;

            if (move.Z > 0f)
            {
                // Jumping
                if (!jumping)
                {
                    // Begin prejump
                    m_animTickJump = Environment.TickCount;
                    return("PREJUMP");
                }
                else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
                {
                    // Start actual jump
                    if (m_animTickJump == -1)
                    {
                        // Already jumping! End the current jump
                        m_animTickJump = 0;
                        return("JUMP");
                    }

                    m_animTickJump = -1;
                    return("JUMP");
                }
                else
                {
                    return("JUMP");
                }
            }
            else
            {
                // Not jumping
                m_animTickJump = 0;

                if (move.X != 0f || move.Y != 0f)
                {
                    // Walking / crouchwalking / running
                    if (move.Z < 0f)
                    {
                        return("CROUCHWALK");
                    }
                    else if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }
                    else
                    {
                        return("WALK");
                    }
                }
                else
                {
                    // Not walking
                    if (move.Z < 0f)
                    {
                        return("CROUCH");
                    }
                    else
                    {
                        return("STAND");
                    }
                }
            }

            #endregion Ground Movement

            //return m_movementAnimation;
        }
Beispiel #33
0
 public override void link(PhysicsActor obj)
 {
     m_taintparent = obj;
 }
Beispiel #34
0
        public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
        {
            if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero)
            {
                PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
                return;
            }

            IntPtr geom = ((OdePrim)actor).prim_geom;

            Vector3    geopos  = d.GeomGetPositionOMV(geom);
            Quaternion geomOri = d.GeomGetQuaternionOMV(geom);

//            Vector3 geopos = actor.Position;
//            Quaternion geomOri = actor.Orientation;

            Quaternion geomInvOri = Quaternion.Conjugate(geomOri);

            Quaternion ori = Quaternion.Identity;

            Vector3 rayDir = geopos + offset - avCameraPosition;

            float raylen = rayDir.Length();

            if (raylen < 0.001f)
            {
                PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
                return;
            }
            float t = 1 / raylen;

            rayDir.X *= t;
            rayDir.Y *= t;
            rayDir.Z *= t;

            raylen += 30f; // focal point may be far
            List <ContactResult> rayResults;

            rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags);
            if (rayResults.Count == 0)
            {
/* if this fundamental ray failed, then just fail so user can try another spot and not be sitted far on a big prim
 *              d.AABB aabb;
 *              d.GeomGetAABB(geom, out aabb);
 *              offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
 *              ori = geomInvOri;
 *              offset *= geomInvOri;
 *              PhysicsSitResponse(1, actor.LocalID, offset, ori);
 */
                PhysicsSitResponse(0, actor.LocalID, offset, ori);
                return;
            }

            int status = 1;

            offset = rayResults[0].Pos - geopos;

            d.GeomClassID geoclass = d.GeomGetClass(geom);

            if (geoclass == d.GeomClassID.SphereClass)
            {
                float r = d.GeomSphereGetRadius(geom);

                offset.Normalize();
                offset *= r;

                RotAroundZ(offset.X, offset.Y, ref ori);

                if (r < 0.4f)
                {
                    offset = new Vector3(0, 0, r);
                }
                else
                {
                    if (offset.Z < 0.4f)
                    {
                        t = offset.Z;
                        float rsq = r * r;

                        t         = 1.0f / (rsq - t * t);
                        offset.X *= t;
                        offset.Y *= t;
                        offset.Z  = 0.4f;
                        t         = rsq - 0.16f;
                        offset.X *= t;
                        offset.Y *= t;
                    }
                    else if (r > 0.8f && offset.Z > 0.8f * r)
                    {
                        status      = 3;
                        avOffset.X  = -avOffset.X;
                        avOffset.Z *= 1.6f;
                    }
                }

                offset += avOffset * ori;

                ori     = geomInvOri * ori;
                offset *= geomInvOri;

                PhysicsSitResponse(status, actor.LocalID, offset, ori);
                return;
            }

            Vector3 norm = rayResults[0].Normal;

            if (norm.Z < -0.4f)
            {
                PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
                return;
            }


            float SitNormX = -rayDir.X;
            float SitNormY = -rayDir.Y;

            Vector3 pivot = geopos + offset;

            float   edgeNormalX = norm.X;
            float   edgeNormalY = norm.Y;
            float   edgeDirX    = -rayDir.X;
            float   edgeDirY    = -rayDir.Y;
            Vector3 edgePos     = rayResults[0].Pos;
            float   edgeDist    = float.MaxValue;

            bool foundEdge = false;

            if (norm.Z < 0.5f)
            {
                float rayDist = 4.0f;

                for (int i = 0; i < 6; i++)
                {
                    pivot.X -= 0.01f * norm.X;
                    pivot.Y -= 0.01f * norm.Y;
                    pivot.Z -= 0.01f * norm.Z;

                    rayDir.X = -norm.X * norm.Z;
                    rayDir.Y = -norm.Y * norm.Z;
                    rayDir.Z = 1.0f - norm.Z * norm.Z;
                    rayDir.Normalize();

                    rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
                    if (rayResults.Count == 0)
                    {
                        break;
                    }

                    if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
                    {
                        rayDist -= rayResults[0].Depth;
                        if (rayDist < 0f)
                        {
                            break;
                        }

                        pivot       = rayResults[0].Pos;
                        norm        = rayResults[0].Normal;
                        edgeNormalX = norm.X;
                        edgeNormalY = norm.Y;
                        edgeDirX    = -rayDir.X;
                        edgeDirY    = -rayDir.Y;
                    }
                    else
                    {
                        foundEdge = true;
                        edgePos   = rayResults[0].Pos;
                        break;
                    }
                }

                if (!foundEdge)
                {
                    PhysicsSitResponse(0, actor.LocalID, offset, ori);
                    return;
                }
                avOffset.X *= 0.5f;
            }

            else if (norm.Z > 0.866f)
            {
                float toCamBaseX = avCameraPosition.X - pivot.X;
                float toCamBaseY = avCameraPosition.Y - pivot.Y;
                float toCamX     = toCamBaseX;
                float toCamY     = toCamBaseY;

                for (int j = 0; j < 4; j++)
                {
                    float rayDist     = 1.0f;
                    float curEdgeDist = 0.0f;

                    for (int i = 0; i < 3; i++)
                    {
                        pivot.Z -= 0.01f;
                        rayDir.X = toCamX;
                        rayDir.Y = toCamY;
                        rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
                        rayDir.Normalize();

                        rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
                        if (rayResults.Count == 0)
                        {
                            break;
                        }

                        curEdgeDist += rayResults[0].Depth;

                        if (rayResults[0].Normal.Z > 0.5f)
                        {
                            rayDist -= rayResults[0].Depth;
                            if (rayDist < 0f)
                            {
                                break;
                            }

                            pivot = rayResults[0].Pos;
                            norm  = rayResults[0].Normal;
                        }
                        else
                        {
                            foundEdge = true;
                            if (curEdgeDist < edgeDist)
                            {
                                edgeDist    = curEdgeDist;
                                edgeNormalX = rayResults[0].Normal.X;
                                edgeNormalY = rayResults[0].Normal.Y;
                                edgeDirX    = rayDir.X;
                                edgeDirY    = rayDir.Y;
                                edgePos     = rayResults[0].Pos;
                            }
                            break;
                        }
                    }
                    if (foundEdge && edgeDist < 0.2f)
                    {
                        break;
                    }

                    pivot = geopos + offset;

                    switch (j)
                    {
                    case 0:
                        toCamX = -toCamBaseY;
                        toCamY = toCamBaseX;
                        break;

                    case 1:
                        toCamX = toCamBaseY;
                        toCamY = -toCamBaseX;
                        break;

                    case 2:
                        toCamX = -toCamBaseX;
                        toCamY = -toCamBaseY;
                        break;

                    default:
                        break;
                    }
                }

                if (!foundEdge)
                {
                    avOffset.X  = -avOffset.X;
                    avOffset.Z *= 1.6f;

                    RotAroundZ(SitNormX, SitNormY, ref ori);

                    offset += avOffset * ori;

                    ori     = geomInvOri * ori;
                    offset *= geomInvOri;

                    PhysicsSitResponse(3, actor.LocalID, offset, ori);
                    return;
                }
                avOffset.X *= 0.5f;
            }

            SitNormX = edgeNormalX;
            SitNormY = edgeNormalY;
            if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0)
            {
                SitNormX = -SitNormX;
                SitNormY = -SitNormY;
            }

            RotAroundZ(SitNormX, SitNormY, ref ori);

            offset  = edgePos + avOffset * ori;
            offset -= geopos;

            ori     = geomInvOri * ori;
            offset *= geomInvOri;

            PhysicsSitResponse(1, actor.LocalID, offset, ori);
            return;
        }
Beispiel #35
0
        private void changelink(float timestep)
        {
            // If the newly set parent is not null
            // create link
            if (_parent == null && m_taintparent != null)
            {
                if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim)
                {
                    OdePrim obj = (OdePrim)m_taintparent;
                    //obj.disableBody();
//Console.WriteLine("changelink calls ParentPrim");
                    obj.AddChildPrim(this);

                    /*
                    if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body)
                    {
                        _linkJointGroup = d.JointGroupCreate(0);
                        m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup);
                        d.JointAttach(m_linkJoint, obj.Body, Body);
                        d.JointSetFixed(m_linkJoint);
                    }
                     */
                }
            }
            // If the newly set parent is null
            // destroy link
            else if (_parent != null && m_taintparent == null)
            {
//Console.WriteLine("  changelink B");
            
                if (_parent is OdePrim)
                {
                    OdePrim obj = (OdePrim)_parent;
                    obj.ChildDelink(this);
                    childPrim = false;
                    //_parent = null;
                }
                
                /*
                    if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0)
                    d.JointGroupDestroy(_linkJointGroup);
                        
                    _linkJointGroup = (IntPtr)0;
                    m_linkJoint = (IntPtr)0;
                */
            }
 
            _parent = m_taintparent;
            m_taintPhysics = IsPhysical;
        }
Beispiel #36
0
        // This is the standard Near. g1 is the ray
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            if (g2 == IntPtr.Zero || g1 == g2)
            {
                return;
            }

            if (m_contactResults.Count >= CurrentMaxCount)
            {
                return;
            }

            if (SafeNativeMethods.GeomIsSpace(g2))
            {
                try
                {
                    SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (Exception e)
                {
                    m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
                }
                return;
            }

            int count = 0;

            try
            {
                count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf);
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            if (count == 0)
            {
                return;
            }

            /*
             *          uint cat1 = d.GeomGetCategoryBits(g1);
             *          uint cat2 = d.GeomGetCategoryBits(g2);
             *          uint col1 = d.GeomGetCollideBits(g1);
             *          uint col2 = d.GeomGetCollideBits(g2);
             */

            uint         ID = 0;
            PhysicsActor p2 = null;

            m_scene.actor_name_map.TryGetValue(g2, out p2);

            if (p2 == null)
            {
                return;
            }

            switch (p2.PhysicsActorType)
            {
            case (int)ActorTypes.Prim:

                RayFilterFlags thisFlags;

                if (p2.IsPhysical)
                {
                    thisFlags = RayFilterFlags.physical;
                }
                else
                {
                    thisFlags = RayFilterFlags.nonphysical;
                }

                if (p2.Phantom)
                {
                    thisFlags |= RayFilterFlags.phantom;
                }

                if (p2.IsVolumeDtc)
                {
                    thisFlags |= RayFilterFlags.volumedtc;
                }

                if ((thisFlags & CurrentRayFilter) == 0)
                {
                    return;
                }

                ID = ((OdePrim)p2).LocalID;
                break;

            case (int)ActorTypes.Agent:

                if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
                {
                    return;
                }
                else
                {
                    ID = ((OdeCharacter)p2).LocalID;
                }
                break;

            case (int)ActorTypes.Ground:

                if ((CurrentRayFilter & RayFilterFlags.land) == 0)
                {
                    return;
                }
                break;

            case (int)ActorTypes.Water:

                if ((CurrentRayFilter & RayFilterFlags.water) == 0)
                {
                    return;
                }
                break;

            default:
                break;
            }

            SafeNativeMethods.ContactGeom curcontact = new SafeNativeMethods.ContactGeom();

            // closestHit for now only works for meshs, so must do it for others
            if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
            {
                // Loop all contacts, build results.
                for (int i = 0; i < count; i++)
                {
                    if (!GetCurContactGeom(i, ref curcontact))
                    {
                        break;
                    }

                    ContactResult collisionresult = new ContactResult();
                    collisionresult.ConsumerID = ID;
                    collisionresult.Pos.X      = curcontact.pos.X;
                    collisionresult.Pos.Y      = curcontact.pos.Y;
                    collisionresult.Pos.Z      = curcontact.pos.Z;
                    collisionresult.Depth      = curcontact.depth;
                    collisionresult.Normal.X   = curcontact.normal.X;
                    collisionresult.Normal.Y   = curcontact.normal.Y;
                    collisionresult.Normal.Z   = curcontact.normal.Z;
                    lock (m_contactResults)
                    {
                        m_contactResults.Add(collisionresult);
                        if (m_contactResults.Count >= CurrentMaxCount)
                        {
                            return;
                        }
                    }
                }
            }
            else
            {
                // keep only closest contact
                ContactResult collisionresult = new ContactResult();
                collisionresult.ConsumerID = ID;
                collisionresult.Depth      = float.MaxValue;

                for (int i = 0; i < count; i++)
                {
                    if (!GetCurContactGeom(i, ref curcontact))
                    {
                        break;
                    }

                    if (curcontact.depth < collisionresult.Depth)
                    {
                        collisionresult.Pos.X    = curcontact.pos.X;
                        collisionresult.Pos.Y    = curcontact.pos.Y;
                        collisionresult.Pos.Z    = curcontact.pos.Z;
                        collisionresult.Depth    = curcontact.depth;
                        collisionresult.Normal.X = curcontact.normal.X;
                        collisionresult.Normal.Y = curcontact.normal.Y;
                        collisionresult.Normal.Z = curcontact.normal.Z;
                    }
                }

                if (collisionresult.Depth != float.MaxValue)
                {
                    lock (m_contactResults)
                        m_contactResults.Add(collisionresult);
                }
            }
        }
Beispiel #37
0
 public override void RemoveAvatar(PhysicsActor actor)
 {
     if (actor is BulletXCharacter)
     {
         lock (BulletXLock)
         {
             try
             {
                 ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody);
             }
             catch (Exception ex)
             {
                 BulletXMessage(is_ex_message + ex.Message, true);
                 ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
                 AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
             }
             _characters.Remove(((BulletXCharacter) actor).RigidBody);
         }
         GC.Collect();
     }
 }
Beispiel #38
0
        /// <summary>
        ///     This method determines the proper movement related animation
        /// </summary>
        public string GetMovementAnimation()
        {
            const float STANDUP_TIME         = 2f;
            const float BRUSH_TIME           = 3.5f;
            const float FALL_AFTER_MOVE_TIME = 0.75f;
            const float SOFTLAND_FORCE       = 80;

            #region Inputs

            if (m_scenePresence.SitGround)
            {
                return("SIT_GROUND_CONSTRAINED");
            }
            AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
            PhysicsActor actor = m_scenePresence.PhysicsActor;

            // Create forward and left vectors from the current avatar rotation
            Vector3 fwd  = Vector3.UnitX * m_scenePresence.Rotation;
            Vector3 left = Vector3.UnitY * m_scenePresence.Rotation;

            // Check control flags
            bool heldForward =
                (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) ==
                  AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) ||
                 ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) ==
                  AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS));
            bool yawPos = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) ==
                          AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS;
            bool yawNeg = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) ==
                          AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG;
            bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) ==
                            AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
            bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) ==
                            AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
            bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) ==
                             AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
            bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) ==
                                AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
            bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) ==
                                 AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
            bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) ==
                          AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
            bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) ==
                            AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
            //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
            //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;

            // Direction in which the avatar is trying to move
            Vector3 move = Vector3.Zero;
            if (heldForward)
            {
                move.X += fwd.X;
                move.Y += fwd.Y;
            }
            if (heldBack)
            {
                move.X -= fwd.X;
                move.Y -= fwd.Y;
            }
            if (heldLeft)
            {
                move.X += left.X;
                move.Y += left.Y;
            }
            if (heldRight)
            {
                move.X -= left.X;
                move.Y -= left.Y;
            }
            if (heldUp)
            {
                move.Z += 1;
            }
            if (heldDown)
            {
                move.Z -= 1;
            }

            float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

            if (heldTurnLeft && yawPos && !heldForward &&
                !heldBack && actor != null && !actor.IsJumping &&
                !actor.Flying && move.Z == 0 &&
                fallVelocity == 0.0f && !heldUp &&
                !heldDown && move.CompareTo(Vector3.Zero) == 0)
            {
                return("TURNLEFT");
            }
            if (heldTurnRight && yawNeg && !heldForward &&
                !heldBack && actor != null && !actor.IsJumping &&
                !actor.Flying && move.Z == 0 &&
                fallVelocity == 0.0f && !heldUp &&
                !heldDown && move.CompareTo(Vector3.Zero) == 0)
            {
                return("TURNRIGHT");
            }

            // Is the avatar trying to move?
            //            bool moving = (move != Vector3.Zero);

            #endregion Inputs

            #region Standup

            float standupElapsed = (Util.EnvironmentTickCount() - m_animTickStandup) / 1000f;
            if (m_scenePresence.PhysicsActor != null && standupElapsed < STANDUP_TIME &&
                m_useSplatAnimation)
            {
                // Falling long enough to trigger the animation
                m_scenePresence.FallenStandUp         = true;
                m_scenePresence.PhysicsActor.Velocity = Vector3.Zero;
                return("STANDUP");
            }

            // need the brush off?
            if (standupElapsed < BRUSH_TIME && m_useSplatAnimation)
            {
                m_scenePresence.FallenStandUp = true;
                return("BRUSH");
            }

            if (m_animTickStandup != 0 || m_scenePresence.FallenStandUp)
            {
                m_scenePresence.FallenStandUp = false;
                m_animTickStandup             = 0;
            }

            #endregion Standup

            #region Flying

            if (actor != null &&
                (m_scenePresence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) ==
                (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY || m_scenePresence.ForceFly)
            {
                m_animTickWalk = 0;
                m_animTickFall = 0;
                if (move.X != 0f || move.Y != 0f)
                {
                    // level?
                    if (move.Z == 0)
                    {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        {
                            return("SWIM_FORWARD");
                        }

                        // must be flying then
                        if (m_timesBeforeSlowFlyIsOff < SLOWFLY_DELAY)
                        {
                            m_timesBeforeSlowFlyIsOff++;
                            return("FLYSLOW");
                        }

                        return("FLY");
                    }

                    // going up then...
                    if (move.Z > 0)
                    {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        {
                            return("SWIM_UP");
                        }

                        // easy does it
                        return("FLYSLOW");
                    }
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                    {
                        return("SWIM_DOWN");
                    }

                    // in the wild blue yonder
                    return("FLY");
                }

                // moving left/right but going up as well?
                if (move.Z > 0f)
                {
                    //This is for the slow fly timer
                    m_timesBeforeSlowFlyIsOff = 0;
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                    {
                        return("SWIM_UP");
                    }

                    // going up...
                    return("HOVER_UP");
                }

                // mabye moving down then?
                if (move.Z < 0f)
                {
                    wasLastFlying = true;
                    //This is for the slow fly timer
                    m_timesBeforeSlowFlyIsOff = 0;
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                    {
                        return("SWIM_DOWN");
                    }
                    else
                    {
                        ITerrainChannel channel = m_scenePresence.Scene.RequestModuleInterface <ITerrainChannel> ();
                        if (channel != null)
                        {
                            float groundHeight =
                                channel.GetNormalizedGroundHeight((int)m_scenePresence.AbsolutePosition.X,
                                                                  (int)m_scenePresence.AbsolutePosition.Y);
                            if (actor != null && (m_scenePresence.AbsolutePosition.Z - groundHeight) < 2)
                            {
                                return("LAND");
                            }

                            return("HOVER_DOWN");
                        }

                        // no ground here...
                        return("HOVER_DOWN");
                    }
                }


                //This is for the slow fly timer
                m_timesBeforeSlowFlyIsOff = 0;
                if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                    actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                {
                    return("SWIM_HOVER");
                }

                return("HOVER");
            }

            m_timesBeforeSlowFlyIsOff = 0;

            #endregion Flying

            #region Jumping

            if (actor != null && actor.IsJumping)
            {
                return("JUMP");
            }

            if (actor != null && actor.IsPreJumping)
            {
                return("PREJUMP");
            }

            #endregion

            #region Falling/Floating/Landing

            float walkElapsed = (Util.EnvironmentTickCount() - m_animTickWalk) / 1000f;
            if (actor != null && actor.IsPhysical && !actor.IsJumping && (!actor.IsColliding) && !actor.Flying && actor.TargetVelocity != Vector3.Zero /* && actor.Velocity.Z < -2*/ &&
                (walkElapsed > FALL_AFTER_MOVE_TIME || m_animTickWalk == 0))//For if they user is walking off something, or they are falling
            {
                //Always return falldown immediately as there shouldn't be a waiting period
                if (m_animTickFall == 0)
                {
                    m_animTickFall = Util.EnvironmentTickCount();
                }
                return("FALLDOWN");
            }

            #endregion Falling/Floating/Landing

            #region Ground Movement

            if (m_movementAnimation == "FALLDOWN")
            {
                float fallElapsed = (Util.EnvironmentTickCount() - m_animTickFall) / 1000f;
                // soft landing?
                if (fallElapsed < 0.75)
                {
                    m_animTickFall = Util.EnvironmentTickCount();

                    return("SOFT_LAND");
                }

                // a bit harder then?
                if (actor != null &&
                    (fallElapsed < 1.1 ||
                     (Math.Abs(actor.Velocity.X) > 1 &&
                      Math.Abs(actor.Velocity.Y) > 1 &&
                      actor.Velocity.Z < 3)
                    )
                    )
                {
                    m_animTickFall = Util.EnvironmentTickCount();

                    return("LAND");
                }

                // maybe a hard one...
                if (m_useSplatAnimation)
                {
                    m_animTickStandup = Util.EnvironmentTickCount();
                    return("STANDUP");
                }

                // just a simple landing
                return("LAND");
            }

            // landing then
            if (m_movementAnimation == "LAND")
            {
                if (actor != null && actor.Velocity.Z < 0)
                {
                    if (actor.Velocity.Z < SOFTLAND_FORCE)
                    {
                        return("LAND");
                    }
                    return("SOFT_LAND");
                }
                //return "LAND";
            }

            m_animTickFall = 0;

            if (move.Z <= 0f)
            {
                if (actor != null && (move.X != 0f || move.Y != 0f ||
                                      actor.Velocity.X != 0 && actor.Velocity.Y != 0))
                {
                    wasLastFlying = false;
                    if (actor.IsColliding)
                    {
                        m_animTickWalk = Util.EnvironmentTickCount();
                    }

                    // Walking / crouchwalking / running
                    if (move.Z < 0f)
                    {
                        return("CROUCHWALK");
                    }

                    // always run?
                    if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }

                    // must be walking then
                    return("WALK");
                }

                // Not walking
                if (move.Z < 0f && !wasLastFlying)
                {
                    return("CROUCH");
                }

                return("STAND");
            }

            #endregion Ground Movement

            // none of the above so just continue the last animation
            return(m_movementAnimation);
        }
Beispiel #39
0
 public override void LinkToNewParent(PhysicsActor obj, Vector3 localPos, Quaternion localRot)
 {
     
 }
Beispiel #40
0
 public void StopMoveToTarget()
 {
     PhysicsActor?.DeactivateTargetList();
 }
Beispiel #41
0
        public void SetParentAndUpdatePhysics(SceneObjectGroup parent)
        {
            this.SetParent(parent, false);

            PhysicsActor physActor = PhysActor;
            if (physActor != null)
            {
                //does the parent have a physactor?
                PhysicsActor parentPhysactor = parent.RootPart.PhysActor;

                if (parentPhysactor != null)
                {
                    physActor.LinkToNewParent(parent.RootPart.PhysActor, this.OffsetPosition, this.RotationOffset);
                }
                else
                {
                    //we're linking a non-phantom prim to a phantom parent, phantomize this prim as well
                    //NOTE: Don't use UpdatePrimFlags here, it only works for roots, and this is not a root 
                    //any longer
                    this.AddFlag(PrimFlags.Phantom);
                    m_parentGroup.Scene.PhysicsScene.RemovePrim(physActor);
                    PhysActor = null;
                }
            }
        }
        // This is the standard Near.   Uses space AABBs to speed up detection.
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            //Don't test against heightfield Geom, or you'll be sorry!

            /*
             * terminate called after throwing an instance of 'std::bad_alloc'
             *    what():  std::bad_alloc
             *  Stacktrace:
             *
             *    at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004>
             *    at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff>
             *    at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280>
             *    at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff
             *  fffff>
             *    at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004>
             *    at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff>
             *    at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) <
             *  0x00114>
             *    at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb>
             *    at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6>
             *    at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042>
             *    at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e>
             *    at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019>
             *    at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>
             *
             *  Native stacktrace:
             *
             *          mono [0x80d2a42]
             *          [0xb7f5840c]
             *          /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018]
             *          /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988]
             *          /usr/lib/libstdc++.so.6 [0xb45fa865]
             *          /usr/lib/libstdc++.so.6 [0xb45fa8a2]
             *          /usr/lib/libstdc++.so.6 [0xb45fa9da]
             *          /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033]
             *          /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d]
             *          libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4]
             *          libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b]
             *          libode.so(dCollide+0x102) [0xb46571b2]
             *          [0x95cfdec9]
             *          [0x8ea07fe1]
             *          [0xab260146]
             *          libode.so [0xb465a5c4]
             *          libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5]
             *          libode.so(dSpaceCollide2+0x177) [0xb465ac67]
             *          [0x95cf978e]
             *          [0x8ea07945]
             *          [0x95cf2bbc]
             *          [0xab2787e7]
             *          [0xab419fb3]
             *          [0xab416657]
             *          [0xab415bda]
             *          [0xb609b08e]
             *          mono(mono_runtime_delegate_invoke+0x34) [0x8192534]
             *          mono [0x81a2f0f]
             *          mono [0x81d28b6]
             *          mono [0x81ea2c6]
             *          /lib/i686/cmov/libpthread.so.0 [0xb7e744c0]
             *          /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de]
             */

            // Exclude heightfield geom

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }
            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
            {
                return;
            }

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
            {
                if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                {
                    return;
                }

                // 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 (AccessViolationException)
                {
                    m_log.Warn("[PHYSICS]: Unable to collide test a space");
                    return;
                }
                //Colliding a space or a geom with a space or a geom. so drill down

                //Collide all geoms in each space..
                //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
                //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
                return;
            }

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

            int count = 0;

            try
            {
                if (g1 == g2)
                {
                    return; // Can't collide with yourself
                }
                lock (contacts)
                {
                    count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
                }
            }
            catch (SEHException)
            {
                m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            PhysicsActor p1 = null;
            PhysicsActor p2 = null;

            if (g1 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p1);
            }

            if (g2 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p2);
            }

            // Loop over contacts, build results.
            for (int i = 0; i < count; i++)
            {
                if (p1 != null)
                {
                    if (p1 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = p1.LocalID;
                        collisionresult.Pos        = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth      = contacts[i].depth;
                        collisionresult.Normal     = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
                                                                 contacts[i].normal.Z);
                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }

                if (p2 != null)
                {
                    if (p2 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = p2.LocalID;
                        collisionresult.Pos        = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth      = contacts[i].depth;
                        collisionresult.Normal     = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
                                                                 contacts[i].normal.Z);

                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }
            }
        }
Beispiel #43
0
 // link me to the specified parent
 public override void link(PhysicsActor obj) {
     BSPrim parent = (BSPrim)obj;
     // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
     // TODO: decide if this parent checking needs to happen at taint time
     if (_parentPrim == null)
     {
         if (parent != null)
         {
             // I don't have a parent so I am joining a linkset
             parent.AddChildToLinkset(this);
         }
     }
     else
     {
         // I already have a parent, is parenting changing?
         if (parent != _parentPrim)
         {
             if (parent == null)
             {
                 // we are being removed from a linkset
                 _parentPrim.RemoveChildFromLinkset(this);
             }
             else
             {
                 // asking to reparent a prim should not happen
                 m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader);
             }
         }
     }
     return; 
 }
Beispiel #44
0
 public override void AddPhysicsActorTaint(PhysicsActor prim, TaintType taint)
 {
 }
Beispiel #45
0
        public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD)
        {
            bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0);
            bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0);
            bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0);
            bool wasVD = VolumeDetectActive;

            if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD))
            {
                return;
            }

            // Special cases for VD. VD can only be called from a script 
            // and can't be combined with changes to other states. So we can rely
            // that...
            // ... if VD is changed, all others are not.
            // ... if one of the others is changed, VD is not.
            if (IsVD) // VD is active, special logic applies
            {
                // State machine logic for VolumeDetect
                // More logic below
                bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom;

                if (phanReset) // Phantom changes from on to off switch VD off too
                {
                    IsVD = false;               // Switch it of for the course of this routine
                    VolumeDetectActive = false; // and also permanently
                    if (PhysActor != null)
                        PhysActor.SetVolumeDetect(0);   // Let physics know about it too
                }
                else
                {
                    IsPhantom = false;
                    // If volumedetect is active we don't want phantom to be applied.
                    // If this is a new call to VD out of the state "phantom"
                    // this will also cause the prim to be visible to physics
                }

            }

            if (UsePhysics && IsJoint())
            {
                IsPhantom = true;
            }

            if (UsePhysics)
            {
                AddFlag(PrimFlags.Physics);
                if (!wasUsingPhysics)
                {
                    DoPhysicsPropertyUpdate(UsePhysics, false);
                    if (m_parentGroup != null)
                    {
                        if (!m_parentGroup.IsDeleted)
                        {
                            if (LocalId == m_parentGroup.RootPart.LocalId)
                            {
                                m_parentGroup.CheckSculptAndLoad();
                            }
                        }
                    }
                }
            }
            else
            {
                RemFlag(PrimFlags.Physics);
                if (wasUsingPhysics)
                {
                    DoPhysicsPropertyUpdate(UsePhysics, false);
                }
            }


            if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
            {
                AddFlag(PrimFlags.Phantom);
                if (PhysActor != null)
                {
                    m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
                    /// that's not wholesome.  Had to make Scene public
                    PhysActor = null;
                }
            }
            else // Not phantom
            {
                RemFlag(PrimFlags.Phantom);

                PhysicsActor pa = PhysActor;
                if (pa == null)
                {
                    // It's not phantom anymore. So make sure the physics engine get's knowledge of it
                    PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
                        Name,
                        Shape,
                        AbsolutePosition,
                        Scale,
                        RotationOffset,
                        UsePhysics);

                    pa = PhysActor;
                    if (pa != null)
                    {
                        pa.LocalID = LocalId;
                        DoPhysicsPropertyUpdate(UsePhysics, true);
                        if (m_parentGroup != null)
                        {
                            if (!m_parentGroup.IsDeleted)
                            {
                                if (LocalId == m_parentGroup.RootPart.LocalId)
                                {
                                    m_parentGroup.CheckSculptAndLoad();
                                }
                            }
                        }
                        if (
                            ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
                            ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
                            ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
                            (CollisionSound != UUID.Zero)
                            )
                        {
                                PhysActor.OnCollisionUpdate += PhysicsCollision;
                                PhysActor.SubscribeEvents(1000);
                        }
                    }
                }
                else // it already has a physical representation
                {
                    pa.IsPhysical = UsePhysics;

                    DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim
                    if (m_parentGroup != null)
                    {
                        if (!m_parentGroup.IsDeleted)
                        {
                            if (LocalId == m_parentGroup.RootPart.LocalId)
                            {
                                m_parentGroup.CheckSculptAndLoad();
                            }
                        }
                    }
                }
            }

            if (IsVD)
            {
                // If the above logic worked (this is urgent candidate to unit tests!)
                // we now have a physicsactor.
                // Defensive programming calls for a check here.
                // Better would be throwing an exception that could be catched by a unit test as the internal 
                // logic should make sure, this Physactor is always here.
                if (this.PhysActor != null)
                {
                    PhysActor.SetVolumeDetect(1);
                    AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active
                    this.VolumeDetectActive = true;
                }
            }
            else
            {   // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like
                // (mumbles, well, at least if you have infinte CPU powers :-))
                PhysicsActor pa = this.PhysActor;
                if (pa != null)
                {
                    PhysActor.SetVolumeDetect(0);
                }
                this.VolumeDetectActive = false;
            }


            if (IsTemporary)
            {
                AddFlag(PrimFlags.TemporaryOnRez);
            }
            else
            {
                RemFlag(PrimFlags.TemporaryOnRez);
            }
            //            m_log.Debug("Update:  PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());

            ParentGroup.HasGroupChanged = true;
            ScheduleFullUpdate();
        }
Beispiel #46
0
 public override void LinkToNewParent(PhysicsActor obj, Vector3 localPos, Quaternion localRot)
 {
 }
 public override void RemovePrim(PhysicsActor prim)
 {
 }
Beispiel #48
0
    public void refresh(Vector3 influence, bool jump, bool sprint, bool crouch)
    {
        //Debug.Log("Hello?");
        capsuleOffsets[0] = Vector3.up * (settings.stepUpMax + settings.collisionRadius);
        capsuleOffsets[1] = capsuleOffsets[0] + Vector3.up * settings.collisionHeight;
        currentVelocity   = currentPhysics.getVelocity();

        Vector3 workingInfluence = influence;

        switch (currentPhysicsMode)
        {
        case PhysicsModes.STANDING:
        case PhysicsModes.WALKING:
        case PhysicsModes.RUNNING: {
            Debug.Log("GROUNDED!!");
            if (!currentPhysics.inValidState())
            {
                //if on a slidable terrain.

                currentPhysics     = movementSelection[(int)key.AIR_TRAVERSAL];
                currentPhysicsMode = PhysicsModes.AIRBORNE;
                currentPhysics.reset();
                currentPhysics.setVelocity(currentVelocity);
            }

            if (jump)
            {
                //if infront of climable that fits a vaulatable, and enough speed, vault it
                //else if infront of climbable and moving towards it, step up it.


                currentPhysics     = movementSelection[(int)key.AIR_TRAVERSAL]; //AIR TRAVERSAL
                currentPhysicsMode = PhysicsModes.AIRBORNE;
                currentPhysics.reset();
                currentPhysics.setVelocity(currentVelocity);
                workingInfluence.y = 1;
            }
        }
        break;

        case PhysicsModes.CROUCHING:
        case PhysicsModes.SLIDING: {
        }
        break;

        case PhysicsModes.CLIMBING: {
        }
        break;

        case PhysicsModes.AIRBORNE:
        default: {
            Debug.Log("AIRBORNE!!");
            if (!currentPhysics.inValidState())
            {
                Debug.Log("in-valid");
                currentPhysicsMode = PhysicsModes.STANDING;
                currentPhysics     = movementSelection[(int)key.GROUND_TRAVERSAL];
                currentPhysics.setVelocity(currentVelocity);
            }
        }
        break;
        }


        currentPhysics.refresh(workingInfluence);
    }
Beispiel #49
0
 /// <summary>
 /// Remove a prim.
 /// </summary>
 /// <param name="prim"></param>
 public abstract void RemovePrim(PhysicsActor prim);
 public override void RemovePrim(PhysicsActor prim)
 {
 }
Beispiel #51
0
 public abstract void AddPhysicsActorTaint(PhysicsActor prim);
Beispiel #52
0
 public override void RemoveAvatar(PhysicsActor actor)
 {
     this.QueueCommand(new Commands.RemoveCharacterCmd((PhysxCharacter)actor));
 }
Beispiel #53
0
    public override void RemoveAvatar(PhysicsActor actor)
    {
        // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader);

        if (!m_initialized) return;

        BSCharacter bsactor = actor as BSCharacter;
        if (bsactor != null)
        {
            try
            {
                lock (PhysObjects)
                    PhysObjects.Remove(bsactor.LocalID);
                // Remove kludge someday
                lock (m_avatars)
                    m_avatars.Remove(bsactor);
            }
            catch (Exception e)
            {
                m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e);
            }
            bsactor.Destroy();
            // bsactor.dispose();
        }
        else
        {
            m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}",
                                        LogHeader, actor.LocalID, actor.GetType().Name);
        }
    }
Beispiel #54
0
 public override void RemovePrim(PhysicsActor prim)
 {
     this.QueueCommand(new Commands.RemoveObjectCmd((PhysxPrim)prim));
 }
Beispiel #55
0
 // This is a call from the simulator saying that some physical property has been updated.
 // The BulletSim driver senses the changing of relevant properties so this taint
 // information call is not needed.
 public override void AddPhysicsActorTaint(PhysicsActor prim) { }
Beispiel #56
0
 public override void AddPhysicsActorTaint(PhysicsActor prim)
 {
     //throw new NotSupportedException("AddPhysicsActorTaint must be called with a taint type");
 }
Beispiel #57
0
 public override void RemovePrim(PhysicsActor prim)
 {
     this.QueueCommand(new Commands.RemoveObjectCmd((PhysxPrim)prim));
 }
Beispiel #58
0
 public override void link(PhysicsActor obj)
 {
     return;
 }
Beispiel #59
0
 public override void AddPhysicsActorTaint(PhysicsActor prim, TaintType taint)
 {
     TaintHandler handler;
     if (_taintHandlers.TryGetValue(taint, out handler))
     {
         handler((PhysxPrim)prim, taint);
     }
 }
        // This is the standard Near.   Uses space AABBs to speed up detection.
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }
//            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
//                return;

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
            {
                if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                {
                    return;
                }

                // 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 (AccessViolationException)
                {
                    m_log.Warn("[PHYSICS]: Unable to collide test a space");
                    return;
                }
                //Colliding a space or a geom with a space or a geom. so drill down

                //Collide all geoms in each space..
                //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
                //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
                return;
            }

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

            int count = 0;

            try
            {
                if (g1 == g2)
                {
                    return; // Can't collide with yourself
                }
                lock (contacts)
                {
                    count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.unmanagedSizeOf);
                }
            }
            catch (SEHException)
            {
                m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            PhysicsActor p1 = null;
            PhysicsActor p2 = null;

            if (g1 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p1);
            }

            if (g2 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p2);
            }

            // Loop over contacts, build results.
            for (int i = 0; i < count; i++)
            {
                if (p1 != null)
                {
                    if (p1 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = p1.LocalID;
                        collisionresult.Pos        = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth      = contacts[i].depth;
                        collisionresult.Normal     = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
                                                                 contacts[i].normal.Z);
                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }

                if (p2 != null)
                {
                    if (p2 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = p2.LocalID;
                        collisionresult.Pos        = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth      = contacts[i].depth;
                        collisionresult.Normal     = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
                                                                 contacts[i].normal.Z);

                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }
            }
        }