From 4e7867ba8c7561fbd2f81f9f986b135ec6c998ba Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 12 Oct 2003 15:20:09 +0000 Subject: [PATCH] From Geoff Michel & Roger James,revised AC3D loader - accepted the improvement from Roger James for texture mapping, and developed his writer until it actually writes most geometries (no text or osgFX nodes of course). --- VisualStudio/osgPlugins/ac3d/ac3d.dsp | 20 + src/osgPlugins/ac3d/Exception.cpp | 9 + src/osgPlugins/ac3d/Exception.h | 19 + src/osgPlugins/ac3d/GNUmakefile | 2 + src/osgPlugins/ac3d/Geode.cpp | 1196 +++++++++++++++++++++++++ src/osgPlugins/ac3d/Geode.h | 98 ++ src/osgPlugins/ac3d/ac3d.cpp | 804 +++++++++-------- src/osgPlugins/ac3d/osgac3d.h | 2 +- 8 files changed, 1794 insertions(+), 356 deletions(-) create mode 100644 src/osgPlugins/ac3d/Exception.cpp create mode 100644 src/osgPlugins/ac3d/Exception.h create mode 100644 src/osgPlugins/ac3d/Geode.cpp create mode 100644 src/osgPlugins/ac3d/Geode.h diff --git a/VisualStudio/osgPlugins/ac3d/ac3d.dsp b/VisualStudio/osgPlugins/ac3d/ac3d.dsp index 3adb263f7..7ec9375d3 100644 --- a/VisualStudio/osgPlugins/ac3d/ac3d.dsp +++ b/VisualStudio/osgPlugins/ac3d/ac3d.dsp @@ -96,10 +96,30 @@ LINK32=link.exe SOURCE=..\..\..\src\osgPlugins\ac3d\ac3d.cpp # End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\ac3d\Exception.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\ac3d\Geode.cpp +# End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\ac3d\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\ac3d\Geode.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\ac3d\osgac3d.h +# End Source File # End Group # Begin Group "Resource Files" diff --git a/src/osgPlugins/ac3d/Exception.cpp b/src/osgPlugins/ac3d/Exception.cpp new file mode 100644 index 000000000..21974d388 --- /dev/null +++ b/src/osgPlugins/ac3d/Exception.cpp @@ -0,0 +1,9 @@ +#include "Exception.h" + +using namespace ac3d; + +Exception::Exception(std::string error){ + _error = error; +} + +Exception::~Exception(){} diff --git a/src/osgPlugins/ac3d/Exception.h b/src/osgPlugins/ac3d/Exception.h new file mode 100644 index 000000000..97e29785f --- /dev/null +++ b/src/osgPlugins/ac3d/Exception.h @@ -0,0 +1,19 @@ +#ifndef AC3D_EXCEPTION +#define AC3D_EXCEPTION 1 + +#include + +namespace ac3d{ + +class Exception{ +public: + Exception(std::string error); + ~Exception(); + std::string getError(){return _error;}; +private: + std::string _error; +}; + +} + +#endif diff --git a/src/osgPlugins/ac3d/GNUmakefile b/src/osgPlugins/ac3d/GNUmakefile index d9a116faa..acc4a6b8a 100644 --- a/src/osgPlugins/ac3d/GNUmakefile +++ b/src/osgPlugins/ac3d/GNUmakefile @@ -2,6 +2,8 @@ TOPDIR = ../../.. include $(TOPDIR)/Make/makedefs CXXFILES =\ + Exception.cpp\ + Geode.cpp\ ac3d.cpp\ LIBS += $(OSG_LIBS) $(OTHER_LIBS) diff --git a/src/osgPlugins/ac3d/Geode.cpp b/src/osgPlugins/ac3d/Geode.cpp new file mode 100644 index 000000000..b4c12e585 --- /dev/null +++ b/src/osgPlugins/ac3d/Geode.cpp @@ -0,0 +1,1196 @@ +/* Code for writing AC3D format files, constructs one object per Geode + * since geodes only have 1 material, and AC3D allows multiple materials you + * may not get an exact vopy of an ac3d file used as input. + * + * originally by Roger James. + * upgraded to different types of Geometry primitive by Geoff Michel. + * Old GeoSet parsing code is commented out - will be removed eventually. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Exception.h" +#include "Geode.h" +#include "osgac3d.h" + +using namespace ac3d; +using namespace std; + + + +void Geode::OutputVertex(int Index, const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, ostream& fout) +{ + int LocalTexIndex; + int LocalVertexIndex; + if (NULL == pVertexIndices) + LocalVertexIndex = Index; + else + LocalVertexIndex = pVertexIndices->index(Index); + if (NULL != pTexCoords) + { + // Got some tex coords + // Check for an index + if (NULL != pTexIndices) + // Access tex coord array indirectly + LocalTexIndex = pTexIndices->index(Index); + else + LocalTexIndex = Index; + fout << LocalVertexIndex << " " << pTexCoords[LocalTexIndex][0] << " " << pTexCoords[LocalTexIndex][1] << std::endl; + } + else + fout << LocalVertexIndex << " 0 0" << std::endl; +} + +void Geode::OutputLines(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, ostream& fout) +{ + unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + OutputSurfHead(iCurrentMaterial,surfaceFlags,indexEnd-drawArray->getFirst(), fout); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + OutputSurfHead(iCurrentMaterial,surfaceFlags,indexEnd-drawArray->getFirst(), fout); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + unsigned int evenodd=0; + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst()+1; vindexgetFirst(), pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuads(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout) +{ + unsigned int primCount = 0; + unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst() + drawArray->getCount(); + OutputSurfHead(iCurrentMaterial,surfaceFlags,drawArray->getCount(), fout); + for(unsigned int vindex=drawArray->getFirst(); vindexgetFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr end(); ++primItr) + { + unsigned int localPrimLength; + localPrimLength = 3; + + for(GLsizei primCount = 0; primCount < *primItr; ++primCount) + { + if ((primCount%localPrimLength)==0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + } + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + ++vindex; + } + + } +} +void Geode::OutputQuadsDARR(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout) +{ + unsigned int vindex = drawArrayLengths->getFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr end()-4; primItr+=4) + { + unsigned int localPrimLength; + localPrimLength = 4; + + for(GLsizei primCount = 0; primCount < *primItr; ++primCount) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+3, pVertexIndices, pTexCoords, pTexIndices, fout); + vindex+=4; + } + + } +} +void Geode::OutputQuadStripDARR(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout) +{ + unsigned int vindex = drawArrayLengths->getFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr end()-2; primItr+=2) + { + unsigned int localPrimLength; + localPrimLength = *primItr; + + for(GLsizei primCount = 0; primCount < *primItr; ++primCount) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+3, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout); + vindex+=2; + } + + } +} +void Geode::OutputPolygonDARR(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout) +{ + unsigned int vindex = drawArrayLengths->getFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr end(); ++primItr) + { + unsigned int localPrimLength; + localPrimLength = *primItr; + + for(GLsizei primCount = 0; primCount < *primItr; ++primCount) + { + if ((primCount%localPrimLength)==0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + } + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + ++vindex; + } + + } +} +void Geode::OutputTriangleStripDARR(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout) +{ + unsigned int vindex = drawArrayLengths->getFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr end(); ++primItr) + { + unsigned int localPrimLength; + bool evenodd=true; + localPrimLength = 3; + + for(GLsizei primCount = 0; primCount < *primItr-2; ++primCount) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + if (evenodd) { + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout); + } else { + OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } + OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout); + ++vindex; + evenodd=!evenodd; + } + + } +} +void Geode::OutputTriangleFanDARR(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout) +{ + unsigned int vindex = drawArrayLengths->getFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr end(); ++primItr) + { + unsigned int localPrimLength; + localPrimLength = *primItr; + + for(GLsizei primCount = 1; primCount < *primItr-1; ++primCount) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,3, fout); + OutputVertex(drawArrayLengths->getFirst(), pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout); + ++vindex; + } + + } +} + +// DrawElements .... Ubyte +void Geode::OutputTriangleDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUByte* drawElements, ostream& fout) +{ + unsigned int primLength =3; + + unsigned int primCount = 0; + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItrend(); ++primCount,++primItr) + { + if ((primCount%primLength) == 0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + } + + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputTriangleStripDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUByte* drawElements, ostream& fout) +{ + unsigned int localPrimLength = 3; + bool evenodd=true; + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItrend()-2; ++primItr) + { + + unsigned int vindex=*primItr; + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + if (evenodd) { + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + } else { + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + evenodd=!evenodd; + } +} +void Geode::OutputTriangleFanDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUByte* drawElements, ostream& fout) +{ + const unsigned int localPrimLength = 3; + unsigned int vindex=*(drawElements->begin()); + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItrend()-2; ++primItr) + { + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuadStripDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUByte* drawElements, ostream& fout) +{ + const unsigned int localPrimLength=4; + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItrend()-3; primItr+=2) + { + unsigned int vindex=*primItr; + + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+3); + unsigned int vindexp3=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuadsDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUByte* drawElements, ostream& fout) +{ + const unsigned int localPrimLength=4; + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItrend()-3; primItr+=4) + { + unsigned int vindex=*primItr; + + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + unsigned int vindexp3=*(primItr+3); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputPolygonDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUByte* drawElements, ostream& fout) +{ + unsigned int primLength =drawElements->size(); + unsigned int primCount = 0; + + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItrend(); ++primCount,++primItr) + { + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +// DrawElements .... UShort +void Geode::OutputTriangleDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUShort* drawElements, ostream& fout) +{ + unsigned int primLength =3; + + unsigned int primCount = 0; + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItrend(); ++primCount,++primItr) + { + + if ((primCount%primLength) == 0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + } + + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputTriangleStripDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUShort* drawElements, ostream& fout) +{ + unsigned int localPrimLength = 3; + bool evenodd=true; + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItrend()-2; ++primItr) + { + unsigned int vindex=*primItr; + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + if (evenodd) { + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + } else { + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + evenodd=!evenodd; + } +} +void Geode::OutputTriangleFanDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUShort* drawElements, ostream& fout) +{ + const unsigned int localPrimLength = 3; + unsigned int vindex=*(drawElements->begin()); + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItrend()-2; ++primItr) + { + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuadStripDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUShort* drawElements, ostream& fout) +{ + const unsigned int localPrimLength=4; + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItrend()-3; primItr+=2) + { + unsigned int vindex=*primItr; + + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+3); + unsigned int vindexp3=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuadsDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUShort* drawElements, ostream& fout) +{ + const unsigned int localPrimLength=4; + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItrend()-3; primItr+=4) + { + unsigned int vindex=*primItr; + + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + unsigned int vindexp3=*(primItr+3); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputPolygonDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUShort* drawElements, ostream& fout) +{ + unsigned int primLength =drawElements->size(); + unsigned int primCount = 0; + + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItrend(); ++primCount,++primItr) + { + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +// DrawElements .... UInt +void Geode::OutputTriangleDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUInt* drawElements, ostream& fout) +{ + unsigned int primLength =3; + + unsigned int primCount = 0; + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItrend(); ++primCount,++primItr) + { + + if ((primCount%primLength) == 0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + } + + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputTriangleStripDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUInt* drawElements, ostream& fout) +{ + unsigned int localPrimLength = 3; + bool evenodd=true; + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItrend()-2; ++primItr) + { + + unsigned int vindex=*primItr; + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + if (evenodd) { + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + } else { + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + evenodd=!evenodd; + } +} +void Geode::OutputTriangleFanDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUInt* drawElements, ostream& fout) +{ + const unsigned int localPrimLength = 3; + unsigned int vindex=*(drawElements->begin()); + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItrend()-2; ++primItr) + { + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuadStripDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUInt* drawElements, ostream& fout) +{ + const unsigned int localPrimLength = 4; + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItrend()-3; primItr+=2) + { + unsigned int vindex=*primItr; + + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+3); + unsigned int vindexp3=*(primItr+2); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputQuadsDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUInt* drawElements, ostream& fout) +{ + const unsigned int localPrimLength=4; + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItrend()-3; primItr+=4) + { + unsigned int vindex=*primItr; + + unsigned int vindexp1=*(primItr+1); + unsigned int vindexp2=*(primItr+2); + unsigned int vindexp3=*(primItr+3); + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout); + OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} +void Geode::OutputPolygonDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, + const osg::DrawElementsUInt* drawElements, ostream& fout) +{ + unsigned int primLength =drawElements->size(); + unsigned int primCount = 0; + + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItrend(); ++primCount,++primItr) + { + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } +} + + +const int Geode::ProcessMaterial(ostream& fout, const unsigned int igeode) +{ + // outputs materials from one geode + // extended for multiple geode models, GWM 2003. + // called before all the geometry as ac3d expects all materials in the header. + // returns number of materials made + unsigned int i; + const unsigned int iNumDrawables = getNumDrawables(); + const osg::StateSet::RefAttributePair* pRAP; + unsigned int iNumMaterials=0; + // Let ac3d optimise the file + // whiz round and get a list of materials + // these may be duplicates of materials on other Geode/geometry sets. + + // Scan for materials + for (i = 0; i < iNumDrawables; i++) + { + const osg::Drawable* Drawable = getDrawable(i); + if (Drawable) { + const osg::StateSet* theState = Drawable->getStateSet(); + if (theState) { + pRAP = theState->getAttributePair(osg::StateAttribute::MATERIAL); + if (NULL != pRAP) + { + const osg::Material *pMaterial = dynamic_cast(pRAP->first.get()); + if (NULL != pMaterial) + { + const osg::Vec4& Diffuse = pMaterial->getDiffuse(osg::Material::FRONT_AND_BACK); + const osg::Vec4& Ambient = pMaterial->getAmbient(osg::Material::FRONT_AND_BACK); + const osg::Vec4& Emissive = pMaterial->getEmission(osg::Material::FRONT_AND_BACK); + const osg::Vec4& Specular = pMaterial->getSpecular(osg::Material::FRONT_AND_BACK); + fout << "MATERIAL " + << "\"osg"<getShininess(osg::Material::FRONT_AND_BACK) << " " + << "trans " << 1.0 - Diffuse[3] << std::endl; + iNumMaterials++; + } + } + } + } + } + return iNumMaterials; +} +void Geode::ProcessGeometry(ostream& fout, const unsigned int ioffset) +{ + // outputs one geode + // extended for multiple geode models, GWM 2003. + unsigned int i, j; //, k, m; + const unsigned int iNumDrawables = getNumDrawables(); + int iNumMaterials = 0; + const osg::StateSet::RefAttributePair* pRAP=NULL; + // Let ac3d optimise the file + // whiz round and get a list of materails + // write them out + // write out an object for each drawable. + // Write out world object + int ngeometry=0; // not all drawables are geometry, text is not converted to facets. + for (i = 0; i < iNumDrawables; i++) + { // so here we count the geometries to be converted to AC3D + const osg::Drawable* Drawable = getDrawable(i); + if (Drawable) { + const osg::Geometry *pGeometry = Drawable->asGeometry(); + if (NULL != pGeometry) ngeometry++; + } + } + if (ngeometry>1) { // create a group + fout << "OBJECT group" << std::endl; + fout << "kids " << ngeometry << std::endl; + } + + // Process each drawable in turn + for (i = 0; i < iNumDrawables; i++) + { + const osg::Drawable* Drawable = getDrawable(i); + if (Drawable) { + const osg::StateSet* theState = Drawable->getStateSet(); + const osg::Geometry *pGeometry = Drawable->asGeometry(); + if (NULL != pGeometry) + { + int iCurrentMaterial = -1; + + if (theState) { + pRAP = theState->getAttributePair(osg::StateAttribute::MATERIAL); + if (NULL != pRAP) + { + iCurrentMaterial = ioffset+iNumMaterials; + iNumMaterials++; + } + } + + //const osg::Vec3Array + const osg::Array *pVertexArray = pGeometry->getVertexArray(); + if (NULL != pVertexArray) + { + const unsigned int iNumVertices = pVertexArray->getNumElements(); // size(); + const osg::IndexArray *pVertexIndices = pGeometry->getVertexIndices(); + const osg::IndexArray * pTexIndices = pGeometry->getTexCoordIndices(0); + const osg::Vec2 *pTexCoords = NULL; + fout << "OBJECT poly" << std::endl; + fout << "name \"" << getName() << "\"" << std::endl; + + // Use zero offset co-ordinate as location IS OPTIONAL + // fout << "loc " << "0 0 0" << std::endl; + /* you could have an offset for the coordinates; it was suggested that the first coord would do. + if((*pVertexArray).getType()==osg::Array::Vec3ArrayType) { + const osg::Vec3Array *verts=static_cast(pVertexArray); + fout << (*verts)[0][0] << " " << (*verts)[0][1] << " " << (*verts)[0][2] << std::endl; + } else if((*pVertexArray).getType()==osg::Array::Vec2ArrayType) { + const osg::Vec2Array *verts=static_cast(pVertexArray); + fout << (*verts)[0][0] << " " << (*verts)[0][1] << " " << 0 << std::endl; + } else if((*pVertexArray).getType()==osg::Array::Vec4ArrayType) { + const osg::Vec4Array *verts=static_cast(pVertexArray); + fout << (*verts)[0][0] << " " << (*verts)[0][1] << " " << (*verts)[0][2] << std::endl; + } + << (*pVertexArray)[0][0] << " " + << (*pVertexArray)[0][1] << " " + << (*pVertexArray)[0][2] << std::endl; */ + + // Check for a texture + if (theState) + { + const osg::StateSet::TextureModeList& TextureModeList = theState->getTextureModeList(); + const osg::StateSet::TextureAttributeList& TextureAttributeList = theState->getTextureAttributeList(); + if (TextureAttributeList.size() > 0) + { + // Dont yet know how to handle more than one texture + assert(TextureAttributeList.size() == 1); + assert(TextureModeList.size() == 1); + const osg::StateSet::ModeList& ModeList = TextureModeList[0]; + assert(ModeList.size() == 1); + // Check for a single mode of GL_TEXTURE_2D and ON + std::pair ModeValuePair = *ModeList.begin(); + assert(ModeValuePair.first == GL_TEXTURE_2D); + assert(ModeValuePair.second == osg::StateAttribute::ON); + const osg::StateSet::AttributeList& AttributeList = TextureAttributeList[0]; + // assert(AttributeList.size() == 1); + const osg::Texture2D *pTexture2D = dynamic_cast(AttributeList.begin()->second.first.get()); + // assert(NULL != pTexture2D); + if (NULL != pTexture2D) + { + float fRep_s, fRep_t; + float fOffset_s, fOffset_t; + + pTexCoords = (const osg::Vec2*)pGeometry->getTexCoordArray(0)->getDataPointer(); + + // OK now see if I can calcualate the repeats + osg::Texture::WrapMode eWrapMode_s = pTexture2D->getWrap(osg::Texture::WRAP_S); + //osg::Texture::WrapMode eWrapMode_t = pTexture2D->getWrap(osg::Texture::WRAP_T); + + if (eWrapMode_s == osg::Texture::REPEAT) + { + if (NULL != pTexCoords) + { + // Find max min s coords + float fMin = std::numeric_limits::max(); + float fMax = std::numeric_limits::min(); + unsigned int iNumTexCoords = pGeometry->getTexCoordArray(0)->getNumElements(); + + for (j = 0; j < iNumTexCoords; j++) + { + if (pTexCoords[j][0] > fMax) + fMax = pTexCoords[j][0]; + if (pTexCoords[j][0] < fMin) + fMin = pTexCoords[j][0]; + } + fRep_s = fMax - fMin; + fOffset_s = fMin; + fMin = std::numeric_limits::max(); + fMax = std::numeric_limits::min(); + for (j = 0; j < iNumTexCoords; j++) + { + if (pTexCoords[j][1] > fMax) + fMax = pTexCoords[j][1]; + if (pTexCoords[j][1] < fMin) + fMin = pTexCoords[j][1]; + } + fRep_t = fMax - fMin; + fOffset_t = fMin; + } + else + { + fRep_s = 1.0; + fOffset_s = 0.0; + fRep_t = 1.0; + fOffset_t = 0.0; + } + } + else + { + fRep_s = 0.0; + fOffset_s = 0.0; + fRep_t = 0.0; + fOffset_t = 0.0; + } + { // replace back slash with / for ac3d convention GWM Sep 2003 + std::string fname=pTexture2D->getImage()->getFileName(); + unsigned int pos; + for (pos=0; pos< fname.length(); pos++) { + if (fname[pos] == '\\') fname[pos]='/'; + } + fout << "texture \"" << fname << "\"" << std::endl; + } + fout << "texrep " << fRep_s << " " << fRep_t << std::endl; + fout << "texoff " << fOffset_s << " " << fOffset_s << std::endl; + } + } + } + + fout << "numvert " << iNumVertices << std::endl; + for (j = 0; j < iNumVertices; j++) + { // use 3 types of osg::Vec for coordinates.... + if((*pVertexArray).getType()==osg::Array::Vec3ArrayType) { + const osg::Vec3Array *verts=static_cast(pVertexArray); + fout << (*verts)[j][0] << " " << (*verts)[j][1] << " " << (*verts)[j][2] << std::endl; + } else if((*pVertexArray).getType()==osg::Array::Vec2ArrayType) { + const osg::Vec2Array *verts=static_cast(pVertexArray); + fout << (*verts)[j][0] << " " << (*verts)[j][1] << " " << 0 << std::endl; + } else if((*pVertexArray).getType()==osg::Array::Vec4ArrayType) { + const osg::Vec4Array *verts=static_cast(pVertexArray); + fout << (*verts)[j][0] << " " << (*verts)[j][1] << " " << (*verts)[j][2] << std::endl; + } + } + + + // Generate a surface for each primitive + unsigned int iNumPrimitives = 0; + unsigned int iNumSurfaces = 0; // complex tri-strip etc prims use more triangles + osg::Geometry::PrimitiveSetList::const_iterator pItr; + for(pItr = pGeometry->getPrimitiveSetList().begin(); pItr != pGeometry->getPrimitiveSetList().end(); ++pItr) { + const osg::PrimitiveSet* primitiveset = pItr->get(); + GLenum mode=primitiveset->getMode(); + //const osg::DrawArrays* drawArray = static_cast(primitiveset); + iNumPrimitives += (*pItr)->getNumPrimitives(); + unsigned int primLength = primitiveset->getNumIndices(); + switch(mode) + { + case(osg::PrimitiveSet::POINTS): + iNumSurfaces+=1; // all points go in one big list + break; + case(osg::PrimitiveSet::LINES): // each line is a pair of vertices + iNumSurfaces+=primLength/2; + break; + case(osg::PrimitiveSet::TRIANGLES): // each tri = 3 verts + iNumSurfaces+=primLength/3; + break; + case(osg::PrimitiveSet::QUADS): + iNumSurfaces+=primLength/4; + break; + case(osg::PrimitiveSet::LINE_LOOP): + iNumSurfaces+=iNumPrimitives; + break; + case(osg::PrimitiveSet::LINE_STRIP): + iNumSurfaces+=iNumPrimitives; + break; + case(osg::PrimitiveSet::TRIANGLE_STRIP): + iNumSurfaces+=primLength-2; + break; + case(osg::PrimitiveSet::TRIANGLE_FAN): + iNumSurfaces+=primLength-2; + break; + case(osg::PrimitiveSet::QUAD_STRIP): + iNumSurfaces+=(primLength-2)/2; + break; + case(osg::PrimitiveSet::POLYGON): + iNumSurfaces+=1; + break; + default: + break; // unknown shape + } + } + fout << "numsurf " << iNumSurfaces << std::endl; + + for(pItr = pGeometry->getPrimitiveSetList().begin(); pItr != pGeometry->getPrimitiveSetList().end(); ++pItr) + { + const osg::PrimitiveSet* primitiveset = pItr->get(); + GLenum mode=primitiveset->getMode(); + + unsigned int primLength; + unsigned int surfaceFlags = 0x00; + + switch(mode) + { + case(osg::PrimitiveSet::POINTS): + primLength = 1; + surfaceFlags = 0x02; + break; + case(osg::PrimitiveSet::LINES): + primLength = 2; + surfaceFlags = 0x02; + break; + case(osg::PrimitiveSet::TRIANGLES): + primLength = 3; + break; + case(osg::PrimitiveSet::QUADS): + primLength = 4; + break; + default: + primLength = 0; + break; // compute later when =0. + } + +// osg::StateAttribute::GLModeValue backface =theState->getMode(osg::StateAttribute::CULLFACE); +// if (backface==osg::StateAttribute::ON) surfaceFlags |= 0x10; +// else if (backface==osg::StateAttribute::OFF) surfaceFlags &= 0x0f; + const osg::DrawArrays* drawArray = static_cast(primitiveset); + switch(primitiveset->getType()) + { + case(osg::PrimitiveSet::DrawArraysPrimitiveType): + { + switch(mode) + { + case(osg::PrimitiveSet::POINTS): + break; + case(osg::PrimitiveSet::LINES): + OutputLines(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::LINE_LOOP): + OutputLineLoop(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::LINE_STRIP): + OutputLineStrip(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::TRIANGLES): + OutputTriangle(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::QUADS): + OutputQuads(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_STRIP): + OutputTriangleStrip(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_FAN): + OutputTriangleFan(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::QUAD_STRIP): + OutputQuadStrip(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + case(osg::PrimitiveSet::POLYGON): + OutputPolygon(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout); + break; + default: + break; // unknown shape + } + break; + } + case(osg::PrimitiveSet::DrawArrayLengthsPrimitiveType): + { + + const osg::DrawArrayLengths* drawArrayLengths = static_cast(primitiveset); + switch(mode) + { + case(osg::PrimitiveSet::TRIANGLES): + OutputTriangleDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout); + break; + case(osg::PrimitiveSet::QUADS): + OutputQuadsDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_STRIP): + OutputTriangleStripDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_FAN): + OutputTriangleFanDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout); + break; + case(osg::PrimitiveSet::QUAD_STRIP): + OutputQuadStripDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout); + break; + case(osg::PrimitiveSet::POLYGON): + OutputPolygonDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout); + break; + default: + break; // unknown shape + } + /* const osg::DrawArrayLengths* drawArrayLengths = static_cast(primitiveset); + unsigned int vindex = drawArrayLengths->getFirst(); + for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr !=drawArrayLengths->end(); ++primItr) + { + unsigned int localPrimLength; + if (primLength == 0) localPrimLength = *primItr; + else localPrimLength = primLength; + + for(GLsizei primCount = 0; primCount < *primItr; ++primCount) + { + if ((primCount%localPrimLength)==0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout); + } + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + ++vindex; + } + + }*/ + break; + } + case(osg::PrimitiveSet::DrawElementsUBytePrimitiveType): + { + const osg::DrawElementsUByte* drawElements = static_cast(primitiveset); + switch(mode) + { + case(osg::PrimitiveSet::TRIANGLES): + OutputTriangleDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::QUADS): + OutputQuadsDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_STRIP): + OutputTriangleStripDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_FAN): + OutputTriangleFanDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::QUAD_STRIP): + OutputQuadStripDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::POLYGON): + OutputPolygonDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + default: + break; // unknown shape + } +/* if (primLength == 0) + primLength = primitiveset->getNumIndices(); + + const osg::DrawElementsUByte* drawElements = static_cast(primitiveset); + + unsigned int primCount = 0; + for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount,++primItr) + { + + if ((primCount%primLength) == 0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + } + + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } + */ + + break; + } + case(osg::PrimitiveSet::DrawElementsUShortPrimitiveType): + { + const osg::DrawElementsUShort* drawElements = static_cast(primitiveset); + switch(mode) + { + case(osg::PrimitiveSet::TRIANGLES): + OutputTriangleDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::QUADS): + OutputQuadsDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_STRIP): + OutputTriangleStripDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_FAN): + OutputTriangleFanDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::QUAD_STRIP): + OutputQuadStripDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::POLYGON): + OutputPolygonDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + default: + break; // unknown shape + } +/* if (primLength == 0) + if (primLength == 0) + primLength = primitiveset->getNumIndices(); + + const osg::DrawElementsUShort* drawElements = static_cast(primitiveset); + + unsigned int primCount = 0; + + for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount,++primItr) + { + + if ((primCount%primLength) == 0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + } + + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } */ + + break; + } + case(osg::PrimitiveSet::DrawElementsUIntPrimitiveType): + { + const osg::DrawElementsUInt* drawElements = static_cast(primitiveset); + switch(mode) + { + case(osg::PrimitiveSet::TRIANGLES): + OutputTriangleDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::QUADS): + OutputQuadsDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_STRIP): + OutputTriangleStripDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::TRIANGLE_FAN): + OutputTriangleFanDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::QUAD_STRIP): + OutputQuadStripDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + case(osg::PrimitiveSet::POLYGON): + OutputPolygonDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout); + break; + default: + break; // unknown shape + } +/* if (primLength == 0) + if (primLength == 0) + primLength = primitiveset->getNumIndices(); + + const osg::DrawElementsUInt* drawElements = static_cast(primitiveset); + + unsigned int primCount=0; + for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount,++primItr) + { + + if ((primCount%primLength)==0) + { + OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout); + } + + unsigned int vindex=*primItr; + OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout); + } */ + + break; + } + default: + { + break; + } + } + } + } + fout << "kids 0" << endl; + } + } + else + { // not sure what else it could be, but perhaps, perhaps, perhaps. + } + } +} diff --git a/src/osgPlugins/ac3d/Geode.h b/src/osgPlugins/ac3d/Geode.h new file mode 100644 index 000000000..b8b3ab631 --- /dev/null +++ b/src/osgPlugins/ac3d/Geode.h @@ -0,0 +1,98 @@ +#ifndef AC3D_GEODE +#define AC3D_GEODE 1 + +#include +#include + +namespace ac3d +{ + class Geode : public osg::Geode + { + public: + const int ProcessMaterial(std::ostream& fout, const unsigned int igeode); + void ProcessGeometry(std::ostream& fout, const unsigned int igeode); + private: + void OutputTriangle(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputTriangleStrip(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputTriangleFan(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputQuads(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputQuadStrip(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputLineStrip(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputLineLoop(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputLines(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + void OutputPolygon(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout); + //== output for prims with draw array lengths + void OutputTriangleDARR(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, std::ostream& fout); + void OutputTriangleStripDARR(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, std::ostream& fout); + void OutputTriangleFanDARR(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, std::ostream& fout); + void OutputQuadStripDARR(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, std::ostream& fout); + void OutputQuadsDARR(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, std::ostream& fout); + void OutputPolygonDARR(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, std::ostream& fout); + // OutputTriangleDelsUByte + // draw elements - 3 types: UByte, UShort, Uint + void OutputTriangleDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUByte* drawElements, std::ostream& fout); + void OutputTriangleStripDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUByte* drawElements, std::ostream& fout); + void OutputTriangleFanDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUByte* drawElements, std::ostream& fout); + void OutputQuadStripDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUByte* drawElements, std::ostream& fout); + void OutputQuadsDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUByte* drawElements, std::ostream& fout); + void OutputPolygonDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUByte* drawElements, std::ostream& fout); + // for UShorts + void OutputTriangleDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUShort* drawElements, std::ostream& fout); + void OutputTriangleStripDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUShort* drawElements, std::ostream& fout); + void OutputTriangleFanDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUShort* drawElements, std::ostream& fout); + void OutputQuadStripDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUShort* drawElements, std::ostream& fout); + void OutputQuadsDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUShort* drawElements, std::ostream& fout); + void OutputPolygonDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUShort* drawElements, std::ostream& fout); + // for UInts + void OutputTriangleDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUInt* drawElements, std::ostream& fout); + void OutputTriangleStripDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUInt* drawElements, std::ostream& fout); + void OutputTriangleFanDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUInt* drawElements, std::ostream& fout); + void OutputQuadStripDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUInt* drawElements, std::ostream& fout); + void OutputQuadsDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUInt* drawElements, std::ostream& fout); + void OutputPolygonDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags, + const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawElementsUInt* drawElements, std::ostream& fout); + // general output for all types + void OutputVertex(int Index, const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, std::ostream& fout); + inline void OutputSurfHead(const int iCurrentMaterial,const unsigned int surfaceFlags, const int nv, std::ostream& fout) { + fout << "SURF 0x" << std::hex << ((int)surfaceFlags) << std::endl; + if (iCurrentMaterial >= 0) + fout << "mat " << std::dec << iCurrentMaterial << std::endl; + fout << "refs " << std::dec << nv << std::endl; + } + }; + +} + +#endif diff --git a/src/osgPlugins/ac3d/ac3d.cpp b/src/osgPlugins/ac3d/ac3d.cpp index 1f2f8750b..5ee4397f7 100644 --- a/src/osgPlugins/ac3d/ac3d.cpp +++ b/src/osgPlugins/ac3d/ac3d.cpp @@ -36,6 +36,37 @@ #include #include "osgac3d.h" +#include "Exception.h" +#include "Geode.h" + +using namespace osg; +using namespace osgDB; + +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(osgAction::ActionHeader& ah); + // virtual void apply(osg::Drawable& dr); + virtual void apply(osg::Geode& geode) { + _geodelist.push_back(&geode); + } + // virtual void apply(osg::Billboard& geode); + virtual void apply(osg::Group& gp){ + traverse(gp); // must continue subgraph traversal. + } + // virtual void apply(osg::Switch& sw); + // virtual void apply(osg::Transform& transform); + std::vector getGeodes() {return _geodelist;} + protected: + + typedef std::vector Geodelist; + Geodelist _geodelist; +}; class ReaderWriterAC : public osgDB::ReaderWriter { @@ -52,6 +83,62 @@ class ReaderWriterAC : public osgDB::ReaderWriter grp=ac_load_ac3d(fileName.c_str()); return grp; }; + virtual WriteResult writeNode(const Node& node,const std::string& fileName, const osgDB::ReaderWriter::Options* /*options*/) + { + std::string ext = getFileExtension(fileName); + if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; + geodeVisitor vs; // this collects geodes. + Node *nd=(Node *)(&node); + std::vectoriNumMaterials; + nd->accept(vs); // this parses the tree to find Geodes + std::vector glist=vs.getGeodes(); + std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::binary); + // Write out the file header + std::vector::iterator itr; + fout << "AC3Db" << std::endl; + // output the Materials + for (itr=glist.begin();itr!= glist.end();itr++) { + iNumMaterials.push_back(const_cast(static_cast(*itr))->ProcessMaterial(fout,itr-glist.begin())); + } + // output the Geometry + unsigned int nfirstmat=0; + fout << "OBJECT world" << std::endl; + fout << "kids " << (glist.end()-glist.begin()) << std::endl; + for (itr=glist.begin();itr!= glist.end();itr++) { + const_cast(static_cast(*itr))->ProcessGeometry(fout,nfirstmat); + nfirstmat+=iNumMaterials[itr-glist.begin()]; + } + fout.close(); + return WriteResult::FILE_SAVED; + } + + virtual WriteResult writeNode(const Node& node,std::ostream& fout, const osgDB::ReaderWriter::Options* opts) + { + try + { + // write ac file. + if(dynamic_cast(&node)) { + const osg::Group *gp=dynamic_cast(&node); + const unsigned int nch=gp->getNumChildren(); + for (unsigned int i=0; igetChild(i)), fout, opts); + } + } + //const_cast(static_cast(&node))->Process(fout, options); + // else if(dynamic_cast(&node)) + // const_cast(static_cast(&node))->Process(fout); + else + std::cout<<"File must start with a geode "< palette; // change to dynamic array +//static int num_palette = 0; static int startmatindex = 0; @@ -295,384 +382,391 @@ protate(osg::Vec3 p, float m[9]) osg::Group *ac_load_object(FILE *f,const ACObject *parent) { - // most of this logic came from Andy Colebourne (developer of the AC3D editor) so it had better be right! - char t[20]; - osg::Group *gp=NULL; - osg::Geode *geode=NULL; - osg::Vec3Array *normals = NULL; // new osg::Vec3Array; // NULL; + // most of this logic came from Andy Colebourne (developer of the AC3D editor) so it had better be right! + char t[20]; + osg::Group *gp=NULL; + osg::Geode *geode=NULL; + osg::Vec3Array *normals = NULL; // new osg::Vec3Array; // NULL; - ACObject ob; // local storage for stuff taken from AC's loader - osg::Vec3Array *vertpool = new osg::Vec3Array; + ACObject ob; // local storage for stuff taken from AC's loader + osg::Vec3Array *vertpool = new osg::Vec3Array; - if (parent) ob.loc=parent->loc; // copy loc - while (!feof(f)) - { - read_line(f); + if (parent) + ob.loc=parent->loc; // copy loc + while (!feof(f)) + { + read_line(f); - sscanf(buff, "%s", t); + sscanf(buff, "%s", t); - if (streq(t, "MATERIAL")) - { - if (get_tokens(buff, &tokc, tokv) != 22) - { - printf("expected 21 params after \"MATERIAL\" - line %d\n", line); - } - else - { - osg::Material *numat=new osg::Material(); - osg::Vec4 cdiff((float)atof(tokv[3]), (float)atof(tokv[4]), - (float)atof(tokv[5]), 1.0-(float)atof(tokv[21])); - numat->setDiffuse(osg::Material::FRONT_AND_BACK,cdiff); - osg::Vec4 camb((float)atof(tokv[7]),(float)atof(tokv[8]), - (float)atof(tokv[9]),1.0-(float)atof(tokv[21])); - numat->setAmbient(osg::Material::FRONT_AND_BACK,camb); - osg::Vec4 cspec((float)atof(tokv[15]), (float)atof(tokv[16]), - (float)atof(tokv[17]),1.0-(float)atof(tokv[21])); - numat->setSpecular(osg::Material::FRONT_AND_BACK,cspec); - osg::Vec4 cemm((float)atof(tokv[11]),(float)atof(tokv[12]),(float)atof(tokv[13]),1.0-(float)atof(tokv[21])); - numat->setSpecular(osg::Material::FRONT_AND_BACK,cemm); - //numat->setTransparency(osg::Material::FRONT_AND_BACK, 1.0-(float)atof(tokv[21])); + if (streq(t, "MATERIAL")) + { + if (get_tokens(buff, &tokc, tokv) != 22) + { + printf("expected 21 params after \"MATERIAL\" - line %d\n", line); + } + else + { + osg::Material *numat=new osg::Material(); + osg::Vec4 cdiff((float)atof(tokv[3]), (float)atof(tokv[4]), + (float)atof(tokv[5]), 1.0-(float)atof(tokv[21])); + numat->setDiffuse(osg::Material::FRONT_AND_BACK,cdiff); + osg::Vec4 camb((float)atof(tokv[7]),(float)atof(tokv[8]), + (float)atof(tokv[9]),1.0-(float)atof(tokv[21])); + numat->setAmbient(osg::Material::FRONT_AND_BACK,camb); + osg::Vec4 cspec((float)atof(tokv[15]), (float)atof(tokv[16]), + (float)atof(tokv[17]),1.0-(float)atof(tokv[21])); + numat->setSpecular(osg::Material::FRONT_AND_BACK,cspec); + osg::Vec4 cemm((float)atof(tokv[11]),(float)atof(tokv[12]),(float)atof(tokv[13]),1.0-(float)atof(tokv[21])); + numat->setSpecular(osg::Material::FRONT_AND_BACK,cemm); + //numat->setTransparency(osg::Material::FRONT_AND_BACK, 1.0-(float)atof(tokv[21])); - palette[num_palette++] = numat; + palette.push_back(numat); // [num_palette++] = numat; - } - } - else - if (streq(t, "OBJECT")) - { - char type[20]; - char str[20]; - osg::Vec3 loc=ob.loc; - if (!gp) gp = new osg::Group(); - initobject(&ob); // rezero data for object - ob.loc=loc; + } + } + else if (streq(t, "OBJECT")) + { + char type[20]; + char str[20]; + osg::Vec3 loc=ob.loc; + if (!gp) gp = new osg::Group(); + initobject(&ob); // rezero data for object + ob.loc=loc; - sscanf(buff, "%s %s", str, type); + sscanf(buff, "%s %s", str, type); - ob.type = string_to_objecttype(type); - } - else - if (streq(t, "data")) - { - if (get_tokens(buff, &tokc, tokv) != 2) - printf("expected 'data ' at line %d\n", line); - else - { - char *str; - int len; + ob.type = string_to_objecttype(type); + } + else if (streq(t, "data")) + { + if (get_tokens(buff, &tokc, tokv) != 2) + printf("expected 'data ' at line %d\n", line); + else + { + char *str; + int len; - len = atoi(tokv[1]); - if (len > 0) - { - str = (char *)myalloc(len+1); - fread(str, len, 1, f); - str[len] = 0; - fscanf(f, "\n"); line++; - ob.data = STRING(str); - myfree(str); - } - } - } - else - if (streq(t, "name")) - { - int numtok = get_tokens(buff, &tokc, tokv); - if (numtok != 2) - { - printf("expected quoted name at line %d (got %d tokens)\n", line, numtok); - } - else - if (gp) gp->setName(tokv[1]); - } - else - if (streq(t, "texture")) - { - if (get_tokens(buff, &tokc, tokv) != 2) - printf("expected quoted texture name at line %d\n", line); + len = atoi(tokv[1]); + if (len > 0) + { + str = (char *)myalloc(len+1); + fread(str, len, 1, f); + str[len] = 0; + fscanf(f, "\n"); line++; + ob.data = STRING(str); + myfree(str); + } + } + } + else if (streq(t, "name")) + { + int numtok = get_tokens(buff, &tokc, tokv); + if (numtok != 2) + { + printf("expected quoted name at line %d (got %d tokens)\n", line, numtok); + } + else + if (gp) gp->setName(tokv[1]); + } + else if (streq(t, "texture")) + { + if (get_tokens(buff, &tokc, tokv) != 2) + printf("expected quoted texture name at line %d\n", line); - else - { - osg::Image *ctx= osgDB::readImageFile(tokv[1]); - if (ctx) { // image coukd be read - ob.texture = new osg::Texture2D;// ac_load_texture(tokv[1]); - ob.texture->setImage(ctx); - if (ob.texture_repeat_x > 0.1) { - ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); - } else { - ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP); - } - if (ob.texture_repeat_y > 0.1) { - ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); - } else { - ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP); - } - } - } - } - else - if (streq(t, "texrep")) - { - if (get_tokens(buff, &tokc, tokv) != 3) - printf("expected 'texrep ' at line %d\n", line); - else - { - ob.texture_repeat_x = atof(tokv[1]); - ob.texture_repeat_y = atof(tokv[2]); - } - } - else - if (streq(t, "texoff")) - { - if (get_tokens(buff, &tokc, tokv) != 3) - printf("expected 'texoff ' at line %d\n", line); - else - { - ob.texture_offset_x = atof(tokv[1]); - ob.texture_offset_y = atof(tokv[2]); - } - } - else - if (streq(t, "rot")) - { - float r[9]; - char str2[5]; - int n; + else + { + osg::Image *ctx= osgDB::readImageFile(tokv[1]); + if (ctx) + { // image coukd be read + ob.texture = new osg::Texture2D;// ac_load_texture(tokv[1]); + ob.texture->setImage(ctx); + ob.texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT); + ob.texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT); + } + } + } + else if (streq(t, "texrep")) + { + if (get_tokens(buff, &tokc, tokv) != 3) + printf("expected 'texrep ' at line %d\n", line); + else + { + ob.texture_repeat_x = atof(tokv[1]); + ob.texture_repeat_y = atof(tokv[2]); + } + } + else if (streq(t, "texoff")) + { + if (get_tokens(buff, &tokc, tokv) != 3) + printf("expected 'texoff ' at line %d\n", line); + else + { + ob.texture_offset_x = atof(tokv[1]); + ob.texture_offset_y = atof(tokv[2]); + } + } + else if (streq(t, "rot")) + { + float r[9]; + char str2[5]; + int n; - sscanf(buff, "%s %f %f %f %f %f %f %f %f %f", str2, - &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8] ); + sscanf(buff, "%s %f %f %f %f %f %f %f %f %f", str2, &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8] ); - for (n = 0; n < 9; n++) - ob.matrix[n] = r[n]; + for (n = 0; n < 9; n++) + ob.matrix[n] = r[n]; - } - else - if (streq(t, "loc")) - { - char str[5]; - osg::Vec3 loc; - sscanf(buff, "%s %f %f %f", str, &loc[0], &loc[1], &loc[2]); - ob.loc+=loc; - } - else - if (streq(t, "url")) - { - int ret; - if ((ret = get_tokens(buff, &tokc, tokv)) != 2) - printf("expected one arg to url at line %d (got %d)\n", line, ret); - else - ob.url = STRING(tokv[1]); - } - else - if (streq(t, "numvert")) - { - int num, n; - char str[10]; - if (ob.type == OBJECT_GROUP || ob.type == OBJECT_WORLD) { - } else if (ob.type == OBJECT_NORMAL) { - if (geode) { - osgUtil::Tesselator tesselator; - for(unsigned int i=0;igetNumDrawables();++i) - { - osg::Geometry* geom = dynamic_cast(geode->getDrawable(i)); - if (geom) tesselator.retesselatePolygons(*geom); - } - } - geode = new osg::Geode(); - gp->addChild(geode); - geode->setName(gp->getName()); - normals = new osg::Vec3Array; - } + } + else if (streq(t, "loc")) + { + char str[5]; + osg::Vec3 loc; + sscanf(buff, "%s %f %f %f", str, &loc[0], &loc[1], &loc[2]); + ob.loc+=loc; + } + else if (streq(t, "url")) + { + int ret; + if ((ret = get_tokens(buff, &tokc, tokv)) != 2) + printf("expected one arg to url at line %d (got %d)\n", line, ret); + else + ob.url = STRING(tokv[1]); + } + else if (streq(t, "numvert")) + { + int num, n; + char str[10]; + if (ob.type == OBJECT_GROUP || ob.type == OBJECT_WORLD) + { + } + else if (ob.type == OBJECT_NORMAL) + { + if (geode) + { + osgUtil::Tesselator tesselator; + for(unsigned int i=0;igetNumDrawables();++i) + { + osg::Geometry* geom = dynamic_cast(geode->getDrawable(i)); + if (geom) tesselator.retesselatePolygons(*geom); + } + } + geode = new osg::Geode(); + gp->addChild(geode); + geode->setName(gp->getName()); + normals = new osg::Vec3Array; + } - sscanf(buff, "%s %d", str, &num); + sscanf(buff, "%s %d", str, &num); - if (num > 0) - { - ob.num_vert = num; + if (num > 0) + { + ob.num_vert = num; - for (n = 0; n < num; n++) - { - osg::Vec3 p; - fscanf(f, "%f %f %f\n", &p[0], &p[1], &p[2]); line++; - protate(p, ob.matrix); - vertpool->push_back(p+ob.loc); - } + for (n = 0; n < num; n++) + { + osg::Vec3 p; + fscanf(f, "%f %f %f\n", &p[0], &p[1], &p[2]); line++; + protate(p, ob.matrix); + vertpool->push_back(p+ob.loc); + } - } - } - else - if (streq(t, "numsurf")) - { - int num, n; - char str[10]; - // this is not obvious (what is?). Each set of surfaces can have different material on each surface. - // so I set up a set of 'bins' for - // the primitives (geometry list, geomlist) - // the coords array of each geometry (Vec3Array list, vertslist) - // the tx coords array for each geometry (Vec2Array list, texslist) - // then I add a new geometry to the current Geode for each new material as it is found. + } + } + else if (streq(t, "numsurf")) + { + int num, n; + char str[10]; + // this is not obvious (what is?). Each set of surfaces can have different material on each surface. + // so I set up a set of 'bins' for + // the primitives (geometry list, geomlist) + // the coords array of each geometry (Vec3Array list, vertslist) + // the tx coords array for each geometry (Vec2Array list, texslist) + // then I add a new geometry to the current Geode for each new material as it is found. - std::vector ia; // list of materials required- generate one geode per material - typedef std::vector geomlist; - geomlist glist; - typedef std::vector vertslist; - vertslist vlists; // list of vertices for each glist element - typedef std::vector texslist; - texslist txlists; // list of texture coords for each glist element - - sscanf(buff, "%s %d", str, &num); - if (num > 0) - { - int needSmooth=0; // flat shaded - ob.num_surf = num; - - for (n = 0; n < num; n++) - { - osg::Geometry *geom=NULL; // the surface will be addded to this geometry - osg::Vec3Array *vgeom=NULL; // vertices corresponding to geom taken from vertexpool - osg::Vec2Array *tgeom=NULL; // texture coords corresponding to geom taken from vertexpool - ACSurface asurf; - osg::UShortArray *nusidx = new osg::UShortArray; // indices into the vertices - osg::Vec2Array *tcs=new osg::Vec2Array; // texture coordinates for this object - ACSurface *news = read_surface(f, &asurf, nusidx, tcs); - if (news == NULL) - { - printf("error whilst reading surface at line: %d\n", line); - return(NULL); - } else { - int i=0; - for (std::vector::iterator itr= ia.begin(); itr ia; // list of materials required- generate one geode per material + typedef std::vector geomlist; + geomlist glist; + typedef std::vector vertslist; + vertslist vlists; // list of vertices for each glist element + typedef std::vector texslist; + texslist txlists; // list of texture coords for each glist element - osg::Vec2Array *tcrds=new osg::Vec2Array; // texture coordinates for this object - vgeom=verts; - tgeom=tcrds; // what is current texture array - vlists.push_back(verts); - txlists.push_back(tcrds); - geom=new osg::Geometry(); - geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE); - geom->setNormalArray(normals); - geom->setVertexArray(verts); - if (ob.texture) { - geom->setTexCoordArray(0,tgeom); // share same set of TexCoords - } - osg::Material*mat=ac_palette_get_material(asurf.mat); - osg::StateSet *dstate = new osg::StateSet; - dstate->setMode( GL_LIGHTING, osg::StateAttribute::ON ); - dstate->setAttribute(mat); - const osg::Vec4 cdiff =mat->getDiffuse(osg::Material::FRONT_AND_BACK); - if (cdiff[3]<0.99) { - dstate->setMode(GL_BLEND,osg::StateAttribute::ON); - dstate->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - } else { - dstate->setMode(GL_BLEND,osg::StateAttribute::OFF); - } - if (ob.texture) dstate->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); - if (ob.texture) { - osg::TexEnv* texenv = new osg::TexEnv; - texenv->setMode(osg::TexEnv::MODULATE); - dstate->setTextureAttribute(0, texenv ); - dstate->setTextureAttributeAndModes(0,ob.texture,osg::StateAttribute::ON); - } - if (asurf.flags & SURFACE_TWOSIDED) dstate->setMode( GL_CULL_FACE, osg::StateAttribute::OFF ); - else dstate->setMode( GL_CULL_FACE, osg::StateAttribute::ON ); + sscanf(buff, "%s %d", str, &num); + if (num > 0) + { + int needSmooth=0; // flat shaded + ob.num_surf = num; - geom->setStateSet( dstate ); - glist.push_back(geom); - geode->addDrawable(geom); - ia.push_back(asurf.mat); - } - - osg::Vec3Array* normals = geom->getNormalArray(); - /** calc surface normal **/ - if (asurf.num_vertref >= 3) { - osg::Vec3 norm; - unsigned short i1=(*nusidx)[0]; - unsigned short i2=(*nusidx)[1]; - unsigned short i3=(*nusidx)[2]; - osgtri_calc_normal((*vertpool)[i1], - (*vertpool)[i2], - (*vertpool)[i3], norm); - normals->push_back(norm); - } - int nstart=(*vgeom).size(); - for (i=0; iaddPrimitiveSet(new osg::DrawArrays(poltype,nstart,asurf.num_vertref)); - if (asurf.flags & 0x10) needSmooth++; - } - } - for (geomlist::iterator itr= glist.begin(); itr::iterator itr= ia.begin(); itrsetNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE); + geom->setNormalArray(normals); + geom->setVertexArray(verts); + if (ob.texture.valid()) + { + geom->setTexCoordArray(0,tgeom); // share same set of TexCoords + } + osg::Material*mat=ac_palette_get_material(asurf.mat); + osg::StateSet *dstate = new osg::StateSet; + dstate->setMode( GL_LIGHTING, osg::StateAttribute::ON ); + dstate->setAttribute(mat); + const osg::Vec4 cdiff =mat->getDiffuse(osg::Material::FRONT_AND_BACK); + if (cdiff[3]<0.99) + { + dstate->setMode(GL_BLEND,osg::StateAttribute::ON); + dstate->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + } + else + { + dstate->setMode(GL_BLEND,osg::StateAttribute::OFF); + } + if (ob.texture.valid()) dstate->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); + if (ob.texture.valid()) + { + osg::TexEnv* texenv = new osg::TexEnv; + texenv->setMode(osg::TexEnv::MODULATE); + dstate->setTextureAttribute(0, texenv ); + dstate->setTextureAttributeAndModes(0,ob.texture.get(),osg::StateAttribute::ON); + } + if (asurf.flags & SURFACE_TWOSIDED) + dstate->setMode( GL_CULL_FACE, osg::StateAttribute::OFF ); + else + dstate->setMode( GL_CULL_FACE, osg::StateAttribute::ON ); - for (n = 0; n < num; n++) - { - osg::Group *k = ac_load_object(f,&ob); //, ob); + geom->setStateSet( dstate ); + glist.push_back(geom); + geode->addDrawable(geom); + ia.push_back(asurf.mat); + } - if (k == NULL) - { - printf("error reading expected child object %d of %d at line: %d\n", n+1, num, line); - return(gp); - } - else - //ob.kids[n] = k; - gp->addChild(k); - } + osg::Vec3Array* normals = geom->getNormalArray(); + /** calc surface normal **/ + if (asurf.num_vertref >= 3) + { + osg::Vec3 norm; + unsigned short i1=(*nusidx)[0]; + unsigned short i2=(*nusidx)[1]; + unsigned short i3=(*nusidx)[2]; + osgtri_calc_normal((*vertpool)[i1], + (*vertpool)[i2], + (*vertpool)[i3], norm); + normals->push_back(norm); + } + int nstart=(*vgeom).size(); + for (i=0; igetNumDrawables();++i) - { - osg::Geometry* geom = dynamic_cast(geode->getDrawable(i)); - if (geom) tesselator.retesselatePolygons(*geom); - } - } - return(gp); - } + int i1=(*nusidx)[i]; + (*vgeom).push_back((*vertpool)[i1]); + TextureCoordinate = (*tcs)[i]; + TextureCoordinate._v[0] = ob.texture_offset_x + TextureCoordinate._v[0] * ob.texture_repeat_x; + TextureCoordinate._v[1] = ob.texture_offset_y + TextureCoordinate._v[1] * ob.texture_repeat_y; + (*tgeom).push_back(TextureCoordinate); +// (*tgeom).push_back((*tcs)[i]); + } + GLenum poltype=osg::PrimitiveSet::POLYGON; + if (asurf.flags & SURFACE_TYPE_CLOSEDLINE) poltype=osg::PrimitiveSet::LINE_LOOP; + if (asurf.flags & SURFACE_TYPE_LINE) poltype=osg::PrimitiveSet::LINE_STRIP; + geom->addPrimitiveSet(new osg::DrawArrays(poltype,nstart,asurf.num_vertref)); + if (asurf.flags & 0x10) needSmooth++; + } + } + for (geomlist::iterator itr= glist.begin(); itrgetNumDrawables();++i) - { - osg::Geometry* geom = dynamic_cast(geode->getDrawable(i)); - if (geom) tesselator.retesselatePolygons(*geom); - } - } - return(gp); + sscanf(buff, "%s %d", t, &num); + if (num != 0) + { + // ob.kids = (ACObject **)myalloc(num * sizeof(ACObject *) ); + ob.num_kids = num; + + for (n = 0; n < num; n++) + { + osg::Group *k = ac_load_object(f,&ob); //, ob); + + if (k == NULL) + { + printf("error reading expected child object %d of %d at line: %d\n", n+1, num, line); + return(gp); + } + else + //ob.kids[n] = k; + gp->addChild(k); + } + + } + if (geode) + { + osgUtil::Tesselator tesselator; + for(unsigned int i=0;igetNumDrawables();++i) + { + osg::Geometry* geom = dynamic_cast(geode->getDrawable(i)); + if (geom) tesselator.retesselatePolygons(*geom); + } + } + return(gp); + } + } + if (geode) + { + osgUtil::Tesselator tesselator; + for(unsigned int i=0;igetNumDrawables();++i) + { + osg::Geometry* geom = dynamic_cast(geode->getDrawable(i)); + if (geom) tesselator.retesselatePolygons(*geom); + } + } + return(gp); } @@ -709,7 +803,7 @@ osg::Group *ret = NULL; } - startmatindex = num_palette; + startmatindex = palette.size(); //num_palette; ret = ac_load_object(f,NULL); //, NULL); diff --git a/src/osgPlugins/ac3d/osgac3d.h b/src/osgPlugins/ac3d/osgac3d.h index 60a441e76..e4404e01c 100644 --- a/src/osgPlugins/ac3d/osgac3d.h +++ b/src/osgPlugins/ac3d/osgac3d.h @@ -30,7 +30,7 @@ typedef struct ACObject_t struct ACObject_t **kids; float matrix[9]; int type; - osg::Texture2D *texture; + osg::ref_ptr texture; } ACObject; #define OBJECT_WORLD 999