- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgPlugins/dw/ReaderWriterDW.cpp
r12365 r13041 9 9 // DW Lite is completely free, produces textured 3D models 10 10 // aimed mostly at the architectural world. Flat polygons are generally produced 11 // No ability to produce smooth shading, unfortunately. 11 // No ability to produce smooth shading, unfortunately. 12 12 // But it is the best bangs per buck. (Anything/nothing = infinite value, and this is quite a lot/nothing) 13 13 … … 34 34 35 35 #ifndef WIN32 36 #define CALLBACK 36 #define CALLBACK 37 37 #endif 38 38 … … 43 43 public: 44 44 typedef enum {Properties,TiledTexture,FullFace, SpotLight,PointLight} mttype; 45 dwmaterial() { type=Properties; 45 dwmaterial() { type=Properties; 46 46 opacity=1; specular=0; specexp=0; fname="";TextureWidth=1; TextureHeight=1; 47 47 ctx=NULL; tx=NULL; id=0; dstate=NULL;colour[0]=colour[1]=colour[2]=colour[3]=1; … … 54 54 if (isTextured()) { // shares common textures 55 55 if (!ctx || !tx) { // new texture needed 56 if (fname.length()>0) { 56 if (fname.length()>0) { 57 57 ctx=osgDB::readRefImageFile(fname.c_str(),options); 58 58 if (ctx.valid()) { … … 112 112 TextureHeight=repy; 113 113 } 114 inline float getRepWid() const { return TextureWidth;} 114 inline float getRepWid() const { return TextureWidth;} 115 115 inline float getRepHt() const { return TextureHeight;} 116 116 inline int isFullFace() const { return type==FullFace;} … … 121 121 inline void setspecexp(float o) { specexp=o;} 122 122 void setType(const char *buff) { 123 if (strncmp(buff,"Tiled_Texture",13)==0) 123 if (strncmp(buff,"Tiled_Texture",13)==0) 124 124 type=dwmaterial::TiledTexture; 125 else if (strncmp(buff,"Spot_Light",11)==0) 125 else if (strncmp(buff,"Spot_Light",11)==0) 126 126 type=dwmaterial::SpotLight; 127 else if (strncmp(buff,"Point_Light",11)==0) 127 else if (strncmp(buff,"Point_Light",11)==0) 128 128 type=dwmaterial::PointLight; 129 else if (strncmp(buff,"Properties",11)==0) 129 else if (strncmp(buff,"Properties",11)==0) 130 130 type=dwmaterial::Properties; 131 else if (strncmp(buff,"Full_Face_Texture",16)==0) 131 else if (strncmp(buff,"Full_Face_Texture",16)==0) 132 132 type=dwmaterial::FullFace; 133 133 } … … 194 194 ~_face() { delete [] idx;} 195 195 void setnv(const int n){ nv=n; idx=new int[n];} 196 void addvtx(const int n){ 196 void addvtx(const int n){ 197 197 if (nset < nv) { 198 198 idx[nset]=n; … … 217 217 while (i2==i1 && ic<nv-1) { 218 218 ic++; 219 i2=idx[ic]; 219 i2=idx[ic]; 220 220 } 221 221 int i3=idx[ic]; // third, must be non-coincident 222 222 while (ic<nv-1 && (i3==i2 || i3==i1)) { 223 223 ic++; 224 i3=idx[ic]; 224 i3=idx[ic]; 225 225 } 226 226 if(ic>=nv) { … … 238 238 norm(nrm, s2, side); 239 239 } 240 void settrans(Matrix &mx, const Vec3 nrm, const std::vector<Vec3> verts, const dwmaterial *mat) const { 240 void settrans(Matrix &mx, const Vec3 nrm, const std::vector<Vec3> verts, const dwmaterial *mat) const { 241 241 // define the matrix perpendcular to normal for mapping textures 242 float wid=mat->getRepWid(); 242 float wid=mat->getRepWid(); 243 243 float ht=mat->getRepHt(); 244 244 Vec3 r1, r2,r3; // 3 rows of rotation matrix … … 274 274 mx(1,j)=r2[j]; 275 275 mx(2,j)=r3[j]; 276 } 276 } 277 277 // mx.postTrans(mx,0.5f,0.5f,0.0f); 278 278 if (mat->isFullFace()) { // set offset such that mx*verts[idx[0]] -> uv=(0,0) … … 293 293 } 294 294 inline int setnvop(const unsigned short n) { // add a new hole in this face with n vertices 295 _face *oldop=opening; 296 opening=new _face[nop+1]; 295 _face *oldop=opening; 296 opening=new _face[nop+1]; 297 297 for (int i=0; i<nop; i++) opening[i].move(&oldop[i]); 298 298 delete [] oldop; … … 328 328 poses.idx=idx[j]; 329 329 } 330 void tessellate(const std::vector<Vec3>& verts, const dwmaterial *themat, 330 void tessellate(const std::vector<Vec3>& verts, const dwmaterial *themat, 331 331 GLUtesselator *ts, _dwobj *dwob, const RefMatrix *tmat) const; 332 332 333 333 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 334 334 inline const int getidx(int i) const { return idx[i];} … … 372 372 void End() { // tessellation is done 373 373 int nverts=vertices->size()-nbegin; 374 osg::DrawArrays *drw=NULL; 374 osg::DrawArrays *drw=NULL; 375 375 switch (primType) { 376 376 case GL_TRIANGLES: //gset->setPrimType( osg::GeoSet::TRIANGLES ); 377 377 //gset->setNumPrims( nload/3 ); 378 drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,nbegin,nverts); 378 drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,nbegin,nverts); 379 379 gset->addPrimitiveSet(drw); 380 380 break; 381 381 case GL_TRIANGLE_STRIP: //gset->setPrimType( osg::GeoSet::TRIANGLE_STRIP ); 382 382 //gset->setPrimLengths( nuprimlengs ); 383 drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP,nbegin,nverts); 383 drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP,nbegin,nverts); 384 384 gset->addPrimitiveSet(drw); 385 385 break; 386 386 case GL_TRIANGLE_FAN: //gset->setPrimType( osg::GeoSet::TRIANGLE_FAN ); 387 387 //gset->setPrimLengths( nuprimlengs ); 388 drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,nbegin,nverts); 388 drw=new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,nbegin,nverts); 389 389 gset->addPrimitiveSet(drw); 390 390 break; 391 391 case GL_QUADS: //gset->setPrimType( osg::GeoSet::QUADS ); 392 392 //gset->setNumPrims( nload/4 ); 393 drw=new osg::DrawArrays(osg::PrimitiveSet::QUADS,nbegin,nverts); 393 drw=new osg::DrawArrays(osg::PrimitiveSet::QUADS,nbegin,nverts); 394 394 gset->addPrimitiveSet(drw); 395 395 break; 396 396 case GL_QUAD_STRIP: //gset->setPrimType( osg::GeoSet::QUAD_STRIP ); 397 drw=new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,nbegin,nverts); 397 drw=new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,nbegin,nverts); 398 398 gset->addPrimitiveSet(drw); 399 399 break; 400 400 case GL_POLYGON: //gset->setPrimType( osg::GeoSet::POLYGON ); 401 drw=new osg::DrawArrays(osg::PrimitiveSet::POLYGON,nbegin,nverts); 401 drw=new osg::DrawArrays(osg::PrimitiveSet::POLYGON,nbegin,nverts); 402 402 gset->addPrimitiveSet(drw); 403 403 break; … … 408 408 nbegin=vertices->size(); 409 409 } 410 void combine( GLdouble coords[3], avertex *d[4], 410 void combine( GLdouble coords[3], avertex *d[4], 411 411 GLfloat w[4], avertex **dataOut , _dwobj *dwob); 412 void linkholes(const std::vector<Vec3> verts, const dwmaterial *themat, 413 const _face *f1, const _face *f2, 412 void linkholes(const std::vector<Vec3> verts, const dwmaterial *themat, 413 const _face *f1, const _face *f2, 414 414 const int ipr[2], const int nv) { 415 415 int gsidx[4]; … … 418 418 gsidx[2]=f2->getidx(nv-ipr[0]-1); // vertex position index 419 419 gsidx[3]=f2->getidx(nv-ipr[1]-1); // vertex position index 420 420 421 421 Matrix mx; // texture matrix transform to plane 422 422 Vec3 s1,s2; … … 435 435 normals->push_back(nrm); 436 436 } 437 osg::DrawArrays *drw=NULL; 437 osg::DrawArrays *drw=NULL; 438 438 drw=new osg::DrawArrays(osg::PrimitiveSet::QUADS,n1,4); 439 439 gset->addPrimitiveSet(drw); 440 440 } 441 void tessellate(_face &fc, const std::vector<Vec3>& verts, const dwmaterial *themat,GLUtesselator* ts, _dwobj *dwob) 441 void tessellate(_face &fc, const std::vector<Vec3>& verts, const dwmaterial *themat,GLUtesselator* ts, _dwobj *dwob) 442 442 { // generates a set of primitives all of one type (eg tris, qstrip trifan...) 443 443 fc.setNBegin(vertices->size()); … … 480 480 } 481 481 void CALLBACK myVertex(void *pv) 482 {// tess vertex call back with texture coord == void *pv1, 482 {// tess vertex call back with texture coord == void *pv1, 483 483 prd->addv((avertex *)pv); 484 484 } 485 void CALLBACK combineCallback( GLdouble coords[3], avertex *d[4], 486 GLfloat w[4], avertex **dataOut , _dwobj *dwob) 487 { 485 void CALLBACK combineCallback( GLdouble coords[3], avertex *d[4], 486 GLfloat w[4], avertex **dataOut , _dwobj *dwob) 487 { 488 488 // dwob needed if there is a combine callback to add the new vertex to group 489 489 prd->combine(coords, d, w, dataOut,dwob); … … 523 523 _dwobj() { nverts=nfaces=0; openings=NULL;faces=NULL; tmat=NULL; edges=NULL; 524 524 nopens=nfaceverts=0; fc1=fc2=NULL; colour[0]=colour[1]=colour[2]=colour[3]=1; 525 } 525 } 526 526 ~_dwobj() {/*delete verts; delete faces;delete openings;*/ 527 527 delete [] fc1;delete [] fc2; 528 } 528 } 529 529 int readOpenings(FILE *fp, const int nexpected) 530 530 { // read up to nexpected openings, each opening may have a number of vertices … … 668 668 }; 669 669 670 void _face::tessellate(const std::vector<Vec3>& verts, const dwmaterial *themat, 670 void _face::tessellate(const std::vector<Vec3>& verts, const dwmaterial *themat, 671 671 GLUtesselator *ts, _dwobj *dwob, const RefMatrix * /*tmat*/) const { 672 672 int nvall=getallverts(); … … 676 676 settrans(mx, nrm, verts,themat); 677 677 dwob->setmx(new RefMatrix(mx)); // may be used by combine callback to define txcoord 678 gluTessBeginPolygon(ts, dwob); 678 gluTessBeginPolygon(ts, dwob); 679 679 gluTessBeginContour(ts); /**/ 680 680 for (int j=0; j<nv; j++) { … … 687 687 nused++; 688 688 } 689 gluTessEndContour(ts); 689 gluTessEndContour(ts); 690 690 for (int k=0; k<nop; k++) { // now holes in the face 691 691 gluTessBeginContour(ts); … … 706 706 delete [] poses; 707 707 } 708 void prims::combine( GLdouble coords[3], avertex *d[4], 708 void prims::combine( GLdouble coords[3], avertex *d[4], 709 709 GLfloat w[4], avertex **dataOut , _dwobj *dwob) { 710 avertex *newv = new avertex(); // (avertex *)calloc(1, sizeof(avertex)); 711 newv->pos[0] = coords[0]; 712 newv->pos[1] = coords[1]; 710 avertex *newv = new avertex(); // (avertex *)calloc(1, sizeof(avertex)); 711 newv->pos[0] = coords[0]; 712 newv->pos[1] = coords[1]; 713 713 newv->pos[2] = coords[2]; 714 714 newv->uv[0] = newv->uv[1] =0; … … 750 750 nfnvf+=faces[i].getallverts(); // get total vertices in object, defines dimensions of NEW arrays 751 751 } 752 753 752 753 754 754 GLUtesselator* ts=gluNewTess(); 755 gluTessCallback(ts, GLU_TESS_BEGIN, (GLU_TESS_CALLBACK) myFaceBegin); 756 gluTessCallback(ts, GLU_TESS_VERTEX, (GLU_TESS_CALLBACK) myVertex); 757 gluTessCallback(ts, GLU_TESS_END, (GLU_TESS_CALLBACK) myFaceEnd); 758 gluTessCallback(ts, GLU_TESS_ERROR, (GLU_TESS_CALLBACK) error); 755 gluTessCallback(ts, GLU_TESS_BEGIN, (GLU_TESS_CALLBACK) myFaceBegin); 756 gluTessCallback(ts, GLU_TESS_VERTEX, (GLU_TESS_CALLBACK) myVertex); 757 gluTessCallback(ts, GLU_TESS_END, (GLU_TESS_CALLBACK) myFaceEnd); 758 gluTessCallback(ts, GLU_TESS_ERROR, (GLU_TESS_CALLBACK) error); 759 759 gluTessCallback(ts, GLU_TESS_COMBINE_DATA, (GLU_TESS_CALLBACK) combineCallback); 760 760 // for (int nvf=0; nvf<6; nvf++) { // for each length of face … … 765 765 osg::Geometry *gset = new osg::Geometry; 766 766 prd->setGeometry(gset); 767 StateSet *dstate=themat->make(options); 767 StateSet *dstate=themat->make(options); 768 768 gset->setStateSet( dstate ); 769 769 grp->addChild( geode ); // add to the world outside 770 770 geode->addDrawable(gset); 771 771 772 772 // each face adds a primitive to the geometry, after it is tessellated 773 773 for (i=0; i<nfaces; i++) { // for each face, collect up … … 791 791 { 792 792 public: 793 793 794 794 ReaderWriterDW() 795 795 { 796 796 supportsExtension("dw","Designer Workbench model format"); 797 797 } 798 798 799 799 virtual const char* className() const { return "Design Workshop Database Reader"; } 800 800 … … 833 833 Group *grp = new Group; 834 834 835 // code for setting up the database path so that internally referenced file are searched for on relative paths. 835 // code for setting up the database path so that internally referenced file are searched for on relative paths. 836 836 osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; 837 837 local_opt->setDatabasePath(osgDB::getFilePath(fileName)); … … 852 852 int id=atoi(buff); 853 853 matpalet[nmat].setid(id); // current material to be modified 854 854 855 855 } else if (strncmp(buff, "Phase:",6)==0) { 856 856 } else if (strncmp(buff, "CurrPhase:",10)==0) { … … 890 890 matpalet[nmat].setfname(buff); 891 891 } else if( strncmp(buff,"Extrusion:",10)==0 || 892 strncmp(buff,"Cube:",5)==0 || 893 strncmp(buff,"Polyline:",9)==0 || 892 strncmp(buff,"Cube:",5)==0 || 893 strncmp(buff,"Polyline:",9)==0 || 894 894 strncmp(buff,"Polyhedron:",11)==0) { 895 895 rdg=OBJECT; … … 899 899 int mt=atoi(buff+4); 900 900 for (int j=0; j<nmn; j++) { 901 if (matpalet[j].getid() == mt) 901 if (matpalet[j].getid() == mt) 902 902 obj.setmat(&(matpalet[j])); 903 903 } … … 937 937 &mx[1][0], &mx[1][1], &mx[1][2], 938 938 &mx[2][0], &mx[2][1], &mx[2][2]); 939 939 940 940 obj.settmat(Matrix(mx[0][0],mx[0][1],mx[0][2],0.0, 941 941 mx[1][0],mx[1][1],mx[1][2],0.0,
