void PhysicsManager::afterSimulation(Node *node)
{
    auto iter = _owners.find(node);
    if (iter != _owners.end())
    {
        auto component = iter->second;
        component->afterSimulation();
    }
    
    for (auto child : node->getChildren())
        afterSimulation(child);
}
void PhysicsWorld::afterSimulation(Node *node, const Mat4& parentToWorldTransform, float parentRotation)
{
    auto nodeToWorldTransform = parentToWorldTransform * node->getNodeToParentTransform();
    auto nodeRotation = parentRotation + node->getRotation();

    auto physicsBody = node->getPhysicsBody();
    if (physicsBody)
    {
        physicsBody->afterSimulation(parentToWorldTransform, parentRotation);
    }

    for (auto child : node->getChildren())
        afterSimulation(child, nodeToWorldTransform, nodeRotation);
}
void PhysicsWorld::update(float delta, bool userCall/* = false*/)
{
    if(!_delayAddBodies.empty())
    {
        updateBodies();
    }
    else if (!_delayRemoveBodies.empty())
    {
        updateBodies();
    }
    
    auto sceneToWorldTransform = _scene->getNodeToParentTransform();
    beforeSimulation(_scene, sceneToWorldTransform, 1.f, 1.f, 0.f);

    if (!_delayAddJoints.empty() || !_delayRemoveJoints.empty())
    {
        updateJoints();
    }
    
    if (delta < FLT_EPSILON)
    {
        return;
    }
    
    if (userCall)
    {
        cpSpaceStep(_cpSpace, delta);
    }
    else
    {
        _updateTime += delta;
        if (++_updateRateCount >= _updateRate)
        {
            const float dt = _updateTime * _speed / _substeps;
            for (int i = 0; i < _substeps; ++i)
            {
                cpSpaceStep(_cpSpace, dt);
            }
            _updateRateCount = 0;
            _updateTime = 0.0f;
        }
    }
    
    if (_debugDrawMask != DEBUGDRAW_NONE)
    {
        debugDraw();
    }

    // Update physics position, should loop as the same sequence as node tree.
    // PhysicsWorld::afterSimulation() will depend on the sequence.
    afterSimulation(_scene, sceneToWorldTransform, 0.f);
}
void PhysicsManager::update(float dt)
{
    // Update physics position, should loop as the same sequence as node tree.
    // ComponentPhysics2d::beforeSimulation() will depend on the sequence.
    beforeSimulation(_scene);
    
    // do simulation
    _physicsWorld->update(dt, false);
    
    // Update physics position, should loop as the same sequence as node tree.
    // ComponentPhysics2d::afterSimulation() will depend on the sequence.
    afterSimulation(_scene);
}
void PhysicsWorld::update(float delta, bool userCall/* = false*/)
{
    if(!_delayAddBodies.empty())
    {
        updateBodies();
    }
    else if (!_delayRemoveBodies.empty())
    {
        updateBodies();
    }
    
    auto sceneToWorldTransform = _scene->getNodeToParentTransform();
    beforeSimulation(_scene, sceneToWorldTransform, 1.f, 1.f, 0.f);

    if (!_delayAddJoints.empty() || !_delayRemoveJoints.empty())
    {
        updateJoints();
    }
    
    if (delta < FLT_EPSILON)
    {
        return;
    }
    
    if (userCall)
    {
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
		cpSpaceStep(_cpSpace, delta);
#else
		cpHastySpaceStep(_cpSpace, delta);
#endif
    }
    else
    {
        _updateTime += delta;
        if(_fixedRate)
        {
            const float step = 1.0f / _fixedRate;
            const float dt = step * _speed;
            while(_updateTime>step)
            {
                _updateTime-=step;
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
				cpSpaceStep(_cpSpace, dt);
#else
				cpHastySpaceStep(_cpSpace, dt);
#endif
			}
        }
        else
        {
            if (++_updateRateCount >= _updateRate)
            {
                const float dt = _updateTime * _speed / _substeps;
                for (int i = 0; i < _substeps; ++i)
                {
#if CC_TARGET_PLATFORM == CC_PLATFORM_WINRT || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
					cpSpaceStep(_cpSpace, dt);
#else
					cpHastySpaceStep(_cpSpace, dt);
#endif 
					for (auto& body : _bodies)
                    {
                        body->update(dt);
                    }
                }
                _updateRateCount = 0;
                _updateTime = 0.0f;
            }
        }
    }
    
    if (_debugDrawMask != DEBUGDRAW_NONE)
    {
        debugDraw();
    }

    // Update physics position, should loop as the same sequence as node tree.
    // PhysicsWorld::afterSimulation() will depend on the sequence.
    afterSimulation(_scene, sceneToWorldTransform, 0.f);
}