#if defined(_MSC_VER) #pragma warning( disable : 4786 ) #endif #include "GeoSet.h" #include "osg/Notify" #include "osgDB/Registry" #include "osgDB/Input" #include "osgDB/ParameterOutput" using namespace osg; using namespace osgDB; // forward declare functions to use later. bool GeoSet_readLocalData(Object& obj, Input& fr); bool GeoSet_writeLocalData(const Object& obj, Output& fw); bool GeoSet_readIndexData(Input& fr, const char* IndexName, GeoSet::IndexPointer& ip, bool& useCIndex); bool GeoSet_writeIndexData(Output& fw, const char* IndexName,const GeoSet::IndexPointer& ip); bool GeoSet_matchBindingTypeStr(const char* str,GeoSet::BindingType& mode); const char* GeoSet_getBindingTypeStr(GeoSet::BindingType mode); const char* GeoSet_getInterleavedRowComposition(GeoSet::InterleaveArrayType at); int GeoSet_getInterleavedRowLength(GeoSet::InterleaveArrayType at); // register the read and write functions with the osgDB::Registry. RegisterDotOsgWrapperProxy g_GeoSetFuncProxy ( new osg::GeoSet, "GeoSet", "Object Drawable GeoSet", &GeoSet_readLocalData, &GeoSet_writeLocalData, DotOsgWrapper::READ_AND_WRITE ); // register the old style 'Geoset' keyword read and write functions with the osgDB::Registry. RegisterDotOsgWrapperProxy g_GeosetFuncProxy ( new osg::GeoSet, "Geoset", "Object Drawable Geoset", &GeoSet_readLocalData, NULL, DotOsgWrapper::READ_ONLY ); bool GeoSet_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; GeoSet& geoset = static_cast(obj); Vec3* coordList = NULL; bool coordIndexUseCIndex = false; GeoSet::IndexPointer coordIndex; Vec3* normalList = NULL; bool normIndexUseCIndex = false; GeoSet::IndexPointer normIndex; Vec4* colorList = NULL; bool colIndexUseCIndex = false; GeoSet::IndexPointer colIndex; Vec2* textureList = NULL; bool tIndexUseCIndex = false; GeoSet::IndexPointer tIndex; float* interleavedArray = NULL; bool iaIndexUseCIndex = false; GeoSet::IndexPointer iaIndex; GeoSet::BindingType bind=GeoSet::BIND_OFF; GeoSet::BindingType normal_bind=GeoSet::BIND_OFF; GeoSet::BindingType color_bind=GeoSet::BIND_OFF; GeoSet::BindingType texture_bind=GeoSet::BIND_OFF; GeoSet::InterleaveArrayType iaType = GeoSet::IA_OFF; int start_indent = fr[0].getNoNestedBrackets(); while (!fr.eof() && fr[0].getNoNestedBrackets()>=start_indent) { bool fieldAdvanced = false; bool readPrimitiveLengths = false; if (fr.matchSequence("tstrips %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::TRIANGLE_STRIP); } else if (fr.matchSequence("flat_tstrips %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::FLAT_TRIANGLE_STRIP); } else if (fr.matchSequence("polys %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::POLYGON); } else if (fr.matchSequence("quadstrip %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::QUAD_STRIP); } else if (fr.matchSequence("lineloops %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::LINE_LOOP); } else if (fr.matchSequence("linestrip %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::LINE_STRIP); } else if (fr.matchSequence("flat_linestrip %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::FLAT_LINE_STRIP); } else if (fr.matchSequence("tfans %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::TRIANGLE_FAN); } else if (fr.matchSequence("flat_tfans %i {")) { readPrimitiveLengths = true; geoset.setPrimType(GeoSet::FLAT_TRIANGLE_FAN); } if (readPrimitiveLengths) { int entry = fr[1].getNoNestedBrackets(); fr += 3; int capacity; if (!fr[1].getInt(capacity)) capacity=100; int size = 0; int* list = new int [capacity]; memset(list,0,capacity*sizeof(int)); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int primLength; if (fr[0].getInt(primLength)) { if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; int* oldList = list; list = new int[capacity]; memset(list,0,capacity*sizeof(int)); for(int i=0;ientry) { float x,y,z; if (fr[0].getFloat(x) && fr[1].getFloat(y) && fr[2].getFloat(z)) { fr += 3; if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; Vec3* oldList = coordList; coordList = new Vec3[capacity]; for(int i=0;ientry) { float x,y,z; if (fr[0].getFloat(x) && fr[1].getFloat(y) && fr[2].getFloat(z)) { fr += 3; if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; Vec3* oldList = normalList; normalList = new Vec3[capacity]; for(int i=0;ientry) { float r,g,b,a; if (fr[0].getFloat(r) && fr[1].getFloat(g) && fr[2].getFloat(b) && fr[3].getFloat(a)) { fr += 4; if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; Vec4* oldList = colorList; colorList = new Vec4[capacity]; for(int i=0;ientry) { float r,s; if (fr[0].getFloat(r) && fr[1].getFloat(s)) { fr += 2; if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; Vec2* oldList = textureList; textureList = new Vec2[capacity]; for(int i=0;ientry) ++fr; } else { // now read the data rows between the {}. const char* rowComp = GeoSet_getInterleavedRowComposition(iaType); int rowLength = GeoSet_getInterleavedRowLength(iaType); int size = 0; unsigned char* dataList = new unsigned char[capacity*rowLength]; unsigned char* rowData = new unsigned char [rowLength]; float floatData; int intData; while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned char* itrRowData = rowData; const char* itrRowComp = rowComp; int rn = 0; while (*itrRowComp!=0 && !fr.eof() && fr[0].getNoNestedBrackets()>entry) { if (*itrRowComp=='f') { if (!fr[rn].getFloat(floatData)) break; *(float*)itrRowData = floatData; itrRowData += 4; } else { if (!fr[rn].getInt(intData)) break; *itrRowData = (unsigned char)intData; itrRowData += 1; } ++itrRowComp; ++rn; } if (*itrRowComp==0) { fr += rn; if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; unsigned char* oldList = dataList; dataList = new unsigned char[capacity*rowLength]; memcpy(dataList,oldList,oldCapacity*rowLength); delete [] oldList; } memcpy(dataList+size*rowLength,rowData,rowLength); ++size; } else { if (!fr.eof() && fr[0].getNoNestedBrackets()>entry) ++fr; } } delete [] rowData; interleavedArray = (float*)dataList; } fieldAdvanced = true; ++fr; } if (GeoSet_readIndexData(fr, "InterleavedArrayIndex" ,iaIndex, iaIndexUseCIndex)) { fieldAdvanced = true; } if (!fieldAdvanced) { if (fr[0].getNoNestedBrackets()>start_indent) fr.advanceToEndOfBlock(start_indent+1); else ++fr; } iteratorAdvanced = true; } // set up the coord lists. if (coordList) { geoset.setCoords(coordList,coordIndex); } // set up the normal lists. if (normalList) { geoset.setNormalBinding(normal_bind); if (normIndexUseCIndex) geoset.setNormals(normalList,coordIndex); else geoset.setNormals(normalList,normIndex); } else geoset.setNormalBinding(GeoSet::BIND_OFF); // set up the color lists. if (colorList) { geoset.setColorBinding(color_bind); if (colIndexUseCIndex) geoset.setColors(colorList,coordIndex); else geoset.setColors(colorList,colIndex); } else geoset.setColorBinding(GeoSet::BIND_OFF); if (textureList) { geoset.setTextureBinding(texture_bind); if (tIndexUseCIndex) geoset.setTextureCoords(textureList,coordIndex); else geoset.setTextureCoords(textureList,tIndex); } else geoset.setTextureBinding(GeoSet::BIND_OFF); if (interleavedArray) { if (iaIndexUseCIndex) geoset.setInterleavedArray(iaType,interleavedArray,coordIndex); else geoset.setInterleavedArray(iaType,interleavedArray,iaIndex); }; return iteratorAdvanced; } bool GeoSet_writeLocalData(const Object& obj, Output& fw) { int i; const GeoSet& geoset = static_cast(obj); // write out primitives. bool writeOutPrimitiveLengths = false; switch(geoset.getPrimType()) { case (GeoSet::TRIANGLE_STRIP): fw.indent()<<"tstrips "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::FLAT_TRIANGLE_STRIP): fw.indent()<<"flat_tstrips "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::POLYGON): fw.indent()<<"polys "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::QUAD_STRIP): fw.indent()<<"quadstrip "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::LINE_LOOP): fw.indent()<<"lineloops "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::LINE_STRIP): fw.indent()<<"linestrip "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::FLAT_LINE_STRIP): fw.indent()<<"flat_linestrip "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::TRIANGLE_FAN): fw.indent()<<"tfans "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; case (GeoSet::FLAT_TRIANGLE_FAN): fw.indent()<<"flat_tfans "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = true; break; case (GeoSet::LINES): fw.indent()<<"lines "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = false; break; case (GeoSet::TRIANGLES): fw.indent()<<"triangles "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = false; break; case (GeoSet::QUADS): fw.indent()<<"quads "<< geoset.getNumPrims() << std::endl; writeOutPrimitiveLengths = false; break; case (GeoSet::POINTS) : fw.indent()<<"points "<< geoset.getNumPrims() << std::endl; break; default: notify(WARN) << "GeoSet::writeLocalData() - unhandled primitive type = "<<(int)geoset.getPrimType()<< std::endl; } if (writeOutPrimitiveLengths) { writeArray(fw,geoset.getPrimLengths(),geoset.getPrimLengths()+geoset.getNumPrims()); } GeoSet& non_const_geoset = const_cast(geoset); non_const_geoset.computeNumVerts(); if (geoset.getCoords()) { // write out _coords. fw.indent() << "Coords " << geoset.getNumCoords()<< std::endl; fw.indent() << "{"<< std::endl; fw.moveIn(); const Vec3* coords = geoset.getCoords(); for(i=0;ientry) { int index; if (fr[0].getInt(index)) { if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; GLushort* oldList = coordIndexList; coordIndexList = new GLushort[capacity]; for(int i=0;ientry) { int index; if (fr[0].getInt(index)) { if (size>=capacity) { int oldCapacity = capacity; while(capacity<=size) capacity *= 2; GLuint* oldList = coordIndexList; coordIndexList = new GLuint[capacity]; for(int i=0;i