📄 readerwriterdw.cpp
字号:
poses.idx=idx[j]; } void tessellate(const std::vector<Vec3> verts, const dwmaterial *themat, GLUtesselator *ts, _dwobj *dwob, const Matrix *tmat) const; void link(const int idop, const _face *f2, const int idop2,const std::vector<Vec3> verts, const dwmaterial *themat) const; // to join up opposed faces of a hole inline const int getidx(int i) const { return idx[i];}private: void linkholes(const std::vector<Vec3> verts, const dwmaterial *themat, const _face *f2) const; void reverse() { // reverse order of the vertices for (int j=0; j<nv/2; j++) { int it=idx[j]; idx[j]=idx[nv-j-1]; idx[nv-j-1]=it; } } int nop; // number of openings so far class _face *opening; // openings in this face. number of verts, vertex list for opening int nv; // number of vertices in the face int nset; // number read so far int nVertStart; // start index of vertices in the grand Geometry Vec3 nrm; // surface normal int *idx; // indices into the vertex list for the object};// structure for generating triangles (and tstrips, tfans etc)// from a design workshop object.class prims {public: prims() { nbegin=0; // primlengs=NULL; gsidx=NULL;nrmidx=NULL; // txidx=NULL;nrms=NULL;txcoords=NULL; // nload=0; nff=0; curmode=0; vertices = new osg::Vec3Array; normals = new osg::Vec3Array; txc = new osg::Vec3Array; txcoords=new osg::Vec3Array; // new Vec2[6*nfnvf]; // one texture coord per vertex tmat=NULL; } ~prims() { /*delete [] primlengs; delete [] nrms; delete [] gsidx; delete [] nrmidx; delete [] txcoords;*/ } void addv(avertex *pos) { // tessellation callback vertices->push_back(osg::Vec3(pos->pos[0],pos->pos[1],pos->pos[2])); normals->push_back(pos->nrmv); txcoords->push_back(osg::Vec3(pos->uv[0],pos->uv[1],0.0f)); } void End() { // tessellation is done int nverts=vertices->size()-nbegin; osg::DrawArrays *drw=NULL; switch (primType) { case GL_TRIANGLES: //gset->setPrimType( osg::GeoSet::TRIANGLES ); //gset->setNumPrims( nload/3 ); drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,nbegin,nverts); gset->addPrimitiveSet(drw); break; case GL_TRIANGLE_STRIP: //gset->setPrimType( osg::GeoSet::TRIANGLE_STRIP ); //gset->setPrimLengths( nuprimlengs ); drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP,nbegin,nverts); gset->addPrimitiveSet(drw); break; case GL_TRIANGLE_FAN: //gset->setPrimType( osg::GeoSet::TRIANGLE_FAN ); //gset->setPrimLengths( nuprimlengs ); drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,nbegin,nverts); gset->addPrimitiveSet(drw); break; case GL_QUADS: //gset->setPrimType( osg::GeoSet::QUADS ); //gset->setNumPrims( nload/4 ); drw=new osg::DrawArrays(osg::PrimitiveSet::QUADS,nbegin,nverts); gset->addPrimitiveSet(drw); break; case GL_QUAD_STRIP: //gset->setPrimType( osg::GeoSet::QUAD_STRIP ); drw=new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,nbegin,nverts); gset->addPrimitiveSet(drw); break; case GL_POLYGON: //gset->setPrimType( osg::GeoSet::POLYGON ); drw=new osg::DrawArrays(osg::PrimitiveSet::POLYGON,nbegin,nverts); gset->addPrimitiveSet(drw); break; } } void begin(GLenum op) { // part of a Tessellator callback - starts a new primitive of type op primType=op; nbegin=vertices->size(); } void combine( GLdouble coords[3], avertex *d[4], GLfloat w[4], avertex **dataOut , _dwobj *dwob); void linkholes(const std::vector<Vec3> verts, const dwmaterial *themat, const _face *f1, const _face *f2, const int ipr[2], const int nv) { int gsidx[4]; gsidx[0]=f1->getidx(ipr[1]); // vertex position index gsidx[1]=f1->getidx(ipr[0]); // vertex position index gsidx[2]=f2->getidx(nv-ipr[0]-1); // vertex position index gsidx[3]=f2->getidx(nv-ipr[1]-1); // vertex position index Matrix mx; // texture matrix transform to plane Vec3 s1,s2; Vec3 nrm; // calculated normal to face s1=verts[gsidx[1]]-verts[gsidx[0]]; s2=verts[gsidx[2]]-verts[gsidx[1]]; f1->norm(nrm, s2, s1); f1->settrans(mx, nrm, verts,themat); int n1=vertices->size(); for (int j=0; j<4; j++) { Vec3 uv; Vec3 coord=(verts[gsidx[j]]); vertices->push_back( coord ); uv=mx*verts[gsidx[j]]; txcoords->push_back(uv); normals->push_back(nrm); } osg::DrawArrays *drw=NULL; drw=new osg::DrawArrays(osg::PrimitiveSet::QUADS,n1,4); gset->addPrimitiveSet(drw); } void tessellate(_face &fc, const std::vector<Vec3> verts, const dwmaterial *themat,GLUtesselator* ts, _dwobj *dwob) { // generates a set of primitives all of one type (eg tris, qstrip trifan...) fc.setNBegin(vertices->size()); fc.tessellate(verts, themat, ts, dwob, tmat); } void buildGeometry() { // at end of all faces, add collection of vertices to geometry gset->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); //BIND_PERPRIM); // gset->setNormalArray(normals); gset->setTexCoordArray(0,txcoords); gset->setVertexArray(vertices); // setCoords( vts, nusidx ); } void setGeometry(osg::Geometry *gs) { gset=gs; } void settmat(const Matrix *mx) { tmat= mx; }private: osg::Geometry *gset; osg::Vec3Array* vertices; osg::Vec3Array* normals; osg::Vec3Array* txc; osg::Vec3Array* txcoords; GLenum primType; int nbegin; // vertex indices for current primitive const Matrix *tmat; // local texture matrix, or may be NULL for default mapping};static prims *prd=NULL; // OK not nice to have a static but the OpenGL Tessellator etc wants to be able to refer// to things that are not available via an argument// tessellation subroutines - have 'C' prototypes, not a member of any class...// But I want ot use the prims class to contain useful information such as texture matrix etc.void CALLBACK myFaceBegin(GLenum op){// tess 'primitive begins' call back prd->begin(op);}void CALLBACK myFaceEnd(){// tess primiitve ends call back prd->End();}void CALLBACK myVertex(void *pv){// tess vertex call back with texture coord == void *pv1, prd->addv((avertex *)pv);}void CALLBACK combineCallback( GLdouble coords[3], avertex *d[4], GLfloat w[4], avertex **dataOut , _dwobj *dwob) { // dwob needed if there is a combine callback to add the new vertex to group prd->combine(coords, d, w, dataOut,dwob);}void CALLBACK error (GLenum errno){ // tess error code const unsigned char *errm=gluErrorString(errno); printf("Tessellator error %d %s\n", static_cast<int>(errno),errm);//, errm} //==========void _face::linkholes(const std::vector<Vec3> verts, const dwmaterial *themat, const _face *f2) const{ int ipr[2]; ipr[0]=nv-1; for (int i=0; i<nv; i++) { // pairs of vertices ipr[1]=nVertStart+i; prd->linkholes(verts, themat, this, f2, ipr, nv); ipr[0]=ipr[1]; }}void _face::link(const int idop, const _face *f2, const int idop2,const std::vector<Vec3> verts, const dwmaterial *themat) const{ // to join up opposed faces of a hole; starts using hole[idop] in THIS, ands at f2.Hole[idop2] opening[idop].linkholes(verts, themat, &f2->opening[idop2]);}//======== Edges link 2 vertices; indicate where a sharp crease can be found ==========class _dwedge {public: _dwedge(){;} ~_dwedge(){;} void set(int i, int j) { e1=i; e2=j; }private: int e1,e2; // ends of the edge - it joins verts[e1] to verts[e2]};//===================class _dwobj { // class for design workshop read of a single objectpublic: _dwobj() { nverts=nfaces=0; openings=NULL;faces=NULL; tmat=NULL; edges=NULL; nopens=nfaceverts=0; fc1=fc2=NULL; colour[0]=colour[1]=colour[2]=colour[3]=1; } ~_dwobj() {/*delete verts; delete faces;delete openings;*/ delete fc1;delete fc2; } int readOpenings(FILE *fp, const int nexpected) { // read up to nexpected openings, each opening may have a number of vertices char buff[256]; openings=new int[nexpected*2]; fc1=new unsigned short[nexpected]; fc2=new unsigned short[nexpected]; nopens=0; int nvop=0; // current number of vertices in hole in object while (nopens<nexpected) { // for each opening if (dwfgets(buff, sizeof( buff ), fp )) { if (strncmp(buff, "Opening:",8)==0) { } else if (strncmp(buff, "faces:",6)==0) { sscanf(buff, "faces: %hu %hu", fc1+nopens, fc2+nopens); } else if (strncmp(buff, "numVerts:",9)==0) { int nvtot=nverts; // total number of hole vertices read so far nvop=atoi(buff+9); openings[nopens*2]=faces[fc1[nopens]].setnvop(nvop/2); // prepare opening in face openings[nopens*2+1]=faces[fc2[nopens]].setnvop(nvop/2); readVerts(fp, nvop); for (; nvtot<nverts; nvtot++) { if (faces[fc1[nopens]].holecomplete()) { if (!faces[fc2[nopens]].holecomplete()) { faces[fc2[nopens]].addholevtx(nvtot); } else { // error } } else { faces[fc1[nopens]].addholevtx(nvtot); } } if (faces[fc2[nopens]].holecomplete()) { nopens++; } } else { // general line } } } return nopens; } int readEdges(FILE *fp, const int nexpected) { // read up to nexpected vertex pairs. These are currently ignored. // will define crease edges in future. edges=new _dwedge[nexpected]; nedges=0; if (edges) { char buff[256]; while (nedges<nexpected) { if (dwfgets(buff, sizeof( buff ), fp )) { int i1, i2; sscanf(buff,"%d %d", &i1, &i2); edges[nedges].set(i1,i2); nedges++; } } } return nedges; } int readFaces(FILE *fp, const int nexpected) { // read up to nexpected faces faces=new _face[nexpected]; char buff[256]; if (faces) { while (nfaces<nexpected) { if (dwfgets(buff, sizeof( buff ), fp )) { if (strncmp(buff,"numVerts:",9)==0) { int nv=atoi(buff+9); faces[nfaces].setnv(nv); } else { int idx=atoi(buff); faces[nfaces].addvtx(idx); if (faces[nfaces].complete()) { nfaceverts+=faces[nfaces].getnv(); nfaces++; } } } } } return nfaces; } void buildDrawable(Group *grp, const osgDB::ReaderWriter::Options *options); // convert dwobj into osg geosets void setcolour(const float rgb[3]) { colour[0]=rgb[0]; colour[1]=rgb[1]; colour[2]=rgb[2]; } void reset() { faces=NULL; //verts=NULL; nverts=nfaces=nfaceverts=nopens=nedges=0; } void setmat(dwmaterial *mt) { themat=mt; } int readVerts(FILE *fp, const int nexpected) { // read up to nexpected vertices int ntot=nverts+nexpected; char buff[256]; verts.reserve(ntot); while (nverts<ntot) { if (dwfgets(buff, sizeof( buff ), fp )) { float x,y,z; sscanf(buff,"%f %f %f", &x, &y, &z); Vec3 pos(x,-y,z); verts.push_back(pos); } nverts++; }// osg::notify(osg::NOTICE) << nverts<<" inp "<<verts[nverts-1].x()<<// " "<<verts[nverts-1].y()<<" "<<verts[nverts-1].z()<<" "<<verts.size()<< std::endl; return nverts; } int addvtx(float x, float y, float z) { // add a single vertex to the object Vec3 pos(x,y,z); verts.push_back(pos); // nverts++; return nverts-1; } void settmat(const Matrix& mx) { tmat= new Matrix(mx); } void makeuv(Vec2 &uv, const double pos[]) { Vec3 p; Vec3 txc; p.set(pos[0],pos[1],pos[2]); txc = (*mx)*p; uv[0]=txc[0]; uv[1]=txc[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -