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

📄 ac3d.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 30 Oct 2002// AC3D loader for models generated by the AC3D modeller (www.ac3d.org)// part of this source code were supplied by the AC3D project (Andy Colebourne)// eg the basic parsing of an AC3D file.// Conversion from AC3D scenegraph to OSG by GW Michel.#include <vector>#include <iostream>#include <osg/GL>#include <osg/GLU>#include <osg/Math>#include <osg/BlendFunc>#include <osg/CullFace>#include <osg/Geode>#include <osg/Group>#include <osg/Geometry>#include <osg/Light>#include <osg/LightSource>#include <osg/Material>#include <osg/Math>#include <osg/Texture2D>#include <osg/TexEnv>#include <osg/StateSet>#include <osg/ShadeModel>#include <osg/Math>#include <osg/Notify>#include <osgUtil/Tessellator>#include <osgDB/FileNameUtils>#include <osgDB/Registry>#include <osgDB/ReadFile>#include <osgDB/FileUtils>#include <osgDB/fstream>#include "Exception.h"#include "Geode.h"namespace ac3d {osg::Node*readFile(std::istream& stream, const osgDB::ReaderWriter::Options* options);}class geodeVisitor : public osg::NodeVisitor { // collects geodes from scene sub-graph attached to 'this'        public:            geodeVisitor():                osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}            ~geodeVisitor() { _geodelist.clear();}            // one apply for each type of Node that might be a user transform            virtual void apply(osg::Geode& geode) {                _geodelist.push_back(&geode);            }            virtual void apply(osg::Group& gp){                traverse(gp);    // must continue subgraph traversal.            }            std::vector<const osg::Geode *> getGeodes() {return _geodelist;}        protected:            typedef std::vector<const osg::Geode *>    Geodelist;            Geodelist  _geodelist;};class ReaderWriterAC : public osgDB::ReaderWriter{    public:            ReaderWriterAC()        {            supportsExtension("ac","AC3D Database format");        }                virtual const char* className() const { return "AC3D Database Reader"; }        virtual ReadResult readNode(const std::string& file,const Options* options) const        {            std::string ext = osgDB::getFileExtension(file);            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;            // GWM added Dec 2003 - get full path name (change in osgDB handling of files).            std::string fileName = osgDB::findDataFile( file, options );            osg::notify(osg::INFO) << "osgDB ac3d reader: starting reading \"" << fileName << "\"" << std::endl;                        // Anders Backmann - correct return if path not found            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;            // allocate per file data and start reading            osgDB::ifstream fin;            fin.open(fileName.c_str(), std::ios::in);            if (!fin.is_open()) return ReadResult::FILE_NOT_FOUND;            // code for setting up the database path so that internally referenced file are            // searched for on relative paths.             osg::ref_ptr<Options> local_opt;            if (options)                local_opt = static_cast<Options*>(options->clone(osg::CopyOp::DEEP_COPY_ALL));            else                local_opt = new Options;            local_opt->getDatabasePathList().push_back(osgDB::getFilePath(fileName));            ReadResult result = readNode(fin, local_opt.get());            if (result.validNode())                result.getNode()->setName(fileName);            return result;        }        virtual ReadResult readNode(std::istream& fin, const Options* options) const        {            std::string header;            fin >> header;            if (header.substr(0, 4) != "AC3D")                return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;            return ac3d::readFile(fin, options);        }        virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName, const Options* /*options*/) const        {            std::string ext = osgDB::getFileExtension(fileName);            if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;            geodeVisitor vs; // this collects geodes.            std::vector<unsigned int>iNumMaterials;            const_cast<osg::Node&>(node).accept(vs); // this parses the tree to streamd Geodes            std::vector<const osg::Geode *> glist=vs.getGeodes();            osgDB::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary);            // Write out the file header            std::vector<const osg::Geode *>::iterator itr;            fout << "AC3Db" << std::endl;            // output the Materials            int iNumGeodesWithGeometry = 0;            for (itr=glist.begin();itr!= glist.end();itr++)            {                iNumMaterials.push_back(const_cast<ac3d::Geode*>(static_cast<const ac3d::Geode*>(*itr))->ProcessMaterial(fout,itr-glist.begin()));                unsigned int iNumDrawables = (*itr)->getNumDrawables();                int iNumGeometries = 0;                for (unsigned int i = 0; i < iNumDrawables; i++)                {                    const osg::Drawable* pDrawable = (*itr)->getDrawable(i);                    if (NULL != pDrawable)                    {                        const osg::Geometry *pGeometry = pDrawable->asGeometry();                        if (NULL != pGeometry)                            iNumGeometries++;                    }                }                if (iNumGeometries > 0)                    iNumGeodesWithGeometry++;            }            // output the Geometry            unsigned int nfirstmat=0;            fout << "OBJECT world" << std::endl;            fout << "kids " << iNumGeodesWithGeometry << std::endl;            for (itr=glist.begin();itr!= glist.end();itr++) {                const_cast<ac3d::Geode*>(static_cast<const ac3d::Geode*>(*itr))->ProcessGeometry(fout,nfirstmat);                nfirstmat+=iNumMaterials[itr-glist.begin()];            }            fout.close();            return WriteResult::FILE_SAVED;        }                virtual WriteResult writeNode(const osg::Node& node,std::ostream& fout, const Options* opts) const        {            try            {                // write ac file.                if(dynamic_cast<const osg::Group*>(&node)) {                    const osg::Group *gp=dynamic_cast<const osg::Group*>(&node);                    const unsigned int nch=gp->getNumChildren();                    for (unsigned int i=0; i<nch; i++) {                        writeNode(*(gp->getChild(i)), fout, opts);                    }                }                else                    osg::notify(osg::WARN)<<"File must start with a geode "<<std::endl;                fout.flush();                return WriteResult::FILE_SAVED;            }            catch(ac3d::Exception e)            {                osg::notify(osg::WARN)<<"Error parsing OSG tree: "<< e.getError() << std::endl;                        }            return WriteResult::FILE_NOT_HANDLED;        }private:};// now register with osg::Registry to instantiate the above// reader/writer.REGISTER_OSGPLUGIN(ac, ReaderWriterAC)namespace ac3d {enum {  ObjectTypeNormal = 0,  ObjectTypeGroup = 1,  ObjectTypeLight = 2,  SurfaceTypePolygon = 0,  SurfaceTypeLineLoop = 1,  SurfaceTypeLineStrip = 2,  SurfaceShaded = 1<<4,  SurfaceTwoSided = 1<<5};/// Returns a possibly quoted string given in the end of the current line in the streamstaticstd::stringreadString(std::istream& stream){    std::string s;    stream >> std::ws;    if (stream.peek() != '\"')    {        // Not quoted, just read the string        stream >> s;    }    else    {        // look for quoted strings            // throw away the quote        stream.get();            // extract characters until either an error happens or a quote is found        while (stream.good())        {            std::istream::char_type c;            stream.get(c);            if (c == '\"')                break;            s += c;        }    }     return s;}static voidsetTranslucent(osg::StateSet* stateSet){    osg::BlendFunc* blendFunc = new osg::BlendFunc;    blendFunc->setDataVariance(osg::Object::STATIC);    blendFunc->setSource(osg::BlendFunc::SRC_ALPHA);    blendFunc->setDestination(osg::BlendFunc::ONE_MINUS_SRC_ALPHA);    stateSet->setAttribute(blendFunc);    stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);    stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);}// Just a container to store an ac3d materialclass MaterialData{  public:    MaterialData() :        mMaterial(new osg::Material),        mColorArray(new osg::Vec4Array(1))    {        mMaterial->setDataVariance(osg::Object::STATIC);        mColorArray->setDataVariance(osg::Object::STATIC);    }    void readMaterial(std::istream& stream)    {        // note that this might be quoted        std::string name = readString(stream);        mMaterial->setName(name);        std::string tmp;        stream >> tmp;        osg::Vec4 diffuse;        stream >> diffuse[0] >> diffuse[1] >> diffuse[2];        mMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);        stream >> tmp;        osg::Vec4 ambient;        stream >> ambient[0] >> ambient[1] >> ambient[2];        mMaterial->setAmbient(osg::Material::FRONT_AND_BACK, ambient);        stream >> tmp;        osg::Vec4 emmissive;        stream >> emmissive[0] >> emmissive[1] >> emmissive[2];        mMaterial->setEmission(osg::Material::FRONT_AND_BACK, emmissive);        stream >> tmp;        osg::Vec4 specular;        stream >> specular[0] >> specular[1] >> specular[2];        mMaterial->setSpecular(osg::Material::FRONT_AND_BACK, specular);        stream >> tmp;        float shininess;        stream >> shininess;        mMaterial->setShininess(osg::Material::FRONT_AND_BACK, shininess);        stream >> tmp;        float transparency;        stream >> transparency;        mMaterial->setTransparency(osg::Material::FRONT_AND_BACK, transparency);        mTranslucent = 0 < transparency;        // must correspond to the material we use for the color array below        mMaterial->setColorMode(osg::Material::DIFFUSE);        // this must be done past the transparency setting ...        (*mColorArray)[0] = mMaterial->getDiffuse(osg::Material::FRONT_AND_BACK);    }    void toStateSet(osg::StateSet* stateSet) const    {        stateSet->setAttribute(mMaterial.get());        if (mTranslucent)            setTranslucent(stateSet);    }    osg::Vec4Array* getColorArray() const    {        return mColorArray.get();    }private:    osg::ref_ptr<osg::Material> mMaterial;    osg::ref_ptr<osg::Vec4Array> mColorArray;    bool mTranslucent;};class TextureData{  public:    TextureData() :        mTranslucent(false),        mRepeat(true)    {    }    bool setTexture(const std::string& name, const osgDB::ReaderWriter::Options* options, osg::TexEnv* modulateTexEnv)    {        mTexture2DRepeat = new osg::Texture2D;        mTexture2DRepeat->setDataVariance(osg::Object::STATIC);        mTexture2DRepeat->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);        mTexture2DRepeat->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);        mTexture2DClamp = new osg::Texture2D;        mTexture2DClamp->setDataVariance(osg::Object::STATIC);        mTexture2DClamp->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);        mTexture2DClamp->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);        std::string absFileName = osgDB::findDataFile(name, options);        if (absFileName.empty())

⌨️ 快捷键说明

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