1 #include "OpenSceneGraphHelper.hh"
3 #include <Utils/TriangleMesh.hh>
6 #include <Base/Image/Image.hh>
7 #include <Filter/Rescale.hh>
8 #include <Gui/biasgl.h>
10 #include <Base/Image/ImageIO.hh>
14 #include <osg/Geometry>
15 #include <osg/Texture2D>
17 #include <osg/MatrixTransform>
18 #include <osg/Billboard>
19 #include <osg/ShapeDrawable>
21 #include <osg/LineWidth>
22 #include <osg/LineStipple>
31 bool OpenSceneGraphHelper::
42 GLenum colormode = GL_RGBA;
43 unsigned int colOff = 4;
50 colormode = GL_LUMINANCE;
66 BIASERR(
"unexpected channel count! " << chNum);
69 out->allocateImage(width,height,colOff, colormode, GL_UNSIGNED_BYTE);
76 void * dest = (
void*) out->data();
77 BIASASSERT(dest!=NULL);
79 BIASASSERT(src!=NULL);
83 memcpy( dest, src, width*height*colOff );
88 for(
unsigned int p=0; p<width*height; p++)
91 ((
unsigned char*) src)[p*3] = ((
unsigned char*) dest)[p*2];
92 ((
unsigned char*) src)[p*3+1] = ((
unsigned char*) dest)[p*2+1];
93 ((
unsigned char*) src)[p*3+2] = 0;
101 BIASWARN(
"texture has too many channels! (channelcount>4)");
108 bool OpenSceneGraphHelper::
109 OSGimageToBIASimage(
const osg::Image* in,
112 if(!in)
return false;
113 if(in->getDataType() !=GL_UNSIGNED_BYTE)
115 BIASWARN(
"only unsigned byte based textures supported!");
118 unsigned int width = in->s();
119 unsigned int height = in->t();
120 unsigned int chNum = 3;
121 switch(in->getPixelFormat())
133 BIASWARN(
"unsupported pixel format!");
136 out.
Init(width,height,chNum);
138 #if defined WIN32 && defined BIAS_BUILD_SHARED_LIBS
145 BIASASSERT(dest!=NULL);
146 void* src = (
void*) in->data();
147 BIASASSERT(src!=NULL);
148 memcpy( dest, src, width*height*chNum );
156 osg::Node * OpenSceneGraphHelper::
158 const std::string& name)
160 osg::MatrixTransform* mTrans =
new osg::MatrixTransform;
161 mTrans->setName(name);
162 osg::Geode* mGeode =
new osg::Geode();
163 osg::Geometry* mGeometry =
new osg::Geometry();
164 mGeode->addDrawable(mGeometry);
165 mTrans->addChild(mGeode);
167 const vector<Vector3<double> > &vertexSet = mesh.
GetVerticesRef();
173 unsigned int vertNumb = vertexSet.size();
174 osg::Vec3Array* vertices =
new osg::Vec3Array(vertNumb);
176 for(
unsigned int vt = 0; vt < vertNumb; vt++)
177 (*vertices)[vt].set(vertexSet[vt][0],vertexSet[vt][1],vertexSet[vt][2]);
179 mGeometry->setVertexArray(vertices);
182 unsigned int texCoordNumb = texCoordSet.size();
183 if(texCoordNumb!= vertNumb)
184 BIASWARN(
"Number of texture coordinates does not match vertex number.");
186 osg::Vec2Array* texCoords =
new osg::Vec2Array(texCoordNumb);
187 for(
unsigned int tc=0; tc<texCoordNumb; tc++)
188 (*texCoords)[tc].set(texCoordSet[tc][0],texCoordSet[tc][1]);
189 mGeometry->setTexCoordArray(0,texCoords);
193 unsigned int faceNumb = faceIndices.size();
195 osg::DrawElementsUInt* drawTriangleElmtsU=NULL;
196 osg::DrawElementsUInt* drawQuadsElmtsU=NULL;
198 for(
unsigned int fc = 0; fc<faceNumb ; fc++)
203 unsigned int indexNum = faceIndices[fc].Size();
204 osg::DrawElementsUInt* actualFace;
209 if(drawTriangleElmtsU==NULL)
212 new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
213 mGeometry->addPrimitiveSet(drawTriangleElmtsU);
215 actualFace = drawTriangleElmtsU;
218 if(drawQuadsElmtsU==NULL)
221 new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS);
222 mGeometry->addPrimitiveSet(drawQuadsElmtsU);
224 actualFace = drawQuadsElmtsU;
228 new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON);
229 mGeometry->addPrimitiveSet(actualFace);
232 for(
unsigned int ix = 0; ix<indexNum; ix++)
235 int idx = (faceIndices[fc])[ix];
237 actualFace->push_back((
unsigned int) idx);
242 osg::Image* mImage =
new osg::Image;
244 const bool CopyImage =
true;
245 if(BIASimageToOSGimage(mesh.
GetTextureRef(),mImage,CopyImage)) {
247 mTex2D->setImage( mImage );
249 osg::StateSet *ss =
new osg::StateSet;
250 ss->setTextureAttributeAndModes(0, mTex2D.get());
254 osg::TexEnv *txenv =
new osg::TexEnv(osg::TexEnv::REPLACE);
255 ss->setTextureAttribute(0, txenv);
259 mGeode->setStateSet(ss);
266 bool OpenSceneGraphHelper::OSG2BIASMatrix(
const osg::Matrixd& OsgMat,
269 const double* pOSDMatD = OsgMat.ptr();
270 double* pBIASMatD = BiasMat.
GetData();
271 if(pOSDMatD&&pBIASMatD)
273 for(
int i=0; i<16; i++)
275 pBIASMatD[i]=pOSDMatD[i];
282 bool OpenSceneGraphHelper::BIAS2OSGMatrix(
284 osg::Matrixd& OsgMat)
286 double* pOSDMatD = OsgMat.ptr();
287 const double* pBIASMatD = BiasMat.
GetData();
288 if(pOSDMatD&&pBIASMatD)
290 for(
int i=0; i<16; i++)
292 pOSDMatD[i]=pBIASMatD[i];
303 unsigned char current=0;
304 unsigned char next=1;
305 tmpi[current] = &tex;
309 GLenum format = GL_RGB;
310 GLenum internalFormat = GL_RGB;
314 internalFormat = GL_RGBA;
318 BIASWARN(
"AdjustImageSizeToGPULimit not implemented for non rgb(a) images");
332 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, tex.
GetWidth(), tex.
GetHeight(), 0, format, GL_UNSIGNED_BYTE, NULL);
333 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &reswidth);
337 cout<<
"rescaling..."<<endl;
338 if (rescale.
DownsampleBy2(*(tmpi[current]),*(tmpi[next]))!=0){
339 BIASERR(
"error downsampling");
343 unsigned char ttt=next;
346 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, tmpi[next]->GetWidth(), tmpi[next]->GetHeight(), 0, format, GL_UNSIGNED_BYTE, NULL);
347 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &reswidth);
367 if(current==1) tex = *(tmpi[1]);
373 bool OpenSceneGraphHelper::
377 BEXCEPTION(
"OpenSceneGraphHelper::HasDescription(): NULL argument.");
378 const osg::Node::DescriptionList &dl = node->getDescriptions();
379 osg::Node::DescriptionList::const_iterator it;
380 for (it=dl.begin(); it!=dl.end(); it++){
381 size_t pos = it->find(key);
382 if (pos!=string::npos){
383 value = it->substr(pos+key.size()+1, it->size()-(pos+key.size())-1);
391 bool OpenSceneGraphHelper::
395 BEXCEPTION(
"OpenSceneGraphHelper::RemoveDescription(): NULL argument.");
396 osg::Node::DescriptionList &dl = node->getDescriptions();
397 osg::Node::DescriptionList::iterator it;
398 for (it=dl.begin(); it!=dl.end(); it++){
399 size_t pos = it->find(key);
400 if (pos!=string::npos){
409 bool OpenSceneGraphHelper::
411 const string &key,
const string &value)
414 BEXCEPTION(
"OpenSceneGraphHelper::AddOrSetInfo(): NULL argument.");
417 if (HasInfo(node, key, former_val)){
418 RemoveInfo(node, key);
421 if (key.find(INFO_SEP)!=string::npos || value.find(INFO_SEP)!=string::npos){
422 BEXCEPTION(
"OpenSceneGraphHelper::AddOrSetInfo(): Invalid character \'"
423 <<INFO_SEP<<
"\' in key or value.");
425 node->addDescription(key+INFO_SEP+value);
430 void OpenSceneGraphHelper::
432 std::map<std::string, std::string> &key_val)
435 const osg::Node::DescriptionList &dl = node->getDescriptions();
436 osg::Node::DescriptionList::const_iterator it;
437 for (it=dl.begin(); it!=dl.end(); it++){
438 size_t pos = it->find(INFO_SEP);
439 if (pos==string::npos){
440 BEXCEPTION(
"OpenSceneGraphHelper::GetInfo(): Invalid info (missing "
441 <<
"separator \'"<<INFO_SEP<<
"\'");
443 string key = it->substr(0, pos);
444 string val = it->substr(pos+1, it->size()-(pos+1));
452 const std::string &key,
const string &value)
455 BEXCEPTION(
"OpenSceneGraphHelper::FindNodeWithInfo(): NULL argument.");
458 if (HasInfo(CurrentNode, key, node_value) &&
459 (value == node_value) ){
464 unsigned numchildr = gr->getNumChildren();
465 for(
unsigned i=0; i<numchildr; i++){
467 FindNodeWithInfo(gr->getChild(i), key, value);
475 std::vector<osg::ref_ptr<osg::Node> > OpenSceneGraphHelper::
477 const std::string &key)
479 vector<osg::ref_ptr<osg::Node> > result;
480 FindNodesWithInfoHelper_(CurrentNode, key, result);
485 void OpenSceneGraphHelper::
487 const std::string &key,
491 BEXCEPTION(
"OpenSceneGraphHelper::FindNodeWithInfo(): NULL argument.");
494 if ( HasInfo(CurrentNode, key, node_value) ){
495 result.push_back(CurrentNode);
499 unsigned numchildr = gr->getNumChildren();
500 for(
unsigned i=0; i<numchildr; i++){
501 FindNodesWithInfoHelper_(gr->getChild(i), key, result);
507 void OpenSceneGraphHelper::
510 const osg::Node::DescriptionList &dl = node->getDescriptions();
511 osg::Node::DescriptionList::const_iterator it;
512 cout <<
"Node \""<<node->getName()<<
"\":\n";
513 for (it=dl.begin(); it!=dl.end(); it++){
514 cout <<
" "<<*it<<endl;
522 for (
int y=0; y<4; y++){
523 for (
int x=0; x<4; x++){
527 if (y!=3) os <<
";\n";
536 os <<
"["<<v[0]<<
" "<<v[1]<<
" "<<v[2]<<
"]";
const std::vector< BIAS::Vector3< double > > & GetVerticesRef() const
const std::vector< BIAS::Vector< int > > & GetTriangleIndicesRef() const
unsigned int GetWidth() const
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Create and represent a 3D triangle mesh.
unsigned int GetHeight() const
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
const BIAS::Image< unsigned char > & GetTextureRef() const
int DownsampleBy2(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Takes the source image that has to have a defined ROI.
int Flip()
flips the image vertically (row order is inverted) In place function return 0 in case of success...
const std::vector< BIAS::Vector2< float > > & GetTexCoordsRef() const