[osg-users] "Robust" Update of an osg::Image attached to a osg::camera ?

Erwan Bigorgne erwan.bigorgne at gmail.com
Mon Mar 9 09:48:21 PDT 2009


My bad,

I must admit that I actually don't know how to simply "reply" to a thread.
anyway, here is my code :


void COSGMesh::Initialization(void)
{


    mp_RootNode = new osg::Group;

    mp_MeshGroup = new osg::Group;

    mp_InternalMatrixTransform = new osg::MatrixTransform;




//    osg::ref_ptr<osg::ShapeDrawable> Target (new osg::ShapeDrawable(new
osg::Cylinder(osg::Vec3f(),0.1f,0.1f)));
//    osg::ref_ptr<osg::Geode> TargetGeode (new osg::Geode);
//    TargetGeode->addDrawable(Target.get());
//    mp_ModelMatrixTransform->addChild(TargetGeode.get());

    osg::ref_ptr<osg::Node> scene =
osgDB::readNodeFile("./Data/11man-3d-headbold.osg");
    if (!scene) scene =
osgDB::readNodeFile("../Data/11man-3d-headbold.osg");
    if (!scene)
    {
        std::cerr << "No Mesh DAta available EXITING. please check data
folder" << std::endl;
        exit (EXIT_FAILURE);

    }


    const osg::BoundingSphere& bs = scene->getBound();

     float size = DEF_MESH_REAL_INIT_MAX_RADIUS/bs.radius();

     mp_InternalMatrixTransform = new osg::MatrixTransform;
     mp_InternalMatrixTransform->setDataVariance(osg::Object::STATIC);

mp_InternalMatrixTransform->setMatrix(osg::Matrix::translate(-bs.center())*

osg::Matrix::scale(size*DEF_X_SIZE_MODIF_FACTOR,

size*DEF_Z_SIZE_MODIF_FACTOR,

size*DEF_Y_SIZE_MODIF_FACTOR));

                                  //
osg::Matrix::rotate(osg::inDegrees(0.0f),0.0f,0.0f,1.0f));

     mp_InternalMatrixTransform->addChild(scene.get());

     mp_ExternalPAT = new osg::PositionAttitudeTransform;
     mp_ExternalPAT->addChild(mp_InternalMatrixTransform);




mp_ExternalPAT->setPosition(osg::Vec3d(mp_CurrT->data.db[0],mp_CurrT->data.db[2],-mp_CurrT->data.db[1]));
     mp_ExternalPAT->setAttitude(osg::Quat(cvNorm(mp_CurrRvect),
                                        osg::Vec3d(mp_CurrRvect->data.db[0],
                                                  mp_CurrRvect->data.db[2],
                                                  -mp_CurrRvect->data.db[1])
                                             )
                                 );





     mp_RootNode->addChild(mp_ExternalPAT);




    m_Optimizer.optimize(mp_RootNode);

    // set the scene to render
    m_Viewer.setSceneData(mp_RootNode);




    m_Viewer.setCameraManipulator(new osgGA::TrackballManipulator());

}



void COSGMesh::SetCameraMatrix(IntrinseqParameters IntraParameters)
{

    CreateMatOnDemand(&K, cvSize(3,3), CV_64FC1);
    cvSetZero(K);
    CreateMatOnDemand(&K_inv, cvSize(3,3), CV_64FC1);
    cvSetZero(K_inv);

    K->data.db[0]    =
IntraParameters.m_FocLength/IntraParameters.m_UPixSize;
    K->data.db[2]    =    IntraParameters.m_U0;
    K->data.db[4]    =
IntraParameters.m_FocLength/IntraParameters.m_VPixSize;
    K->data.db[5]    =    IntraParameters.m_V0;
    K->data.db[8]    =    1.;

    cvInvert(K,K_inv);

    m_CameraIntraParam = IntraParameters ;


    if (mp_VirtualCamera == NULL)
        mp_VirtualCamera =  new osg::Camera;

    if (mp_ViewerCamera == NULL)
        mp_ViewerCamera =  new osg::Camera;



    // Recuperation parametres "intrinseques"

    double fovy = (180./CV_PI)*2.  * ((CV_PI/2.)

-atan(2.*(m_CameraIntraParam.m_FocLength/m_CameraIntraParam.m_VPixSize)/m_SimImageSize.height));
    double aspectRatio = ((m_SimImageSize.width *
m_CameraIntraParam.m_UPixSize)
                            /(m_SimImageSize.height *
m_CameraIntraParam.m_VPixSize));
    int xoffset = cvRound(m_CameraIntraParam.m_U0 -
(double)m_SimImageSize.width/2.);
    int yoffset = cvRound(((double)m_SimImageSize.height/2.) -
m_CameraIntraParam.m_V0);

    double zNear = DEF_ZNEAR;   // 10 cm
    double zFar    =  DEF_ZFAR;      // 5 m

    std::cout << fovy << std::endl;
    std::cout << aspectRatio << std::endl;
    std::cout << xoffset << std::endl;
    std::cout << yoffset << std::endl;
    std::cout << zNear << std::endl;
    std::cout << zFar << std::endl;


    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new
osg::GraphicsContext::Traits;
    traits->x = xoffset + 0;
    traits->y = yoffset + 0;
    traits->width = m_SimImageSize.width;
    traits->height = m_SimImageSize.height;
    traits->windowDecoration = true;
    traits->doubleBuffer = false;
    traits->sharedContext = 0;
    traits->windowName = " Viewer Cam";

    osg::ref_ptr<osg::GraphicsContext> gc =
osg::GraphicsContext::createGraphicsContext(traits.get());

    mp_ViewerCamera->setGraphicsContext(gc.get());
    mp_ViewerCamera->setViewport(new osg::Viewport(xoffset,yoffset,
traits->width, traits->height));

    traits->x += m_SimImageSize.width;
    traits->windowName = "Virtual Cam";

    osg::ref_ptr<osg::GraphicsContext> gc_2 =
osg::GraphicsContext::createGraphicsContext(traits.get());

    mp_VirtualCamera->setGraphicsContext(gc_2.get());
    mp_VirtualCamera->setViewport(new osg::Viewport(xoffset,yoffset,
traits->width, traits->height));


    mp_VirtualCamera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
    mp_VirtualCamera->setClearMask(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);



  // set up projection.

      // set view
  mp_VirtualCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);

//m_VirtualCamera->setViewMatrixAsLookAt(bs.center()-osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

  mp_VirtualCamera->setViewMatrixAsLookAt(osg::Vec3(0.0f,
0.0f,0.0f),osg::Vec3(0.0f,2.0f,0.0f),osg::Vec3(0.0f,0.0f,1.0f));

mp_VirtualCamera->setProjectionMatrixAsPerspective(fovy,aspectRatio,zNear,zFar);



  // set the m_VirtualCamera to render before the main Camera.
  mp_VirtualCamera->setRenderOrder(osg::Camera::PRE_RENDER);


 //mp_VirtualCamera->setRenderTargetImplementation(osg::Camera::SEPERATE_WINDOW);

mp_VirtualCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);




  mp_Image = new osg::Image;
  //image->allocateImage(tex_width, tex_height, 1, GL_RGBA,
GL_UNSIGNED_BYTE);
  mp_Image->allocateImage(m_SimImageSize.width, m_SimImageSize.height, 1,
GL_DEPTH_COMPONENT, GL_FLOAT);

  // attach the image so its copied on each frame.
  unsigned int samples = 0;
  unsigned int colorSamples = 0;
  mp_VirtualCamera->attach(osg::Camera::DEPTH_BUFFER, mp_Image, samples,
colorSamples);


  m_Viewer.addSlave(mp_ViewerCamera, osg::Matrixd(), osg::Matrixd());


  mp_VirtualCamera->addChild(mp_ExternalPAT);

  mp_RootNode->addChild(mp_VirtualCamera);

  allocateOnDemand(&mp_Z_Buffer,m_SimImageSize,IPL_DEPTH_32F,1);


}





void COSGMesh::SetCurrentROI(void)
{
    double FocalLengthNorm = K->data.db[0];
    double XPixOpticalAxePosition = K->data.db[2];
    double YPixOpticalAxePosition = K->data.db[5];

    double MIN_X = mp_CurrT->data.db[0] - DEF_MESH_REAL_INIT_MAX_RADIUS;
    double MIN_Y = mp_CurrT->data.db[1] - DEF_MESH_REAL_INIT_MAX_RADIUS;
    double MIN_Z = mp_CurrT->data.db[2] - DEF_MESH_REAL_INIT_MAX_RADIUS;

    double MAX_X = mp_CurrT->data.db[0] + DEF_MESH_REAL_INIT_MAX_RADIUS;
    double MAX_Y = mp_CurrT->data.db[1] + DEF_MESH_REAL_INIT_MAX_RADIUS;

    double MIN_U = FocalLengthNorm * MIN_X/MIN_Z + XPixOpticalAxePosition;
    double MIN_V = FocalLengthNorm * MIN_Y/MIN_Z + YPixOpticalAxePosition;
    double MAX_U = FocalLengthNorm * MAX_X/MIN_Z + XPixOpticalAxePosition;
    double MAX_V = FocalLengthNorm * MAX_Y/MIN_Z + YPixOpticalAxePosition;

    m_CurrentROI =
cvRect(cvRound(MIN_U),cvRound(MIN_V),cvRound(MAX_U-MIN_U),cvRound(MAX_V-MIN_V));




}




void COSGMesh::SetCurrentTransform(CvMat * R, CvMat *T)
{

    if (R->cols * R->rows == 9)
    {
        cvCopy(R, mp_CurrRmat);
        cvRodrigues2(R , mp_CurrRvect);
    }
    else
    {
        cvCopy(R, mp_CurrRvect);
        cvRodrigues2(R , mp_CurrRmat);
    }

    cvCopy(T,mp_CurrT);




mp_ExternalPAT->setPosition(osg::Vec3d(mp_CurrT->data.db[0],mp_CurrT->data.db[2],-mp_CurrT->data.db[1]));
    mp_ExternalPAT->setAttitude(osg::Quat(cvNorm(mp_CurrRvect),
                                        osg::Vec3d(mp_CurrRvect->data.db[0],
                                                  mp_CurrRvect->data.db[2],
                                                  -mp_CurrRvect->data.db[1])
                                            )
                                );


    this->SetCurrentROI();
    this->apply();

}




void COSGMesh::AddIncrementalTransform(CvMat * R, CvMat *T)
{

    if (R->cols * R->rows == 9)
    {
        cvGEMM( R, mp_CurrT, 1., T , 1., mp_CurrT);
        cvGEMM(R, mp_CurrRmat,  1.,NULL, 0., mp_CurrRmat);
        cvRodrigues2(mp_CurrRmat , mp_CurrRvect);
    }
    else
    {
        cvRodrigues2(R , mp_TmpRotMat);
        cvGEMM( mp_TmpRotMat, mp_CurrT, 1., T , 1., mp_CurrT);
        cvGEMM(mp_TmpRotMat, mp_CurrRmat,  1.,NULL, 0., mp_CurrRmat);


        cvRodrigues2(mp_CurrRmat , mp_CurrRvect);
    }



mp_ExternalPAT->setPosition(osg::Vec3d(mp_CurrT->data.db[0],mp_CurrT->data.db[2],-mp_CurrT->data.db[1]));
    mp_ExternalPAT->setAttitude(osg::Quat(cvNorm(mp_CurrRvect),
                                        osg::Vec3d(mp_CurrRvect->data.db[0],
                                                  mp_CurrRvect->data.db[2],
                                                  -mp_CurrRvect->data.db[1])
                                            )
                                );

    this->SetCurrentROI();
    this->apply();
}







void COSGMesh::apply()
{


    mp_Image->dirty();
//    m_Viewer.updateTraversal();
    m_Viewer.frame();

}



"Initialization" and "SetCameraMatrix" are called by the COSGMesh instance's
constructor.

and the use of the instance takes the following form :


while (!done)
{
 // do something

COSGMesh_instance->AddIncrementalTransform(somerotation, sometranslation);
COSGMesh_instance->"GiveMeApointerOn_mp_Image()";    //(actually the depth
map)

//do something
}


1. - I dont know how to specify that the viewer have to be single-threaded
(shame on me)

2 - when i try "
mp_VirtualCamera->setRenderTargetImplementation(osg::Camera::SEPERATE_WINDOW);"
i'm quite surprise to observe *two* unnamed windows that
*alternatively*display the mp_VirtualCamera view


thank you for your patience...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/attachments/20090309/0aa5be48/attachment-0003.htm>


More information about the osg-users mailing list