//-----------------------------------------------------------------------------
//
// VActorPhysicsController::processCollisions();
//
// ...
//
//-----------------------------------------------------------------------------
void VActorPhysicsController::processCollisions( void )
{
    // Find & Resolve Collisions.
    Collision *collision;
    if ( findCollision( collision ) )
    {
        // Solve the Collision.
        solveCollision( collision );
    }
}
void LVL_Player::_collideUnduck()
{
    _syncPosition();
    if(isWarping) return;

    #ifdef COLLIDE_DEBUG
    qDebug() << "do unduck!";
    #endif

    //Detect collidable blocks!
    QVector<PGE_Phys_Object*> bodies;
    PGE_RectF posRectC = posRect;
    posRectC.setTop(posRectC.top()-4.0f);
    posRectC.setLeft(posRectC.left()+1.0f);
    posRectC.setRight(posRectC.right()-1.0f);
    posRectC.setBottom(posRectC.bottom()+ (ducking ? 0.0:(-posRect.height()/2.0))+4.0 );
    LvlSceneP::s->queryItems(posRectC, &bodies);

    forceCollideCenter=true;
    for(PGE_RenderList::iterator it=bodies.begin();it!=bodies.end(); it++ )
    {
        PGE_Phys_Object*body=*it;
        if(body==this) continue;
        if(body->isPaused()) continue;
        if(!body->isVisible()) continue;
        solveCollision(body);
    }
    forceCollideCenter=false;

    #ifdef COLLIDE_DEBUG
    int hited=0;
    PGE_RectF nearestRect;
    #endif

    bool resolveTop=false;
    double _floorY=0;
    QVector<PGE_Phys_Object*> blocks_to_hit;

    if((!collided_center.isEmpty())&&(collided_bottom.isEmpty()))
    {
        for(PlayerColliders::iterator it=collided_center.begin(); it!=collided_center.end() ; it++)
        {
            PGE_Phys_Object *collided= *it;
            LVL_Block *blk= static_cast<LVL_Block*>(collided);
            if(blk) blocks_to_hit.push_back(blk);
        }
        for(PlayerColliders::iterator it=collided_top.begin(); it!=collided_top.end() ; it++)
        {
            PGE_Phys_Object *collided= *it;
            LVL_Block *blk= static_cast<LVL_Block*>(collided);
            if(blk) blocks_to_hit.push_back(blk);
        }
        if(isFloor(blocks_to_hit))
        {
            PGE_Phys_Object*nearest = nearestBlockY(blocks_to_hit);
            if(nearest)
            {
                _floorY=nearest->posRect.bottom()+1.0;
                resolveTop=true;
            }
        }
    }

    if(resolveTop)
    {
        posRect.setY(_floorY);
        if(!blocks_to_hit.isEmpty())
        {
            PGE_Phys_Object*nearest_obj=nearestBlock(blocks_to_hit);
            if(nearest_obj && (nearest_obj->type==PGE_Phys_Object::LVLBlock))
            {
                LVL_Block*nearest = static_cast<LVL_Block*>(nearest_obj);
                resolveTop=true;
                long npcid=nearest->data.npc_id;
                nearest->hit();
                if( nearest->setup->hitable || (npcid!=0) || (nearest->destroyed) || (nearest->setup->bounce) )
                {
                    bump(false, speedY());
                }
            }
            else
            {
                PGE_Audio::playSoundByRole(obj_sound_role::BlockHit);
            }
        }
        setSpeedY(0.0);
        _syncPosition();
    }

    _heightDelta = 0.0;
    #ifdef COLLIDE_DEBUG
    qDebug() << "unduck: blocks to hit"<< hited << " Nearest: "<<nearestRect.top() << nearestRect.bottom() << "are bottom empty: " << collided_bottom.isEmpty() << "bodies found: "<<bodies.size() << "bodies at center: "<<collided_center.size();
    #endif
}