diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index dec0f67c0..ca24ff801 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -153,8 +153,6 @@ IF(FBX_FOUND AND OSG_CPP_EXCEPTIONS_AVAILABLE) ADD_SUBDIRECTORY(fbx) ENDIF() -ADD_SUBDIRECTORY(dw) - ADD_SUBDIRECTORY(bvh) ADD_SUBDIRECTORY(x) ADD_SUBDIRECTORY(dxf) diff --git a/src/osgPlugins/dw/CMakeLists.txt b/src/osgPlugins/dw/CMakeLists.txt deleted file mode 100644 index 13627b499..000000000 --- a/src/osgPlugins/dw/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -SET(TARGET_SRC ReaderWriterDW.cpp ) -#### end var setup ### -SETUP_PLUGIN(dw) diff --git a/src/osgPlugins/dw/ReaderWriterDW.cpp b/src/osgPlugins/dw/ReaderWriterDW.cpp deleted file mode 100644 index eb60cdd03..000000000 --- a/src/osgPlugins/dw/ReaderWriterDW.cpp +++ /dev/null @@ -1,977 +0,0 @@ -#include -#include -#include -// reading a design workshop file utility -// (c) GW Michel, 2001-2003. -// (c) 2003 - modified to use Geometry rather than old GeoSet. -// Design Workshop format files can be downloaded from www.artifice.com -// Design Workshop editor can be downloaded from www.artifice.com = Mac & Win95/98/NT versions are available. -// DW Lite is completely free, produces textured 3D models -// aimed mostly at the architectural world. Flat polygons are generally produced -// No ability to produce smooth shading, unfortunately. -// But it is the best bangs per buck. (Anything/nothing = infinite value, and this is quite a lot/nothing) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -using namespace osg; - -#ifndef WIN32 - #define CALLBACK -#endif - -class _dwobj; // predefine for later call -int dwfgets(char *clin, int max, FILE *fin); // , end of line= 13 as well as Creturn=10 - -class dwmaterial {// design workshop material, to be translated to OGL -public: - typedef enum {Properties,TiledTexture,FullFace, SpotLight,PointLight} mttype; - dwmaterial() { type=Properties; - opacity=1; specular=0; specexp=0; fname="";TextureWidth=1; TextureHeight=1; - ctx=NULL; tx=NULL; id=0; dstate=NULL;colour[0]=colour[1]=colour[2]=colour[3]=1; - bright=halfIn=halfOut=falloff=0;atyp=NONE; - _lightnum=1; - } - ~dwmaterial() { } - void settexture(const osgDB::ReaderWriter::Options *options) { - if (!dstate) dstate = new StateSet; - if (isTextured()) { // shares common textures - if (!ctx || !tx) { // new texture needed - if (fname.length()>0) { - ctx=osgDB::readRefImageFile(fname.c_str(),options); - if (ctx.valid()) { - ctx->setFileName(fname); - tx=new Texture2D(ctx.get()); - tx->setWrap(Texture2D::WRAP_S, Texture2D::REPEAT); - tx->setWrap(Texture2D::WRAP_T, Texture2D::REPEAT); - } - osg::TexEnv* texenv = new osg::TexEnv; - texenv->setMode(osg::TexEnv::MODULATE); - dstate->setTextureAttribute(0, texenv ); - } - } - if (ctx.valid() && tx.valid()) { // texture exists - dstate->setTextureAttributeAndModes(0,tx.get(),osg::StateAttribute::ON); - } - } - } - StateSet *make(const osgDB::ReaderWriter::Options *options) { // returns the OSG material - if (!dstate) { // if it does not exist, then make it - dstate = new StateSet; - osg::Material* osgMaterial = new osg::Material; - dstate->setAttribute(osgMaterial); - if (opacity<0.99) { - osgMaterial->setTransparency(Material::FRONT_AND_BACK, opacity); - dstate->setMode(GL_BLEND,StateAttribute::ON); - dstate->setRenderingHint(StateSet::TRANSPARENT_BIN); - colour[3]=opacity; - } - osgMaterial->setAmbient(Material::FRONT_AND_BACK,colour); - osgMaterial->setDiffuse(Material::FRONT_AND_BACK,colour); - - Vec4 colspec=colour*specular; - colspec[3]=colour[3]; - osgMaterial->setSpecular(Material::FRONT_AND_BACK,colspec); - osgMaterial->setShininess(Material::FRONT_AND_BACK,specexp); - - dstate->setMode( GL_LIGHTING, StateAttribute::ON ); - dstate->setMode( GL_CULL_FACE, StateAttribute::ON ); - - osg::CullFace *cf = new osg::CullFace; // to define non-default culling - cf->setMode(osg::CullFace::BACK); - dstate->setAttribute(cf); - - dstate->setTextureMode(0,GL_TEXTURE_2D,StateAttribute::OFF); - settexture(options); - } - return dstate; - } - inline int isType(mttype t1) const {return (type==t1 ); } - inline int isTextured() {return (type==TiledTexture || type==FullFace ); } - void setcolour(const float rgb[3]) { - colour[0]=rgb[0]; colour[1]=rgb[1]; colour[2]=rgb[2]; - } - void settxrep(const float repx, const float repy) { - TextureWidth=repx; - TextureHeight=repy; - } - inline float getRepWid() const { return TextureWidth;} - inline float getRepHt() const { return TextureHeight;} - inline int isFullFace() const { return type==FullFace;} - inline int getid() const { return id;} - inline void setid(const int i) { id=i;} - inline void setopacity(float o) { opacity=o;} - inline void setspecular(float o) { specular=o;} - inline void setspecexp(float o) { specexp=o;} - void setType(const char *buff) { - if (strncmp(buff,"Tiled_Texture",13)==0) - type=dwmaterial::TiledTexture; - else if (strncmp(buff,"Spot_Light",11)==0) - type=dwmaterial::SpotLight; - else if (strncmp(buff,"Point_Light",11)==0) - type=dwmaterial::PointLight; - else if (strncmp(buff,"Properties",11)==0) - type=dwmaterial::Properties; - else if (strncmp(buff,"Full_Face_Texture",16)==0) - type=dwmaterial::FullFace; - } - void setfname(const char *buff) { - //fname=new char[strlen(buff+13)+5]; - fname= (buff+13); - fname+= ".tga"; - } - LightSource *makeLight(const Vec4 pos) - { - Light *lt= new Light; - Vec4 cdef; - cdef[0]=cdef[1]=cdef[2]=0.0f; cdef[3]=0.0f; - lt->setLightNum(_lightnum++); - lt->setSpecular(colour*bright/2.0f); - lt->setDiffuse(colour*bright/4.0f); - lt->setAmbient(cdef); - if (atyp==NONE) ; - else if (atyp==INVERSE_DIST) { - lt->setLinearAttenuation(1.0f); - lt->setConstantAttenuation(0.01f); - } - lt->setPosition(pos); - LightSource *ls=new LightSource(); - ls->setLight(lt); - return ls; - } - void setAtten(const char *buff) { - if (strstr(buff,"kQ3AttenuationTypeNone")) atyp=NONE; - else if (strstr(buff,"kQ3AttenuationTypeInverseDistance")) atyp=INVERSE_DIST; - // else if (strstr(buff,"kQ3AttenuationTypeNone")) ; - } - void setBright(const float br) { bright=br;} - void setHalfAngleIn(const float ha) { halfIn=ha;} - void setHalfAngleOut(const float ha) { halfOut=ha;} - void setFallOff(const float fo) { falloff=fo;} - const Vec4 getcolour() { return colour;} -private: - int id; - Vec4 colour; // the ambient/diffuse+alpha colour - mttype type; - float opacity, specular, specexp; // transp, specularity properties - float TextureWidth, TextureHeight; - std::string fname; // picture file - enum atten {NONE, INVERSE_DIST, INVERSE_SQUARE} atyp; - float bright,halfIn,halfOut,falloff; // light brightness - osg::ref_ptr ctx; - osg::ref_ptr tx; - int _lightnum; - StateSet *dstate; // used to represent the dw material in OSG -}; -// structure to use as data for tessellation - -typedef struct { - double pos[3]; // must be double for the tessellator to detect vertices - Vec2 uv; // texture coordainte - may not be used? - Vec3 nrmv; // surface normal - int idx; // index in the verts[] array -} avertex; - -class _face { -public: - _face() { nVertStart=0; opening=NULL; idx=NULL; nv=0; nop=0; nset=0; nrm[0]=nrm[1]=nrm[2]=0;} - ~_face() { delete [] idx;} - void setnv(const int n){ nv=n; idx=new int[n];} - void addvtx(const int n){ - if (nset < nv) { - idx[nset]=n; - nset++; - } - } - void addholevtx(const int nvtot) { - if (opening) { - opening[nop-1].addvtx(nvtot); - } - } - void setNBegin(int n1) {nVertStart=n1;} - void norm(Vec3 &n, const Vec3& side, const Vec3& s2) const { - n=s2^side; // perpendicular - n.normalize(); // unit norm - } - const Vec3 getnorm(void) const { return nrm; } // use the predefined normal - void getside12(Vec3 &s1, Vec3 &s2, const std::vector& verts) const { - int ic=0; // counter for later vertices to ensure not coincident - int i1=idx[0]; // first vertex of face - int i2=idx[1]; // second, must be non-coincident - while (i2==i1 && ic=nv) { - printf("Invalid vertices %d of %d. I1-3 %d %d %d.\n", ic, nv, i1, i2, i3); - } - if(i1>=static_cast(verts.size()) || i2>=static_cast(verts.size()) || i3>=static_cast(verts.size())) { - printf("Invalid indices %d, %d, %d max allowed %d.\n", i1,i2,i3,static_cast(verts.size()));//, errm - } - s1=(verts[i2]-verts[i1]); // side 1 of face - s2=(verts[i3]-verts[i2]); // side 2 of face - } - void getnorm(const std::vector& verts) { - Vec3 side, s2; // used in cross product to find normal - getside12(side,s2, verts); - norm(nrm, side, s2); - } - void settrans(Matrix &mx, const Vec3& normal, const std::vector& verts, const dwmaterial *mat) const { - // define the matrix perpendcular to normal for mapping textures - float wid=mat->getRepWid(); - float ht=mat->getRepHt(); - Vec3 r1, r2,r3; // 3 rows of rotation matrix - if (mat->isFullFace()) { // set wid, ht from polygon - Vec3 s2; // want transformed u coordinate parallel to 'r1' - getside12(r1,s2, verts); // r1 = edge of first side -// printf("fullface s2 %f %f %f\n", s2.x(),s2.y(),s2.z());//, errm - r3=normal; - float len=r1.length(); - r1=r1/len; - r2=r3^r1; - r1=r1/len; - r2=r2/s2.length(); - } else { - // mat.nrm= (0,0,1) AND mat (0,1,0) => (0,a,b) - // the transformation is unitary - preserves lengths; and - // converts points on a plane into (s,t, constant) coords for use with texturing - // Rinv.(0,0,1) = (nrm) implies R since Rinv=R(transpose) - r3=normal; // already a unit vector - // mat.(010) = (0ab) -> Minv.(0ab) = (010); and this row DOT nrm=0 - if (r3.z() < 0.99f && r3.z() > -0.99f) { // not face parallel to ground - choose r1 perpendicular to nrm & 001 - r2.set(0,0,1); // therefore r1 is in plane of face. - r1=r2^r3; - r1.normalize(); - } else { // parallel to ground - make perpendicular to edge 1 of face - r1=verts[idx[1]]-verts[idx[0]]; - r1.normalize(); - } - r2=r3^r1; - } - for (int j=0; j<3; j++) { // and create the transpose matrix (inverse of rotation matrix) - mx(0,j)=r1[j]; - mx(1,j)=r2[j]; - mx(2,j)=r3[j]; - } - // mx.postTrans(mx,0.5f,0.5f,0.0f); - if (mat->isFullFace()) { // set offset such that mx*verts[idx[0]] -> uv=(0,0) - Vec3 pos; - pos=mx*verts[idx[0]]; - mx(0,3)=-pos.x(); - mx(1,3)=-pos.y(); - mx(2,3)=-pos.z(); - } else { // scale inversely to the texture preferred repeat size - mx(0,0)*=1.0f/wid; - mx(1,0)*=1.0f/wid; - mx(0,1)*=1.0f/ht; - mx(1,1)*=1.0f/ht; - mx(0,3)=0.5f/wid; - mx(1,3)=0.5f/ht; - } - // mx.postScale(mx,1.0f/themat->TextureWidth, 1.0f/themat->TextureHeight,1); - } - inline int setnvop(const unsigned short n) { // add a new hole in this face with n vertices - _face *oldop=opening; - opening=new _face[nop+1]; - for (int i=0; iidx=NULL;} - inline int getnv() { return nv;} - inline int getvert(const int j) { return idx[j];} - inline int complete() { return (idx && nv>0 && nset==nv);} // face has all defined - inline int holecomplete() { if (!opening) return 1; // no hole, so it is complete - return opening[nop-1].complete();} // latest opening in face has all vertices defined - int getallverts(void) const { int ntot=nv; - for (int i=0; i& verts) { // set the face normal - getnorm(verts); - for (int i=0; i 0.0f) { // normals are parallel - reverse order of vertices - opening[i].reverse(); - opening[i].setnorm(verts); - } - } - } - void setposes(avertex &poses, const int j, const std::vector& verts) const { - poses.pos[0]=verts[idx[j]].x(); - poses.pos[1]=verts[idx[j]].y(); - poses.pos[2]=verts[idx[j]].z(); - poses.nrmv=nrm; - poses.idx=idx[j]; - } - void tessellate(const std::vector& verts, const dwmaterial *themat, - GLUtesselator *ts, _dwobj *dwob, const RefMatrix *tmat) const; - - void link(const int idop, const _face *f2, const int idop2,const std::vector& verts, const dwmaterial *themat) const; // to join up opposed faces of a hole - inline int getidx(int i) const { return idx[i];} -private: - void linkholes(const std::vector& verts, const dwmaterial *themat, const _face *f2) const; - void reverse() { // reverse order of the vertices - for (int j=0; jpush_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& 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& 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.get()); - } - void buildGeometry() { // at end of all faces, add collection of vertices to geometry - gset->setNormalArray(normals.get(), osg::Array::BIND_PER_VERTEX); - gset->setTexCoordArray(0,txcoords.get()); - gset->setVertexArray(vertices.get()); // setCoords( vts, nusidx ); - } - void setGeometry(osg::Geometry *gs) { - gset=gs; - } - void settmat(const RefMatrix *mx) { - tmat= mx; - } -private: - osg::ref_ptr gset; - osg::ref_ptr vertices; - osg::ref_ptr normals; - osg::ref_ptr txc; - osg::ref_ptr txcoords; - GLenum primType; - int nbegin; // vertex indices for current primitive - osg::ref_ptr 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(errno),errm);//, errm -} - //========== -void _face::linkholes(const std::vector& verts, const dwmaterial *themat, const _face *f2) const -{ - int ipr[2]; - ipr[0]=nv-1; - for (int i=0; ilinkholes(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& 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 object -public: - _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 verts; - dwmaterial *themat; - unsigned short nverts,nfaces,nedges; - unsigned short nfaceverts; - unsigned short nopens; - _face *faces; - _dwedge *edges; - int *openings; - unsigned short *fc1, *fc2; // openings[i] is in faces[fc1[i]] to faces[fc2[i]] - osg::ref_ptr tmat; - osg::ref_ptr mx; // current uvw transform for currently tessealting face -}; - -void _face::tessellate(const std::vector& verts, const dwmaterial *themat, - GLUtesselator *ts, _dwobj *dwob, const RefMatrix * /*tmat*/) const { - int nvall=getallverts(); - int nused=0; - avertex *poses=new avertex[2*nvall]; // passed to Tessellator to redraw - Matrix mx; // texture matrix transform to plane - settrans(mx, nrm, verts,themat); - dwob->setmx(new RefMatrix(mx)); // may be used by combine callback to define txcoord - gluTessBeginPolygon(ts, dwob); - gluTessBeginContour(ts); /**/ - for (int j=0; jpos[0] = coords[0]; - newv->pos[1] = coords[1]; - newv->pos[2] = coords[2]; - newv->uv[0] = newv->uv[1] =0; - newv->nrmv[0] = newv->nrmv[1] = newv->nrmv[2] =0; - for (int i=0; i<4; i++) { - if (d[i]) { - newv->uv[0] = w[i]*d[i]->uv[0]; - newv->uv[1] = w[i]*d[i]->uv[1]; - newv->nrmv[0] = w[i]*d[i]->nrmv[0]; - newv->nrmv[1] = w[i]*d[i]->nrmv[1]; - newv->nrmv[2] = w[i]*d[i]->nrmv[2]; - } - } - dwob->makeuv(newv->uv, newv->pos); - newv->idx=dwob->addvtx(coords[0], coords[1], coords[2]); - *dataOut = newv; -} -void _dwobj::buildDrawable(Group *grp, const osgDB::ReaderWriter::Options *options) -{ // current DWobject complete; make a drawable, and add it to a osg::Group - if (nfaces>0) { - if (themat->isType(dwmaterial::PointLight) || themat->isType(dwmaterial::SpotLight)) { - Vec4 pos; - pos.set(0.0f,0.0f,0.0f,0.0f); - for (int i=0; imakeLight(pos); - grp->addChild(ls); - } else { - Geode *geode = new Geode; - int nfnvf=0; // number of vertices for faces plus holes - int i; // a general counter - for (i=0; isettmat(tmat.get()); - osg::Geometry *gset = new osg::Geometry; - prd->setGeometry(gset); - StateSet *dstate=themat->make(options); - gset->setStateSet( dstate ); - grp->addChild( geode ); // add to the world outside - geode->addDrawable(gset); - - // each face adds a primitive to the geometry, after it is tessellated - for (i=0; itessellate(faces[i],verts, themat, ts, this); - } - for (i=0; ibuildGeometry(); - gluDeleteTess(ts); - delete prd; - } - } // nfaces>0 - verts.clear(); -} -////////// tessellation complete - -class ReaderWriterDW : public osgDB::ReaderWriter -{ - public: - - ReaderWriterDW() - { - supportsExtension("dw","Designer Workbench model format"); - } - - virtual const char* className() const { return "Design Workshop Database Reader"; } - - virtual ReadResult readNode(const std::string& file,const osgDB::ReaderWriter::Options* options) const - { - - std::string ext = osgDB::getLowerCaseFileExtension(file); - if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; - - std::string fileName = osgDB::findDataFile( file, options ); - if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - - - _dwobj obj; - enum reading {NONE, MATERIAL, OBJECT}; - //unsigned short nrecs=0; // number of records read after a divider (numVerts, numFaces, numOpenings...) - int nexpected=0; // number of records to be read in a block - dwmaterial *matpalet=NULL; - int nmat=-1; // current element of matpalet being modified - int nmn=0; // number of materials found - reading rdg=NONE; - - char buff[256]; - - OSG_INFO<< "ReaderWriterDW::readNode( "< local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; - local_opt->setDatabasePath(osgDB::getFilePath(fileName)); - - - while( !feof( fp ) ) - { // reads the Design Workshop format in ASCII - if (dwfgets( buff, sizeof( buff ), fp )) { - if( buff[0] == '#' ) - continue; - else if( strncmp(buff,"numMaterials:",13)==0) { // No of materials - nmn=atoi(buff+14); - matpalet=new dwmaterial[nmn]; - } else if( strncmp(buff,"Material:",9)==0) { // No of materials - dwfgets(buff, sizeof( buff ), fp ); - nmat++; - rdg=MATERIAL; - int id=atoi(buff); - matpalet[nmat].setid(id); // current material to be modified - - } else if (strncmp(buff, "Phase:",6)==0) { - } else if (strncmp(buff, "CurrPhase:",10)==0) { - } else if (strncmp(buff, "numPhases:",10)==0) { - } else if (strncmp(buff, "Opacity:",8)==0) { - float opacity=osg::asciiToFloat(buff+8); - matpalet[nmat].setopacity(opacity); - } else if (strncmp(buff, "FallOff:",8)==0) { - float fo=osg::asciiToFloat(buff+8); - matpalet[nmat].setFallOff(fo); - } else if (strncmp(buff, "InnerHalfAngle:",15)==0) { - float ha=osg::asciiToFloat(buff+15); - matpalet[nmat].setHalfAngleIn(ha); - } else if (strncmp(buff, "OuterHalfAngle:",15)==0) { - float ha=osg::asciiToFloat(buff+15); - matpalet[nmat].setHalfAngleOut(ha); - } else if (strncmp(buff, "Brightness:",11)==0) { - float br=osg::asciiToFloat(buff+11); - matpalet[nmat].setBright(br); - } else if (strncmp(buff, "Attentuation:",13)==0) { // oops - they can't spell - matpalet[nmat].setAtten(buff+13); - } else if (strncmp(buff, "MaterialType:",13)==0) { - matpalet[nmat].setType(buff+14); - } else if (strncmp(buff, "SpecularReflectivity:",21)==0) { - float spec=osg::asciiToFloat(buff+21); - matpalet[nmat].setspecular(spec); - } else if (strncmp(buff, "SmoothnessExponent:",19)==0) { - float spec=osg::asciiToFloat(buff+19); - matpalet[nmat].setspecexp(spec*128.0f/100.0f); // convert to 0-128 range from percent - } else if (strncmp(buff, "TextureWidthAndHeight:",22)==0) { - char *ct=strchr(buff+22,','); - float repx=osg::asciiToFloat(buff+23), repy=osg::asciiToFloat(ct+1); - matpalet[nmat].settxrep(repx, repy); - } else if (strncmp(buff, "PictureFile:",12)==0) { - char *end=strchr(buff,'\n'); // end of line - if (end) *end='\0'; // removed - matpalet[nmat].setfname(buff); - } else if( strncmp(buff,"Extrusion:",10)==0 || - strncmp(buff,"Cube:",5)==0 || - strncmp(buff,"Polyline:",9)==0 || - strncmp(buff,"Polyhedron:",11)==0) { - rdg=OBJECT; - obj.buildDrawable(grp, options); - obj.reset(); - } else if( strncmp(buff,"Mat:",4)==0) { - int mt=atoi(buff+4); - for (int j=0; j0) obj.readOpenings(fp, nexpected); - } else if( strncmp(buff,"UVW:",4)==0) { // texture application matrix - double mx[3][3]; - sscanf(buff+4,"%lf %lf %lf %lf %lf %lf %lf %lf %lf", - &mx[0][0], &mx[0][1], &mx[0][2], - &mx[1][0], &mx[1][1], &mx[1][2], - &mx[2][0], &mx[2][1], &mx[2][2]); - - obj.settmat(Matrix(mx[0][0],mx[0][1],mx[0][2],0.0, - mx[1][0],mx[1][1],mx[1][2],0.0, - mx[2][0],mx[2][1],mx[2][2],0.0, - 0.0 ,0.0 ,0.0 ,1.0)); - } - } - - } - fclose( fp ); - obj.buildDrawable(grp, options); // tidy up any remaining objects - - if (matpalet) delete [] matpalet; - - return grp; - - } -private: -}; - -int dwfgets(char *clin, int max, FILE *fin) -{ // replace fgets to detect EOL = char 13 as well as Creturn=10 GWM 111100 - // Macintosh produced files (such as those obtainable - //from the great buildings site at www.Artifice.com) use 13 format, PC models use 10. - int nread=0; - int c1=1; - do { - if (!feof( fin )) - { - c1=fgetc(fin); - clin[nread++]=static_cast(c1); - } - } while (nread0) clin[nread-1]='\0'; // null terminate and remove training blank - return nread; -} - -// now register with osg::Registry to instantiate the above -// reader/writer. -REGISTER_OSGPLUGIN(dw, ReaderWriterDW) -