Universe.Physics.BulletSPlugin.BSAPITemplate.PhysicsStep C# (CSharp) Method

PhysicsStep() public abstract method

public abstract PhysicsStep ( BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep, int &updatedEntityCount, int &collidersCount ) : int
world BulletWorld
timeStep float
maxSubSteps int
fixedTimeStep float
updatedEntityCount int
collidersCount int
return int
        public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
            out int updatedEntityCount, out int collidersCount);

Usage Example

Example #1
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);

                //if (PhysicsLogging.Enabled)
                //{
                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);
            }
        }
BSAPITemplate