Ejemplo n.º 1
0
 public override void Clear()
 {
     Index = 0;
     OffsetFromRoot = OMV.Vector3.Zero;
     OffsetFromCenterOfMass = OMV.Vector3.Zero;
     OffsetRot = OMV.Quaternion.Identity;
 }
Ejemplo n.º 2
0
 public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r)
 {
     Index = indx;
     OffsetFromRoot = p;
     OffsetFromCenterOfMass = p;
     OffsetRot = r;
 }
Ejemplo n.º 3
0
    protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
    {
        PhysicsScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        Name = name;    // PhysicsActor also has the name of the object. Someday consolidate.
        TypeName = typeName;

        // Initialize variables kept in base.
        GravModifier = 1.0f;
        Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);

        // We don't have any physical representation yet.
        PhysBody = new BulletBody(localID);
        PhysShape = new BulletShape();

        LastAssetBuildFailed = false;

        // Default material type. Also sets Friction, Restitution and Density.
        SetMaterial((int)MaterialAttributes.Material.Wood);

        CollisionCollection = new CollisionEventUpdate();
        CollisionsLastTick = CollisionCollection;
        SubscribedEventsMs = 0;
        CollidingStep = 0;
        CollidingGroundStep = 0;
        CollisionAccumulation = 0;
        ColliderIsMoving = false;
        CollisionScore = 0;

        // All axis free.
        LockedAxis = LockedAxisFree;
    }
Ejemplo n.º 4
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);
 }
Ejemplo n.º 5
0
 // Clears any center-of-mass displacement introduced by linksets, etc.
 // Does not clear the displacement set by the user.
 public void ClearDisplacement()
 {
     if (UserSetCenterOfMassDisplacement.HasValue)
         PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement;
     else
         PositionDisplacement = OMV.Vector3.Zero;
 }
 /// <summary>
 /// Create the animation. The passed animation block is expected
 /// to contain a defintion of a fixed rotation. If not, bad things will happen.
 /// </summary>
 /// <param name="anim">The IAnimation block with the info.</param>
 /// <param name="id">localID to lookup the prim in the RegionRenderInfo.renderPrimList</param>
 public AnimatPosition(OMV.Vector3 newPos, float durationSeconds, RegionRenderInfo rri, uint id)
     : base(AnimatBase.AnimatTypePosition)
 {
     m_infoID = id;
     RenderablePrim rp = rri.renderPrimList[id];
     m_origionalPosition = rp.Position;
     m_targetPosition = newPos;
     m_durationSeconds = durationSeconds;
     m_distanceVector = m_targetPosition - m_origionalPosition;
     m_progress = 0f;
 }
Ejemplo n.º 7
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;
    }
Ejemplo n.º 8
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;
        }
 /// <summary>
 /// Create the animation. The passed animation block is expected
 /// to contain a defintion of a fixed rotation. If not, bad things will happen.
 /// </summary>
 /// <param name="anim">The IAnimation block with the info.</param>
 /// <param name="id">localID to lookup the prim in the RegionRenderInfo.renderPrimList</param>
 public AnimatFixedRotation(IAnimation anim, uint id)
     : base(AnimatBase.AnimatTypeFixedRotation)
 {
     m_infoID = id;
     if (anim.DoStaticRotation) {
         m_rotationsPerSecond = anim.StaticRotationRotPerSec;
         m_rotationAxis = anim.StaticRotationAxis;
     }
     else {
         // shouldn't get here
         m_rotationsPerSecond = 1;
         m_rotationAxis = OMV.Vector3.UnitX;
     }
 }
Ejemplo n.º 10
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;
        }
Ejemplo n.º 11
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();
 }
Ejemplo n.º 12
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;
    }
Ejemplo n.º 13
0
        // Set motion values to zero.
        // Do it to the properties so the values get set in the physics engine.
        // Push the setting of the values to the viewer.
        // Called at taint time!
        public override void ZeroMotion(bool inTaintTime)
        {
            RawVelocity         = OMV.Vector3.Zero;
            _acceleration       = OMV.Vector3.Zero;
            _rotationalVelocity = OMV.Vector3.Zero;

            // Zero some other properties directly into the physics engine
            PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
            {
                if (PhysBody.HasPhysicalBody)
                {
                    PhysicsScene.PE.ClearAllForces(PhysBody);
                }
            });
        }
Ejemplo n.º 14
0
        public override void ZeroAngularMotion(bool inTaintTime)
        {
            _rotationalVelocity = OMV.Vector3.Zero;

            PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
            {
                if (PhysBody.HasPhysicalBody)
                {
                    PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero);
                    PhysScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero);
                    // The next also get rid of applied linear force but the linear velocity is untouched.
                    PhysScene.PE.ClearForces(PhysBody);
                }
            });
        }
 void SetVelocityAndTargetInternal(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime,
                                   int targetValueDecayTimeScale)
 {
     m_physicsScene.TaintedObject(inTaintTime, m_controllingPrim.LocalID, "BSActorAvatarMove.setVelocityAndTarget", delegate()
     {
         if (m_velocityMotor != null)
         {
             m_velocityMotor.Reset();
             m_velocityMotor.SetTarget(targ);
             m_velocityMotor.SetCurrent(vel);
             m_velocityMotor.TargetValueDecayTimeScale = targetValueDecayTimeScale;
             m_velocityMotor.Enabled = true;
         }
     });
 }
 // Set all the parameters for this constraint to a fixed, non-movable constraint.
 public void ResetToFixedConstraint()
 {
     constraintType = ConstraintType.D6_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;
 }
Ejemplo n.º 17
0
        private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
        {
            OMV.Vector3 newScale;

            // Bullet's capsule total height is the "passed height + radius * 2";
            // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1)
            // The number we pass in for 'scaling' is the multiplier to get that base
            //     shape to be the size desired.
            // So, when creating the scale for the avatar height, we take the passed height
            //     (size.Z) and remove the caps.
            // An oddity of the Bullet capsule implementation is that it presumes the Y
            //     dimension is the radius of the capsule. Even though some of the code allows
            //     for a asymmetrical capsule, other parts of the code presume it is cylindrical.

            // Scale is multiplier of radius with one of "0.5"
            newScale.X = size.X / 2f;
            newScale.Y = size.Y / 2f;

            float heightAdjust = BSParam.AvatarHeightMidFudge;

            if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
            {
                // An avatar is between 1.61 and 2.12 meters. Midpoint is 1.87m.
                // The "times 4" relies on the fact that the difference from the midpoint to the extremes is exactly 0.25
                float midHeightOffset = size.Z - 1.87f;
                if (midHeightOffset < 0f)
                {
                    // Small avatar. Add the adjustment based on the distance from midheight
                    heightAdjust += -1f * midHeightOffset * 4f * BSParam.AvatarHeightLowFudge;
                }
                else
                {
                    // Large avatar. Add the adjustment based on the distance from midheight
                    heightAdjust += midHeightOffset * 4f * BSParam.AvatarHeightHighFudge;
                }
            }
            // The total scale height is the central cylindar plus the caps on the two ends.
            newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f;
            // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale);

            // If smaller than the endcaps, just fake like we're almost that small
            if (newScale.Z < 0)
            {
                newScale.Z = 0.1f;
            }

            return(newScale);
        }
Ejemplo n.º 18
0
        public OMV.Vector3 ParamVector3(string key)
        {
            OMV.Vector3 ret     = OMV.Vector3.Zero;
            string      lkey    = key.ToLower();
            bool        success = false;

            lock (m_params) {
                try {
                    if (m_runtimeValues.ContainsKey(key))
                    {
                        if (OMV.Vector3.TryParse(m_runtimeValues[lkey](lkey).AsString(), out ret))
                        {
                            success = true;
                        }
                    }
                    else
                    {
                        if (m_params.ContainsKey(lkey))
                        {
                            if (OMV.Vector3.TryParse(m_params[lkey].AsString(), out ret))
                            {
                                success = true;
                            }
                        }
                    }
                }
                catch {
                    success = false;
                }
            }
            if (!success)
            {
                switch (ParamErrorMethod)
                {
                case paramErrorType.eDefaultValue:
                    ret = OMV.Vector3.Zero;
                    break;

                case paramErrorType.eException:
                    throw new ParameterException("Float param '" + key + "' not found");

                case paramErrorType.eNullValue:
                    ret = OMV.Vector3.Zero;
                    break;
                }
            }
            return(ret);
        }
Ejemplo n.º 19
0
        public override void UpdateProperties(EntityProperties entprop)
        {
            // Undo any center-of-mass displacement that might have been done.
            if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity)
            {
                // Correct for any rotation around the center-of-mass
                // TODO!!!

                OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation);
                DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos);
                entprop.Position = displacedPos;
                // entprop.Rotation = something;
            }

            base.UpdateProperties(entprop);
        }
        private void FixCoordinateSystem(ref Vector3 position, ref Quaternion rotation)
        {
            //center the object
            var centerPos = position + _centerAdj;

            //change coordinate system
            centerPos.X = -centerPos.X;
            //re-translate the object
            position = centerPos - _centerAdj;

            //compensate Y/Z flip
            var fixRot = Quaternion.CreateFromAxisAngle(1.0f, 0.0f, 0.0f, -(float)Math.PI / 2f);

            position = position * fixRot;
            rotation = fixRot * rotation;
        }
Ejemplo n.º 21
0
        private void ComputeAvatarScale(OMV.Vector3 size)
        {
            OMV.Vector3 newScale = size;
            // newScale.X = PhysicsScene.Params.avatarCapsuleWidth;
            // newScale.Y = PhysicsScene.Params.avatarCapsuleDepth;

            // From the total height, remove the capsule half spheres that are at each end
            // The 1.15f came from ODE. Not sure what this factors in.
            // newScale.Z = (size.Z * 1.15f) - (newScale.X + newScale.Y);

            // The total scale height is the central cylindar plus the caps on the two ends.
            newScale.Z = size.Z + (Math.Min(size.X, size.Y) * 2f);

            // Convert diameters to radii and height to half height -- the way Bullet expects it.
            Scale = newScale / 2f;
        }
Ejemplo n.º 22
0
        public override bool Collide(uint collidingWith, BSPhysObject collidee,
                                     OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
        {
            // prims in the same linkset cannot collide with each other
            BSPrimLinkable convCollidee = collidee as BSPrimLinkable;

            if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID))
            {
                return(false);
            }

            // TODO: handle collisions of other objects with with children of linkset.
            //    This is a problem for LinksetCompound since the children are packed into the root.

            return(base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth));
        }
Ejemplo n.º 23
0
 // Usually called when target velocity changes to set the current velocity and the target
 //     into the movement motor.
 public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
 {
     m_physicsScene.TaintedObject(inTaintTime, m_controllingPrim.LocalID, "BSActorAvatarMove.setVelocityAndTarget", delegate()
     {
         if (m_velocityMotor != null)
         {
             m_velocityMotor.Reset();
             m_velocityMotor.SetTarget(targ);
             m_velocityMotor.SetCurrent(vel);
             m_velocityMotor.Enabled = true;
             m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,SetVelocityAndTarget,vel={1}, targ={2}",
                                      m_controllingPrim.LocalID, vel, targ);
             m_waitingForLowVelocityForStationary = 0;
         }
     });
 }
 /// <summary>
 /// Create the animation. The passed animation block is expected
 /// to contain a defintion of a fixed rotation. If not, bad things will happen.
 /// </summary>
 /// <param name="anim">The IAnimation block with the info.</param>
 /// <param name="id">localID to lookup the prim in the RegionRenderInfo.renderPrimList</param>
 public AnimatFixedRotation(IAnimation anim, uint id)
     : base(AnimatBase.AnimatTypeFixedRotation)
 {
     m_infoID = id;
     if (anim.DoStaticRotation)
     {
         m_rotationsPerSecond = anim.StaticRotationRotPerSec;
         m_rotationAxis       = anim.StaticRotationAxis;
     }
     else
     {
         // shouldn't get here
         m_rotationsPerSecond = 1;
         m_rotationAxis       = OMV.Vector3.UnitX;
     }
 }
Ejemplo n.º 25
0
 public virtual void ComputeAndSetLocalInertia(OMV.Vector3 inertiaFactor, float linksetMass)
 {
     ForEachMember((member) =>
     {
         if (member.PhysBody.HasPhysicalBody)
         {
             OMV.Vector3 inertia = PhysicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, linksetMass);
             member.Inertia      = inertia * inertiaFactor;
             PhysicsScene.PE.SetMassProps(member.PhysBody, linksetMass, member.Inertia);
             PhysicsScene.PE.UpdateInertiaTensor(member.PhysBody);
             DetailLog("{0},BSLinkset.ComputeAndSetLocalInertia,m.mass={1}, inertia={2}", member.LocalID, linksetMass, member.Inertia);
         }
         return(false);      // 'false' says to continue looping
     }
                   );
 }
Ejemplo n.º 26
0
    public void Update()
    {
        if (setClearFlags == false)
        {
            Camera.main.clearFlags = CameraClearFlags.Skybox;
            setClearFlags          = true;
        }

        OpenMetaverse.Vector3 camPos = Client.Self.SimPosition +
                                       new OpenMetaverse.Vector3(-4, 0, 1) * Client.Self.Movement.BodyRotation;
        Camera.main.transform.position = new UnityEngine.Vector3(camPos.X, camPos.Y, -camPos.Z);                //watch out the negated z

        OpenMetaverse.Vector3 focalPos = Client.Self.SimPosition +
                                         new OpenMetaverse.Vector3(5, 0, 0) * Client.Self.Movement.BodyRotation;
        Camera.main.transform.LookAt(new UnityEngine.Vector3(focalPos.X, focalPos.Y, -focalPos.Z), UnityEngine.Vector3.back);        //watch out the negated z
    }
Ejemplo n.º 27
0
        // Walk through all the vertices and scale the included meshes
        // Returns 'true' of the mesh was changed.
        public static bool ScaleMeshes(MeshInfo meshInfo, OMV.Vector3 scale)
        {
            bool ret = false;

            if (scale.X != 1.0 || scale.Y != 1.0 || scale.Z != 1.0)
            {
                ret = true;
                for (int ii = 0; ii < meshInfo.vertexs.Count; ii++)
                {
                    OMVR.Vertex aVert = meshInfo.vertexs[ii];
                    aVert.Position      *= scale;
                    meshInfo.vertexs[ii] = aVert;
                }
            }
            return(ret);
        }
Ejemplo n.º 28
0
        public LSL_List modInvokeL(string fname, params object[] parms)
        {
            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 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));
        }
Ejemplo n.º 29
0
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            IsInitialized = false;

            PhysScene      = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            Name           = name; // PhysicsActor also has the name of the object. Someday consolidate.
            TypeName       = typeName;

            // Oddity if object is destroyed and recreated very quickly it could still have the old body.
            if (!PhysBody.HasPhysicalBody)
            {
                PhysBody = new BulletBody(localID);
            }

            // Clean out anything that might be in the physical actor list.
            // Again, a workaround for destroying and recreating an object very quickly.
            PhysicalActors.Dispose();

            UserSetCenterOfMassDisplacement = null;

            PrimAssetState = PrimAssetCondition.Unknown;

            // Initialize variables kept in base.
            // Beware that these cause taints to be queued whch can cause race conditions on startup.
            GravModifier = 1.0f;
            Gravity      = new OMV.Vector3(0f, 0f, BSParam.Gravity);
            HoverActive  = false;

            // Default material type. Also sets Friction, Restitution and Density.
            SetMaterial((int)MaterialAttributes.Material.Wood);

            CollisionsLastTickStep = -1;

            SubscribedEventsMs = 0;
            // Crazy values that will never be true
            CollidingStep         = BSScene.NotASimulationStep;
            CollidingGroundStep   = BSScene.NotASimulationStep;
            CollisionAccumulation = BSScene.NotASimulationStep;
            ColliderIsMoving      = false;
            CollisionScore        = 0;

            // All axis free.
            LockedLinearAxis  = LockedAxisFree;
            LockedAngularAxis = LockedAxisFree;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Determines whether a collision is valid, and updates appropriate
        /// collision flags.
        /// </summary>
        /// <param name="colliderID">The unique identifier of the object that
        /// is colliding</param>
        /// <param name="collider">The object that is colliding</param>
        /// <param name="contactPoint">The point at which contact was
        /// made</param>
        /// <param name="contactNormal">The normal of the contact point</param>
        /// <param name="penetrationDepth">How far one collider has penetrated
        /// the other</param>
        /// <returns>Whether the collision is valid</returns>
        public virtual bool Collide(uint colliderID,
                                    RemotePhysicsObject collider, OpenMetaverse.Vector3 contactPoint,
                                    OpenMetaverse.Vector3 contactNormal, float penetrationDepth)
        {
            lock (m_collisionStepLock)
            {
                // Update the step at which a collision has occurred
                LastCollisionStep = ParentScene.CurrentSimulationStep;

                // Check to see if this is a collision with terrain
                if (colliderID <= ParentScene.TerrainID)
                {
                    GroundCollisionStep = ParentScene.CurrentSimulationStep;
                }
                else
                {
                    ObjectCollisionStep = ParentScene.CurrentSimulationStep;
                }
            }

            // Update the number of collisions for this object
            NumCollisions++;

            // Check to see if something is subscribed to events from
            // this object
            if (SubscribedEvents())
            {
                // Add this collision to the collection of collisions to be sent
                // back to the simulator at the next update, in a
                // thread-safe manner
                lock (Collisions)
                {
                    Collisions.AddCollider(colliderID,
                                           new ContactPoint(contactPoint, contactNormal,
                                                            penetrationDepth));
                }

                // Indicate that the collision has been successfully processed
                return(true);
            }
            else
            {
                // Indicate that the collision wasn't processed, since there are
                // no subscribers to this object
                return(false);
            }
        }
Ejemplo n.º 31
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;
        _appliedVelocity = OMV.Vector3.Zero;
        _buoyancy = ComputeBuoyancyFromFlying(isFlying);
        _currentFriction = PhysicsScene.Params.avatarStandingFriction;
        _avatarDensity = PhysicsScene.Params.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, MassRaw);

        ShapeData shapeData = new ShapeData();
        shapeData.ID = LocalID;
        shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
        shapeData.Position = _position;
        shapeData.Rotation = _orientation;
        shapeData.Velocity = _velocity;
        shapeData.Size = Scale; // capsule is a native shape but scale is not just <1,1,1>
        shapeData.Scale = Scale;
        shapeData.Mass = _mass;
        shapeData.Buoyancy = _buoyancy;
        shapeData.Static = ShapeData.numericFalse;
        shapeData.Friction = PhysicsScene.Params.avatarStandingFriction;
        shapeData.Restitution = PhysicsScene.Params.avatarRestitution;

        // do actual create at taint time
        PhysicsScene.TaintedObject("BSCharacter.create", delegate()
        {
            DetailLog("{0},BSCharacter.create,taint", LocalID);
            // New body and shape into BSBody and BSShape
            PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null);

            SetPhysicalProperties();
        });
        return;
    }
Ejemplo n.º 32
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);
            _currentFriction = BSParam.AvatarStandingFriction;
            _avatarDensity   = BSParam.AvatarDensity;

            // 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, _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;
        }
Ejemplo n.º 33
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;

            DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                      LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
        }
Ejemplo n.º 34
0
        public BSCharacter(
            uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, float footOffset, bool isFlying)

            : base(parent_scene, localID, avName, "BSCharacter")
        {
            _physicsActorType = (int)ActorTypes.Agent;
            RawPosition       = pos;

            _flying        = isFlying;
            RawOrientation = OMV.Quaternion.Identity;
            RawVelocity    = vel;
            _buoyancy      = ComputeBuoyancyFromFlying(isFlying);
            Friction       = BSParam.AvatarStandingFriction;
            Density        = BSParam.AvatarDensity;
            _isPhysical    = true;

            _footOffset = footOffset;
            // Adjustments for zero X and Y made in Size()
            // This also computes avatar scale, volume, and mass
            SetAvatarSize(size, footOffset, true /* initializing */);

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

            // do actual creation in taint time
            PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
            {
                DetailLog("{0},BSCharacter.create,taint", LocalID);

                // New body and shape into PhysBody and PhysShape
                PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this);

                // 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(PhysScene, this, AvatarMoveActorName);
                PhysicalActors.Add(AvatarMoveActorName, m_moveActor);

                SetPhysicalProperties();

                IsInitialized = true;
            });
            return;
        }
Ejemplo n.º 35
0
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            IsInitialized = false;

            PhysScene      = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            Name           = name; // PhysicsActor also has the name of the object. Someday consolidate.
            TypeName       = typeName;

            // The collection of things that push me around
            PhysicalActors = new BSActorCollection(PhysScene);

            // Initialize variables kept in base.
            GravModifier = 1.0f;
            Gravity      = new OMV.Vector3(0f, 0f, BSParam.Gravity);
            HoverActive  = false;

            // We don't have any physical representation yet.
            PhysBody  = new BulletBody(localID);
            PhysShape = new BSShapeNull();

            UserSetCenterOfMassDisplacement = null;

            PrimAssetState = PrimAssetCondition.Unknown;

            // Default material type. Also sets Friction, Restitution and Density.
            SetMaterial((int)MaterialAttributes.Material.Wood);

            CollisionCollection    = new CollisionEventUpdate();
            CollisionsLastReported = CollisionCollection;
            CollisionsLastTick     = new CollisionEventUpdate();
            CollisionsLastTickStep = -1;

            SubscribedEventsMs = 0;
            // Crazy values that will never be true
            CollidingStep         = BSScene.NotASimulationStep;
            CollidingGroundStep   = BSScene.NotASimulationStep;
            CollisionAccumulation = BSScene.NotASimulationStep;
            ColliderIsMoving      = false;
            CollisionScore        = 0;

            // All axis free.
            LockedLinearAxis  = LockedAxisFree;
            LockedAngularAxis = LockedAxisFree;
        }
Ejemplo n.º 36
0
    public void Set(float x, float y, float z)
    {
        if (float.IsInfinity(x) || float.IsNaN(x))
        {
            x = 0f;
        }
        if (float.IsInfinity(y) || float.IsNaN(y))
        {
            y = 0f;
        }
        if (float.IsInfinity(z) || float.IsNaN(z))
        {
            z = 0f;
        }

        _impl = new Vector3(x, y, z);
    }
Ejemplo n.º 37
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)
        {
            Linkset = BSLinkset.Factory(PhysicsScene, this);

            PhysicsScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
            {
                base.SetMaterial(material);
                base.Friction          = friction;
                base.Restitution       = restitution;
                base.GravityMultiplier = gravityMultiplier;
                base.Density           = density;
                Linkset.Refresh(this);
            });
        }
Ejemplo n.º 38
0
        // A version of the sanity check that also makes sure a new position value is
        //    pushed back to the physics engine. This routine would be used by anyone
        //    who is not already pushing the value.
        private bool PositionSanityCheck(bool inTaintTime)
        {
            bool ret = false;

            if (PositionSanityCheck())
            {
                // The new position value must be pushed into the physics engine but we can't
                //    just assign to "Position" because of potential call loops.
                PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.PositionSanityCheck", delegate()
                {
                    DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
                    ForcePosition = RawPosition;
                });
                ret = true;
            }
            return(ret);
        }
Ejemplo n.º 39
0
        // Usually called when target velocity changes to set the current velocity and the target
        //     into the movement motor.
        public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
        {
            m_physicsScene.TaintedObject(inTaintTime, m_controllingPrim.LocalID, "BSActorAvatarMove.setVelocityAndTarget", delegate()
            {
                if (m_velocityMotor != null)
                {
//                    if (targ == OMV.Vector3.Zero)
//                        Util.PrintCallStack();
//
//                    Console.WriteLine("SetVelocityAndTarget, {0} {1}", vel, targ);
                    m_velocityMotor.Reset();
                    m_velocityMotor.SetTarget(targ);
                    m_velocityMotor.SetCurrent(vel);
                    m_velocityMotor.Enabled = true;
                }
            });
        }
Ejemplo n.º 40
0
        // Decide if the character is colliding with a low object and compute a force to pop the
        //    avatar up so it can walk up and over the low objects.
        private OMV.Vector3 WalkUpStairs()
        {
            OMV.Vector3 ret = OMV.Vector3.Zero;

            // This test is done if moving forward, not flying and is colliding with something.
            if (m_controllingPrim.IsColliding && !m_controllingPrim.Flying && m_controllingPrim.TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
            {
                // The range near the character's feet where we will consider stairs
                float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f;
                float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;

                // Look for a collision point that is near the character's feet and is oriented the same as the charactor is
                foreach (KeyValuePair <uint, ContactPoint> kvp in m_controllingPrim.CollisionsLastTick.GetCollisionEvents())
                {
                    // Don't care about collisions with the terrain
                    if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID)
                    {
                        OMV.Vector3 touchPosition = kvp.Value.Position;

                        if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
                        {
                            // This contact is within the 'near the feet' range.
                            // The normal should be our contact point to the object so it is pointing away
                            //    thus the difference between our facing orientation and the normal should be small.
                            OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
                            OMV.Vector3 touchNormal     = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
                            float       diff            = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
                            if (diff < BSParam.AvatarStepApproachFactor)
                            {
                                // Found the stairs contact point. Push up a little to raise the character.
                                float upForce = (touchPosition.Z - nearFeetHeightMin) * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor;
                                ret = new OMV.Vector3(0f, 0f, upForce);

                                // Also move the avatar up for the new height
                                OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
                                m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
                            }
                            m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
                                                     m_controllingPrim.LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
                        }
                    }
                }
            }

            return(ret);
        }
Ejemplo n.º 41
0
    protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
    {
        IsInitialized = false;

        PhysScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        Name = name;    // PhysicsActor also has the name of the object. Someday consolidate.
        TypeName = typeName;

        // The collection of things that push me around
        PhysicalActors = new BSActorCollection(PhysScene);

        // Initialize variables kept in base.
        GravModifier = 1.0f;
        Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
        HoverActive = false;

        // We don't have any physical representation yet.
        PhysBody = new BulletBody(localID);
        PhysShape = new BSShapeNull();

        UserSetCenterOfMassDisplacement = null;

        PrimAssetState = PrimAssetCondition.Unknown;

        // Default material type. Also sets Friction, Restitution and Density.
        SetMaterial((int)MaterialAttributes.Material.Wood);

        CollisionCollection = new CollisionEventUpdate();
        CollisionsLastReported = CollisionCollection;
        CollisionsLastTick = new CollisionEventUpdate();
        CollisionsLastTickStep = -1;

        SubscribedEventsMs = 0;
        // Crazy values that will never be true
        CollidingStep = BSScene.NotASimulationStep;
        CollidingGroundStep = BSScene.NotASimulationStep;
        CollisionAccumulation = BSScene.NotASimulationStep;
        ColliderIsMoving = false;
        CollisionScore = 0;

        // All axis free.
        LockedLinearAxis = LockedAxisFree;
        LockedAngularAxis = LockedAxisFree;
    }
Ejemplo n.º 42
0
 // tell the renderer about the camera position
 public void UpdateCamera(CameraControl cam)
 {
     if (m_focusRegion != null)
     {
         OMV.Vector3 newPos = new OMV.Vector3();
         newPos.X = (float)(cam.GlobalPosition.X - m_focusRegion.GlobalPosition.X);
         newPos.Y = (float)(cam.GlobalPosition.Y - m_focusRegion.GlobalPosition.Y);
         // another kludge camera offset. Pairs with position kludge in Viewer.
         newPos.Z = (float)(cam.GlobalPosition.Z - m_focusRegion.GlobalPosition.Z) + 10f;
         m_log.Log(LogLevel.DRENDERDETAIL, "UpdateCamera: g={0}, f={1}, n={2}",
                   cam.GlobalPosition.ToString(), m_focusRegion.GlobalPosition.ToString(), newPos.ToString());
         Camera.Position = newPos;
         OMV.Vector3 dir = new OMV.Vector3(1f, 0f, 0f);
         Camera.FocalPoint = (dir * cam.Heading) + Camera.Position;
     }
     return;
 }
Ejemplo n.º 43
0
        public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
                                    OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
        {
            bool ret = false;

            // The following lines make IsColliding(), CollidingGround() and CollidingObj work
            CollidingStep = PhysScene.SimulationStep;
            if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID)
            {
                CollidingGroundStep = PhysScene.SimulationStep;
            }
            else
            {
                CollidingObjectStep = PhysScene.SimulationStep;
            }

            CollisionAccumulation++;

            // For movement tests, remember if we are colliding with an object that is moving.
            ColliderIsMoving       = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
            ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;

            // Make a collection of the collisions that happened the last simulation tick.
            // This is different than the collection created for sending up to the simulator as it is cleared every tick.
            if (CollisionsLastTickStep != PhysScene.SimulationStep)
            {
                CollisionsLastTick     = new CollisionEventUpdate();
                CollisionsLastTickStep = PhysScene.SimulationStep;
            }
            CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));

            // If someone has subscribed for collision events log the collision so it will be reported up
            if (SubscribedEvents())
            {
                lock (PhysScene.CollisionLock)
                {
                    CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
                }
                DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
                          LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);

                ret = true;
            }
            return(ret);
        }
Ejemplo n.º 44
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;
            }
        }
Ejemplo 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)
        {
            _position           = entprop.Position;
            _orientation        = entprop.Rotation;
            _velocity           = entprop.Velocity;
            _acceleration       = entprop.Acceleration;
            _rotationalVelocity = entprop.RotationalVelocity;
            // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
            // base.RequestPhysicsterseUpdate();

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

            float heightHere = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug

            DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
                      LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
        }
Ejemplo n.º 46
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);
        _currentFriction = BSParam.AvatarStandingFriction;
        _avatarDensity = BSParam.AvatarDensity;

        // 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, _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;
    }
Ejemplo n.º 47
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;
            });
        }
        public LLRegionContext(RegionContextBase rcontext, AssetContextBase acontext, 
                        LLTerrainInfo tinfo, OMV.Simulator sim)
            : base(rcontext, acontext)
        {
            m_terrainInfo = tinfo;

            // until we have a better protocol, we know the sims are a fixed size
            m_size = new OMV.Vector3(256f, 256f, 8000f);

            // believe it or not the world coordinates of a sim are hidden in the handle
            uint x, y;
            OMV.Utils.LongToUInts(sim.Handle, out x, out y);
            m_worldBase = new OMV.Vector3d((double)x, (double)y, 0d);

            m_simulator = sim;

            // this should be more general as "GRID/SIM"
            m_name = new EntityName(sim.Name);

            // a cache of requested localIDs so we don't ask too often
            m_recentLocalIDRequests = new Dictionary<uint, int>();

            this.RegisterInterface<LLRegionContext>(this);
        }
Ejemplo n.º 49
0
 /// <summary>
 /// When multiple regions are displayed, there is a focus region (the one the main avatar
 /// is in) and other regions that are offset from that focus region. Here we come up with
 /// that offset.
 /// </summary>
 /// <param name="rcontext"></param>
 /// <returns></returns>
 private OMV.Vector3 CalcRegionOffset(RegionContextBase rcontext)
 {
     if (rcontext == m_renderer.m_focusRegion) return OMV.Vector3.Zero;
     OMV.Vector3 ret = new OMV.Vector3();
     ret.X = (float)(m_renderer.m_focusRegion.GlobalPosition.X - rcontext.GlobalPosition.X);
     ret.Y = (float)(m_renderer.m_focusRegion.GlobalPosition.Y - rcontext.GlobalPosition.Y);
     ret.Z = (float)(m_renderer.m_focusRegion.GlobalPosition.Z - rcontext.GlobalPosition.Z);
     return ret;
 }
        // Decide if the character is colliding with a low object and compute a force to pop the
        //    avatar up so it can walk up and over the low objects.
        private OMV.Vector3 WalkUpStairs()
        {
            OMV.Vector3 ret = OMV.Vector3.Zero;

            // This test is done if moving forward, not flying and is colliding with something.
            // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
            //                 LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
            if (m_controllingPrim.IsColliding && !m_controllingPrim.Flying && m_controllingPrim.TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
            {
                // The range near the character's feet where we will consider stairs
                float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f;
                float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;

                // Look for a collision point that is near the character's feet and is oriented the same as the charactor is
                foreach (KeyValuePair<uint, ContactPoint> kvp in m_controllingPrim.CollisionsLastTick.GetCollisionEvents())
                {
                    // Don't care about collisions with the terrain
                    if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID)
                    {
                        OMV.Vector3 touchPosition = kvp.Value.Position;
                        // DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
                        //                 LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
                        if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
                        {
                            // This contact is within the 'near the feet' range.
                            // The normal should be our contact point to the object so it is pointing away
                            //    thus the difference between our facing orientation and the normal should be small.
                            OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
                            OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
                            float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
                            if (diff < BSParam.AvatarStepApproachFactor)
                            {
                                // Found the stairs contact point. Push up a little to raise the character.
                                float upForce = (touchPosition.Z - nearFeetHeightMin) * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor;
                                ret = new OMV.Vector3(0f, 0f, upForce);

                                // Also move the avatar up for the new height
                                OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
                                m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
                            }
                            m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
                                    m_controllingPrim.LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
                        }
                    }
                }
            }

            return ret;
        }
        // Usually called when target velocity changes to set the current velocity and the target
        //     into the movement motor.
        public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime, int targetValueDecayTimeScale)
        {
            if (m_disallowTargetVelocitySet)
            {
                if (m_controllingPrim.Flying && (m_controllingPrim.IsJumping || m_controllingPrim.IsPreJumping))//They started flying while jumping
                {
                    m_physicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate()
                    {
                        //Reset everything in case something went wrong
                        m_disallowTargetVelocitySet = false;
                        m_jumpFallState = false;
                        m_controllingPrim.IsPreJumping = false;
                        m_controllingPrim.IsJumping = false;
                        m_jumpStart = 0;
                        m_preJumpStart = 0;
                    });
                }
                return;
            }

            if (!m_controllingPrim.Flying && m_controllingPrim.IsColliding && targ.Z >= 0.5f)
            {
                m_controllingPrim.IsPreJumping = true;
                m_disallowTargetVelocitySet = true;
                m_jumpDirection = targ;
                m_preJumpStart = Util.EnvironmentTickCount();
                return;
            }

            SetVelocityAndTargetInternal(vel, targ, inTaintTime, targetValueDecayTimeScale);
        }
Ejemplo n.º 52
0
    // No locking here because this is done when we know physics is not simulating
    private void CreateGeomMesh()
    {
        float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
        ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
        // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);

        // if this new shape is the same as last time, don't recreate the mesh
        if (_meshKey == newMeshKey) return;

        // Since we're recreating new, get rid of any previously generated shape
        if (_meshKey != 0)
        {
            // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
            BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
            _mesh = null;
            _meshKey = 0;
        }

        _meshKey = newMeshKey;
        // always pass false for physicalness as this creates some sort of bounding box which we don't need
        _mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, lod, false);

        int[] indices = _mesh.getIndexListAsInt();
        List<OMV.Vector3> vertices = _mesh.getVertexList();

        float[] verticesAsFloats = new float[vertices.Count * 3];
        int vi = 0;
        foreach (OMV.Vector3 vv in vertices)
        {
            // m_log.DebugFormat("{0}:  {1}: <{2:0.00}, {3:0.00}, {4:0.00}>", LogHeader, vi / 3, vv.X, vv.Y, vv.Z);
            verticesAsFloats[vi++] = vv.X;
            verticesAsFloats[vi++] = vv.Y;
            verticesAsFloats[vi++] = vv.Z;
        }

        // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", 
        //                   LogHeader, _localID, _meshKey, indices.Length, vertices.Count);
        BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices, 
                                                        vertices.Count, verticesAsFloats);

        _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
        // meshes are already scaled by the meshmerizer
        _scale = new OMV.Vector3(1f, 1f, 1f);
        return;
    }
Ejemplo n.º 53
0
    }// end CalculateMass
    #endregion Mass Calculation

    // Create the geometry information in Bullet for later use
    // The objects needs a hull if it's physical otherwise a mesh is enough
    // No locking here because this is done when we know physics is not simulating
    // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
    private void CreateGeom(bool forceRebuild)
    {
        // the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
        if (!_scene.NeedsMeshing(_pbs))
        {
            if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
            {
                if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
                {
                    // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
                    _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
                    // Bullet native objects are scaled by the Bullet engine so pass the size in
                    _scale = _size;
                }
            }
            else
            {
                // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
                _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
                _scale = _size;
            }
        }
        else
        {
            if (IsPhysical)
            {
                if (forceRebuild || _hullKey == 0)
                {
                    // physical objects require a hull for interaction.
                    // This will create the mesh if it doesn't already exist
                    CreateGeomHull();
                }
            }
            else
            {
                if (forceRebuild || _meshKey == 0)
                {
                    // Static (non-physical) objects only need a mesh for bumping into
                    CreateGeomMesh();
                }
            }
        }
    }
Ejemplo n.º 54
0
 // Set motion values to zero.
 // Do it to the properties so the values get set in the physics engine.
 // Push the setting of the values to the viewer.
 private void ZeroMotion()
 {
     Velocity = OMV.Vector3.Zero;
     _acceleration = OMV.Vector3.Zero;
     RotationalVelocity = OMV.Vector3.Zero;
     base.RequestPhysicsterseUpdate();
 }
Ejemplo n.º 55
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();
            }
        }
    }
Ejemplo n.º 56
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();
     });
 }
Ejemplo n.º 57
0
        /// <summary>
        /// hook to the physics scene to apply angular impulse
        /// This is sent up to the group, which then finds the root prim
        /// and applies the force on the root prim of the group
        /// </summary>
        /// <param name="impulsei">Vector force</param>
        /// <param name="localGlobalTF">true for the local frame, false for the global frame</param>
        public void SetAngularImpulse(Vector3 impulsei, bool localGlobalTF)
        {
            OpenMetaverse.Vector3 impulse = new OpenMetaverse.Vector3(impulsei.X, impulsei.Y, impulsei.Z);

            if (localGlobalTF)
            {
                Quaternion grot = GetWorldRotation();
                Quaternion AXgrot = grot;
                Vector3 AXimpulsei = impulsei;
                Vector3 newimpulse = AXimpulsei * AXgrot;
                impulse = new OpenMetaverse.Vector3(newimpulse.X, newimpulse.Y, newimpulse.Z);
            }

            if (m_parentGroup != null)
            {
                m_parentGroup.setAngularImpulse(impulse);
            }
        }
Ejemplo n.º 58
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);

        RawPosition = entprop.Position;
        RawOrientation = entprop.Rotation;

        // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
        //    and will send agent updates to the clients if velocity changes by more than
        //    0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
        //    extra updates.
        //
        // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to 
        // avatar movement rather than removes it.  The larger the threshold, the bigger the jitter.
        // This is most noticeable in level flight and can be seen with
        // the "show updates" option in a viewer.  With an update threshold, the RawVelocity cycles between a lower
        // bound and an upper bound, where the difference between the two is enough to trigger a large delta v update
        // and subsequently trigger an update in ScenePresence.SendTerseUpdateToAllClients().  The cause of this cycle (feedback?)
        // has not yet been identified.
        //
        // If there is a threshold below 0.4 or no threshold check at all (as in ODE), then RawVelocity stays constant and extra
        // updates are not triggered in ScenePresence.SendTerseUpdateToAllClients().
//        if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f))
            RawVelocity = entprop.Velocity;

        _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, RawPosition);
            entprop.Position = RawPosition;
        }

        // 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.
        // PhysScene.PostUpdate(this);

        DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
                LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity);
    }
Ejemplo n.º 59
0
    private OMV.Vector3 ComputeStairCorrection(float stepUp)
    {
        OMV.Vector3 ret = OMV.Vector3.Zero;
        OMV.Vector3 displacement = OMV.Vector3.Zero;

        if (stepUp > 0f)
        {
            // Found the stairs contact point. Push up a little to raise the character.
            if (BSParam.AvatarStepForceFactor > 0f)
            {
                float upForce = stepUp * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor;
                ret = new OMV.Vector3(0f, 0f, upForce);
            }

            // Also move the avatar up for the new height
            if (BSParam.AvatarStepUpCorrectionFactor > 0f)
            {
                // Move the avatar up related to the height of the collision
                displacement = new OMV.Vector3(0f, 0f, stepUp * BSParam.AvatarStepUpCorrectionFactor);
                m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
            }
            else
            {
                if (BSParam.AvatarStepUpCorrectionFactor < 0f)
                {
                    // Move the avatar up about the specified step height
                    displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight);
                    m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
                }
            }
            m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs.ComputeStairCorrection,disp={1},force={2}",
                                        m_controllingPrim.LocalID, displacement, ret);

        }
        return ret;
    }
Ejemplo n.º 60
0
    // No locking here because this is done when we know physics is not simulating
    private void CreateGeomHull()
    {
        float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
        ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
        // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);

        // if the hull hasn't changed, don't rebuild it
        if (newHullKey == _hullKey) return;

        // Since we're recreating new, get rid of any previously generated shape
        if (_hullKey != 0)
        {
            // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
            BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
            _hullKey = 0;
            _hulls.Clear();
            BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
            _mesh = null;   // the mesh cannot match either
            _meshKey = 0;
        }

        _hullKey = newHullKey;
        if (_meshKey != _hullKey)
        {
            // if the underlying mesh has changed, rebuild it
            CreateGeomMesh();
        }

        int[] indices = _mesh.getIndexListAsInt();
        List<OMV.Vector3> vertices = _mesh.getVertexList();

        //format conversion from IMesh format to DecompDesc format
        List<int> convIndices = new List<int>();
        List<float3> convVertices = new List<float3>();
        for (int ii = 0; ii < indices.GetLength(0); ii++)
        {
            convIndices.Add(indices[ii]);
        }
        foreach (OMV.Vector3 vv in vertices)
        {
            convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
        }

        // setup and do convex hull conversion
        _hulls = new List<ConvexResult>();
        DecompDesc dcomp = new DecompDesc();
        dcomp.mIndices = convIndices;
        dcomp.mVertices = convVertices;
        ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
        // create the hull into the _hulls variable
        convexBuilder.process(dcomp);

        // Convert the vertices and indices for passing to unmanaged
        // The hull information is passed as a large floating point array. 
        // The format is:
        //  convHulls[0] = number of hulls
        //  convHulls[1] = number of vertices in first hull
        //  convHulls[2] = hull centroid X coordinate
        //  convHulls[3] = hull centroid Y coordinate
        //  convHulls[4] = hull centroid Z coordinate
        //  convHulls[5] = first hull vertex X
        //  convHulls[6] = first hull vertex Y
        //  convHulls[7] = first hull vertex Z
        //  convHulls[8] = second hull vertex X
        //  ...
        //  convHulls[n] = number of vertices in second hull
        //  convHulls[n+1] = second hull centroid X coordinate
        //  ...
        //
        // TODO: is is very inefficient. Someday change the convex hull generator to return
        //   data structures that do not need to be converted in order to pass to Bullet.
        //   And maybe put the values directly into pinned memory rather than marshaling.
        int hullCount = _hulls.Count;
        int totalVertices = 1;          // include one for the count of the hulls
        foreach (ConvexResult cr in _hulls)
        {
            totalVertices += 4;                         // add four for the vertex count and centroid
            totalVertices += cr.HullIndices.Count * 3;  // we pass just triangles
        }
        float[] convHulls = new float[totalVertices];

        convHulls[0] = (float)hullCount;
        int jj = 1;
        foreach (ConvexResult cr in _hulls)
        {
            // copy vertices for index access
            float3[] verts = new float3[cr.HullVertices.Count];
            int kk = 0;
            foreach (float3 ff in cr.HullVertices)
            {
                verts[kk++] = ff;
            }

            // add to the array one hull's worth of data
            convHulls[jj++] = cr.HullIndices.Count;
            convHulls[jj++] = 0f;   // centroid x,y,z
            convHulls[jj++] = 0f;
            convHulls[jj++] = 0f;
            foreach (int ind in cr.HullIndices)
            {
                convHulls[jj++] = verts[ind].x;
                convHulls[jj++] = verts[ind].y;
                convHulls[jj++] = verts[ind].z;
            }
        }

        // create the hull definition in Bullet
        // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount);
        BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls);
        _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
        // meshes are already scaled by the meshmerizer
        _scale = new OMV.Vector3(1f, 1f, 1f);
        return;
    }