[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.htm>
More information about the osg-users
mailing list