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

📄 ac3d.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      unsigned index;    };    std::vector<Ref> _refs;  public:    LineBin(unsigned flags, VertexSet* vertexSet) :        PrimitiveBin(flags, vertexSet),        _geometry(new osg::Geometry),        _vertices(new osg::Vec3Array),        _texCoords(new osg::Vec2Array)    {        _geometry->setDataVariance(osg::Object::STATIC);        _vertices->setDataVariance(osg::Object::STATIC);        _texCoords->setDataVariance(osg::Object::STATIC);        _geometry->setVertexArray(_vertices.get());        _geometry->setTexCoordArray(0, _texCoords.get());        osg::StateSet* stateSet = _geode->getOrCreateStateSet();        stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);    }    virtual bool beginPrimitive(unsigned nRefs)    {        // Check if we have enough for a line or someting broken ...        if (nRefs < 2) {            osg::notify(osg::WARN) << "osgDB ac3d reader: detected line with less than 2 vertices!" << std::endl;            return false;        }        _refs.reserve(nRefs);        _refs.resize(0);        return true;    }    virtual bool vertex(unsigned vertexIndex, const osg::Vec2& texCoord)    {        Ref ref;        ref.index = vertexIndex;        ref.texCoord = texCoord;        _refs.push_back(ref);        return true;    }    virtual bool endPrimitive()    {        GLint type;        if (isLineLoop())            type = osg::PrimitiveSet::LINE_LOOP;        else if (isLineStrip())            type = osg::PrimitiveSet::LINE_STRIP;        else {            osg::notify(osg::FATAL) << "osgDB ac3d reader: non surface flags in surface bin!" << std::endl;            return false;        }        unsigned nRefs = _refs.size();        unsigned start = _vertices->size();        for (unsigned i = 0; i < nRefs; ++i) {            osg::Vec3 vertex = _vertexSet->getVertex(_refs[i].index);            _vertices->push_back(vertex);            _texCoords->push_back(_refs[i].texCoord);        }        _geometry->addPrimitiveSet(new osg::DrawArrays(type, start, nRefs));        return true;    }    virtual osg::Geode* finalize(const MaterialData& material, const TextureData& textureData)    {        _geode->addDrawable(_geometry.get());        material.toStateSet(_geode->getOrCreateStateSet());        _geometry->setColorArray(material.getColorArray());        _geometry->setColorBinding(osg::Geometry::BIND_OVERALL);        _geometry->setNormalBinding(osg::Geometry::BIND_OFF);        return _geode.get();    }};class SurfaceBin : public PrimitiveBin {  private:    struct Ref {        osg::Vec2 texCoord;        unsigned index;    };    std::vector<Ref> _refs;      struct TriangleData {        VertexIndex index[3];    };    std::vector<TriangleData> _triangles;      struct QuadData {        VertexIndex index[4];    };    std::vector<QuadData> _quads;    struct PolygonData {        std::vector<VertexIndex> index;    };    std::vector<PolygonData> _polygons;    std::vector<PolygonData> _toTessellatePolygons;  public:    SurfaceBin(unsigned flags, VertexSet *vertexSet) :        PrimitiveBin(flags, vertexSet)    { }    virtual bool beginPrimitive(unsigned nRefs)    {        _refs.reserve(nRefs);        _refs.clear();        // Check if we have enough for a line or someting broken ...        if (nRefs < 3) {            osg::notify(osg::WARN) << "osgDB ac3d reader: detected surface with less than 3 vertices!" << std::endl;            return false;        }        return true;    }    virtual bool vertex(unsigned vertexIndex, const osg::Vec2& texCoord)    {        Ref ref;        ref.index = vertexIndex;        ref.texCoord = texCoord;        _refs.push_back(ref);        return true;    }    virtual bool endPrimitive()    {        unsigned nRefs = _refs.size();        // Compute the normal times the enclosed area.        // During that check if the surface is convex. If so, put in the surface as such.        bool needTessellation = false;        osg::Vec3 prevEdgeNormal;        osg::Vec3 weightedNormal(0, 0, 0);        osg::Vec3 v0 = _vertexSet->getVertex(_refs[0].index);        for (unsigned i = 2; i < nRefs; ++i) {            osg::Vec3 side1 = _vertexSet->getVertex(_refs[i-1].index) - v0;            osg::Vec3 side2 = _vertexSet->getVertex(_refs[i].index) - v0;            osg::Vec3 newNormal = side1^side2;            if (!needTessellation)            {                if (3 < nRefs && newNormal*weightedNormal < 0)                {                    needTessellation = true;                }                if (i < 3)                {                    prevEdgeNormal = newNormal;                }                else // if (3 <= i) // due to the for loop                {                    osg::Vec3 sideim1 = _vertexSet->getVertex(_refs[i-1].index) - _vertexSet->getVertex(_refs[i-2].index);                    osg::Vec3 sidei = _vertexSet->getVertex(_refs[i].index) - _vertexSet->getVertex(_refs[i-2].index);                    osg::Vec3 edgeNormal = sideim1^sidei;                    if (edgeNormal*prevEdgeNormal < 0)                    {                        needTessellation = true;                    }                    prevEdgeNormal = edgeNormal;                }            }            weightedNormal += newNormal;        }                if (needTessellation)        {            unsigned polygonIndex = _toTessellatePolygons.size();            _toTessellatePolygons.resize(polygonIndex + 1);            for (unsigned i = 0; i < nRefs; ++i) {                RefData refData(weightedNormal, _refs[i].texCoord, isSmooth());                VertexIndex vertexIndex = _vertexSet->addRefData(_refs[i].index, refData);                _toTessellatePolygons[polygonIndex].index.push_back(vertexIndex);            }        }        else if (nRefs == 3)        {            unsigned triangleIndex = _triangles.size();            _triangles.resize(triangleIndex + 1);            for (unsigned i = 0; i < 3; ++i) {                RefData refData(weightedNormal, _refs[i].texCoord, isSmooth());                VertexIndex vertexIndex = _vertexSet->addRefData(_refs[i].index, refData);                _triangles[triangleIndex].index[i] = vertexIndex;            }        }        else if (nRefs == 4)        {            unsigned quadIndex = _quads.size();            _quads.resize(quadIndex + 1);            for (unsigned i = 0; i < 4; ++i) {                RefData refData(weightedNormal, _refs[i].texCoord, isSmooth());                VertexIndex vertexIndex = _vertexSet->addRefData(_refs[i].index, refData);                _quads[quadIndex].index[i] = vertexIndex;            }        }        else        {            unsigned polygonIndex = _polygons.size();            _polygons.resize(polygonIndex + 1);            for (unsigned i = 0; i < nRefs; ++i) {                RefData refData(weightedNormal, _refs[i].texCoord, isSmooth());                VertexIndex vertexIndex = _vertexSet->addRefData(_refs[i].index, refData);                _polygons[polygonIndex].index.push_back(vertexIndex);            }        }        return true;    }    void pushVertex(const VertexIndex& vertexIndex, osg::Vec3Array* vertexArray,                    osg::Vec3Array* normalArray, osg::Vec2Array* texcoordArray)    {        vertexArray->push_back(_vertexSet->getVertex(vertexIndex));        normalArray->push_back(_vertexSet->getNormal(vertexIndex));        if (texcoordArray)            texcoordArray->push_back(_vertexSet->getTexCoord(vertexIndex));    }    virtual osg::Geode* finalize(const MaterialData& material, const TextureData& textureData)    {        osg::StateSet* stateSet = _geode->getOrCreateStateSet();        material.toStateSet(stateSet);        textureData.toTextureStateSet(stateSet);        stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);        // Single- or doublesided culling        if (isTwoSided()) {            stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);        } else {            osg::CullFace* cullFace = new osg::CullFace;            cullFace->setDataVariance(osg::Object::STATIC);            cullFace->setMode(osg::CullFace::BACK);            stateSet->setAttribute(cullFace);            stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON);        }        // Flat or smooth shading        osg::ShadeModel* shadeModel = new osg::ShadeModel;        shadeModel->setDataVariance(osg::Object::STATIC);        if (isSmooth())            shadeModel->setMode(osg::ShadeModel::SMOOTH);        else            shadeModel->setMode(osg::ShadeModel::FLAT);        stateSet->setAttribute(shadeModel);                // Set up the arrays, allways store texture coords, may be we need them later ...        osg::Geometry* geometry = new osg::Geometry;        _geode->addDrawable(geometry);        geometry->setDataVariance(osg::Object::STATIC);        geometry->setColorArray(material.getColorArray());        geometry->setColorBinding(osg::Geometry::BIND_OVERALL);        geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);        osg::Vec3Array* normalArray = new osg::Vec3Array;        normalArray->setDataVariance(osg::Object::STATIC);        geometry->setNormalArray(normalArray);        osg::Vec3Array* vertexArray = new osg::Vec3Array;        vertexArray->setDataVariance(osg::Object::STATIC);        geometry->setVertexArray(vertexArray);        osg::Vec2Array* texcoordArray = 0;        if (textureData.valid())        {            texcoordArray = new osg::Vec2Array;            texcoordArray->setDataVariance(osg::Object::STATIC);            geometry->setTexCoordArray(0, texcoordArray);        }        // At first handle the the polygons to tessellate, fix them and append the other polygons later        if (!_toTessellatePolygons.empty())        {            unsigned start = vertexArray->size();            osg::DrawArrayLengths* drawArrayLengths = new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON, start);            drawArrayLengths->reserve(_toTessellatePolygons.size());            for (unsigned i = 0; i < _toTessellatePolygons.size(); ++i)            {                for (unsigned j = 0; j < _toTessellatePolygons[i].index.size(); ++j)                {                    pushVertex(_toTessellatePolygons[i].index[j], vertexArray, normalArray, texcoordArray);                }                drawArrayLengths->push_back(_toTessellatePolygons[i].index.size());            }            geometry->addPrimitiveSet(drawArrayLengths);            osgUtil::Tessellator Tessellator;            Tessellator.retessellatePolygons(*geometry);        }        // handle triangles        if (!_triangles.empty())        {            unsigned start = vertexArray->size();            for (unsigned i = 0; i < _triangles.size(); ++i)            {                for (unsigned j = 0; j < 3; ++j)                {                    pushVertex(_triangles[i].index[j], vertexArray, normalArray, texcoordArray);                }            }            osg::DrawArrays* drawArray = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, start, 3*_triangles.size());            geometry->addPrimitiveSet(drawArray);        }        // handle quads        if (!_quads.empty())        {            unsigned start = vertexArray->size();            for (unsigned i = 0; i < _quads.size(); ++i)            {                for (unsigned j = 0; j < 4; ++j)                {                    pushVertex(_quads[i].index[j], vertexArray, normalArray, texcoordArray);                }            }            osg::DrawArrays* drawArray = new osg::DrawArrays(osg::PrimitiveSet::QUADS, start, 4*_quads.size());            geometry->addPrimitiveSet(drawArray);        }        // handle polygons        if (!_polygons.empty())        {            unsigned start = vertexArray->size();            osg::DrawArrayLengths* drawArrayLengths = new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON, start);            drawArrayLengths->reserve(_polygons.size());            for (unsigned i = 0; i < _polygons.size(); ++i)            {                for (unsigned j = 0; j < _polygons[i].index.size(); ++j)                {                    pushVertex(_polygons[i].index[j], vertexArray, normalArray, texcoordArray);                }                drawArrayLengths->push_back(_polygons[i].index.size());            }            geometry->addPrimitiveSet(drawArrayLengths);        }        return _geode.get();    }};struct Bins{    PrimitiveBin* getOrCreatePrimitiveBin(unsigned flags, VertexSet* vertexSet)    {        if ((flags & SurfaceTypeLineLoop) || (flags & SurfaceTypeLineStrip))        {            if (!lineBin.valid())            {                lineBin = new LineBin(flags, vertexSet);            }            return lineBin.get();        }

⌨️ 快捷键说明

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