Esempio n. 1
0
        // Set this sets and computes the displacement from the passed prim to the center-of-mass.
        // A user set value for center-of-mass overrides whatever might be passed in here.
        // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
        public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
        {
            Vector3 comDisp;

            if (UserSetCenterOfMassDisplacement.HasValue)
            {
                comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
            }
            else
            {
                comDisp = centerOfMassDisplacement;
            }

            DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}",
                      LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp);
            if (comDisp == Vector3.Zero)
            {
                // If there is no diplacement. Things get reset.
                PositionDisplacement    = OMV.Vector3.Zero;
                OrientationDisplacement = OMV.Quaternion.Identity;
            }
            else
            {
                // Remember the displacement from root as well as the origional rotation of the
                //    new center-of-mass.
                PositionDisplacement    = comDisp;
                OrientationDisplacement = OMV.Quaternion.Identity;
            }
        }
Esempio n. 2
0
 public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
 {
     Index                  = indx;
     OffsetFromRoot         = p;
     OffsetFromCenterOfMass = p;
     OffsetRot              = r;
 }
 public override void Clear()
 {
     Index = 0;
     OffsetFromRoot = OMV.Vector3.Zero;
     OffsetFromCenterOfMass = OMV.Vector3.Zero;
     OffsetRot = OMV.Quaternion.Identity;
 }
Esempio n. 4
0
 public override void Clear()
 {
     Index                  = 0;
     OffsetFromRoot         = OMV.Vector3.Zero;
     OffsetFromCenterOfMass = OMV.Vector3.Zero;
     OffsetRot              = OMV.Quaternion.Identity;
 }
 public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
 {
     Index = indx;
     OffsetFromRoot = p;
     OffsetFromCenterOfMass = p;
     OffsetRot = r;
 }
 public EntityCamera(RegionContextBase rcontext, AssetContextBase acontext)
     : base(rcontext, acontext)
 {
     m_yawFixed = true;
     m_globalPosition = new OMV.Vector3d(40f, 40f, 30f);
     m_heading = new OMV.Quaternion(0f, 1f, 0f);
 }
Esempio n. 7
0
        // Set this sets and computes the displacement from the passed prim to the center-of-mass.
        // A user set value for center-of-mass overrides whatever might be passed in here.
        // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
        public virtual void SetEffectiveCenterOfMassW(Vector3 centerOfMassDisplacement)
        {
            Vector3 comDisp;

            if (UserSetCenterOfMass.HasValue)
            {
                comDisp = (OMV.Vector3)UserSetCenterOfMass;
            }
            else
            {
                comDisp = centerOfMassDisplacement;
            }

            if (comDisp == Vector3.Zero)
            {
                // If there is no diplacement. Things get reset.
                PositionDisplacement    = OMV.Vector3.Zero;
                OrientationDisplacement = OMV.Quaternion.Identity;
            }
            else
            {
                // Remember the displacement from root as well as the origional rotation of the
                //    new center-of-mass.
                PositionDisplacement    = comDisp;
                OrientationDisplacement = OMV.Quaternion.Identity;
            }
        }
Esempio n. 8
0
 public EntityCamera(RegionContextBase rcontext, AssetContextBase acontext)
     : base(rcontext, acontext)
 {
     m_yawFixed       = true;
     m_globalPosition = new OMV.Vector3d(40f, 40f, 30f);
     m_heading        = new OMV.Quaternion(0f, 1f, 0f);
 }
 // Set all the parameters for this constraint to a fixed, non-movable constraint.
 public override void ResetLink()
 {
     // constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
     constraintType     = ConstraintType.BS_FIXED_CONSTRAINT_TYPE;
     linearLimitLow     = OMV.Vector3.Zero;
     linearLimitHigh    = OMV.Vector3.Zero;
     angularLimitLow    = OMV.Vector3.Zero;
     angularLimitHigh   = OMV.Vector3.Zero;
     useFrameOffset     = BSParam.LinkConstraintUseFrameOffset;
     enableTransMotor   = BSParam.LinkConstraintEnableTransMotor;
     transMotorMaxVel   = BSParam.LinkConstraintTransMotorMaxVel;
     transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce;
     cfm = BSParam.LinkConstraintCFM;
     erp = BSParam.LinkConstraintERP;
     solverIterations         = BSParam.LinkConstraintSolverIterations;
     frameInAloc              = OMV.Vector3.Zero;
     frameInArot              = OMV.Quaternion.Identity;
     frameInBloc              = OMV.Vector3.Zero;
     frameInBrot              = OMV.Quaternion.Identity;
     useLinearReferenceFrameA = true;
     springAxisEnable         = new bool[6];
     springDamping            = new float[6];
     springStiffness          = new float[6];
     for (int ii = 0; ii < springAxisEnable.Length; ii++)
     {
         springAxisEnable[ii] = false;
         springDamping[ii]    = BSAPITemplate.SPRING_NOT_SPECIFIED;
         springStiffness[ii]  = BSAPITemplate.SPRING_NOT_SPECIFIED;
     }
     springLinearEquilibriumPoint  = OMV.Vector3.Zero;
     springAngularEquilibriumPoint = OMV.Vector3.Zero;
     member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.ResetLink", member.LocalID);
 }
Esempio n. 10
0
        public void Populate(Scene scene)
        {
            SceneObjectPart part = scene.GetSceneObjectPart(Key);

            if (part == null) // Avatar, maybe?
            {
                ScenePresence presence = scene.GetScenePresence(Key);
                if (presence == null)
                {
                    return;
                }

                Name  = presence.Firstname + " " + presence.Lastname;
                Owner = Key;

                Position = presence.AbsolutePosition;
                Rotation = presence.Rotation;
                Velocity = presence.Velocity;

                Type = 0x01; // Avatar
                if (presence.Velocity != Vector3.Zero)
                {
                    Type |= 0x02; // Active
                }
                Group = presence.ControllingClient.ActiveGroupId;
            }
            else //object
            {
                part = part.ParentGroup.RootPart; // We detect objects only

                LinkNum = 0; // Not relevant

                Group = part.GroupID;
                Name  = part.Name;
                Owner = part.OwnerID;
                if (part.Velocity == Vector3.Zero)
                {
                    Type = 0x04; // Passive
                }
                else
                {
                    Type = 0x02; // Passive
                }
                foreach (SceneObjectPart p in part.ParentGroup.Children.Values)
                {
                    if (p.Inventory.ContainsScripts())
                    {
                        Type |= 0x08; // Scripted
                        break;
                    }
                }

                Position = part.AbsolutePosition;

                Quaternion wr = part.ParentGroup.GroupRotation;
                Rotation = wr;
                Velocity = part.Velocity;
            }
        }
 public CameraControl()
 {
     m_heading = new OMV.Quaternion(OMV.Vector3.UnitY, 0f);
     m_globalPosition = new OMV.Vector3d(0d, 20d, 30d);   // World coordinates (Z up)
     m_zoom = 1.0f;
     m_far = 300.0f;
     m_yawFixed = true;
 }
Esempio n. 12
0
 public CameraControl()
 {
     m_heading        = new OMV.Quaternion(OMV.Vector3.UnitY, 0f);
     m_globalPosition = new OMV.Vector3d(0d, 20d, 30d); // World coordinates (Z up)
     m_zoom           = 1.0f;
     m_far            = 300.0f;
     m_yawFixed       = true;
 }
Esempio n. 13
0
        public LSL_List modInvokeL(string fname, params object[] parms)
        {
//            m_log.DebugFormat(
//                "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
//                fname,
//                string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
//                ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);

            Type returntype = m_comms.LookupReturnType(fname);

            if (returntype != typeof(object[]))
            {
                MODError(String.Format("return type mismatch for {0}", fname));
            }

            object[] result = (object[])modInvoke(fname, parms);
            object[] llist  = new object[result.Length];
            for (int i = 0; i < result.Length; i++)
            {
                if (result[i] is string)
                {
                    llist[i] = new LSL_String((string)result[i]);
                }
                else if (result[i] is int)
                {
                    llist[i] = new LSL_Integer((int)result[i]);
                }
                else if (result[i] is float)
                {
                    llist[i] = new LSL_Float((float)result[i]);
                }
                else if (result[i] is double)
                {
                    llist[i] = new LSL_Float((double)result[i]);
                }
                else if (result[i] is UUID)
                {
                    llist[i] = new LSL_Key(result[i].ToString());
                }
                else if (result[i] is OpenMetaverse.Vector3)
                {
                    OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i];
                    llist[i] = new LSL_Vector(vresult.X, vresult.Y, vresult.Z);
                }
                else if (result[i] is OpenMetaverse.Quaternion)
                {
                    OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i];
                    llist[i] = new LSL_Rotation(qresult.X, qresult.Y, qresult.Z, qresult.W);
                }
                else
                {
                    MODError(String.Format("unknown list element {1} returned by {0}", fname, result[i].GetType().Name));
                }
            }

            return(new LSL_List(llist));
        }
 public RenderableInfo()
 {
     basicObject = null; RegionRoot = null;
     // parentID = 0;
     parentEntity = null;
     position     = OMV.Vector3.Zero;
     rotation     = new OMV.Quaternion(0f, 0f, 0f, 0f);
     scale        = new OMV.Vector3(1f, 1f, 1f);
 }
Esempio n. 15
0
 // rotate the camera by the given quaternion
 public void rotate(OMV.Quaternion rot)
 {
     rot.Normalize();
     m_heading = rot * m_heading;
     if (OnCameraUpdate != null)
     {
         OnCameraUpdate(this);
     }
 }
Esempio n. 16
0
        public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
            : base(parent_scene, localID, avName, "BSCharacter")
        {
            _physicsActorType = (int)ActorTypes.Agent;
            _position         = pos;

            // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
            //     replace with the default values.
            _size = size;
            if (_size.X == 0f)
            {
                _size.X = BSParam.AvatarCapsuleDepth;
            }
            if (_size.Y == 0f)
            {
                _size.Y = BSParam.AvatarCapsuleWidth;
            }

            // A motor to control the acceleration and deceleration of the avatar movement.
            // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
            // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
            // Infinite decay and timescale values so motor only changes current to target values.
            _velocityMotor = new BSVMotor("BSCharacter.Velocity",
                                          0.2f,                   // time scale
                                          BSMotor.Infinite,       // decay time scale
                                          BSMotor.InfiniteVector, // friction timescale
                                          1f                      // efficiency
                                          );
            _velocityMotor.PhysicsScene = PhysicsScene;           // DEBUG DEBUG so motor will output detail log messages.

            _flying          = isFlying;
            _orientation     = OMV.Quaternion.Identity;
            _velocity        = OMV.Vector3.Zero;
            _appliedVelocity = OMV.Vector3.Zero;
            _buoyancy        = ComputeBuoyancyFromFlying(isFlying);
            _currentFriction = BSParam.AvatarStandingFriction;
            _avatarDensity   = BSParam.AvatarDensity;

            // The dimensions of the avatar capsule are kept in the scale.
            // Physics creates a unit capsule which is scaled by the physics engine.
            ComputeAvatarScale(_size);
            // set _avatarVolume and _mass based on capsule size, _density and Scale
            ComputeAvatarVolumeAndMass();
            DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
                      LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);

            // do actual creation in taint time
            PhysicsScene.TaintedObject("BSCharacter.create", delegate()
            {
                DetailLog("{0},BSCharacter.create,taint", LocalID);
                // New body and shape into PhysBody and PhysShape
                PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this);

                SetPhysicalProperties();
            });
            return;
        }
Esempio n. 17
0
        public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
                           bool isFlying)
            : base(parent_scene, localID, avName, "BSCharacter")
        {
            _physicsActorType = (int)ActorTypes.Agent;
            _isPhysical       = true;
            _position         = pos;

            _flying      = isFlying;
            _orientation = OMV.Quaternion.Identity;
            RawVelocity  = OMV.Vector3.Zero;
            _buoyancy    = ComputeBuoyancyFromFlying(isFlying);
            Friction     = BSParam.AvatarStandingFriction;
            Density      = BSParam.AvatarDensity / BSParam.DensityScaleFactor;

            // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
            //     replace with the default values.
            _size = size;
            if (_size.X == 0f)
            {
                _size.X = BSParam.AvatarCapsuleDepth;
            }
            if (_size.Y == 0f)
            {
                _size.Y = BSParam.AvatarCapsuleWidth;
            }

            // The dimensions of the physical capsule are kept in the scale.
            // Physics creates a unit capsule which is scaled by the physics engine.
            Scale = ComputeAvatarScale(_size);
            // set _avatarVolume and _mass based on capsule size, _density and Scale
            ComputeAvatarVolumeAndMass();

            // The avatar's movement is controlled by this motor that speeds up and slows down
            //    the avatar seeking to reach the motor's target speed.
            // This motor runs as a prestep action for the avatar so it will keep the avatar
            //    standing as well as moving. Destruction of the avatar will destroy the pre-step action.
            m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName);
            PhysicalActors.Add(AvatarMoveActorName, m_moveActor);

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

            // do actual creation in taint time
            PhysicsScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
            {
                DetailLog("{0},BSCharacter.create,taint", LocalID);
                // New body and shape into PhysBody and PhysShape
                PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this);

                SetPhysicalProperties();

                SubscribeEvents(1000);
            });
            return;
        }
Esempio n. 18
0
 public static void AddPositionToHash(BHasher hasher, OMV.Vector3 pos, OMV.Quaternion rot)
 {
     hasher.Add(pos.X);
     hasher.Add(pos.Y);
     hasher.Add(pos.Z);
     hasher.Add(rot.X);
     hasher.Add(rot.Y);
     hasher.Add(rot.Z);
     hasher.Add(rot.W);
 }
Esempio n. 19
0
            // Add another level of parenting
            public InvertedMesh AddDisplayableLevel(InvertedMesh imesh, Displayable pDisp, DisplayableRenderable pDispRend)
            {
                InvertedMesh newIMesh = new InvertedMesh(imesh.containingScene, imesh.containingInstance,
                                                         imesh.containingDisplayable, imesh.containingDisplayableRenderable, imesh.renderableMesh);

                globalPosition += pDisp.offsetPosition;
                globalRotation *= pDisp.offsetRotation;
                newIMesh.containingDisplayable           = pDisp;
                newIMesh.containingDisplayableRenderable = pDispRend;
                return(newIMesh);
            }
Esempio n. 20
0
 public InvertedMesh(BScene pBs, BInstance pInst, Displayable pDisp, DisplayableRenderable pDisprend, RenderableMesh pRm)
 {
     containingScene                 = pBs;
     containingInstance              = pInst;
     containingDisplayable           = pDisp;
     containingDisplayableRenderable = pDisprend;
     renderableMesh = pRm;
     // Compute the global position of the Displayable
     globalPosition = containingDisplayable.offsetPosition * containingInstance.Rotation + containingInstance.Position;
     globalRotation = containingDisplayable.offsetRotation * containingInstance.Rotation;
 }
Esempio n. 21
0
        /// <summary>
        /// Update both position and heading with one call. Remember that the position
        /// is a global position.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="heading"></param>
        public void Update(OMV.Vector3d pos, OMV.Quaternion heading)
        {
            bool changed = (m_heading != heading) | (m_globalPosition != pos);

            m_globalPosition = pos;
            m_heading        = heading;
            if (changed && (OnCameraUpdate != null))
            {
                OnCameraUpdate(this);
            }
        }
 // Rotate a vector by a quaternian
 public static OMV.Vector3 RotateVector(OMV.Quaternion q, OMV.Vector3 v)
 {
     OMV.Vector3 v2, v3;
     q.Normalize();
     OMV.Vector3 qv = new OMV.Vector3(q.X, q.Y, q.Z);
     v2  = OMV.Vector3.Cross(qv, v);
     v3  = OMV.Vector3.Cross(qv, v2);
     v2 *= (2.0f * q.W);
     v3 *= 2.0f;
     return(v + v2 + v3);
 }
Esempio n. 23
0
 public void at_rot_target(UUID scriptID, uint handle, OpenMetaverse.Quaternion targetrot, OpenMetaverse.Quaternion atrot)
 {
     PostScriptEvent(scriptID, new EventParams(
                         "at_rot_target",
                         new object[] {
         new LSL_Integer(handle),
         new LSL_Rotation(targetrot.X, targetrot.Y, targetrot.Z, targetrot.W),
         new LSL_Rotation(atrot.X, atrot.Y, atrot.Z, atrot.W)
     },
                         zeroDetectParams));
 }
Esempio n. 24
0
        public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
                              OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
            : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
        {
            Linkset = BSLinkset.Factory(PhysScene, this);

            PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
            {
                Linkset.Refresh(this);
            });
        }
Esempio n. 25
0
        public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
                              OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
            : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
        {
            // Default linkset implementation for this prim
            LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation;

            Linkset = BSLinkset.Factory(PhysScene, this);

            Linkset.Refresh(this);
        }
Esempio n. 26
0
        // The physics engine says that properties have updated. Update same and inform
        // the world that things have changed.
        public override void UpdateProperties(EntityProperties entprop)
        {
            _position           = entprop.Position;
            _orientation        = entprop.Rotation;
            _velocity           = entprop.Velocity;
            _acceleration       = entprop.Acceleration;
            _rotationalVelocity = entprop.RotationalVelocity;

            // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
            PositionSanityCheck(true);

            if (_velocityMotor.Enabled)
            {
                // TODO: Decide if the step parameters should be changed depending on the avatar's
                //     state (flying, colliding, ...).

                OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep);

                // If falling, we keep the world's downward vector no matter what the other axis specify.
                if (!Flying && !IsColliding)
                {
                    stepVelocity.Z = entprop.Velocity.Z;
                    DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
                }

                // If the user has said stop and we've stopped applying velocity correction,
                //     the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer.
                if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero)
                {
                    ZeroMotion(true);
                    stepVelocity           = OMV.Vector3.Zero;
                    _velocityMotor.Enabled = false;
                    DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor);
                }

                _velocity        = stepVelocity;
                entprop.Velocity = _velocity;
                BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
            }

            // remember the current and last set values
            LastEntityProperties    = CurrentEntityProperties;
            CurrentEntityProperties = entprop;

            // Tell the linkset about value changes
            Linkset.UpdateProperties(this, true);

            // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
            // base.RequestPhysicsterseUpdate();

            DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                      LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
        }
Esempio n. 27
0
        public LSL_Rotation modInvokeR(string fname, params object[] parms)
        {
            Type returntype = m_comms.LookupReturnType(fname);

            if (returntype != typeof(OpenMetaverse.Quaternion))
            {
                MODError(String.Format("return type mismatch for {0}", fname));
            }

            OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname, parms);
            return(new LSL_Rotation(result.X, result.Y, result.Z, result.W));
        }
Esempio n. 28
0
        // The physics engine says that properties have updated. Update same and inform
        // the world that things have changed.
        public override void UpdateProperties(EntityProperties entprop)
        {
            // Don't change position if standing on a stationary object.
            if (!IsStationary)
            {
                _position = entprop.Position;
            }

            _orientation = entprop.Rotation;

            if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) &&
                Velocity != OMV.Vector3.Zero)
            {
                entprop.Velocity           = OMV.Vector3.Zero;
                entprop.Acceleration       = OMV.Vector3.Zero;
                entprop.RotationalVelocity = OMV.Vector3.Zero;
                Velocity = OMV.Vector3.Zero;

                TriggerSignificantMovement();
                TriggerMovementUpdate();
            }

            if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f))
            {
                RawVelocity = entprop.Velocity;

                TriggerSignificantMovement();
                TriggerMovementUpdate();
            }

            _acceleration       = entprop.Acceleration;
            _rotationalVelocity = entprop.RotationalVelocity;

            // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
            if (PositionSanityCheck(true))
            {
                DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
                entprop.Position = _position;
            }

            // remember the current and last set values
            LastEntityProperties    = CurrentEntityProperties;
            CurrentEntityProperties = entprop;

            // Tell the linkset about value changes
            // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);

            // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
            // base.RequestPhysicsterseUpdate();

            DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                      LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
        }
Esempio n. 29
0
 public static float[] ComposeMatrix4(OMV.Vector3 pos, OMV.Quaternion rot)
 {
     float[] aPos = new float[3] {
         pos.X, pos.Y, pos.Z
     };
     float[] aRot = new float[4] {
         rot.X, rot.Y, rot.Z, rot.W
     };
     float[] aScale = new float[3] {
         1.0f, 1.0f, 1.0f
     };
     return(Utilities.ComposeMatrix4(aPos, aRot, aScale));
 }
Esempio n. 30
0
        // Convert the positions and all the vertices in an ExtendedPrim from one
        //     coordinate space to another. ExtendedPrim.coordSpace gives the current
        //     coordinates and we specify a new one here.
        // This is not a general solution -- it pretty much only works to convert
        //     right-handed,Z-up coordinates (OpenSimulator) to right-handed,Y-up
        //     (OpenGL).
        public static void FixCoordinates(BInstance inst, CoordAxis newCoords)
        {
            if (inst.coordAxis.system != newCoords.system)
            {
                OMV.Matrix4    coordTransform  = OMV.Matrix4.Identity;
                OMV.Quaternion coordTransformQ = OMV.Quaternion.Identity;
                if (inst.coordAxis.getUpDimension == CoordAxis.Zup &&
                    newCoords.getUpDimension == CoordAxis.Yup)
                {
                    // The one thing we know to do is change from Zup to Yup
                    coordTransformQ = OMV.Quaternion.CreateFromAxisAngle(1.0f, 0.0f, 0.0f, -(float)Math.PI / 2f);
                    // Make a clean matrix version.
                    // The libraries tend to create matrices with small numbers (1.119093e-07) for zero.
                    coordTransform = new OMV.Matrix4(
                        1, 0, 0, 0,
                        0, 0, -1, 0,
                        0, 1, 0, 0,
                        0, 0, 0, 1);
                }

                OMV.Vector3    oldPos = inst.Position; // DEBUG DEBUG
                OMV.Quaternion oldRot = inst.Rotation; // DEBUG DEBUG
                // Fix the location in space
                inst.Position = inst.Position * coordTransformQ;
                inst.Rotation = coordTransformQ * inst.Rotation;

                inst.coordAxis = newCoords;
                // ConvOAR.Globals.log.DebugFormat("{0} FixCoordinates. dispID={1}, oldPos={2}, newPos={3}, oldRot={4}, newRot={5}",
                //     _logHeader, inst.handle, oldPos, inst.Position, oldRot, inst.Rotation);

                // Go through all the vertices and change the UV coords if necessary
                List <MeshInfo> meshInfos = CollectMeshesFromDisplayable(inst.Representation);

                meshInfos.ForEach(meshInfo => {
                    if (meshInfo.coordAxis.getUVOrigin != newCoords.getUVOrigin)
                    {
                        for (int ii = 0; ii < meshInfo.vertexs.Count; ii++)
                        {
                            var vert             = meshInfo.vertexs[ii];
                            vert.TexCoord.Y      = 1f - vert.TexCoord.Y;
                            meshInfo.vertexs[ii] = vert;
                        }
                        meshInfo.coordAxis = newCoords;
                    }
                });
            }
            else
            {
                ConvOAR.Globals.log.DebugFormat("FixCoordinates. Not converting coord system. dispID={0}", inst.handle);
            }
        }
Esempio n. 31
0
        // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
        public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
        {
            // Each child position and rotation is given relative to the center-of-mass.
            OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
            OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation;
            OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement;
            OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation;

            // Save relative position for recomputing child's world position after moving linkset.
            Index = indx;
            OffsetFromRoot = displacementFromRoot;
            OffsetFromCenterOfMass = displacementFromCOM;
            OffsetRot = displacementRot;
        }
Esempio n. 32
0
        public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
                              OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, int material, float friction,
                              float restitution, float gravityMultiplier, float density)
            : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
        {
            // Default linkset implementation for this prim
            LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation;

            Linkset = BSLinkset.Factory(PhysicsScene, this);
            if (Linkset != null)
            {
                Linkset.Refresh(this);
            }
        }
Esempio n. 33
0
        // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
        public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
        {
            // Each child position and rotation is given relative to the center-of-mass.
            OMV.Quaternion invRootOrientation   = OMV.Quaternion.Inverse(root.RawOrientation);
            OMV.Vector3    displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation;
            OMV.Vector3    displacementFromCOM  = displacementFromRoot - centerDisplacement;
            OMV.Quaternion displacementRot      = child.RawOrientation * invRootOrientation;

            // Save relative position for recomputing child's world position after moving linkset.
            Index                  = indx;
            OffsetFromRoot         = displacementFromRoot;
            OffsetFromCenterOfMass = displacementFromCOM;
            OffsetRot              = displacementRot;
        }
Esempio n. 34
0
 public DetectParams()
 {
     Key       = UUID.Zero;
     OffsetPos = new OpenMetaverse.Vector3();
     LinkNum   = 0;
     Group     = UUID.Zero;
     Name      = String.Empty;
     Owner     = UUID.Zero;
     Position  = new OpenMetaverse.Vector3();
     Rotation  = new OpenMetaverse.Quaternion();
     Type      = 0;
     Velocity  = new OpenMetaverse.Vector3();
     initializeSurfaceTouch();
 }
Esempio n. 35
0
 public DetectParams()
 {
     Key = UUID.Zero;
     OffsetPos = new OpenMetaverse.Vector3();
     LinkNum = 0;
     Group = UUID.Zero;
     Name = String.Empty;
     Owner = UUID.Zero;
     Position = new OpenMetaverse.Vector3();
     Rotation = new OpenMetaverse.Quaternion();
     Type = 0;
     Velocity = new OpenMetaverse.Vector3();
     initializeSurfaceTouch();
 }
Esempio n. 36
0
        public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
            bool isFlying)
            : base(parent_scene, localID, avName, "BSCharacter")
        {
            _physicsActorType = (int)ActorTypes.Agent;
            _isPhysical = true;
            _position = pos;

            _flying = isFlying;
            _orientation = OMV.Quaternion.Identity;
            RawVelocity = OMV.Vector3.Zero;
            _buoyancy = ComputeBuoyancyFromFlying(isFlying);
            Friction = BSParam.AvatarStandingFriction;
            Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;

            // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
            //     replace with the default values.
            _size = size;
            if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
            if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;

            // The dimensions of the physical capsule are kept in the scale.
            // Physics creates a unit capsule which is scaled by the physics engine.
            Scale = ComputeAvatarScale(_size);
            // set _avatarVolume and _mass based on capsule size, _density and Scale
            ComputeAvatarVolumeAndMass();

            // The avatar's movement is controlled by this motor that speeds up and slows down
            //    the avatar seeking to reach the motor's target speed.
            // This motor runs as a prestep action for the avatar so it will keep the avatar
            //    standing as well as moving. Destruction of the avatar will destroy the pre-step action.
            m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName);
            PhysicalActors.Add(AvatarMoveActorName, m_moveActor);

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

            // do actual creation in taint time
            PhysicsScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
            {
                DetailLog("{0},BSCharacter.create,taint", LocalID);
                // New body and shape into PhysBody and PhysShape
                PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this);

                SetPhysicalProperties();

                SubscribeEvents(1000);
            });
            return;
        }
Esempio n. 37
0
        public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
        {
            base.BaseInitialize(parent_scene, localID, avName, "BSCharacter");
            _physicsActorType = (int)ActorTypes.Agent;
            _position         = pos;
            _size             = size;
            _flying           = isFlying;
            _orientation      = OMV.Quaternion.Identity;
            _velocity         = OMV.Vector3.Zero;
            _buoyancy         = ComputeBuoyancyFromFlying(isFlying);

            // The dimensions of the avatar capsule are kept in the scale.
            // Physics creates a unit capsule which is scaled by the physics engine.
            ComputeAvatarScale(_size);
            _avatarDensity = PhysicsScene.Params.avatarDensity;
            // set _avatarVolume and _mass based on capsule size, _density and _scale
            ComputeAvatarVolumeAndMass();

            ShapeData shapeData = new ShapeData();

            shapeData.ID          = LocalID;
            shapeData.Type        = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
            shapeData.Position    = _position;
            shapeData.Rotation    = _orientation;
            shapeData.Velocity    = _velocity;
            shapeData.Scale       = _scale;
            shapeData.Mass        = _mass;
            shapeData.Buoyancy    = _buoyancy;
            shapeData.Static      = ShapeData.numericFalse;
            shapeData.Friction    = PhysicsScene.Params.avatarFriction;
            shapeData.Restitution = PhysicsScene.Params.avatarRestitution;

            // do actual create at taint time
            PhysicsScene.TaintedObject("BSCharacter.create", delegate()
            {
                DetailLog("{0},BSCharacter.create,taint", LocalID);
                BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData);

                // Set the buoyancy for flying. This will be refactored when all the settings happen in C#.
                // If not set at creation, the avatar will stop flying when created after crossing a region boundry.
                BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy);

                BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID));

                // This works here because CreateObject has already put the character into the physical world.
                BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr,
                                                     (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask);
            });
            return;
        }
Esempio n. 38
0
    public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
    {
        base.BaseInitialize(parent_scene, localID, avName, "BSCharacter");
        _physicsActorType = (int)ActorTypes.Agent;
        _position = pos;
        _size = size;
        _flying = isFlying;
        _orientation = OMV.Quaternion.Identity;
        _velocity = OMV.Vector3.Zero;
        _buoyancy = ComputeBuoyancyFromFlying(isFlying);

        // The dimensions of the avatar capsule are kept in the scale.
        // Physics creates a unit capsule which is scaled by the physics engine.
        ComputeAvatarScale(_size);
        _avatarDensity = PhysicsScene.Params.avatarDensity;
        // set _avatarVolume and _mass based on capsule size, _density and _scale
        ComputeAvatarVolumeAndMass();

        ShapeData shapeData = new ShapeData();
        shapeData.ID = LocalID;
        shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
        shapeData.Position = _position;
        shapeData.Rotation = _orientation;
        shapeData.Velocity = _velocity;
        shapeData.Scale = _scale;
        shapeData.Mass = _mass;
        shapeData.Buoyancy = _buoyancy;
        shapeData.Static = ShapeData.numericFalse;
        shapeData.Friction = PhysicsScene.Params.avatarFriction;
        shapeData.Restitution = PhysicsScene.Params.avatarRestitution;

        // do actual create at taint time
        PhysicsScene.TaintedObject("BSCharacter.create", delegate()
        {
            DetailLog("{0},BSCharacter.create,taint", LocalID);
            BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData);

            // Set the buoyancy for flying. This will be refactored when all the settings happen in C#.
            // If not set at creation, the avatar will stop flying when created after crossing a region boundry.
            BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy);

            BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID));

            // This works here because CreateObject has already put the character into the physical world.
            BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr,
                            (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask);
        });
        return;
    }
Esempio n. 39
0
    public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
            : base(parent_scene, localID, avName, "BSCharacter")
    {
        _physicsActorType = (int)ActorTypes.Agent;
        _position = pos;

        _flying = isFlying;
        _orientation = OMV.Quaternion.Identity;
        _velocity = OMV.Vector3.Zero;
        _buoyancy = ComputeBuoyancyFromFlying(isFlying);
        Friction = BSParam.AvatarStandingFriction;
        Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;

        // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
        //     replace with the default values.
        _size = size;
        if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth;
        if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth;

        // The dimensions of the physical capsule are kept in the scale.
        // Physics creates a unit capsule which is scaled by the physics engine.
        Scale = ComputeAvatarScale(_size);
        // set _avatarVolume and _mass based on capsule size, _density and Scale
        ComputeAvatarVolumeAndMass();

        SetupMovementMotor();

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

        // do actual creation in taint time
        PhysicsScene.TaintedObject("BSCharacter.create", delegate()
        {
            DetailLog("{0},BSCharacter.create,taint", LocalID);
            // New body and shape into PhysBody and PhysShape
            PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this);

            SetPhysicalProperties();
        });
        return;
    }
Esempio n. 40
0
        public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
            OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
            : base(parent_scene, localID, primName, "BSPrim")
        {
            // MainConsole.Instance.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
            _physicsActorType = (int)ActorTypes.Prim;
            _position = pos;
            _size = size;
            Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
            _orientation = rotation;
            _buoyancy = 0f;
            RawVelocity = OMV.Vector3.Zero;
            _rotationalVelocity = OMV.Vector3.Zero;
            BaseShape = pbs;
            _isPhysical = pisPhysical;
            _isVolumeDetect = false;

            // Add a dynamic vehicle to our set of actors that can move this prim.
	          VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName);
            PhysicalActors.Add(VehicleActorName, VehicleActor);
            //PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysicsScene, this, VehicleActorName));

            _mass = CalculateMass();

            // DetailLog("{0},BSPrim.constructor,call", LocalID);
            // do the actual object creation at taint time
            PhysicsScene.TaintedObject(LocalID, "BSPrim.create", delegate()
            {
                // Make sure the object is being created with some sanity.
                ExtremeSanityCheck(true /* inTaintTime */);

                CreateGeomAndObject(true);

                CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody);

                IsInitialized = true;
            });
        }
Esempio n. 41
0
        // The physics engine says that properties have updated. Update same and inform
        // the world that things have changed.
        public override void UpdateProperties(EntityProperties entprop)
        {
            bool needSendUpdate = false;

            // Don't change position if standing on a stationary object.
            if (!IsStationary)
                _position = entprop.Position;
 
            _orientation = entprop.Rotation;

            if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) &&
                Velocity != OMV.Vector3.Zero)
            {
                entprop.Velocity = OMV.Vector3.Zero;
                entprop.Acceleration = OMV.Vector3.Zero;
                entprop.RotationalVelocity = OMV.Vector3.Zero;
                Velocity = OMV.Vector3.Zero;
                m_ZeroUpdateSent = 3;
                needSendUpdate = true;
            }

            if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f))
            {
                RawVelocity = entprop.Velocity;
                needSendUpdate = true;
            }

            // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
            if (PositionSanityCheck(true))
            {
                DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
                entprop.Position = _position;
            }

            // animation checks
            const float POSITION_TOLERANCE = 5.0f;
            float VELOCITY_TOLERANCE = 0.025f * 0.025f;
            if (PhysicsScene.TimeDilation < 0.5)
            {
                float percent = (1f - PhysicsScene.TimeDilation) * 100;
                VELOCITY_TOLERANCE *= percent*2;
            }

            bool VelIsZero = false;
            OMV.Vector3 _velocity = Velocity;
            int vcntr = 0;
            if (Math.Abs(_velocity.X) < 0.01)
            {
                vcntr++;
                _velocity.X = 0;
            }
            if (Math.Abs(_velocity.Y) < 0.01)
            {
                vcntr++;
                _velocity.Y = 0;
            }
            if (Math.Abs(_velocity.Z) < 0.01)
            {
                vcntr++;
                _velocity.Z = 0;
            }
            if (vcntr == 3)
            {
                Velocity = _velocity;
                VelIsZero = true;
            }
            
            float vlength = (Velocity - m_lastVelocity).LengthSquared();
            float plength = (_position - m_lastPosition).LengthSquared();
            if ( vlength > VELOCITY_TOLERANCE || plength > POSITION_TOLERANCE )
            {
                needSendUpdate = true;
                m_ZeroUpdateSent = 3;
            }
            else if (VelIsZero)
            {
                if (m_ZeroUpdateSent > 0)
                {
                    needSendUpdate = true;
                    m_ZeroUpdateSent--;
                }
            }


            if (needSendUpdate)
            {
                m_lastPosition = _position;
                m_lastVelocity = Velocity;
                               
                TriggerSignificantMovement();
                TriggerMovementUpdate();

                // remember the current and last set values
                _acceleration = entprop.Acceleration;
                _rotationalVelocity = entprop.RotationalVelocity;
                LastEntityProperties = CurrentEntityProperties;
                CurrentEntityProperties = entprop;

            }

            // Tell the linkset about value changes
            // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);

            // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
            // base.RequestPhysicsterseUpdate();

            DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
        }
Esempio n. 42
0
    // The physics engine says that properties have updated. Update same and inform
    // the world that things have changed.
    public override void UpdateProperties(EntityProperties entprop)
    {
        _position = entprop.Position;
        _orientation = entprop.Rotation;
        _velocity = entprop.Velocity;
        _acceleration = entprop.Acceleration;
        _rotationalVelocity = entprop.RotationalVelocity;

        // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
        PositionSanityCheck(true);

        // remember the current and last set values
        LastEntityProperties = CurrentEntityProperties;
        CurrentEntityProperties = entprop;

        // Tell the linkset about value changes
        Linkset.UpdateProperties(this, true);

        // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
        // base.RequestPhysicsterseUpdate();

        DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
    }
 /// <summary>
 /// rotate the specified amounts around the camera's local axis
 /// </summary>
 /// <param name="X"></param>
 /// <param name="Y"></param>
 /// <param name="Z"></param>
 public void rotate(float X, float Y, float Z)
 {
     if (YawFixed) {
         // some of the rotation is around X
         OMV.Quaternion xvec = OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitX, X);
         xvec.Normalize();
         // some of the rotation is around Z
         OMV.Quaternion zvec = OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitZ, Z);
         zvec.Normalize();
         m_heading = zvec * m_heading;
         m_heading = m_heading * xvec;
     }
     else {
         OMV.Quaternion rot = new OMV.Quaternion(X, Y, Z);
         rot.Normalize();
         rotate(rot);
     }
 }
Esempio n. 44
0
 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
                                           Vector3 size, Quaternion rotation) //To be removed
 {
     return AddPrimShape(primName, pbs, position, size, rotation, false);
 }
Esempio n. 45
0
        // The physics engine says that properties have updated. Update same and inform
        // the world that things have changed.
        public override void UpdateProperties(EntityProperties entprop)
        {
            // Don't change position if standing on a stationary object.
            if (!IsStationary)
                _position = entprop.Position;

            _orientation = entprop.Rotation;

            if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) &&
                Velocity != OMV.Vector3.Zero)
            {
                entprop.Velocity = OMV.Vector3.Zero;
                entprop.Acceleration = OMV.Vector3.Zero;
                entprop.RotationalVelocity = OMV.Vector3.Zero;
                Velocity = OMV.Vector3.Zero;

                TriggerSignificantMovement();
                TriggerMovementUpdate();
            }

            if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f))
            {
                RawVelocity = entprop.Velocity;

                TriggerSignificantMovement();
                TriggerMovementUpdate();
            }

            _acceleration = entprop.Acceleration;
            _rotationalVelocity = entprop.RotationalVelocity;

            // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
            if (PositionSanityCheck(true))
            {
                DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
                entprop.Position = _position;
            }

            // remember the current and last set values
            LastEntityProperties = CurrentEntityProperties;
            CurrentEntityProperties = entprop;

            // Tell the linkset about value changes
            // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);

            // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
            // base.RequestPhysicsterseUpdate();

            DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
        }
Esempio n. 46
0
 private PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation)
 {
     Vec3 pos = new Vec3();
     pos.X = position.X;
     pos.Y = position.Y;
     pos.Z = position.Z;
     Vec3 siz = new Vec3();
     siz.X = size.X;
     siz.Y = size.Y;
     siz.Z = size.Z;
     PhysXPrim act = new PhysXPrim(scene.AddNewBox(pos, siz));
     _prims.Add(act);
     return act;
 }
Esempio n. 47
0
    public override void UpdateProperties(EntityProperties entprop)
    {
        // Updates only for individual prims and for the root object of a linkset.
        if (Linkset.IsRoot(this))
        {
            // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
            // TODO: handle physics introduced by Bullet with computed vehicle physics.
            if (_vehicle.IsActive)
            {
                entprop.RotationalVelocity = OMV.Vector3.Zero;
            }

            // Assign directly to the local variables so the normal set action does not happen
            _position = entprop.Position;
            _orientation = entprop.Rotation;
            _velocity = entprop.Velocity;
            _acceleration = entprop.Acceleration;
            _rotationalVelocity = entprop.RotationalVelocity;

            // The sanity check can change the velocity and/or position.
            if (IsPhysical && PositionSanityCheck(true))
            {
                entprop.Position = _position;
                entprop.Velocity = _velocity;
            }

            OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation;   // DEBUG DEBUG DEBUG
            DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
                    LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);

            // remember the current and last set values
            LastEntityProperties = CurrentEntityProperties;
            CurrentEntityProperties = entprop;

            base.RequestPhysicsterseUpdate();
        }
            /*
        else
        {
            // For debugging, report the movement of children
            DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                    LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
                    entprop.Acceleration, entprop.RotationalVelocity);
        }
             */

        // The linkset implimentation might want to know about this.
        Linkset.UpdateProperties(this, true);
    }
Esempio n. 48
0
        // The physics engine says that properties have updated. Update same and inform
        // the world that things have changed.
        public override void UpdateProperties(EntityProperties entprop)
        {
            // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
            TriggerPreUpdatePropertyAction(ref entprop);

            // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop);   // DEBUG DEBUG

            // Assign directly to the local variables so the normal set actions do not happen
            _position = entprop.Position;
            _orientation = entprop.Rotation;

            bool terseUpdate = false;

            if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero)
            {
            entprop.Velocity = OMV.Vector3.Zero;
            entprop.Acceleration = OMV.Vector3.Zero;
            entprop.RotationalVelocity = OMV.Vector3.Zero;
            Velocity = RawVelocity = OMV.Vector3.Zero;
            ZeroMotion(true);
            terseUpdate = true;
            }

            // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
            //    very sensitive to velocity changes.
            if (entprop.Velocity == OMV.Vector3.Zero || (VehicleType != 0 /*&& !entprop.Velocity.ApproxEquals(RawVelocity, 0.01f)*/) ||
            !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold / 2f))
            {
            terseUpdate = true;
            RawVelocity = entprop.Velocity;
            }
            _acceleration = entprop.Acceleration;
            _rotationalVelocity = entprop.RotationalVelocity;

            // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop);   // DEBUG DEBUG

            // The sanity check can change the velocity and/or position.
            if (PositionSanityCheck(true /* inTaintTime */ ))
            {
            entprop.Position = _position;
            entprop.Velocity = RawVelocity;
            entprop.RotationalVelocity = _rotationalVelocity;
            entprop.Acceleration = _acceleration;
            }

            // 20131224 not used        OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation;   // DEBUG DEBUG DEBUG
            //DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);

            // remember the current and last set values
            LastEntityProperties = CurrentEntityProperties;
            CurrentEntityProperties = entprop;

            if (terseUpdate)
            base.RequestPhysicsterseUpdate();
            /*
            else
            {
            // For debugging, report the movement of children
            DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                    LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
                    entprop.Acceleration, entprop.RotationalVelocity);
            }
             */
        }
Esempio n. 49
0
    public void UpdateProperties(EntityProperties entprop)
    {
        UpdatedProperties changed = 0;
        if (SHOULD_DAMP_UPDATES)
        {
            // assign to the local variables so the normal set action does not happen
            // if (_position != entprop.Position)
            if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE))
            {
                _position = entprop.Position;
                // m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position);
                changed |= UpdatedProperties.Position;
            }
            // if (_orientation != entprop.Rotation)
            if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE))
            {
                _orientation = entprop.Rotation;
                // m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation);
                changed |= UpdatedProperties.Rotation;
            }
            // if (_velocity != entprop.Velocity)
            if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE))
            {
                _velocity = entprop.Velocity;
                // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity);
                changed |= UpdatedProperties.Velocity;
            }
            // if (_acceleration != entprop.Acceleration)
            if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE))
            {
                _acceleration = entprop.Acceleration;
                // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration);
                changed |= UpdatedProperties.Acceleration;
            }
            // if (_rotationalVelocity != entprop.RotationalVelocity)
            if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE))
            {
                _rotationalVelocity = entprop.RotationalVelocity;
                // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity);
                changed |= UpdatedProperties.RotationalVel;
            }
            if (changed != 0)
            {
                // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
                // Only update the position of single objects and linkset roots
                if (this._parentPrim == null)
                {
                    // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
                    base.RequestPhysicsterseUpdate();
                }
            }
        }
        else
        {
            // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.

            // Only updates only for individual prims and for the root object of a linkset.
            if (this._parentPrim == null)
            {
                // Assign to the local variables so the normal set action does not happen
                _position = entprop.Position;
                _orientation = entprop.Rotation;
                _velocity = entprop.Velocity;
                _acceleration = entprop.Acceleration;
                _rotationalVelocity = entprop.RotationalVelocity;
                // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
                base.RequestPhysicsterseUpdate();
            }
        }
    }
Esempio n. 50
0
        public BasicActor(BasicScene scene, float height, float radius,
            OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation,
            bool flying, OpenMetaverse.Vector3 initialVelocity)
        {
            _scene = scene;

            _radius = Math.Max(radius, 0.2f);

            /*
             * The capsule is defined as a position, a vertical height, and a radius. The height is the distance between the 
             * two sphere centers at the end of the capsule. In other words:
             *
             *   p = pos (returned by controller)
             *   h = height
             *   r = radius
             *
             *   p = center of capsule
             *   top sphere center = p.z + h*0.5
             *   bottom sphere center = p.z - h*0.5
             *   top capsule point = p.z + h*0.5 + r
             *   bottom capsule point = p.z - h*0.5 - r
             */
            _height = height;

            _flying = flying;

            float volume = (float)(Math.PI * Math.Pow(_radius, 2) * this.CapsuleHeight);
            _mass = CHARACTER_DENSITY * volume;

            _position = position;
            _rotation = rotation;

            DoZDepenetration();

            _lastSync = (uint)Environment.TickCount;

            _vTarget = initialVelocity;
            _velocity = initialVelocity;
            if (_vTarget != OpenMetaverse.Vector3.Zero)
            {
                //hack to continue at velocity until the controller picks up
                _lastVelocityNonZero = OpenSim.Framework.Util.GetLongTickCount() - VELOCITY_RAMPUP_TIME;
            }
        }
Esempio n. 51
0
 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
                                           Vector3 size, Quaternion rotation, bool isPhysical)
 {
     return AddPrim(position, size, rotation);
 }
Esempio n. 52
0
    public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
                       OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
            : base(parent_scene, localID, primName, "BSPrim")
    {
        // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
        _physicsActorType = (int)ActorTypes.Prim;
        _position = pos;
        _size = size;
        Scale = size;   // prims are the size the user wants them to be (different for BSCharactes).
        _orientation = rotation;
        _buoyancy = 1f;
        _velocity = OMV.Vector3.Zero;
        _rotationalVelocity = OMV.Vector3.Zero;
        BaseShape = pbs;
        _isPhysical = pisPhysical;
        _isVolumeDetect = false;

        // Someday set default attributes based on the material but, for now, we don't know the prim material yet.
        // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical);
        _density = PhysicsScene.Params.defaultDensity;
        _friction = PhysicsScene.Params.defaultFriction;
        _restitution = PhysicsScene.Params.defaultRestitution;

        _vehicle = new BSDynamics(PhysicsScene, this);            // add vehicleness

        _mass = CalculateMass();

        Linkset.Refresh(this);

        DetailLog("{0},BSPrim.constructor,call", LocalID);
        // do the actual object creation at taint time
        PhysicsScene.TaintedObject("BSPrim.create", delegate()
        {
            CreateGeomAndObject(true);

            CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr);
        });
    }
Esempio n. 53
0
 // Set all the parameters for this constraint to a fixed, non-movable constraint.
 public override void ResetLink()
 {
     // constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
     constraintType = ConstraintType.BS_FIXED_CONSTRAINT_TYPE;
     linearLimitLow = OMV.Vector3.Zero;
     linearLimitHigh = OMV.Vector3.Zero;
     angularLimitLow = OMV.Vector3.Zero;
     angularLimitHigh = OMV.Vector3.Zero;
     useFrameOffset = BSParam.LinkConstraintUseFrameOffset;
     enableTransMotor = BSParam.LinkConstraintEnableTransMotor;
     transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel;
     transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce;
     cfm = BSParam.LinkConstraintCFM;
     erp = BSParam.LinkConstraintERP;
     solverIterations = BSParam.LinkConstraintSolverIterations;
     frameInAloc = OMV.Vector3.Zero;
     frameInArot = OMV.Quaternion.Identity;
     frameInBloc = OMV.Vector3.Zero;
     frameInBrot = OMV.Quaternion.Identity;
     useLinearReferenceFrameA = true;
     springAxisEnable = new bool[6];
     springDamping = new float[6];
     springStiffness = new float[6];
     for (int ii = 0; ii < springAxisEnable.Length; ii++)
     {
         springAxisEnable[ii] = false;
         springDamping[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
         springStiffness[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
     }
     springLinearEquilibriumPoint = OMV.Vector3.Zero;
     springAngularEquilibriumPoint = OMV.Vector3.Zero;
     member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.ResetLink", member.LocalID);
 }
        // ==========================================================================
        /// <summary>
        /// Update the camera. The coordinate system from the EntityCamera is LL's
        /// (Z up). We have to convert the rotation and position to Ogre coords
        /// (Y up).
        /// </summary>
        /// <param name="cam"></param>
        // private bool haveAttachedCamera = false;
        public void UpdateCamera(CameraControl cam)
        {
            /* Historical Note: This is part of code to attach the camera to the avatar. When this was written
             * the avatar code was not in place so the actual scene node to attach the camera too is problematic.
             * Fix this when there is an avatar.
            if (!haveAttachedCamera && cam.AssociatedAgent != null && cam.AssociatedAgent.AssociatedAvatar != null) {
            m_log.Log(LogLevel.DVIEWDETAIL, "OnAgentUpdate: Attaching camera with {0}", cam.AssociatedAgent.AssociatedAvatar.Name);
            haveAttachedCamera = Ogr.AttachCamera(cam.AssociatedAgent.AssociatedAvatar.Name.Name, 1.0f, 0.0f, 1.0f, 0f, 0f, 0f, 1f);
            }
             */

            // OMV.Quaternion orient = new OMV.Quaternion(OMV.Vector3.UnitX, -Constants.PI / 2)
                    // * new OMV.Quaternion(OMV.Vector3.UnitZ, -Constants.PI / 2)
                    // * cam.Direction;
            // we need to rotate the camera 90 to make it work out in Ogre. Not sure why.
            // OMV.Quaternion orient = cam.Heading * OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitZ, -Constants.PI / 2);
            OMV.Quaternion orient = OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitZ, -Constants.PI / 2) * cam.Heading;
            // OMV.Quaternion orient = cam.Heading;
            orient.Normalize();
            m_lastCameraPosition = cam.GlobalPosition;
            m_lastCameraOrientation = orient;
            // note the conversion from LL coordinates (Z up) to Ogre coordinates (Y up)
            OMV.Vector3d pos = cam.GlobalPosition * m_sceneMagnification;
            Ogr.UpdateCameraBF(pos.X, pos.Z, -pos.Y,
            orient.W, orient.X, orient.Z, -orient.Y,
            1.0f, (float)cam.Far*m_sceneMagnification, 1.0f);

            // m_log.Log(LogLevel.DRENDERDETAIL, "UpdateCamera: Camera to p={0}, r={1}", pos, orient);
            return;
        }
 public override void VehicleRotationParam(int param, Quaternion rotation)
 {
 }
Esempio n. 56
0
    // The physics engine says that properties have updated. Update same and inform
    // the world that things have changed.
    public override void UpdateProperties(EntityProperties entprop)
    {
        // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
        TriggerPreUpdatePropertyAction(ref entprop);

        // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop);   // DEBUG DEBUG

        // Assign directly to the local variables so the normal set actions do not happen
        _position = entprop.Position;
        _orientation = entprop.Rotation;
        // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
        //    very sensitive to velocity changes.
        if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
            RawVelocity = entprop.Velocity;
        _acceleration = entprop.Acceleration;
        _rotationalVelocity = entprop.RotationalVelocity;

        // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop);   // DEBUG DEBUG

        // The sanity check can change the velocity and/or position.
        if (PositionSanityCheck(true /* inTaintTime */ ))
        {
            entprop.Position = _position;
            entprop.Velocity = RawVelocity;
            entprop.RotationalVelocity = _rotationalVelocity;
            entprop.Acceleration = _acceleration;
        }

        OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation;   // DEBUG DEBUG DEBUG
        DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);

        // remember the current and last set values
        LastEntityProperties = CurrentEntityProperties;
        CurrentEntityProperties = entprop;

        // Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims.
        base.RequestPhysicsterseUpdate();
    }
Esempio n. 57
0
 public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
                    OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
 {
     // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
     _localID = localID;
     _avName = primName;
     _scene = parent_scene;
     _position = pos;
     _size = size;
     _scale = new OMV.Vector3(1f, 1f, 1f);   // the scale will be set by CreateGeom depending on object type
     _orientation = rotation;
     _buoyancy = 1f;
     _velocity = OMV.Vector3.Zero;
     _rotationalVelocity = OMV.Vector3.Zero;
     _angularVelocity = OMV.Vector3.Zero;
     _hullKey = 0;
     _meshKey = 0;
     _pbs = pbs;
     _isPhysical = pisPhysical;
     _isVolumeDetect = false;
     _subscribedEventsMs = 0;
     _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
     _density = _scene.Params.defaultDensity; // TODO: compute based on object material
     _restitution = _scene.Params.defaultRestitution;
     _parentPrim = null;     // not a child or a parent
     _vehicle = new BSDynamics(this);    // add vehicleness
     _childrenPrims = new List<BSPrim>();
     if (_isPhysical)
         _mass = CalculateMass();
     else
         _mass = 0f;
     // do the actual object creation at taint time
     _scene.TaintedObject(delegate()
     {
         RecreateGeomAndObject();
     });
 }
Esempio n. 58
0
 internal void MetricsInit(float timeStep, 
                    OpenMetaverse.Quaternion vframe,       OpenMetaverse.Quaternion rotation, 
                    OpenMetaverse.Vector3 worldAngularVel, OpenMetaverse.Vector3 worldLinearVel,
                    OpenMetaverse.Vector3 localAngularVel, OpenMetaverse.Vector3 localLinearVel)
 {
     this.timeStep = timeStep;
     this.vframe = vframe;
     this.rotation = rotation;
     this.worldAngularVel = worldAngularVel;
     this.worldLinearVel = worldLinearVel;
     this.localAngularVel = localAngularVel;
     this.localLinearVel = localLinearVel;
 }
Esempio n. 59
0
 public BSPrim(ISceneChildEntity entity, bool isPhysical, BSScene parent_scene)
 {
     _parent_entity = entity;
     // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
     _localID = _parent_entity.LocalId;
     _avName = _parent_entity.Name;
     _scene = parent_scene;
     _position = _parent_entity.AbsolutePosition;
     _size = _parent_entity.Scale;
     _scale = new OMV.Vector3(1f, 1f, 1f);   // the scale will be set by CreateGeom depending on object type
     _orientation = _parent_entity.Rotation;
     _buoyancy = 1f;
     _velocity = OMV.Vector3.Zero;
     _rotationalVelocity = OMV.Vector3.Zero;
     _angularVelocity = OMV.Vector3.Zero;
     _hullKey = 0;
     _pbs = _parent_entity.Shape;
     _isPhysical = isPhysical;
     _isVolumeDetect = _parent_entity.VolumeDetectActive;
     _subscribedEventsMs = 0;
     _parentPrim = null;
     _vehicle = new BSDynamics(this);
     _childrenPrims = new List<BSPrim>();
     if (_isPhysical)
         _mass = CalculateMass();
     else
         _mass = 0f;
     // do the actual object creation at taint time
     _scene.TaintedObject(delegate()
     {
         RecreateGeomAndObject();
     });
 }
Esempio n. 60
0
        //
        // Main simulation entry point, called every physics frame (nominally 64x/sec).
        // This is a pipelined simulation, several physical events happen at the same time, and
        // the results of the previous physics frame feed forward into the next frame.
        //
        internal void Simulate(float timeStep, uint frameNum)
        {
            if (_props.Type == VehicleType.None) return;

            // If the vehicle's oriented bounding box is null, request it now.
            // This could end up null ayway, but the subsequent code checks for that possibility.
            if (_actor.OBBobject == null)
            {
                _actor.OBBobject = _actor.DoRequestOBB();
            }

            // Tick smoothing. Under even light loads, the timestep bobbles between 1 and 2 physics frames,
            // sufficiently often that it noticibly affects the movement timings. This smoothing cleans up the glitches.
            // This performs a weighted average of this frame's timestep and the one in the previous frame.
            timeStep = _props.Dynamics.Timestep * 0.8f +  timeStep * 0.2f;

            //handle a race condition where a physics state save happened after the vehicle type has been
            //set, but before physics got a chance to set the default properties
            if (_props.ParamsRot.Count == 0)
            {
                m_log.InfoFormat("[VehicleSimulate] race condition");
                SetVehicleDefaults(_props);
                SetVehicleDefaultActions();
            }

            // Debug params every 10ish seconds.
            if (VehicleLimits.DebugPrintParams && (frameNum % 600) == 0)
            {
                DisplayParameters();
            }

            // Grab overrides vehicle movement.
            // If the vehicle is being grabbed skip the simulation, otherwise
            // severe squirming and tossing will happen.
            if (_actor.Properties.GrabTargetTau != 0) return;

            // Metrics: both world and local angular deltaV, linear deltaV
            vframe           = _props.ParamsRot[RotationParams.VehicleReferenceFrame];
            rotation         = _actor.RotationUnsafe * vframe; // Safe from physics thread (as in this code)

            // A PhysX velocity behavior sends strong and opposite velocities when an object collides: e.g., -55,+55,=55,...
            // Per axis, when velocities are opposing, make a two-frame average to eliminate that physX jitter.

            // Angular
            if ((worldAngularVel.X * _actor.DynActorImpl.AngularVelocity.X) >= 0)
                worldAngularVel.X = _actor.DynActorImpl.AngularVelocity.X;
            else
                worldAngularVel.X  = worldAngularVel.X * 0.5f + _actor.DynActorImpl.AngularVelocity.X * 0.5f;

            if ((worldAngularVel.Y * _actor.DynActorImpl.AngularVelocity.Y) >= 0)
                worldAngularVel.Y = _actor.DynActorImpl.AngularVelocity.Y;
            else
                worldAngularVel.Y  = worldAngularVel.Y * 0.5f + _actor.DynActorImpl.AngularVelocity.Y * 0.5f;

            if ((worldAngularVel.Z * _actor.DynActorImpl.AngularVelocity.Z) >= 0)
                worldAngularVel.Z = _actor.DynActorImpl.AngularVelocity.Z;
            else
                worldAngularVel.Z  = worldAngularVel.Z * 0.5f + _actor.DynActorImpl.AngularVelocity.Z * 0.5f;

            //Linear
            if ((worldLinearVel.X * _actor.DynActorImpl.LinearVelocity.X) >= 0)
                worldLinearVel.X = _actor.DynActorImpl.LinearVelocity.X;
            else
                worldLinearVel.X  = worldLinearVel.X * 0.5f + _actor.DynActorImpl.LinearVelocity.X * 0.5f;

            if ((worldLinearVel.Y * _actor.DynActorImpl.LinearVelocity.Y) >= 0)
                worldLinearVel.Y = _actor.DynActorImpl.LinearVelocity.Y;
            else
                worldLinearVel.Y  = worldLinearVel.Y * 0.5f + _actor.DynActorImpl.LinearVelocity.Y * 0.5f;

            if ((worldLinearVel.Z * _actor.DynActorImpl.LinearVelocity.Z) >= 0)
                worldLinearVel.Z = _actor.DynActorImpl.LinearVelocity.Z;
            else
                worldLinearVel.Z  = worldLinearVel.Z * 0.5f + _actor.DynActorImpl.LinearVelocity.Z * 0.5f;

            localAngularVel  = worldAngularVel * OpenMetaverse.Quaternion.Inverse(rotation);
            localLinearVel   = worldLinearVel * OpenMetaverse.Quaternion.Inverse(rotation);

            //m_log.DebugFormat("[Vehicle Simulate] lvel={0} lspd={1} step={2} frame={3}", localLinearVel, localLinearVel, timeStep, frameNum);

            // Region change check. If the region has changed, the stall detection logic has to be reset one
            // frame, and various vehicle actions (hover, buoyancy, etc.) have to be reestablished
            // Note that the local region field gets cleared on crossings since the object is actually getting recreated.
            //
            if (_scene.RegionID != _regionId)
            {
                if (VehicleLimits.DebugRegionChange)
                    m_log.InfoFormat("[Vehicle Simulate] changed region: new={0}", _scene.RegionID);

                _regionId = _scene.RegionID;

                // Do this to prevent a phantom stall-detection at the crossing
                // object rez or object made physical.
                _props.Dynamics.LastAccessTOD = DateTime.Now;
                SetVehicleDefaultActions();
            }

            // Reset motors if the time between calls is greater than one second. 
            // This handles cases when the vehicle has been edited or rezzed.
            // It prevents the vehicle from taking off using stale forces.
            float actualstep = _motor.CheckResetMotors(timeStep);
            _motor.TorqueInit();
            _motor.ClearLinearMotorStalled();
            _props.Dynamics.Timestep = timeStep;

            // -------------------------------------------------------------------------------------------
            // Mitigate a PhysX velocity spiking bug.
            // This has the side effect of changing the local velocities.
            //
            if (VehicleLimits.DoSpikeDetection)
            {
                MitigatePhysxSpiking(actualstep);
            }

            // Initialize the motor with the entry metrics.
            _motor.MetricsInit(timeStep, vframe, rotation, worldAngularVel, worldLinearVel, localAngularVel, localLinearVel);

            // -------------------------------------------------------------------------------------------
            // Camera based movement:
            //
            SimulateCameraBasedMotorInput(timeStep, frameNum);

            // -------------------------------------------------------------------------------------------
            // Build the wind direction data for this moment.
            //
            BuildWindData(timeStep, frameNum);          

            // -------------------------------------------------------------------------------------------
            // Ground penetration fix. A bug in PhysX permits a vehicle to punch through
            // the ground plane if sufficient force is present. When that happens, apply a very
            // strong upward force. This also fixes the case where someone edits/moves a physical vehicle below
            // ground, which can grief the region.
            //
            float gnd = _motor.GetGroundHeightBeneathVehicle();

            if (_actor.Position.Z - gnd < VehicleLimits.MaxGroundPenetration)
            {
                OpenMetaverse.Vector3 zforce = OpenMetaverse.Vector3.Zero;
                zforce.Z = 1.0f + Math.Abs(localLinearVel.Z * 3.0f);
                _actor.DynActorImpl.AddForce(PhysUtil.OmvVectorToPhysx(zforce), PhysX.ForceMode.VelocityChange, true);
            }

            // -------------------------------------------------------------------------------------------
            // Ground drag for boats - boats have differential friction.
            //
            SimulateBoatGroundDrag(timeStep);

            // -------------------------------------------------------------------------------------------
            // Angular deflection - turning toward the direction of movement.
            //
            if (VehicleLimits.DoAngularDeflection)
            {
                SimulateAngularDeflection(timeStep);
            }

            // -------------------------------------------------------------------------------------------
            // Linear deflection - changing direction of movement toward forward axis.
            //
            if (VehicleLimits.DoLinearDeflection)
            {
                SimulateLinearDeflection(timeStep);
            }

            // -------------------------------------------------------------------------------------------
            // Sled movement - Motors are usually inoperative but a sled needs force assist on downslopes.
            //
            if (_props.Type == VehicleType.Sled)
            {
                SimulateSledMovement(timeStep);
            }

            // -------------------------------------------------------------------------------------------
            // Vertical attractor - Pointing  the local Z axis to the sky in the designated timescale.
            // Banking - induce yaw rotation (about the world z-axis) proportional to angle of roll (about the local x-axis).
            //
            OpenMetaverse.Vector3 attractionForces = OpenMetaverse.Vector3.Zero;
            if (VehicleLimits.DoVerticalAttractor)
            {
                float angle;
                bool  inverted;

                SimulateVerticalAttractor(timeStep, frameNum, out attractionForces, out angle, out inverted);
                SimulateBankingToYaw(timeStep, angle, inverted);
            }

            // -------------------------------------------------------------------------------------------
            // Wind forces
            //
            if ((_props.Flags & VehicleFlags.ReactToWind) != 0)
            {
                SimulateWindForces(timeStep);
            }

            // -------------------------------------------------------------------------------------------
            // Motors
            //
            if (VehicleLimits.DoMotors)
            {
                _motor.Simulate(timeStep, frameNum, attractionForces);
            }

            // -------------------------------------------------------------------------------------------
            // Angular Friction - apply inverse rotational velocity along each axis based on the friction timescales.
            //
            if (VehicleLimits.DoAngularFriction)
            {
                SimulateAngularFriction(timeStep);
            }

            // -------------------------------------------------------------------------------------------
            // Linear Friction - apply inverse velocity along each axis based on the friction timescales.
            //
            if (VehicleLimits.DoLinearFriction)
            {
                SimulateLinearFriction(timeStep);
            }

            // Apply the accumulated torque
            _motor.TorqueFini();

            // Save parameters to be fed forward and used in the next frame.
            _props.Dynamics.LastPosition         = _actor.Position;
            _props.Dynamics.Timestep             = timeStep;
            _props.Dynamics.LocalLinearVelocity  = localLinearVel;
            _props.Dynamics.LocalAngularVelocity = localAngularVel;
        }