void PhysicsHandler::handleUpdate(EventDetails* const details)
{
    commitChanges();

    //Start the physics timing statistic
    StatTimeElem *PhysicsTimeStatElem = StatCollector::getGlobalElem(statPhysicsTime);
    if(PhysicsTimeStatElem) { PhysicsTimeStatElem->start(); }

    _TimeSinceLast += dynamic_cast<UpdateEventDetails* const>(details)->getElapsedTime();

    if(osgFloor(_TimeSinceLast/getStepSize()) > getMaxStepsPerUpdate())
    {
        SWARNING << "Physics Simulation slowing: dropping " << osgFloor(_TimeSinceLast/getStepSize())-getMaxStepsPerUpdate() << " steps" << std::endl;
        _TimeSinceLast = getMaxStepsPerUpdate()*getStepSize();
    }

    StatIntElem *NPhysicsStepsStatElem = StatCollector::getGlobalElem(statNPhysicsSteps);
    StatTimeElem *CollisionTimeStatElem = StatCollector::getGlobalElem(statCollisionTime);
    StatTimeElem *DynamicsTimeStatElem = StatCollector::getGlobalElem(statSimulationTime);
    while(_TimeSinceLast > getStepSize())
    {
        //Increment the steps statistic
        if(NPhysicsStepsStatElem) { NPhysicsStepsStatElem->inc(); }

        //*********** Collision Checks *************
        //Start the collision timing statistic
        if(CollisionTimeStatElem) { CollisionTimeStatElem->start(); }

        //Do collision checks
        for(UInt32 i(0) ; i<getMFSpaces()->size() ; ++i)
        {
            getSpaces(i)->Collide(getWorld());
        }

        //Stop the collision timing statistic
        if(CollisionTimeStatElem) { CollisionTimeStatElem->stop(); }


        //*********** Simulation step *************

        //Start the simulation timing statistic
        if(DynamicsTimeStatElem) { DynamicsTimeStatElem->start(); }

        //Step the dynamics simulation
        getWorld()->worldQuickStep(getStepSize());

        //Stop the simulation timing statistic
        if(DynamicsTimeStatElem) { DynamicsTimeStatElem->stop(); }

        //Decrease the time since last simulation step
        _TimeSinceLast -= getStepSize();
    }
    StatRealElem *NCollisionTestsStatElem = StatCollector::getGlobalElem(statNCollisionTests);
    if(NCollisionTestsStatElem) { NCollisionTestsStatElem->set(NCollisionTestsStatElem->get()/static_cast<Real32>(NPhysicsStepsStatElem->get())); }
    StatRealElem *NCollisionsStatElem = StatCollector::getGlobalElem(statNCollisions);
    if(NCollisionsStatElem) { NCollisionsStatElem->set(NCollisionsStatElem->get()/static_cast<Real32>(NPhysicsStepsStatElem->get())); }

    
    
    StatTimeElem *TransformUpdateTimeStatElem = StatCollector::getGlobalElem(statTransformUpdateTime);
    //Start the transform update timing statistic
    if(TransformUpdateTimeStatElem) { TransformUpdateTimeStatElem->start(); }
    //update matrices
    updateWorld(getUpdateNode());
    //Start the transform update timing statistic
    if(TransformUpdateTimeStatElem) { TransformUpdateTimeStatElem->stop(); }

    //Stop the physics timing statistic
    if(PhysicsTimeStatElem) { PhysicsTimeStatElem->stop(); }
}
Beispiel #2
0
/*!
 * \fn bool OSG::Animation::update(const Time& ElapsedTime)
 *
 * \brief Update the animation with the time since the last update
 *
 * The result of the animation will also be applied to the
 * object it is connected to.
 *
 * \param[in] ElapsedTime The time, in seconds, since the previous call to
 * update.
 */
bool Animation::update(const Time& ElapsedTime)
{
    if(!_IsPlaying || _IsPaused)
    {
        return false;
    }

    //Increment the updated animations statistic
    StatIntElem *NAnimationsStatElem = StatCollector::getGlobalElem(statNAnimations);
    if(NAnimationsStatElem) { NAnimationsStatElem->inc(); }

    //Start the  animation update time statistic
    StatTimeElem *AnimUpdateTimeStatElem = StatCollector::getGlobalElem(statAnimUpdateTime);
    if(AnimUpdateTimeStatElem) { AnimUpdateTimeStatElem->start(); }

    _CurrentTime += getScale()*ElapsedTime;
    UInt32 PreUpdateCycleCount(getCycles());
    if(getCycling() < 0 || PreUpdateCycleCount < getCycling())
    {
        Real32 CycleLength(getCycleLength() * getScale());

        //Check if the Animation Time is past the end
        if(_CurrentTime >= CycleLength)
        {
            //Update the number of cycles completed
            setCycles( (CycleLength <= 0.0f) ? (0): (static_cast<UInt32>( osgFloor( _CurrentTime / CycleLength ) )) );
            //commitChanges();
        }
        Real32 t(_CurrentTime);

        if(getCycling() > 0 && getCycles() >= getCycling())
        {
            if(getSpan() > 0.0f)
            {
                t = getSpan();
            }
            t -= 0.0001f;
        }
        else
        {
            if(getSpan() > 0.0f)
            {
                t -= osgFloor(_CurrentTime/getSpan())*getSpan();
            }
        }
        t += getOffset();

        //Internal Update
        internalUpdate(t, _PrevTime);


        //If the number of cycles has changed
        if(getCycles() != PreUpdateCycleCount)
        {
            if(getCycling() > 0 && getCycles() >= getCycling())
            {
                //Animation has reached the end
                //Remove the Animation from it's update producer
                _UpdateEventConnection.disconnect();
                _IsPlaying = false;

                //Produce the Ended event
                produceAnimationEnded();
            }
            else
            {
                //Animation hasn't finished yet
                //Produce the Cycled event
                produceAnimationCycled();
            }
        }
    }

    _PrevTime = _CurrentTime;

    //Stp[ the  animation update time statistic
    if(AnimUpdateTimeStatElem) { AnimUpdateTimeStatElem->stop(); }

    //Return true if the animation has completed its number of cycles, false otherwise
    return (getCycling() > 0 && getCycles() >= getCycling());
}