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

📄 ac3d.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        {            osg::notify(osg::FATAL) << "osgDB ac3d reader: could not find texture \"" << name << "\"" << std::endl;            return false;        }        mImage = osgDB::readImageFile(absFileName, options);        if (!mImage.valid())        {            osg::notify(osg::FATAL) << "osgDB ac3d reader: could not read texture \"" << name << "\"" << std::endl;            return false;        }        mTexture2DRepeat->setImage(mImage.get());        mTexture2DClamp->setImage(mImage.get());        mTranslucent = mImage->isImageTranslucent();        // Use a shared modulate TexEnv        mModulateTexEnv = modulateTexEnv;        return true;    }    void setRepeat(bool repeat)    {        mRepeat = repeat;    }    bool valid() const    {        return mImage.valid();    }    std::string getFileName() const    {        if (!mImage.valid())            return std::string();        return mImage->getFileName();    }    void toTextureStateSet(osg::StateSet* stateSet) const    {        if (!valid())            return;        stateSet->setTextureAttribute(0, mModulateTexEnv.get());        if (mRepeat)           stateSet->setTextureAttribute(0, mTexture2DRepeat.get());        else           stateSet->setTextureAttribute(0, mTexture2DClamp.get());        stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);        if (mTranslucent)            setTranslucent(stateSet);    }private:    osg::ref_ptr<osg::TexEnv> mModulateTexEnv;    osg::ref_ptr<osg::Texture2D> mTexture2DClamp;    osg::ref_ptr<osg::Texture2D> mTexture2DRepeat;    osg::ref_ptr<osg::Image> mImage;    bool mTranslucent;    bool mRepeat;};class FileData{  public:    FileData(const osgDB::ReaderWriter::Options* options) :        mOptions(options),        mLightIndex(1)    {        mModulateTexEnv = new osg::TexEnv;        mModulateTexEnv->setDataVariance(osg::Object::STATIC);        mModulateTexEnv->setMode(osg::TexEnv::MODULATE);    }    TextureData toTextureData(const std::string& texName)    {        TextureDataMap::iterator i = mTextureStates.find(texName);        if (i == mTextureStates.end())            mTextureStates[texName].setTexture(texName, mOptions.get(), mModulateTexEnv.get());        return mTextureStates[texName];    }    osg::Light* getNextLight()    {        osg::Light* light = new osg::Light;        light->setDataVariance(osg::Object::STATIC);        light->setLightNum(mLightIndex++);        return light;    }    void addMaterial(const MaterialData& material)    {        mMaterials.push_back(material);    }    unsigned getNumMaterials() const    {        return mMaterials.size();    }    const MaterialData& getMaterial(unsigned idx) const    {        return mMaterials[idx];    }private:    /// Stores the ac3d file reader options, only used for reading texture files    osg::ref_ptr<osgDB::ReaderWriter::Options const> mOptions;    /// The list of ac3d MATERIALS    std::vector<MaterialData> mMaterials;    /// Local per model texture attribute cache.    /// ... images are usualy cached in the registries object cache    typedef std::map<std::string, TextureData> TextureDataMap;    TextureDataMap mTextureStates;    /// A common shared TexEnv set to modulate    osg::ref_ptr<osg::TexEnv> mModulateTexEnv;    /// Hack to include light nodes from ac3d into the scenegraph    unsigned mLightIndex;};struct RefData {    RefData(const osg::Vec3& _weightedNormal, const osg::Vec2& _texCoord, bool _smooth) :        weightedFlatNormal(_weightedNormal),        weightedFlatNormalLength(_weightedNormal.length()),        texCoord(_texCoord),        smooth(_smooth)    { }    // weighted flat surface normal    osg::Vec3 weightedFlatNormal;    float weightedFlatNormalLength;    osg::Vec2 texCoord;    // resulting vertex normal    osg::Vec3 finalNormal;    // if zero no need to smooth    unsigned smooth;};struct VertexData {    VertexData(const osg::Vec3& vertex) : _vertex(vertex) {}    unsigned addRefData(const RefData& refData)    {        unsigned index = _refs.size();        _refs.push_back(refData);        return index;    }    void collect(float cosCreaseAngle, const RefData& ref)    {        unsigned size = _refs.size();        for (unsigned i = 0; i < size; ++i)        {            if (_refs[i].smooth == ~0u)            {                float dot = _refs[i].weightedFlatNormal*ref.weightedFlatNormal;                float lengths = _refs[i].weightedFlatNormalLength*ref.weightedFlatNormalLength;                if (cosCreaseAngle*lengths <= dot)                {                    // Ok put that into the current set                    _refs[i].smooth = ref.smooth;                    collect(cosCreaseAngle, _refs[i]);                }            }        }    }    void smoothNormals(float cosCreaseAngle)    {        // compute sets of vertices smoothed to the same normal        // if smooth is zero we do not need to smooth        // in a first pass mark all refs not yet in a set to ~0u        unsigned size = _refs.size();        for (unsigned i = 0; i < size; ++i)        {            if (_refs[i].smooth)            {                _refs[i].smooth = ~0u;            }        }        // Now collect the sets        unsigned currentSet = 1;        for (unsigned i = 0; i < size; ++i)        {            if (_refs[i].smooth == ~0u)            {                _refs[i].smooth = currentSet++;                collect(cosCreaseAngle, _refs[i]);            }        }        // smooth and normalize the sets        for (--currentSet; 0 < currentSet; --currentSet)        {            osg::Vec3 normal(0, 0, 0);            for (unsigned i = 0; i < size; ++i)            {                if (_refs[i].smooth == currentSet)                {                    normal += _refs[i].weightedFlatNormal;                }            }            normal.normalize();            for (unsigned i = 0; i < size; ++i)            {                if (_refs[i].smooth == currentSet)                {                  _refs[i].finalNormal = normal;                }            }        }        // normalize the ones which do not need smoothing        for (unsigned i = 0; i < size; ++i)        {            if (_refs[i].smooth == 0)            {                _refs[i].finalNormal = _refs[i].weightedFlatNormal;                _refs[i].finalNormal.normalize();            }        }    }    osg::Vec3 _vertex;    std::vector<RefData> _refs;};struct VertexIndex {    VertexIndex(unsigned _vertexIndex = 0, unsigned _refIndex = 0) :        vertexIndex(_vertexIndex), refIndex(_refIndex)    { }    unsigned vertexIndex;    unsigned refIndex;};class VertexSet : public osg::Referenced {public:    VertexSet() : _dirty(true)    { }    void reserve(unsigned n)    {        _vertices.reserve(n);    }    unsigned size() const    {        return _vertices.size();    }    void setCreaseAngle(float crease)    {        _dirty = true;        if (crease <= 0)            _cosCreaseAngle = 1;        else if (180 <= crease)            _cosCreaseAngle = -1;        else            _cosCreaseAngle = cosf(osg::DegreesToRadians(crease));    }    void addVertex(const osg::Vec3& vertex)    {        _dirty = true;        _vertices.push_back(vertex);    }    const osg::Vec3& getVertex(unsigned index)    {        return _vertices[index]._vertex;    }    const osg::Vec3& getVertex(const VertexIndex& vertexIndex)    {        return _vertices[vertexIndex.vertexIndex]._vertex;    }    const osg::Vec3& getNormal(const VertexIndex& vertexIndex)    {        if (_dirty)            smoothNormals();        return _vertices[vertexIndex.vertexIndex]._refs[vertexIndex.refIndex].finalNormal;    }    const osg::Vec2& getTexCoord(const VertexIndex& vertexIndex)    {        return _vertices[vertexIndex.vertexIndex]._refs[vertexIndex.refIndex].texCoord;    }    VertexIndex addRefData(unsigned i, const RefData& refData)    {         if (_vertices.size() <= i)         {             osg::notify(osg::FATAL) << "osgDB ac3d reader: internal error, got invalid vertex index!" << std::endl;             return VertexIndex(0, 0);         }        _dirty = true;        return VertexIndex(i, _vertices[i].addRefData(refData));    }private:    void smoothNormals()    {        std::vector<VertexData>::iterator i;        for (i = _vertices.begin(); i != _vertices.end(); ++i)        {            i->smoothNormals(_cosCreaseAngle);        }        _dirty = false;    }    std::vector<VertexData> _vertices;    float _cosCreaseAngle;    bool _dirty;};class PrimitiveBin : public osg::Referenced{  public:    PrimitiveBin(unsigned flags, VertexSet* vertexSet) :        _geode(new osg::Geode),        _vertexSet(vertexSet),        _flags(flags)    {        _geode->setDataVariance(osg::Object::STATIC);    }    virtual bool beginPrimitive(unsigned nRefs) = 0;    virtual bool vertex(unsigned vertexIndex, const osg::Vec2& texCoord) = 0;    virtual bool endPrimitive() = 0;    virtual osg::Geode* finalize(const MaterialData& material, const TextureData& textureData) = 0;  protected:    bool isLineLoop() const    {        return (_flags & SurfaceTypeLineLoop)!=0;    }    bool isLineStrip() const    {        return (_flags & SurfaceTypeLineStrip)!=0;    }    bool isTwoSided() const    {        return (_flags & SurfaceTwoSided)!=0;    }    bool isSmooth() const    {        return (_flags & SurfaceShaded)!=0;    }    osg::ref_ptr<osg::Geode> _geode;    osg::ref_ptr<VertexSet> _vertexSet;  private:    unsigned _flags;};class LineBin : public PrimitiveBin{  private:    osg::ref_ptr<osg::Geometry> _geometry;    osg::ref_ptr<osg::Vec3Array> _vertices;    osg::ref_ptr<osg::Vec2Array> _texCoords;    struct Ref {      osg::Vec2 texCoord;

⌨️ 快捷键说明

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