//------------------------------------------------------------------------------
//
void GLPickingSelect::processTriangles(
    const SubNode::Ptr rootNode,
    const double seconds,
    const size_t numTriangles,
    VBOProxy::VBOMode vboMode
)
{
    const unsigned int bufferSize = (unsigned int)std::min(numTriangles,size_t(100000));
    boost::shared_array<GLuint>buffer (new GLuint[bufferSize*4]);

    M3dView view = fSelectInfo.view();

    MMatrix projMatrix;
    view.projectionMatrix(projMatrix);
    MMatrix modelViewMatrix;
    view.modelViewMatrix(modelViewMatrix);

    unsigned int x, y, w, h;
    view.viewport(x, y, w, h);
    double viewportX = static_cast<int>(x);   // can be less than 0
    double viewportY = static_cast<int>(y);   // can be less than 0
    double viewportW = w;
    double viewportH = h;

    fSelectInfo.selectRect(x, y, w, h);
    double selectX = static_cast<int>(x);  // can be less than 0
    double selectY = static_cast<int>(y);  // can be less than 0
    double selectW = w;
    double selectH = h;

    MMatrix selectAdjustMatrix;
    selectAdjustMatrix[0][0] = viewportW / selectW;
    selectAdjustMatrix[1][1] = viewportH / selectH;
    selectAdjustMatrix[3][0] = ((viewportX + viewportW/2.0) - (selectX + selectW/2.0)) / 
        viewportW * 2.0 * selectAdjustMatrix[0][0];
    selectAdjustMatrix[3][1] = ((viewportY + viewportH/2.0) - (selectY + selectH/2.0)) /
        viewportH * 2.0 * selectAdjustMatrix[1][1];

    MMatrix localToPort = modelViewMatrix * projMatrix * selectAdjustMatrix;

    view.beginSelect(buffer.get(), bufferSize*4);
    view.pushName(0);
    {
        Frustum frustum(localToPort.inverse());
        MMatrix xform(modelViewMatrix);
        
        DrawShadedState state(frustum, seconds, vboMode);
        DrawShadedTraversal traveral(state, xform, false, Frustum::kUnknown);
        rootNode->accept(traveral);
    }
    view.popName();
    int nbPick = view.endSelect();

    if (nbPick > 0) {
        unsigned int Zdepth = closestElem(nbPick, buffer.get());    
        float depth = float(Zdepth)/MAX_HW_DEPTH_VALUE;
        fMinZ = std::min(depth,fMinZ);
    }
}
//------------------------------------------------------------------------------
//
RasterSelect::RasterSelect(
    MSelectInfo& selectInfo
) 
    : fSelectInfo(selectInfo),
      fMinZ(std::numeric_limits<float>::max())
{
    M3dView view = fSelectInfo.view();

    view.beginGL();

    unsigned int sxl, syl, sw, sh;
    fSelectInfo.selectRect(sxl, syl, sw, sh);

    unsigned int vxl, vyl, vw, vh;
    view.viewport(vxl, vyl, vw, vh);

    // Compute a new matrix that, when it is post-multiplied with the
    // projection matrix, will cause the picking region to fill only
    // a small region.

    const unsigned int width = (MAX_RASTER_SELECT_RENDER_SIZE < sw) ?
        MAX_RASTER_SELECT_RENDER_SIZE : sw;
    const unsigned int height = (MAX_RASTER_SELECT_RENDER_SIZE < sh) ?
        MAX_RASTER_SELECT_RENDER_SIZE : sh;

    const double sx = double(width) / double(sw);
    const double sy = double(height) / double(sh);

    const double fx = 2.0 / double(vw);
    const double fy = 2.0 / double(vh);
    
    MMatrix  selectMatrix;
    selectMatrix.matrix[0][0] = sx;
    selectMatrix.matrix[1][1] = sy;
    selectMatrix.matrix[3][0] = -1.0 - sx * (fx * (sxl - vxl) - 1.0);
    selectMatrix.matrix[3][1] = -1.0 - sy * (fy * (syl - vyl) - 1.0);
    
        
    MMatrix projMatrix;
    view.projectionMatrix(projMatrix);

    ::glMatrixMode(GL_PROJECTION);
    ::glPushMatrix();
    ::glLoadMatrixd(selectMatrix[0]);
    ::glMultMatrixd(projMatrix[0]);
    ::glMatrixMode(GL_MODELVIEW);

    ::glScissor(vxl, vyl, width, height);
    ::glEnable(GL_SCISSOR_TEST);
    ::glClear(GL_DEPTH_BUFFER_BIT);

    fWasDepthTestEnabled = ::glIsEnabled(GL_DEPTH_TEST);
    if (!fWasDepthTestEnabled) {
        ::glEnable(GL_DEPTH_TEST);
    }
}
//------------------------------------------------------------------------------
//
void RasterSelect::end()
{
    M3dView view = fSelectInfo.view();
    
    unsigned int sxl, syl, sw, sh;
    fSelectInfo.selectRect(sxl, syl, sw, sh);

    unsigned int vxl, vyl, vw, vh;
    view.viewport(vxl, vyl, vw, vh);

    const unsigned int width = (MAX_RASTER_SELECT_RENDER_SIZE < sw) ?
        MAX_RASTER_SELECT_RENDER_SIZE : sw;
    const unsigned int height = (MAX_RASTER_SELECT_RENDER_SIZE < sh) ?
        MAX_RASTER_SELECT_RENDER_SIZE : sh;

    float* selDepth = new float[MAX_RASTER_SELECT_RENDER_SIZE*
                                MAX_RASTER_SELECT_RENDER_SIZE];
    

    GLint buffer;
    ::glGetIntegerv( GL_READ_BUFFER, &buffer );
    ::glReadBuffer( GL_BACK );
    ::glReadPixels(vxl, vyl, width, height,
                   GL_DEPTH_COMPONENT, GL_FLOAT, (void *)selDepth); 
    ::glReadBuffer( buffer );

    for (unsigned int j=0; j<height; ++j) {
        for (unsigned int i=0; i<width; ++i) {
            const GLfloat depth = selDepth[j*width + i];
            if (depth < 1.0f) {
                fMinZ = std::min(fMinZ, depth);
            }
        }   
    }

    ::glMatrixMode(GL_PROJECTION);
    ::glPopMatrix();
    ::glMatrixMode(GL_MODELVIEW);

    ::glDisable(GL_SCISSOR_TEST);

    if (!fWasDepthTestEnabled) {
        ::glDisable(GL_DEPTH_TEST);        
    }

    view.endGL();
}
//------------------------------------------------------------------------------
//
void RasterSelect::processTriangles(
    const SubNode::Ptr rootNode,
    double seconds,
    size_t /* numTriangles */,
    VBOProxy::VBOMode vboMode
)
{
    M3dView view = fSelectInfo.view();

    MMatrix projMatrix;
    view.projectionMatrix(projMatrix);
    MMatrix modelViewMatrix;
    view.modelViewMatrix(modelViewMatrix);

    unsigned int x, y, w, h;
    view.viewport(x, y, w, h);
    double viewportX = static_cast<int>(x);   // can be less than 0
    double viewportY = static_cast<int>(y);   // can be less than 0
    double viewportW = w;
    double viewportH = h;

    fSelectInfo.selectRect(x, y, w, h);
    double selectX = static_cast<int>(x);  // can be less than 0
    double selectY = static_cast<int>(y);  // can be less than 0
    double selectW = w;
    double selectH = h;

    MMatrix selectAdjustMatrix;
    selectAdjustMatrix[0][0] = viewportW / selectW;
    selectAdjustMatrix[1][1] = viewportH / selectH;
    selectAdjustMatrix[3][0] = ((viewportX + viewportW/2.0) - (selectX + selectW/2.0)) / 
        viewportW * 2.0 * selectAdjustMatrix[0][0];
    selectAdjustMatrix[3][1] = ((viewportY + viewportH/2.0) - (selectY + selectH/2.0)) /
        viewportH * 2.0 * selectAdjustMatrix[1][1];

    MMatrix localToPort = modelViewMatrix * projMatrix * selectAdjustMatrix;

    {
        Frustum frustum(localToPort.inverse());
        MMatrix xform(modelViewMatrix);
        
        DrawShadedState state(frustum, seconds, vboMode);
        DrawShadedTraversal traveral(state, xform, false, Frustum::kUnknown);
        rootNode->accept(traveral);
    }
}
Example #5
0
void
UsdMayaGLBatchRenderer::Draw(
    const MDrawRequest& request,
    M3dView &view )
{
    // VP 1.0 Implementation
    //
    MDrawData drawData = request.drawData();
    
    _BatchDrawUserData* batchData =
                static_cast<_BatchDrawUserData*>(drawData.geometry());
    if( !batchData )
        return;
    
    MMatrix projectionMat;
    view.projectionMatrix(projectionMat);
    
    MMatrix modelViewMat;
    view.modelViewMatrix(modelViewMat);

    if( batchData->_bounds )
    {
        px_vp20Utils::RenderBoundingBox(*(batchData->_bounds),
                                        *(batchData->_wireframeColor),
                                        modelViewMat,
                                        projectionMat);
    }
    
    if( batchData->_drawShape && !_renderQueue.empty() )
    {
        MMatrix viewMat( request.matrix().inverse() * modelViewMat );

        unsigned int viewX, viewY, viewWidth, viewHeight;
        view.viewport(viewX, viewY, viewWidth, viewHeight);
        GfVec4d viewport(viewX, viewY, viewWidth, viewHeight);

        // Only the first call to this will do anything... After that the batch
        // queue is cleared.
        //
        _RenderBatches( NULL, viewMat, projectionMat, viewport );
    }
    
    // Clean up the _BatchDrawUserData!
    delete batchData;
}