void EDA_3D_CANVAS::calcBBox()
{
    BOARD* pcb = GetBoard();

    m_fastAABBox.Reset();

    for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
    {
        CBBOX tmpFastAABBox;

        // Compute the transformation matrix for this module based on translation, rotation and orientation.
        float  zpos = GetPrm3DVisu().GetModulesZcoord3DIU( module->IsFlipped() );
        wxPoint pos = module->GetPosition();

        glm::mat4 fullTransformMatrix;
        fullTransformMatrix = glm::translate( glm::mat4(),  S3D_VERTEX( (float)(pos.x * GetPrm3DVisu().m_BiuTo3Dunits),
                                                                        (float)(-pos.y * GetPrm3DVisu().m_BiuTo3Dunits),
                                                                        zpos ) );

        if( module->GetOrientation() )
            fullTransformMatrix = glm::rotate( fullTransformMatrix,
                                               glm::radians( (float)(module->GetOrientation() / 10.0f) ),
                                               S3D_VERTEX( 0.0f, 0.0f, 1.0f ) );

        if( module->IsFlipped() )
        {
            fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( 180.0f ), S3D_VERTEX( 0.0f, 1.0f, 0.0f ) );
            fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( 180.0f ), S3D_VERTEX( 0.0f, 0.0f, 1.0f ) );
        }

        // Compute a union bounding box for all the shapes of the model

        S3D_MASTER* shape3D = module->Models();

        for( ; shape3D; shape3D = shape3D->Next() )
        {
            if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) )
                tmpFastAABBox.Union( shape3D->getFastAABBox() );
        }

        tmpFastAABBox.ApplyTransformationAA( fullTransformMatrix );

        m_fastAABBox.Union( tmpFastAABBox );
    }

    // Create a board bounding box based on board size
    wxSize  brd_size = getBoardSize();
    wxPoint brd_center_pos = getBoardCenter();

    float xsize   = brd_size.x;
    float ysize   = brd_size.y;

    float scale   = GetPrm3DVisu().m_BiuTo3Dunits;
    float xmin    = (brd_center_pos.x - xsize / 2.0) * scale;
    float xmax    = (brd_center_pos.x + xsize / 2.0) * scale;
    float ymin    = (brd_center_pos.y - ysize / 2.0) * scale;
    float ymax    = (brd_center_pos.y + ysize / 2.0) * scale;

    float zmin = GetPrm3DVisu().GetLayerZcoordBIU( B_Adhes ) * scale;
    float zmax = GetPrm3DVisu().GetLayerZcoordBIU( F_Adhes ) * scale;

    m_boardAABBox = CBBOX(  S3D_VERTEX(xmin, ymin, zmin),
                            S3D_VERTEX(xmax, ymax, zmax) );

    // Add BB board with BB models and scale it a bit
    m_fastAABBox.Union( m_boardAABBox );
    m_fastAABBox_Shadow = m_fastAABBox;
    m_fastAABBox_Shadow.Scale( SHADOW_BOUNDING_BOX_SCALE );
}