⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readerwriterdw.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <stdio.h>#include <string.h>// 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 <osg/CullFace>#include <osg/Geode>#include <osg/Group>#include <osg/Geometry>#include <osg/Light>#include <osg/LightSource>#include <osg/Material>#include <osg/Texture2D>#include <osg/TexEnv>#include <osg/StateSet>#include <osg/Notify>#include <osgDB/FileNameUtils>#include <osgDB/Registry>#include <osgDB/ReadFile>#include <osgDB/FileUtils>#include <osg/GLU>using namespace osg;#ifndef WIN32    #define CALLBACK #endifclass _dwobj; // predefine for later callint dwfgets(char *clin, int max, FILE *fin); // , end of line= 13 as well as Creturn=10class dwmaterial {// design workshop material, to be translated to OGLpublic:    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::readImageFile(fname.c_str(),options);                    if (ctx) {                        ctx->setFileName(fname);                        tx=new Texture2D;                        tx->setImage(ctx);                        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 && tx) { // texture exists                dstate->setTextureAttributeAndModes(0,tx,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    Image *ctx;    Texture2D *tx;    int _lightnum;    StateSet *dstate; // used to represent the dw material in OSG};// structure to use as data for tessellationtypedef 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<Vec3> 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-1) {            ic++;            i2=idx[ic];         }        int i3=idx[ic]; // third, must be non-coincident        while (ic<nv-1 && (i3==i2 || i3==i1)) {            ic++;            i3=idx[ic];         }        if(ic>=nv) {            printf("Invalid vertices %d of %d. I1-3 %d %d %d.\n", ic, nv, i1, i2, i3);        }        if(i1>=static_cast<int>(verts.size()) || i2>=static_cast<int>(verts.size()) || i3>=static_cast<int>(verts.size())) {            printf("Invalid indices %d, %d, %d max allowed %d.\n", i1,i2,i3,static_cast<int>(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<Vec3> verts) {        Vec3 side, s2; // used in cross product to find normal        getside12(side,s2, verts);        norm(nrm, s2, side);    }    void settrans(Matrix &mx, const Vec3 nrm, const std::vector<Vec3> 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=nrm;            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=nrm; // 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; i<nop; i++) opening[i].move(&oldop[i]);        delete [] oldop;        opening[nop].setnv(n);        nop++;        return (nop-1);    }    void move(class _face *oldop) { *this=*oldop; oldop->idx=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<nop; i++) ntot+=opening[i].getnv();        return ntot;    }    void setnorm(const std::vector<Vec3> verts) { // set the face normal        getnorm(verts);        for (int i=0; i<nop; i++) {            opening[i].setnorm(verts);            if (nrm*opening[i].nrm > 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<Vec3> 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -