📄 readerwritergeo.cpp
字号:
++rcitr) { if ((*rcitr)->getType()==DB_DSK_STRING_CONTENT_ACTION) { geoStrContentBehaviour *cb=new geoStrContentBehaviour; gfd=(*rcitr)->getField(GEO_DB_STRING_CONTENT_ACTION_INPUT_VAR); if (gfd) { ok=cb->makeBehave((*rcitr), theHeader.get()); if (ok) gcb->addBehaviour(cb); else delete cb; // ok=false; } } } } } return numt; } void addPolyActions(std::vector< georecord *>bhv, geoInfo &gi , const uint nv) { const vertexInfo *vinf=gi.getVinf(); const uint nstart=gi.getStart(nv); if (hasColorAction(bhv) || vinf->hasVertexActions()) { osg::Geometry *nugeom=gi.getGeom(); geoBehaviourDrawableCB *gcb=new geoBehaviourDrawableCB; nugeom->setUpdateCallback(gcb); nugeom->setUseDisplayList(false); // as we are updating arrays, cannot change colours for (std::vector< georecord *>::const_iterator rcitr=bhv.begin(); rcitr!=bhv.end(); ++rcitr) { if ((*rcitr)->getType()==DB_DSK_COLOR_RAMP_ACTION) { geoColourBehaviour *cb=new geoColourBehaviour; cb->setColorPalette(theHeader->getColorPalette()); if (nugeom->getColorBinding()==osg::Geometry::BIND_PER_VERTEX) { cb->setVertIndices(nstart,nv); // part of colours array to be modified } else if (nugeom->getColorBinding()==osg::Geometry::BIND_PER_PRIMITIVE) { // per primitive const uint nst=nugeom->getNumPrimitiveSets(); cb->setVertIndices(nst,1); // part of colours array to be modified } else { // overall cb->setVertIndices(0,1); // part of colours array to be modified } bool ok=cb->makeBehave((*rcitr), theHeader.get()); if (ok) gcb->addBehaviour(cb); else delete cb; } } vinf->addVertexActions(gcb); } } void makeLightPointNode(const georecord *grec, osgSim::LightPointNode *lpn) { // light points.. require OSG professional license // OR LGPL software. const std::vector<georecord *> gr=grec->getchildren(); for (std::vector<georecord *>::const_iterator itr=gr.begin(); itr!=gr.end(); ++itr) { if ((*itr)->getType()==DB_DSK_VERTEX || (*itr)->getType()==DB_DSK_FAT_VERTEX || (*itr)->getType()==DB_DSK_SLIM_VERTEX) { // light point vertices const geoField *gfd=(*itr)->getField(GEO_DB_VRTX_COORD); osg::Vec3 pos; if (gfd->getType()==DB_INT) { if (gfd) { int idx=gfd->getInt(); pos=coord_pool[idx]; } else { osg::notify(osg::WARN) << "No valid vertex index" << std::endl; } } else if (gfd->getType()==DB_VEC3F) { float *p=gfd->getVec3Arr(); pos.set(p[0],p[1],p[2]); } gfd=(*itr)->getField(GEO_DB_VRTX_PACKED_COLOR); if (gfd) { unsigned char *cls=gfd->getUCh4Arr(); float red=cls[0]/255.0f; float green=cls[1]/255.0f; float blue=cls[2]/255.0f; //float alpha=1.0f; // cls[3]*frac/255.0f; osg::Vec4 colour(red,green,blue,1.0f); lpn->addLightPoint(osgSim::LightPoint(true,pos,colour,1.0f,1.0f,0,0,osgSim::LightPoint::BLENDED)); } else { // get colour from palette gfd=(*itr)->getField(GEO_DB_VRTX_COLOR_INDEX); // use color pool... int icp= gfd ? gfd->getInt() : 0; float col[4]; theHeader->getPalette(icp, col); lpn->addLightPoint(osgSim::LightPoint(pos, osg::Vec4(col[0],col[1],col[2],1.0f))); } } } } void makeLightPointGeometry(const georecord *grec, Group *nug) { const std::vector<georecord *> gr=grec->getchildren(); for (std::vector<georecord *>::const_iterator itr=gr.begin(); itr!=gr.end(); ++itr) { if ((*itr)->getType()==DB_DSK_LIGHTPT) { // light points ONLY geoInfo ginf(0,0, 1); ginf.setPools(&coord_pool, &normal_pool); // holds all types of coords, indices etc osgSim::LightPointNode *gd=new osgSim::LightPointNode; // to be implemented const geoField *gfd=(*itr)->getField(GEO_DB_LIGHTPT_TYPE); // omni, uni, bi makeLightPointNode((*itr),gd); // add vertex positions to light point set nug->addChild(gd); } } } int makeAnimatedGeometry(const georecord grec, const int imat,Group *nug) { // animated polygons - create a matrix & geode & poly & add to group nug const std::vector<georecord *> gr=grec.getchildren(); int nanimations=0; const geoField *gfd=grec.getField(GEO_DB_RENDERGROUP_CULLING); // back, front, none unsigned int bothsides=gfd ? gfd->getUInt() : 0;// int bothsides =allOneSided(&grec); for (std::vector<georecord *>::const_iterator itr=gr.begin(); itr!=gr.end(); ++itr) { std::vector< georecord *>bhv=(*itr)->getBehaviour(); // behaviours attached to facets, eg colour! if ((*itr)->getType()==DB_DSK_POLYGON && !bhv.empty()) { // animated facets go here nanimations++; if (hasMotionAction(bhv)) { // make matrix if motion needed. const geoField *gfd=(*itr)->getField(GEO_DB_POLY_TEX0); int txidx= gfd ? gfd->getInt() : -1; gfd=(*itr)->getField(GEO_DB_POLY_SHADEMODEL); // shaded gouraud, flat... int shademodel=gfd ? gfd->getInt() : GEO_POLY_SHADEMODEL_LIT_GOURAUD; gfd=(*itr)->getField(GEO_DB_POLY_USE_MATERIAL_DIFFUSE); // true: use material... bool usemat= gfd ? gfd->getBool() : false; geoInfo ginf(txidx,shademodel, bothsides); ginf.setPools(&coord_pool, &normal_pool); // holds all types of coords, indices etc MatrixTransform *mtr=makeBehave(*itr); Geode *gd=new Geode; gfd=(*itr)->getField(GEO_DB_POLY_DSTYLE); // solid, wire... int dstyle= gfd ? gfd->getInt() : GEO_POLY_DSTYLE_SOLID; if (!usemat && (shademodel== GEO_POLY_SHADEMODEL_LIT ||shademodel== GEO_POLY_SHADEMODEL_LIT_GOURAUD) ) { // get the per vertex colours OR per face colours. gfd=(*itr)->getField(GEO_DB_POLY_PACKED_COLOR); // the colour if (gfd) { unsigned char *cls=gfd->getUCh4Arr(); float red=cls[0]/255.0f; float green=cls[1]/255.0f; float blue=cls[2]/255.0f; float alpha=1.0f; // cls[3]*frac/255.0f; ginf.getVinf()->addPolcolour(osg::Vec4(red,green,blue,alpha)); } else { // get colour from palette gfd=(*itr)->getField(GEO_DB_POLY_COLOR_INDEX); // use color pool... int icp= gfd ? gfd->getInt() : 0; float col[4]; theHeader->getPalette(icp, col); ginf.getVinf()->addPolcolour(osg::Vec4(col[0],col[1],col[2],1.0)); } } nug->addChild(mtr); mtr->addChild(gd); osg::Geometry *nugeom=makeNewGeometry((*itr), ginf, imat); int nv=getprim((*itr),ginf); gd->addDrawable(nugeom); // now add the polygon if (dstyle==GEO_POLY_DSTYLE_SOLID_BOTH_SIDES || dstyle == GEO_POLY_DSTYLE_SOLID) nugeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,nv)); if (dstyle==GEO_POLY_DSTYLE_OPEN_WIRE) nugeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,0,nv)); if (dstyle==GEO_POLY_DSTYLE_CLOSED_WIRE) nugeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,nv)); if (dstyle==GEO_POLY_DSTYLE_POINTS) nugeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,nv)); addPolyActions(bhv, ginf ,nv); } } } return nanimations; } bool hasColorAction(std::vector< georecord *>bhv) { // true if one of the actions changes colour bool ok=false; // if (bhv) { for (std::vector< georecord *>::const_iterator rcitr=bhv.begin(); rcitr!=bhv.end() && !ok; ++rcitr) { switch ((*rcitr)->getType()) { case DB_DSK_COLOR_RAMP_ACTION: ok=true; break; default: break; } } // } return ok; } bool hasMotionAction(std::vector< georecord *>bhv) { // true if one of the actions is a motion bool ok=false; // if (bhv) { for (std::vector< georecord *>::const_iterator rcitr=bhv.begin(); rcitr!=bhv.end() && !ok; ++rcitr) { switch ((*rcitr)->getType()) { case DB_DSK_ROTATE_ACTION: case DB_DSK_SCALE_ACTION: case DB_DSK_TRANSLATE_ACTION: ok=true; break; default: break; } } // } return ok; } geoInfo *getGeometry(const georecord *grec,Geode *nug, std::vector<class geoInfo> *ia, const unsigned int imat, const int shademodel, const int bothsides) { int igidx=0, igeom=-1; const geoField *gfd=grec->getField(GEO_DB_POLY_TEX0); int txidx= gfd ? gfd->getInt() : -1; for (std::vector<class geoInfo>::iterator itrint=ia->begin(); itrint!=ia->end() && igeom<0; ++itrint) { // find a geometry that shares this texture. // also test for other properties of a unique material: // - use material/vertex colours; geoInfo gu(txidx,shademodel, bothsides); if (gu==&(*itrint) && !(*itrint).getGeom()->getUpdateCallback()) igeom=igidx; igidx++; } std::vector< georecord *>bhv=grec->getBehaviour(); // behaviours attached to facets, eg colour! if (igeom<0 || hasColorAction(bhv)) { // we need a new geometry for this due to new texture/material combo or an action gfd=grec->getField(GEO_DB_POLY_SHADEMODEL); // shaded gouraud, flat... int shademodel=gfd ? gfd->getInt() : GEO_POLY_SHADEMODEL_LIT_GOURAUD; geoInfo gi(txidx,shademodel, bothsides); gi.setPools(&coord_pool, &normal_pool); gfd=grec->getField(GEO_DB_POLY_LINE_WIDTH); // integer line width... if (gfd) { int w=gfd->getInt(); gi.setlineWidth(w); } osg::Geometry *nugeom=makeNewGeometry(grec, gi, imat); nug->addDrawable(nugeom); igeom=ia->size(); ia->push_back(gi); // look up table for which texture corresponds to which geom } return (&((*ia)[igeom])); } int makeGeometry(const georecord &grec, const unsigned int imat,Geode *nug) { // makegeometry makes a set of Geometrys attached to current parent (Geode nug) const std::vector<georecord *> gr=grec.getchildren(); // std::vector<osg::Geometry *> geom; if (gr.size()>0) { std::vector<class geoInfo> ia; // list of texture indices & vinfo found in this geode; sort into new const geoField *gfd=grec.getField(GEO_DB_RENDERGROUP_CULLING); // back, front, none unsigned int bothsides=gfd ? gfd->getUInt() : 0; // vertexInfo vinf(&coord_pool, &normal_pool); // holds all types of coords, indices etc// bool bothsides=allOneSided(&grec); for (std::vector<georecord *>::const_iterator itr=gr.begin(); itr!=gr.end(); ++itr) { std::vector< georecord *>bhv=(*itr)->getBehaviour(); // behaviours attached to facets, eg colour! if ( !hasMotionAction(bhv)) { // animated facets go elsewhere if ((*itr)->getType()==DB_DSK_POLYGON) { // a normal facet const geoField *gfd=(*itr)->getField(GEO_DB_POLY_DSTYLE); // solid, wire... int dstyle= gfd ? gfd->getInt() : GEO_POLY_DSTYLE_SOLID; gfd=(*itr)->getField(GEO_DB_POLY_SHADEMODEL); // shaded gouraud, flat... int shademodel=gfd ? gfd->getInt() : GEO_POLY_SHADEMODEL_LIT_GOURAUD; geoInfo *gi=getGeometry((*itr), nug, &ia, imat,shademodel, bothsides); //shade models GEO_POLY_SHADEMODEL_FLAT GEO_POLY_SHADEMODEL_GOURAUD // GEO_POLY_SHADEMODEL_LIT GEO_POLY_SHADEMODEL_LIT_GOURAUD gfd=(*itr)->getField(GEO_DB_POLY_USE_MATERIAL_DIFFUSE); // true: use material... bool usemat= gfd ? gfd->getBool() : false; if (!usemat || shademodel== GEO_POLY_SHADEMODEL_LIT /*||shademodel== GEO_POLY_SHADEMODEL_LIT_GOURAUD) */ ) { // get the per vertex colours OR per face colours. gfd=(*itr)->getField(GEO_DB_POLY_PACKED_COLOR); // the colour if (gfd) { unsigned char *cls=gfd->getUCh4Arr(); float red=cls[0]/255.0f; float green=cls[1]/255.0f; float blue=cls[2]/255.0f; float alpha=1.0f; // cls[3]*frac/255.0f; gi->getVinf()->addPolcolour(osg::Vec4(red,green,blue,alpha)); } else { // get colour from palette gfd=(*itr)->getField(GEO_DB_POLY_COLOR_INDEX); // use color pool... int icp= gfd ? gfd->getInt() : 0; float col[4]; theHeader->getPalette(icp, col); gi->getVinf()->addPolcolour(osg::Vec4(col[0],col[1],col[2],1.0));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -