Exemple #1
0
        protected void TriggerPreUpdatePropertyAction(ref EntityProperties entprop)
        {
            PreUpdatePropertyAction actions = OnPreUpdateProperty;

            if (actions != null)
            {
                actions(ref entprop);
            }
        }
        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!!!
                entprop.Position = entprop.Position + (PositionDisplacement * entprop.Rotation);
            }

            base.UpdateProperties(entprop);
        }
Exemple #3
0
        public override void UpdateProperties(EntityProperties entprop)
        {
            if (Linkset.IsRoot(this))
            {
                // Properties are only updated for the roots of a linkset.
                // TODO: this will have to change when linksets are articulated.
                base.UpdateProperties(entprop);
            }

            // The linkset might like to know about changing locations
            Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
        }
Exemple #4
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);
        }
Exemple #5
0
        // Simulate one timestep
        public override void Simulate(float timeStep)
        {
            // prevent simulation until we've been initialized
            if (!m_initialized)
            {
                return;
            }

            LastTimeStep = timeStep;

            int updatedEntityCount = 0;
            int collidersCount     = 0;

            int beforeTime = 0;

            // update the prim states while we know the physics engine is not busy
            int numTaints = _taintOperations.Count;

            InTaintTime = true; // Only used for debugging so locking is not necessary.

            beforeTime = Util.EnvironmentTickCount();

            ProcessTaints();

            // Some of the physical objects requre individual, pre-step calls
            //      (vehicles and avatar movement, in particular)
            TriggerPreStepEvent(timeStep);

            // the prestep actions might have added taints
            numTaints += _taintOperations.Count;
            ProcessTaints();

            StatPhysicsTaintTime = Util.EnvironmentTickCountSubtract(beforeTime);
            InTaintTime          = false; // Only used for debugging so locking is not necessary.

            // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
            // Only enable this in a limited test world with few objects.
            if (m_physicsPhysicalDumpEnabled)
            {
                PE.DumpAllInfo(World);
            }

            // step the physical world one interval
            m_simulationStep++;
            int numSubSteps = 0;

            try
            {
                beforeTime = Util.EnvironmentTickCount();

                numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);

                {
                    StatContactLoopTime = Util.EnvironmentTickCountSubtract(beforeTime);
                    DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
                              DetailLogZero, m_simulationStep, numTaints, StatContactLoopTime, numSubSteps,
                              updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
                }
            }
            catch (Exception e)
            {
                MainConsole.Instance.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
                                                LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
                DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
                          DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
                updatedEntityCount = 0;
                collidersCount     = 0;
            }

            if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0))
            {
                PE.DumpPhysicsStatistics(World);
            }

            // Get a value for 'now' so all the collision and update routines don't have to get their own.
            SimulationNowTime = Util.EnvironmentTickCount();

            beforeTime = Util.EnvironmentTickCount();

            // If there were collisions, process them by sending the event to the prim.
            // Collisions must be processed before updates.
            if (collidersCount > 0)
            {
                for (int ii = 0; ii < collidersCount; ii++)
                {
                    uint    cA          = m_collisionArray[ii].aID;
                    uint    cB          = m_collisionArray[ii].bID;
                    Vector3 point       = m_collisionArray[ii].point;
                    Vector3 normal      = m_collisionArray[ii].normal;
                    float   penetration = m_collisionArray[ii].penetration;
                    SendCollision(cA, cB, point, normal, penetration);
                    SendCollision(cB, cA, point, -normal, penetration);
                }
            }

            // The above SendCollision's batch up the collisions on the objects.
            //      Now push the collisions into the simulator.
            if (ObjectsWithCollisions.Count > 0)
            {
                foreach (BSPhysObject bsp in ObjectsWithCollisions)
                {
                    if (!bsp.SendCollisions())
                    {
                        // If the object is done colliding, see that it's removed from the colliding list
                        ObjectsWithNoMoreCollisions.Add(bsp);
                    }
                }
            }

            // This is a kludge to get avatar movement updates.
            // The simulator expects collisions for avatars even if there are have been no collisions.
            //    The event updates avatar animations and stuff.
            // If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
            foreach (BSPhysObject bsp in m_avatars)
            {
                if (!ObjectsWithCollisions.Contains(bsp))   // don't call avatars twice
                {
                    bsp.SendCollisions();
                }
            }

            // Objects that are done colliding are removed from the ObjectsWithCollisions list.
            // Not done above because it is inside an iteration of ObjectWithCollisions.
            // This complex collision processing is required to create an empty collision
            //     event call after all real collisions have happened on an object. This enables
            //     the simulator to generate the 'collision end' event.
            if (ObjectsWithNoMoreCollisions.Count > 0)
            {
                foreach (BSPhysObject po in ObjectsWithNoMoreCollisions)
                {
                    ObjectsWithCollisions.Remove(po);
                }
                ObjectsWithNoMoreCollisions.Clear();
            }
            // Done with collisions.

            // If any of the objects had updated properties, tell the object it has been changed by the physics engine
            if (updatedEntityCount > 0)
            {
                for (int ii = 0; ii < updatedEntityCount; ii++)
                {
                    EntityProperties entprop = m_updateArray[ii];
                    BSPhysObject     pobj;
                    if (PhysObjects.TryGetValue(entprop.ID, out pobj))
                    {
                        pobj.UpdateProperties(entprop);
                    }
                }
            }

            StatPhysicsMoveTime = Util.EnvironmentTickCountSubtract(beforeTime);

            TriggerPostStepEvent(timeStep);

            // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
            // Only enable this in a limited test world with few objects.
            if (m_physicsPhysicalDumpEnabled)
            {
                PE.DumpAllInfo(World);
            }
        }
Exemple #6
0
 // Update the physical location and motion of the object. Called with data from Bullet.
 public abstract void UpdateProperties(EntityProperties entprop);