objwriternodevisitor.cpp

来自「最新osg包」· C++ 代码 · 共 575 行 · 第 1/2 页

CPP
575
字号
// -*-c++-*-/* * Wavefront OBJ loader for Open Scene Graph * * Copyright (C) 2001 Ulrich Hertlein <u.hertlein@web.de> * * Modified by Robert Osfield to support per Drawable coord, normal and * texture coord arrays, bug fixes, and support for texture mapping. * * Writing support added 2007 by Stephan Huber, http://digitalmind.de,  * some ideas taken from the dae-plugin * * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for  * real-time rendering of large 3D photo-realistic models.  * The OSG homepage is http://www.openscenegraph.org/ */#include <osg/io_utils>#include "OBJWriterNodeVisitor.h" /** writes all values of an array out to a stream, applies a matrix beforehand if necessary */class ValueVisitor : public osg::ValueVisitor {    public:        ValueVisitor(std::ostream& fout, const osg::Matrix& m = osg::Matrix::identity(), bool isNormal = false) :                osg::ValueVisitor(),             _fout(fout),             _m(m),             _isNormal(isNormal)        {             _applyMatrix = (_m != osg::Matrix::identity());            if (_isNormal) _origin = osg::Vec3(0,0,0) * _m;        }                virtual void apply (osg::Vec2 & inv)         {             _fout << inv[0] << ' ' << inv[1];         }                virtual void apply (osg::Vec3 & inv)         {             osg::Vec3 v(inv);            if (_applyMatrix)  v = (_isNormal) ? (v * _m) - _origin : v * _m;            _fout << v[0] << ' ' << v[1] << ' ' << v[2];         }                virtual void apply (osg::Vec2b & inv)        {             _fout << inv[0] << ' ' << inv[1];         }                virtual void apply (osg::Vec3b & inv)         {             osg::Vec3 v(inv[0], inv[1], inv[2]);            if (_applyMatrix)  v = (_isNormal) ? (v * _m) - _origin : v * _m;            _fout << v[0] << ' ' << v[1] << ' ' << v[2];         }                virtual void apply (osg::Vec2s & inv)         {                _fout << inv[0] << ' ' << inv[1];         }                virtual void apply (osg::Vec3s & inv)         {             osg::Vec3 v(inv[0], inv[1], inv[2]);            if (_applyMatrix)  v = (_isNormal) ? (v * _m) - _origin : v * _m;            _fout << v[0] << ' ' << v[1] << ' ' << v[2];         }    private:        std::ostream&    _fout;        osg::Matrix        _m;        bool            _applyMatrix, _isNormal;        osg::Vec3        _origin;};/** writes all primitives of a primitive-set out to a stream, decomposes quads to triangles, line-strips to lines etc */class PrimitiveIndexWriter : public osg::PrimitiveIndexFunctor {        public:        PrimitiveIndexWriter(std::ostream& fout,osg::Geometry* geo, unsigned int normalIndex, unsigned int lastVertexIndex, unsigned int  lastNormalIndex, unsigned int lastTexIndex) :             osg::PrimitiveIndexFunctor(),             _fout(fout),            _lastVertexIndex(lastVertexIndex),            _lastNormalIndex(lastNormalIndex),            _lastTexIndex(lastTexIndex),            _hasNormalCoords(geo->getNormalArray() != NULL),            _hasTexCoords(geo->getTexCoordArray(0) != NULL),            _geo(geo),            _normalIndex(normalIndex)        {        }                virtual void setVertexArray(unsigned int,const osg::Vec2*) {}        virtual void setVertexArray(unsigned int ,const osg::Vec3* ) {}        virtual void setVertexArray(unsigned int,const osg::Vec4* ) {}                virtual void setVertexArray(unsigned int,const osg::Vec2d*) {}        virtual void setVertexArray(unsigned int ,const osg::Vec3d* ) {}        virtual void setVertexArray(unsigned int,const osg::Vec4d* ) {}                void write(unsigned int i)         {            _fout << (i + _lastVertexIndex) << "/";                        if (_hasTexCoords || _hasNormalCoords)             {                if (_hasTexCoords)                    _fout << (i + _lastTexIndex);                _fout << "/";                if (_hasNormalCoords)                 {                    if (_geo->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX)                        _fout << (i+_lastNormalIndex);                    else                        _fout << (_normalIndex + _lastNormalIndex);                }            }            _fout << " ";        }                // operator for triangles        void writeTriangle(unsigned int i1, unsigned int i2, unsigned int i3)         {            _fout << "f ";            write(i1);            write(i2);            write(i3);            _fout << std::endl;            // not sure if this is correct?            if(_geo->getNormalBinding() && _geo->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE) ++_normalIndex;        }                // operator for lines        void writeLine(unsigned int i1, unsigned int i2)         {            _fout << "l ";            write(i1);            write(i2);            _fout << std::endl;            // not sure if this is correct?            if(_geo->getNormalBinding() && _geo->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE) ++_normalIndex;        }                // operator for points        void writePoint(unsigned int i1)         {            _fout << "p ";            write(i1);            _fout << std::endl;            // not sure if this is correct?            if(_geo->getNormalBinding() && _geo->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE) ++_normalIndex;        }        virtual void begin(GLenum mode)        {            _modeCache = mode;            _indexCache.clear();        }        virtual void vertex(unsigned int vert)        {            _indexCache.push_back(vert);        }        virtual void end()        {            if (!_indexCache.empty())            {                drawElements(_modeCache,_indexCache.size(),&_indexCache.front());            }        }        virtual void drawArrays(GLenum mode,GLint first,GLsizei count);                                    virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)        {            drawElementsImplementation<GLubyte>(mode, count, indices);        }        virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)        {            drawElementsImplementation<GLushort>(mode, count, indices);        }            virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)        {            drawElementsImplementation<GLuint>(mode, count, indices);        }        protected:                template<typename T>void drawElementsImplementation(GLenum mode, GLsizei count, const T* indices)         {            if (indices==0 || count==0) return;            typedef const T* IndexPointer;                    switch(mode)            {                case(GL_TRIANGLES):                {                    IndexPointer ilast = &indices[count];                    for(IndexPointer  iptr=indices;iptr<ilast;iptr+=3)                        writeTriangle(*iptr,*(iptr+1),*(iptr+2));                        break;                }                case(GL_TRIANGLE_STRIP):                {                    IndexPointer iptr = indices;                    for(GLsizei i=2;i<count;++i,++iptr)                    {                        if ((i%2)) writeTriangle(*(iptr),*(iptr+2),*(iptr+1));                        else       writeTriangle(*(iptr),*(iptr+1),*(iptr+2));                    }                    break;                }                case(GL_QUADS):                {                    IndexPointer iptr = indices;                    for(GLsizei i=3;i<count;i+=4,iptr+=4)                    {                        writeTriangle(*(iptr),*(iptr+1),*(iptr+2));                        writeTriangle(*(iptr),*(iptr+2),*(iptr+3));                    }                    break;                }                case(GL_QUAD_STRIP):                {                    IndexPointer iptr = indices;                    for(GLsizei i=3;i<count;i+=2,iptr+=2)                    {                        writeTriangle(*(iptr),*(iptr+1),*(iptr+2));                        writeTriangle(*(iptr+1),*(iptr+3),*(iptr+2));                    }                    break;                }                case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN                case(GL_TRIANGLE_FAN):                {                    IndexPointer iptr = indices;                    unsigned int first = *iptr;                    ++iptr;                    for(GLsizei i=2;i<count;++i,++iptr)                    {                        writeTriangle(first,*(iptr),*(iptr+1));                    }                    break;                }                case(GL_POINTS):                {                    IndexPointer ilast = &indices[count];                    for(IndexPointer  iptr=indices;iptr<ilast;++iptr)                                        {                        writePoint(*iptr);                    }                    break;                }                case(GL_LINES):                {                    IndexPointer ilast = &indices[count];                    for(IndexPointer  iptr=indices;iptr<ilast;iptr+=2)                    {                        writeLine(*iptr, *(iptr+1));                    }                    break;                }                case(GL_LINE_STRIP):                {                                        IndexPointer ilast = &indices[count];                    for(IndexPointer  iptr=indices+1;iptr<ilast;iptr+=2)                    {                        writeLine(*(iptr-1), *iptr);                    }                    break;                }                case(GL_LINE_LOOP):                {

⌨️ 快捷键说明

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