📄 readerwritergeo.cpp
字号:
} txindices->push_back(txcoords->size()); float *uvc=NULL; gfd=gr->getField(GEO_DB_VRTX_UV_SET_0); if (gfd) { uvc=(float *)gfd->getstore(0); if (uvc) { // then there are tx coords osg::Vec2 uv(uvc[0], uvc[1]); txcoords->push_back(uv); } else { txcoords->push_back(osg::Vec2(0,0)); } } else { txcoords->push_back(osg::Vec2(0,0)); } gfd=gr->getField(GEO_DB_VRTX_PACKED_COLOR); if (gfd) { unsigned char *cp=gfd->getUCh4Arr(); float red=cp[0]/255.0f; float green=cp[1]/255.0f; float blue=cp[2]/255.0f; // may need alpha in future:: float alpha=cp[3]/255.0f; colors->push_back(Vec4(red,green,blue,1.0)); } else { // look for a colour index (exclusive!) gfd=gr->getField(GEO_DB_VRTX_COLOR_INDEX); if (gfd) { uint icp=gfd->getInt(); if (icp<128*(ghdr->getColorPalette())->size()) { float col[4]; ghdr->getPalette(icp,col); colors->push_back(Vec4(col[0],col[1],col[2],1.0)); } else { colors->push_back(Vec4(cdef[0],cdef[1],cdef[2],cdef[3])); } } else { colors->push_back(Vec4(cdef[0],cdef[1],cdef[2],cdef[3])); } int idx=colors->size()-1; colorindices->push_back(idx); } } return hbeh; } friend inline std::ostream& operator << (std::ostream& output, const vertexInfo& vf) { const osg::Vec2Array *txa=vf.getTexCoords(); osg::IntArray *normindices=vf.getNormIndices(); osg::IntArray *txind = vf.getTextureIndices(); output << " vertexinfo " << txa->size() << " nrm: " << normindices->size()<< " txinds " << txind->size()<<std::endl; uint i; for (i=0; i< txa->size(); i++) { const osg::Vec2 uvt=(*txa)[i]; output << " U " << uvt.x() << " v " << uvt.y() << std::endl; } for (i=0; i<normindices->size(); i++) { output << "Nind " << i << " = " << (*normindices)[i] << std::endl; } return output; // to enable cascading, monkey copy from osg\plane or \quat, Ubyte4, vec2,3,4,... }private: const std::vector<osg::Vec3> *cpool; // passed in from the geo file const std::vector<osg::Vec3> *npool; osg::Vec3Array *norms; osg::Vec3Array *coords; osg::Vec2Array *txcoords; osg::Vec4Array *colors; osg::IntArray *colorindices; osg::IntArray *coordindices; osg::IntArray *normindices; osg::IntArray *txindices; drBehList BehList; Vec4Array *polycols;};class geoInfo { // identifies properties required to make a new Geometry, and holds collection of vertices, indices, etcpublic: geoInfo(const int txidx=-2, const int sm=1, const int bs=1) { texture=txidx; // will be -1 or 0-number of textures geom=NULL; nstart=0; linewidth=1; bothsides=bs; shademodel=sm; } virtual ~geoInfo() { }; inline int getShademodel(void) const { return shademodel;} inline int getBothsides(void) const { return bothsides;} inline int getTexture(void) const { return texture;} inline vertexInfo *getVinf(void) { return &vinf;} void setPools(const std::vector<osg::Vec3> *coord_pool, const std::vector<osg::Vec3> *normal_pool) { vinf.setPools(coord_pool,normal_pool); } float getlinewidth(void) const { return linewidth;} void setlineWidth(const int w) { linewidth=w;} void setGeom(osg::Geometry *nugeom) { geom=nugeom;} osg::Geometry *getGeom() { return geom.get();} uint getStart(uint nv) { uint ns=nstart; nstart+=nv; return ns; } bool operator == (const geoInfo *gt) { // compare two geoInfos for same type of geometry if (gt->texture!=texture) return false; if (gt->bothsides == !bothsides) return false; if (gt->shademodel!=shademodel) return false; // other tests if failed return false return true; }private: int texture; // texture index int bothsides; // none, back,front int shademodel; int linewidth; vertexInfo vinf; uint nstart; // start vertex for a primitive osg::ref_ptr<osg::Geometry> geom; // the geometry created for this vinf and texture};class ReaderGEO{ public: osgDB::ReaderWriter::ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) { osgDB::ifstream fin(fileName.c_str(), std::ios::binary | std::ios::in ); if (fin.is_open() ) { // read the input file. // code for setting up the database path so that internally referenced file are searched for on relative paths. osg::ref_ptr<osgDB::ReaderWriter::Options> local_opt = options ? static_cast<osgDB::ReaderWriter::Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new osgDB::ReaderWriter::Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); typedef std::vector<osg::Node*> NodeList; NodeList nodeList; osg::Material *mt=new osg::Material; matlist.push_back(mt); theHeader=NULL; // load all nodes in file, placing them in a linear list corresponding to the on disk file. while(!fin.eof()) { georecord gr; gr.readfile(fin);// osg::notify(osg::WARN) << "end of record " << (int)gr.getType() << std::endl; if (gr.getType() == DB_DSK_NORMAL_POOL) { geoField *gfff=gr.getModField(GEO_DB_NORMAL_POOL_VALUES); gfff->uncompress();// uncompress the normals } recs.push_back(gr); // add to a list of all records } fin.close(); // now sort the records so that any record followed by a PUSh has a child set = next record, etc std::vector<georecord *> sorted=sort(recs); // tree-list of sorted record pointers#ifdef _DEBUG osgDB::Output fout("georex.txt"); //, std::ios_base::out ); // fout << "Debug raw file " << fileName << std::endl; // output(fout,recs); fout << "Debug Sorted file " << fileName << std::endl; output(fout,sorted); fout.close();#endif /**/ makeHeader(*(sorted.begin()), local_opt.get()); nodeList=makeosg(sorted, local_opt.get()); // make a list of osg nodes geotxlist.clear(); geomatlist.clear(); txlist.clear(); txenvlist.clear(); matlist.clear();/* */ coord_pool.clear(); normal_pool.clear(); osg::Node * groupnode = NULL; if (nodeList.empty()) { return osgDB::ReaderWriter::ReadResult("No data loaded from "+fileName); } else if (nodeList.size()==1) { groupnode = nodeList.front(); } else { osg::Group *group = new Group; group->setName("import group"); for(NodeList::iterator itr=nodeList.begin(); itr!=nodeList.end(); ++itr) { group->addChild(*itr); } groupnode=group; } (theHeader.get())->addChild(groupnode); groupnode=theHeader.get();#ifdef _DEBUG // output a .osg version osgDB::writeNodeFile(*groupnode,"geoosg.osg");#endif /**/ recs.clear(); return groupnode; } return 0L; } std::vector<georecord *> sort(geoRecordList &recs) { // return a tree-list of sorted record pointers // which mirrors the original .geo file (containers hold push/pop blocks). std::vector<georecord *> sorted; class georecord *curparent=NULL; for (geoRecordList::iterator itr=recs.begin(); itr!=recs.end(); ++itr) { const geoField *gfd; // osg::notify(osg::WARN) << *itr << std::endl; // now parse for push/pops and add to lists switch ((*itr).getType()) { case 101: // old header - not appropriate! curparent= &(*itr); sorted.push_back(&(*itr)); osg::notify(osg::WARN) << "Old version 2 header block found - possible error!" << std::endl; break; case DB_DSK_PUSH: if (!(curparent->getchildren().empty())) { curparent= curparent->getLastChild(); // itr-1; } else { //curparent=itr-1; } break; case DB_DSK_POP: if (curparent) curparent=curparent->getparent(); break; case DB_DSK_HEADER: // attach to previous curparent= &(*itr); sorted.push_back(&(*itr)); cpalrec=NULL; break; case DB_DSK_INTERNAL_VARS: // attach to parent case DB_DSK_LOCAL_VARS: case DB_DSK_EXTERNAL_VARS: (curparent)->addBehaviourRecord(&(*itr)); break; case DB_DSK_FLOAT_VAR: // attach to parent case DB_DSK_INT_VAR: case DB_DSK_LONG_VAR: case DB_DSK_DOUBLE_VAR: case DB_DSK_BOOL_VAR: case DB_DSK_FLOAT2_VAR: case DB_DSK_FLOAT3_VAR: case DB_DSK_FLOAT4_VAR: // else if ((*itr).isVar(): (curparent)->addBehaviourRecord(&(*itr)); break; case DB_DSK_TEXTURE: // attach to parent geotxlist.push_back(&(*itr)); break; case DB_DSK_MATERIAL: // attach to parent geomatlist.push_back(&(*itr)); break; case DB_DSK_VIEW: // not needed for Real Time break; case DB_DSK_COORD_POOL: // global - attach to readerwriterGEO class for whole model gfd=itr->getField(GEO_DB_COORD_POOL_VALUES); { float *crds= (gfd) ? (gfd->getVec3Arr()):NULL; uint nm=gfd->getNum(); for (uint i=0; i<nm; i++) { coord_pool.push_back(Vec3(crds[i*3],crds[i*3+1],crds[i*3+2])); } } break; case DB_DSK_NORMAL_POOL: // global - attach to readerwriterGEO gfd=itr->getField(GEO_DB_NORMAL_POOL_VALUES); { float *nrms= (gfd) ? (gfd->getVec3Arr()):NULL; uint nm=gfd->getNum(); for (uint i=0; i<nm; i++) { normal_pool.push_back(Vec3(nrms[i*3],nrms[i*3+1],nrms[i*3+2])); } } break; case DB_DSK_COLOR_PALETTE: // global - attach to readerwriterGEO cpalrec=&(*itr); break; case DB_DSK_BEHAVIOR: // || (*itr).isAction() // attach to previous case DB_DSK_CLAMP_ACTION:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -