/********************************************************************** * * FILE: DataInputStream.cpp * * DESCRIPTION: Implements methods to read simpel datatypes from an * input stream. * * CREATED BY: Rune Schmidt Jensen * * HISTORY: Created 11.03.2003 * * Copyright 2003 VR-C **********************************************************************/ #include "DataInputStream.h" #include "StateSet.h" #include "BlendFunc.h" #include "Material.h" #include "CullFace.h" #include "PolygonOffset.h" #include "ShadeModel.h" #include "Point.h" #include "Texture2D.h" #include "TextureCubeMap.h" #include "TexEnv.h" #include "TexEnvCombine.h" #include "TexGen.h" #include "Group.h" #include "MatrixTransform.h" #include "Geode.h" #include "LightSource.h" #include "Billboard.h" #include "Sequence.h" #include "LOD.h" #include "PagedLOD.h" //#include "ViewPoint.h" #include "PositionAttitudeTransform.h" #include "Transform.h" #include "Switch.h" #include "OccluderNode.h" #include "Impostor.h" #include "Geometry.h" #include using namespace ive; using namespace std; DataInputStream::DataInputStream(std::istream* istream){ _istream = istream; _peeking = false; _peekValue = 0; if(!istream){ throw Exception("DataInputStream::DataInputStream(): null pointer exception in argument."); } _version = readInt(); // Are we trying to open a binary .ive file which version are newer than this library. if(_version>VERSION){ throw Exception("DataInputStream::DataInputStream(): The version found in the file is newer than this library can handle."); } } DataInputStream::~DataInputStream(){} bool DataInputStream::readBool(){ bool b; _istream->read((char*)&b, BOOLSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readBool(): Failed to read boolean value."); return b; } char DataInputStream::readChar(){ char c; _istream->read(&c, CHARSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readChar(): Failed to read char value."); return c; } unsigned short DataInputStream::readUShort(){ unsigned short s; _istream->read((char*)&s, SHORTSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readUShort(): Failed to read unsigned short value."); return s; } unsigned int DataInputStream::readUInt(){ unsigned int s; _istream->read((char*)&s, INTSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readUInt(): Failed to read unsigned int value."); return s; } int DataInputStream::readInt(){ if(_peeking){ _peeking = false; return _peekValue; } int i; _istream->read((char*)&i, INTSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readInt(): Failed to read int value."); return i; } /** * Read an integer from the stream, but * save it such that the next readInt call will * return the same integer. */ int DataInputStream::peekInt(){ if(_peeking){ return _peekValue; } _peekValue = readInt(); _peeking = true; return _peekValue; } float DataInputStream::readFloat(){ float f; _istream->read((char*)&f, FLOATSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readFloat(): Failed to read float value."); return f; } long DataInputStream::readLong(){ long l; _istream->read((char*)&l, LONGSIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readLong(): Failed to read long value."); return l; } double DataInputStream::readDouble(){ double d; _istream->read((char*)&d, DOUBLESIZE); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readDouble(): Failed to read double value."); return d; } std::string DataInputStream::readString(){ std::string s; int size = readInt(); s.resize(size); _istream->read((char*)s.c_str(), size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readString(): Failed to read string value."); return s; } void DataInputStream::readCharArray(char* data, int size){ _istream->read(data, size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readCharArray(): Failed to read char value."); } osg::Vec2 DataInputStream::readVec2(){ osg::Vec2 v; v.x()=readFloat(); v.y()=readFloat(); return v; } osg::Vec3 DataInputStream::readVec3(){ osg::Vec3 v; v.x()=readFloat(); v.y()=readFloat(); v.z()=readFloat(); return v; } osg::Vec4 DataInputStream::readVec4(){ osg::Vec4 v; v.x()=readFloat(); v.y()=readFloat(); v.z()=readFloat(); v.w()=readFloat(); return v; } osg::UByte4 DataInputStream::readUByte4(){ osg::UByte4 v; v.r()=readChar(); v.g()=readChar(); v.b()=readChar(); v.a()=readChar(); return v; } osg::Quat DataInputStream::readQuat(){ osg::Quat q; q.set(readFloat(), readFloat(), readFloat(), readFloat()); return q; } osg::Geometry::AttributeBinding DataInputStream::readBinding(){ char c = readChar(); switch((int)c){ case 0: return osg::Geometry::BIND_OFF; case 1: return osg::Geometry::BIND_OVERALL; case 2: return osg::Geometry::BIND_PER_PRIMITIVE; case 3: return osg::Geometry::BIND_PER_PRIMITIVE_SET; case 4: return osg::Geometry::BIND_PER_VERTEX; default: throw Exception("Unknown binding type in DataInputStream::readBinding()"); } } osg::Array* DataInputStream::readArray(){ char c = readChar(); switch((int)c){ case 0: return readIntArray(); case 1: return readUByteArray(); case 2: return readUShortArray(); case 3: return readUIntArray(); case 4: return readUByte4Array(); case 5: return readFloatArray(); case 6: return readVec2Array(); case 7: return readVec3Array(); case 8: return readVec4Array(); default: throw Exception("Unknown array type in DataInputStream::readArray()"); } } osg::IntArray* DataInputStream::readIntArray(){ int size = readInt(); osg::IntArray* a = new osg::IntArray(size); _istream->read((char*)&((*a)[0]), INTSIZE*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readIntArray(): Failed to read Int array."); // a->reserve(size); // for(int i =0; ipush_back(readInt()); // } return a; } osg::UByteArray* DataInputStream::readUByteArray(){ int size = readInt(); osg::UByteArray* a = new osg::UByteArray(size); _istream->read((char*)&((*a)[0]), CHARSIZE*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readUByteArray(): Failed to read UByte array."); // a->reserve(size); // for(int i =0; ipush_back(readChar()); // } return a; } osg::UShortArray* DataInputStream::readUShortArray(){ int size = readInt(); osg::UShortArray* a = new osg::UShortArray(size); _istream->read((char*)&((*a)[0]), SHORTSIZE*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readUShortArray(): Failed to read UShort array."); // // a->reserve(size); // for(int i =0; ipush_back(readUShort()); // } return a; } osg::UIntArray* DataInputStream::readUIntArray(){ int size = readInt(); osg::UIntArray* a = new osg::UIntArray(size); _istream->read((char*)&((*a)[0]), INTSIZE*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readUIntArray(): Failed to read UInt array."); // // a->reserve(size); // for(int i =0; ipush_back((unsigned int)readInt()); // } return a; } osg::UByte4Array* DataInputStream::readUByte4Array(){ int size = readInt(); osg::UByte4Array* a = new osg::UByte4Array(size); _istream->read((char*)&((*a)[0]), INTSIZE*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readUbyte4Array(): Failed to read UByte4 array."); // a->reserve(size); // for(int i =0; ipush_back(readUByte4()); // } return a; } osg::FloatArray* DataInputStream::readFloatArray(){ int size = readInt(); osg::FloatArray* a = new osg::FloatArray(size); _istream->read((char*)&((*a)[0]), FLOATSIZE*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readFloatArray(): Failed to read float array."); // a->reserve(size); // for(int i =0; ipush_back(readFloat()); // } return a; } osg::Vec2Array* DataInputStream::readVec2Array(){ int size = readInt(); osg::Vec2Array* a = new osg::Vec2Array(size); _istream->read((char*)&((*a)[0]), FLOATSIZE*2*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readVec2Array(): Failed to read Vec2 array."); // for(int i = 0; i < size; i++){ // (*a)[i] = (readVec2()); // } return a; } osg::Vec3Array* DataInputStream::readVec3Array(){ int size = readInt(); osg::Vec3Array* a = new osg::Vec3Array(size); _istream->read((char*)&((*a)[0]), FLOATSIZE*3*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readVec3Array(): Failed to read Vec3 array."); // for(int i = 0; i < size; i++){ // (*a)[i] = readVec3(); // } return a; } osg::Vec4Array* DataInputStream::readVec4Array(){ int size = readInt(); osg::Vec4Array* a = new osg::Vec4Array(size); _istream->read((char*)&((*a)[0]), FLOATSIZE*4*size); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readVec4Array(): Failed to read Vec4 array."); // for(int i = 0; i < size; i++){ // (*a)[i] = (readVec4()); // } return a; } osg::Matrix DataInputStream::readMatrix(){ osg::Matrix mat; _istream->read((char*)(mat.ptr()), FLOATSIZE*16); if (_istream->rdstate() & _istream->failbit) throw Exception("DataInputStream::readMatrix(): Failed to read Matrix array."); // float* p = mat.ptr(); // for(int i=0;i<16;i++){ // p[i] = readFloat(); // } return mat; } osg::Image* DataInputStream::readImage(std::string filename) { // If image is already read and in list // then just return pointer to this. ImageMap::iterator mitr=_imageMap.find(filename); if (mitr!=_imageMap.end()) mitr->second.get(); // Image is not in list. // Read it from disk, osg::Image* image = osgDB::readImageFile(filename.c_str()); // add it to the imageList, _imageMap[filename] = image; // and return image pointer. return image; } osg::StateSet* DataInputStream::readStateSet() { // Read statesets unique ID. int id = readInt(); // See if stateset is already in the list. StateSetMap::iterator itr= _statesetMap.find(id); if (itr!=_statesetMap.end()) return itr->second.get(); // StateSet is not in list. // Create a new stateset, osg::StateSet* stateset = new osg::StateSet(); // read its properties from stream ((ive::StateSet*)(stateset))->read(this); // and add it to the stateset map, _statesetMap[id] = stateset; return stateset; } osg::StateAttribute* DataInputStream::readStateAttribute() { // Read stateattributes unique ID. int id = readInt(); // See if stateattribute is already in the list. StateAttributeMap::iterator itr= _stateAttributeMap.find(id); if (itr!=_stateAttributeMap.end()) return itr->second.get(); // stateattribute is not in list. // Create a new stateattribute, osg::StateAttribute* attribute; int attributeID = peekInt(); if(attributeID == IVEBLENDFUNC){ attribute = new osg::BlendFunc(); ((ive::BlendFunc*)(attribute))->read(this); } else if(attributeID == IVEMATERIAL){ attribute = new osg::Material(); ((ive::Material*)(attribute))->read(this); } else if(attributeID == IVECULLFACE){ attribute = new osg::CullFace(); ((ive::CullFace*)(attribute))->read(this); } else if(attributeID == IVEPOLYGONOFFSET){ attribute = new osg::PolygonOffset(); ((ive::PolygonOffset*)(attribute))->read(this); } else if(attributeID == IVESHADEMODEL){ attribute = new osg::ShadeModel(); ((ive::ShadeModel*)(attribute))->read(this); } else if(attributeID == IVEPOINT){ attribute = new osg::Point(); ((ive::Point*)(attribute))->read(this); } else if(attributeID == IVETEXTURE2D){ attribute = new osg::Texture2D(); ((ive::Texture2D*)(attribute))->read(this); } else if(attributeID == IVETEXTURECUBEMAP){ attribute = new osg::TextureCubeMap(); ((ive::TextureCubeMap*)(attribute))->read(this); } else if(attributeID == IVETEXENV){ attribute = new osg::TexEnv(); ((ive::TexEnv*)(attribute))->read(this); } else if(attributeID == IVETEXENVCOMBINE){ attribute = new osg::TexEnvCombine(); ((ive::TexEnvCombine*)(attribute))->read(this); } else if(attributeID == IVETEXGEN){ attribute = new osg::TexGen(); ((ive::TexGen*)(attribute))->read(this); } else{ throw Exception("Unkown StateAttribute in StateSet::read()"); } // and add it to the stateattribute map, _stateAttributeMap[id] = attribute; return attribute; } osg::Drawable* DataInputStream::readDrawable() { // Read stateattributes unique ID. int id = readInt(); // See if stateattribute is already in the list. DrawableMap::iterator itr= _drawableMap.find(id); if (itr!=_drawableMap.end()) return itr->second.get(); // stateattribute is not in list. // Create a new stateattribute, int drawableTypeID = peekInt(); osg::Drawable* drawable; if(drawableTypeID == IVEGEOMETRY){ drawable = new osg::Geometry(); ((Geometry*)(drawable))->read(this); } else throw Exception("Unknown drawable drawableTypeIDentification in Geode::read()"); // and add it to the stateattribute map, _drawableMap[id] = drawable; return drawable; } osg::Node* DataInputStream::readNode() { // Read node unique ID. int id = readInt(); // See if node is already in the list. NodeMap::iterator itr= _nodeMap.find(id); if (itr!=_nodeMap.end()) return itr->second.get(); // stateattribute is not in list. // Create a new node, osg::Node* node; int nodeTypeID= peekInt(); if(nodeTypeID== IVEMATRIXTRANSFORM){ node = new osg::MatrixTransform(); ((ive::MatrixTransform*)(node))->read(this); } // else if(nodeTypeID== IVEVIEWPOINT){ // node = new osgfIVE::ViewPoint(); // ((ive::ViewPoint*)(node))->read(this); // } else if(nodeTypeID== IVEPOSITIONATTITUDETRANSFORM){ node = new osg::PositionAttitudeTransform(); ((ive::PositionAttitudeTransform*)(node))->read(this); } else if(nodeTypeID== IVETRANSFORM){ node = new osg::Transform(); ((ive::Transform*)(node))->read(this); } else if(nodeTypeID== IVELIGHTSOURCE){ node = new osg::LightSource(); ((ive::LightSource*)(node))->read(this); } else if(nodeTypeID== IVESEQUENCE){ node = new osg::Sequence(); ((ive::Sequence*)(node))->read(this); } else if(nodeTypeID== IVELOD){ node = new osg::LOD(); ((ive::LOD*)(node))->read(this); } else if(nodeTypeID== IVEPAGEDLOD){ node = new osg::PagedLOD(); ((ive::PagedLOD*)(node))->read(this); } else if(nodeTypeID== IVESWITCH){ node = new osg::Switch(); ((ive::Switch*)(node))->read(this); } else if(nodeTypeID== IVEIMPOSTOR){ node = new osg::Impostor(); ((ive::Impostor*)(node))->read(this); } else if(nodeTypeID== IVEOCCLUDERNODE){ node = new osg::OccluderNode(); ((ive::OccluderNode*)(node))->read(this); } else if(nodeTypeID== IVEGROUP){ node = new osg::Group(); ((ive::Group*)(node))->read(this); } else if(nodeTypeID== IVEBILLBOARD){ node = new osg::Billboard(); ((ive::Billboard*)(node))->read(this); } else if(nodeTypeID== IVEGEODE){ node = new osg::Geode(); ((ive::Geode*)(node))->read(this); } else{ throw Exception("Unknown node identification in DataInputStream::readNode()"); } // and add it to the stateattribute map, _nodeMap[id] = node; return node; }