diff --git a/src/osgPlugins/OpenFlight/DataInputStream.cpp b/src/osgPlugins/OpenFlight/DataInputStream.cpp index d2f347a5f..32861ebb5 100644 --- a/src/osgPlugins/OpenFlight/DataInputStream.cpp +++ b/src/osgPlugins/OpenFlight/DataInputStream.cpp @@ -8,88 +8,78 @@ #include #include -#include using namespace flt; -DataInputStream::DataInputStream(std::istream* istream): - _istream(istream) +DataInputStream::DataInputStream(std::streambuf* sb): + std::istream(sb) { _byteswap = osg::getCpuByteOrder() == osg::LittleEndian; - - if (!istream) - throw std::string("DataInputStream::DataInputStream(): null pointer exception in argument."); } - -DataInputStream::~DataInputStream() -{ -} - - -int8 DataInputStream::readInt8(int8 def) const +int8 DataInputStream::readInt8(int8 def) { int8 d=def; - read((char*)&d, sizeof(int8)); + vread((char*)&d, sizeof(int8)); return d; } -uint8 DataInputStream::readUInt8(uint8 def) const +uint8 DataInputStream::readUInt8(uint8 def) { uint8 d=def; - read((char*)&d, sizeof(uint8)); + vread((char*)&d, sizeof(uint8)); return d; } -int16 DataInputStream::readInt16(int16 def) const +int16 DataInputStream::readInt16(int16 def) { int16 d=def; - read((char*)&d, sizeof(int16)); - if (_byteswap && !_istream->fail()) + vread((char*)&d, sizeof(int16)); + if (_byteswap && good()) osg::swapBytes2((char *)&d); return d; } -uint16 DataInputStream::readUInt16(uint16 def) const +uint16 DataInputStream::readUInt16(uint16 def) { uint16 d=def; - read((char*)&d, sizeof(uint16)); - if (_byteswap && !_istream->fail()) + vread((char*)&d, sizeof(uint16)); + if (_byteswap && good()) osg::swapBytes2((char *)&d); return d; } -int32 DataInputStream::readInt32(int32 def) const +int32 DataInputStream::readInt32(int32 def) { int32 d=def; - read((char*)&d, sizeof(int32)); - if (_byteswap && !_istream->fail()) + vread((char*)&d, sizeof(int32)); + if (_byteswap && good()) osg::swapBytes4((char *)&d); return d; } -uint32 DataInputStream::readUInt32(uint32 def) const +uint32 DataInputStream::readUInt32(uint32 def) { uint32 d=def; - read((char*)&d, sizeof(uint32)); - if (_byteswap && !_istream->fail()) + vread((char*)&d, sizeof(uint32)); + if (_byteswap && good()) osg::swapBytes4((char *)&d); return d; } -float32 DataInputStream::readFloat32(float32 def) const +float32 DataInputStream::readFloat32(float32 def) { float32 d=def; char buf[sizeof(float32)]; - read(buf, sizeof(float32)); - if (_byteswap && !_istream->fail()) + vread(buf, sizeof(float32)); + if (_byteswap && good()) { osg::swapBytes4(buf); memcpy(&d,buf,sizeof(float32)); @@ -98,12 +88,12 @@ float32 DataInputStream::readFloat32(float32 def) const } -float64 DataInputStream::readFloat64(float64 def) const +float64 DataInputStream::readFloat64(float64 def) { float64 d=def; char buf[sizeof(float64)]; - read(buf, sizeof(float64)); - if (_byteswap && !_istream->fail()) + vread(buf, sizeof(float64)); + if (_byteswap && good()) { osg::swapBytes8(buf); memcpy(&d,buf,sizeof(float64)); @@ -112,16 +102,16 @@ float64 DataInputStream::readFloat64(float64 def) const } -void DataInputStream::readCharArray(char* data, int size) const +void DataInputStream::readCharArray(char* data, int size) { - read(data, size); + vread(data,size); } -std::string DataInputStream::readString(int size) const +std::string DataInputStream::readString(int size) { char* buf = new char[size+1]; - read(buf,size); + vread(buf,size); buf[size] = '\0'; std::string str = buf; delete [] buf; @@ -129,7 +119,7 @@ std::string DataInputStream::readString(int size) const } -osg::Vec4f DataInputStream::readColor32() const +osg::Vec4f DataInputStream::readColor32() { uint8 alpha = readUInt8(); uint8 blue = readUInt8(); @@ -142,7 +132,7 @@ osg::Vec4f DataInputStream::readColor32() const } -osg::Vec2f DataInputStream::readVec2f() const +osg::Vec2f DataInputStream::readVec2f() { float32 x = readFloat32(); float32 y = readFloat32(); @@ -153,7 +143,7 @@ osg::Vec2f DataInputStream::readVec2f() const } -osg::Vec3f DataInputStream::readVec3f() const +osg::Vec3f DataInputStream::readVec3f() { float32 x = readFloat32(); float32 y = readFloat32(); @@ -165,7 +155,7 @@ osg::Vec3f DataInputStream::readVec3f() const } -osg::Vec3d DataInputStream::readVec3d() const +osg::Vec3d DataInputStream::readVec3d() { float64 x = readFloat64(); float64 y = readFloat64(); @@ -177,34 +167,34 @@ osg::Vec3d DataInputStream::readVec3d() const } -int16 DataInputStream::peekInt16() const +int16 DataInputStream::peekInt16() { // Get current read position in stream. - std::istream::pos_type pos = _istream->tellg(); + std::istream::pos_type pos = tellg(); int16 value = readInt16(); // Restore position - _istream->seekg(pos, std::ios_base::beg); + seekg(pos, std::ios_base::beg); return value; } -void DataInputStream::forward(std::istream::off_type _Off) const +std::istream& DataInputStream::forward(std::istream::off_type off) { - seekg(_Off, std::ios_base::cur); + return vforward(off); } -std::istream& DataInputStream::read(std::istream::char_type *_Str, std::streamsize _Count) const +std::istream& DataInputStream::vread(char_type *str, std::streamsize count) { - return _istream->read(_Str, _Count); + return read(str,count); } -std::istream& DataInputStream::seekg(std::istream::off_type _Off, std::ios_base::seekdir _Way) const +std::istream& DataInputStream::vforward(std::istream::off_type off) { - return _istream->seekg(_Off, _Way); + return seekg(off, std::ios_base::cur); } diff --git a/src/osgPlugins/OpenFlight/DataInputStream.h b/src/osgPlugins/OpenFlight/DataInputStream.h index 9016717b9..4d3250138 100644 --- a/src/osgPlugins/OpenFlight/DataInputStream.h +++ b/src/osgPlugins/OpenFlight/DataInputStream.h @@ -7,52 +7,49 @@ #ifndef FLT_DATAINPUTSTREAM #define FLT_DATAINPUTSTREAM 1 -#include // for ifstream +//#include // for ifstream +#include #include #include #include #include -#include "types.h" +#include "types.h" namespace flt { class Record; -class DataInputStream +class DataInputStream : public std::istream { -public: + public: - DataInputStream(std::istream* istream); - virtual ~DataInputStream(); + explicit DataInputStream(std::streambuf* sb); - int8 readInt8(int8 def=0) const; - uint8 readUInt8(uint8 def=0) const; - int16 readInt16(int16 def=0) const; - uint16 readUInt16(uint16 def=0) const; - int32 readInt32(int32 def=0) const; - uint32 readUInt32(uint32 def=0) const; - float32 readFloat32(float32 def=0) const; - float64 readFloat64(float64 def=0) const; - void readCharArray(char* data, int size) const; - std::string readString(int size) const; - osg::Vec4f readColor32() const; - osg::Vec2f readVec2f() const; - osg::Vec3f readVec3f() const; - osg::Vec3d readVec3d() const; + int8 readInt8(int8 def=0); + uint8 readUInt8(uint8 def=0); + int16 readInt16(int16 def=0); + uint16 readUInt16(uint16 def=0); + int32 readInt32(int32 def=0); + uint32 readUInt32(uint32 def=0); + float32 readFloat32(float32 def=0); + float64 readFloat64(float64 def=0); + void readCharArray(char* data, int size); + std::string readString(int size); + osg::Vec4f readColor32(); + osg::Vec2f readVec2f(); + osg::Vec3f readVec3f(); + osg::Vec3d readVec3d(); - void forward(std::istream::off_type _Off) const; + std::istream& forward(std::istream::off_type off); - int16 peekInt16() const; + int16 peekInt16(); - inline std::istream& operator() () { return *_istream; } + protected: -protected: + virtual std::istream& vread(char_type *str, std::streamsize count); + virtual std::istream& vforward(std::istream::off_type off); - virtual std::istream& read(std::istream::char_type *_Str, std::streamsize _Count) const; - virtual std::istream& seekg(std::istream::off_type _Off, std::ios_base::seekdir _Way) const; - - bool _byteswap; - std::istream* _istream; + bool _byteswap; }; } // end namespace diff --git a/src/osgPlugins/OpenFlight/Document.cpp b/src/osgPlugins/OpenFlight/Document.cpp index 5e73e4efe..b6748ef02 100644 --- a/src/osgPlugins/OpenFlight/Document.cpp +++ b/src/osgPlugins/OpenFlight/Document.cpp @@ -15,6 +15,7 @@ Document::Document() : _subfaceLevel(0), _version(0), _unitScale(1.0), + _preserveFace(false), _defaultDOFAnimationState(false), _useTextureAlphaForTransparancyBinning(true), _doUnitsConversion(true), diff --git a/src/osgPlugins/OpenFlight/Document.h b/src/osgPlugins/OpenFlight/Document.h index ba822d7dd..3323b1aa7 100644 --- a/src/osgPlugins/OpenFlight/Document.h +++ b/src/osgPlugins/OpenFlight/Document.h @@ -129,6 +129,8 @@ class Document ShaderPool* getOrCreateShaderPool(); // Options + void setPreserveFace(bool flag) { _preserveFace = flag; } + bool getPreserveFace() const { return _preserveFace; } void setDefaultDOFAnimationState(bool state) { _defaultDOFAnimationState = state; } bool getDefaultDOFAnimationState() const { return _defaultDOFAnimationState; } void setUseTextureAlphaForTransparancyBinning(bool flag) { _useTextureAlphaForTransparancyBinning=flag; } @@ -142,6 +144,7 @@ class Document // Options osg::ref_ptr _options; + bool _preserveFace; bool _defaultDOFAnimationState; bool _useTextureAlphaForTransparancyBinning; bool _doUnitsConversion; diff --git a/src/osgPlugins/OpenFlight/GeometryRecords.cpp b/src/osgPlugins/OpenFlight/GeometryRecords.cpp index 7b70062ac..4809b8c2e 100644 --- a/src/osgPlugins/OpenFlight/GeometryRecords.cpp +++ b/src/osgPlugins/OpenFlight/GeometryRecords.cpp @@ -509,14 +509,14 @@ protected: int vertices = (in.getRecordSize()-4) / 4; // Use the Vertex pool as a record stream. - RecordInputStream inVP(vp); + RecordInputStream inVP(vp->rdbuf()); for (int n=0; nrdbuf()); for (int n=0; nstr(),paletteSize); // read beyond record end so use isream::read(). - document.setVertexPool(vp); - in.setEndOfRecord(in.getStartOfRecord()+(std::istream::pos_type)paletteSize); + + std::string buffer(paletteSize,'\0'); + in.read(&(*buffer.begin()),paletteSize); + document.setVertexPool(new VertexPool(buffer)); } }; @@ -504,7 +504,7 @@ protected: appearance->LODScale = in.readFloat32(); appearance->texturePatternIndex = in.readInt16(-1); // The final short is reserved; don't bother reading it. - + // Add to pool LightPointAppearancePool* lpaPool = document.getOrCreateLightPointAppearancePool(); (*lpaPool)[appearance->index] = appearance.get(); diff --git a/src/osgPlugins/OpenFlight/Pools.h b/src/osgPlugins/OpenFlight/Pools.h index 3fa63774e..af2c4dc81 100644 --- a/src/osgPlugins/OpenFlight/Pools.h +++ b/src/osgPlugins/OpenFlight/Pools.h @@ -9,10 +9,7 @@ #include #include - -// need to replace this... and associated istrstream as its deprecated -#include - +#include #include #include #include @@ -22,21 +19,16 @@ namespace flt { -class VertexPool : public osg::Referenced, public std::istrstream +class VertexPool : public osg::Referenced, public std::istringstream { - const char* _buffer; - public: - explicit VertexPool(std::streamsize count) : - std::istrstream(_buffer=new char[count],count) {} + explicit VertexPool( const std::string& str) : + std::istringstream(str,std::istringstream::in|std::istringstream::binary) {} protected: - virtual ~VertexPool() - { - if (_buffer) delete [] _buffer; - } + virtual ~VertexPool() {} }; diff --git a/src/osgPlugins/OpenFlight/ReaderWriterATTR.cpp b/src/osgPlugins/OpenFlight/ReaderWriterATTR.cpp index 49054a367..16aa77add 100644 --- a/src/osgPlugins/OpenFlight/ReaderWriterATTR.cpp +++ b/src/osgPlugins/OpenFlight/ReaderWriterATTR.cpp @@ -54,7 +54,7 @@ ReaderWriter::ReadResult ReaderWriterATTR::readObject(const std::string& file, c if ( fin.fail()) return ReadResult::ERROR_IN_READING_FILE; - flt::DataInputStream in(&fin); + flt::DataInputStream in(fin.rdbuf()); AttrData* attr = new AttrData; diff --git a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp index 37d790af6..bf450d5d1 100644 --- a/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp +++ b/src/osgPlugins/OpenFlight/ReaderWriterFLT.cpp @@ -139,10 +139,19 @@ class FLTReaderWriter : public ReaderWriter // option string if (options) { + const char readerMsg[] = "flt reader option: "; + + document.setPreserveFace((options->getOptionString().find("FLT_preserveFace")!=std::string::npos)); + osg::notify(osg::DEBUG_INFO) << readerMsg << "FLT_preserveFace=" << document.getPreserveFace() << std::endl; + + document.setDefaultDOFAnimationState((options->getOptionString().find("dofAnimation")!=std::string::npos)); + osg::notify(osg::DEBUG_INFO) << readerMsg << "dofAnimation=" << document.getDefaultDOFAnimationState() << std::endl; + document.setUseTextureAlphaForTransparancyBinning(options->getOptionString().find("noTextureAlphaForTransparancyBinning")==std::string::npos); - osg::notify(osg::DEBUG_INFO) << "FltFile.getUseTextureAlphaForTransparancyBinning()=" << document.getUseTextureAlphaForTransparancyBinning() << std::endl; - document.setDoUnitsConversion((options->getOptionString().find("noUnitsConversion")==std::string::npos)); // default to true, unless noUnitsConversion is specified.o - osg::notify(osg::DEBUG_INFO) << "FltFile.getDoUnitsConversion()=" << document.getDoUnitsConversion() << std::endl; + osg::notify(osg::DEBUG_INFO) << readerMsg << "noTextureAlphaForTransparancyBinning=" << document.getUseTextureAlphaForTransparancyBinning() << std::endl; + + document.setDoUnitsConversion((options->getOptionString().find("noUnitsConversion")==std::string::npos)); // default to true, unless noUnitsConversion is specified. + osg::notify(osg::DEBUG_INFO) << readerMsg << "noUnitsConversion=" << document.getDoUnitsConversion() << std::endl; if (document.getDoUnitsConversion()) { @@ -161,8 +170,8 @@ class FLTReaderWriter : public ReaderWriter { // read records - flt::RecordInputStream recordStream(&fin); - while (recordStream().good() && !document.done()) + flt::RecordInputStream recordStream(fin.rdbuf()); + while (recordStream.good() && !document.done()) { recordStream.readRecord(document); } diff --git a/src/osgPlugins/OpenFlight/RecordInputStream.cpp b/src/osgPlugins/OpenFlight/RecordInputStream.cpp index 292f8e70c..0a007d69e 100644 --- a/src/osgPlugins/OpenFlight/RecordInputStream.cpp +++ b/src/osgPlugins/OpenFlight/RecordInputStream.cpp @@ -4,6 +4,7 @@ // Copyright (C) 2005-2006 Brede Johansen // +#include #include "opcodes.h" #include "Registry.h" #include "Document.h" @@ -13,50 +14,49 @@ using namespace flt; using namespace std; -RecordInputStream::RecordInputStream(std::istream* istream): - DataInputStream(istream) +RecordInputStream::RecordInputStream(std::streambuf* sb): + DataInputStream(sb), + _recordSize(0), + _recordOffset(0) +{} + + +std::istream& RecordInputStream::vread(char_type *str, std::streamsize count) { - -#if 0 //def _DEBUG - ios::iostate mask = istream->exceptions(); - cout << "ios::badbit=" << ( mask & ios::badbit ) << std::endl; - cout << "ios::failbit=" << ( mask & ios::failbit ) << std::endl; - cout << "ios::eofbit=" << ( mask & ios::eofbit ) << std::endl; -#endif - - // dont't throw an exception on failbit - istream->exceptions(istream->exceptions() & ~ios::failbit); -} - - -RecordInputStream::~RecordInputStream() -{ -} - - -std::istream& RecordInputStream::read(std::istream::char_type *_Str, std::streamsize _Count) const -{ - // Bounds check - istream::pos_type pos = _istream->tellg(); - if (pos+(istream::pos_type)_Count > _end) + if ((_recordSize>0) && (_recordOffset+count > _recordSize)) { - _istream->setstate(ios::failbit); // end-of-record (EOR) - return *_istream; + setstate(ios::failbit); // end-of-record (EOR) + return *this; } - return _istream->read(_Str,_Count); + _recordOffset += count; + return DataInputStream::vread(str,count); +} + + +std::istream& RecordInputStream::vforward(std::istream::off_type off) +{ + if ((_recordSize>0) && (_recordOffset+off > _recordSize)) + { + setstate(ios::failbit); // end-of-record (EOR) + return *this; + } + + _recordOffset += off; + return DataInputStream::vforward(off); } bool RecordInputStream::readRecord(Document& document) { // Get current read position in stream. - _start = _istream->tellg(); + _start = tellg(); + _recordOffset = 0; // Get record header without bounds check. - DataInputStream distream(_istream); - uint16 opcode = distream.readUInt16(); - uint16 size = distream.readUInt16(); + _recordSize = 0; // disable boundary check + uint16 opcode = readUInt16(); + int size = (int)readUInt16(); // Correct endian error in Creator v2.5 gallery models. // Last pop level record in little-endian. @@ -68,17 +68,19 @@ bool RecordInputStream::readRecord(Document& document) size=4; } + _recordSize = size; + // Update end-of-record _end = _start + (std::istream::pos_type)size; #if 0 // TODO: Peek at next opcode looking for continuation record. - _istream->seekg(_end, std::ios_base::beg); + seekg(_end, std::ios_base::beg); if (_istream->fail()) return false; int16 nextOpcode = readUInt16(); - _istream->seekg(_start+(std::istream::pos_type)4, std::ios_base::beg); + seekg(_start+(std::istream::pos_type)4, std::ios_base::beg); if (nextOpcode == CONTINUATION_OP) { @@ -109,7 +111,7 @@ bool RecordInputStream::readRecord(Document& document) } // Clear failbit, it's used for end-of-record testing. - _istream->clear(_istream->rdstate() & ~std::ios::failbit); + clear(rdstate() & ~std::ios::failbit); } else // prototype not found { @@ -120,7 +122,7 @@ bool RecordInputStream::readRecord(Document& document) } // Move to beginning of next record - _istream->seekg(_end, std::ios_base::beg); + seekg(_end, std::ios_base::beg); - return _istream->good(); + return good(); } diff --git a/src/osgPlugins/OpenFlight/RecordInputStream.h b/src/osgPlugins/OpenFlight/RecordInputStream.h index 0d6848088..3f593aba0 100644 --- a/src/osgPlugins/OpenFlight/RecordInputStream.h +++ b/src/osgPlugins/OpenFlight/RecordInputStream.h @@ -18,11 +18,7 @@ class RecordInputStream : public DataInputStream { public: - RecordInputStream(std::istream* istream); - virtual ~RecordInputStream(); - - // end of record -// bool eor() const; + explicit RecordInputStream(std::streambuf* sb); bool readRecord(Document& data); @@ -31,15 +27,16 @@ class RecordInputStream : public DataInputStream inline std::streamsize getRecordSize() const { return _end-_start; } inline std::streamsize getRecordBodySize() const { return getRecordSize()-(std::streamsize)4; } - inline void moveToStartOfRecord() const { _istream->seekg(_start,std::ios_base::beg); } + inline void moveToStartOfRecord() { seekg(_start /*,std::ios_base::beg*/); } inline void setEndOfRecord(std::istream::pos_type pos) { _end=pos; } - protected: - virtual std::istream& read(std::istream::char_type *_Str, std::streamsize _Count) const; + virtual std::istream& vread(char_type *str, std::streamsize count); + virtual std::istream& vforward(std::istream::off_type off); -// std::istream* _istream; + int _recordSize; + int _recordOffset; std::istream::pos_type _start; // start of record std::istream::pos_type _end; // end of record }; diff --git a/src/osgPlugins/OpenFlight/VertexRecords.cpp b/src/osgPlugins/OpenFlight/VertexRecords.cpp index 2e9a71fc4..719dc7f8e 100644 --- a/src/osgPlugins/OpenFlight/VertexRecords.cpp +++ b/src/osgPlugins/OpenFlight/VertexRecords.cpp @@ -212,7 +212,7 @@ class AbsoluteVertex : public Record vertex.setCoord(osg::Vec3(x,y,z) * document.unitScale()); // optional texture coordinates - if (in().tellg() < in.getEndOfRecord()) + if (in.tellg() < in.getEndOfRecord()) { osg::Vec2f uv = in.readVec2f(); vertex.setUV(0,uv); @@ -260,7 +260,7 @@ class ShadedVertex : public Record vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool // optional texture coordinates - if (in().tellg() < in.getEndOfRecord()) + if (in.tellg() < in.getEndOfRecord()) { osg::Vec2f uv = in.readVec2f(); vertex.setUV(0,uv); @@ -308,7 +308,7 @@ class NormalVertex : public Record vertex.setColor(getColorFromPool(colorIndex, document.getColorPool())); // Color from pool // optional texture coordinates - if (in().tellg() < in.getEndOfRecord()) + if (in.tellg() < in.getEndOfRecord()) { osg::Vec2f uv = in.readVec2f(); vertex.setUV(0,uv);