From e24dad3b71c4ee7bc1f031e31fc22e2a30151814 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 May 2009 11:00:26 +0000 Subject: [PATCH] From Ulrich Hertlein, "please find a patch for the DirectX loader to use std::istreams. This will make it usable with the zip plugin." --- src/osgPlugins/x/ReaderWriterDirectX.cpp | 52 +++++++++++++++--------- src/osgPlugins/x/directx.cpp | 26 +++++------- src/osgPlugins/x/directx.h | 9 ++-- src/osgPlugins/x/mesh.cpp | 8 ++-- src/osgPlugins/x/mesh.h | 8 ++-- src/osgPlugins/x/types.cpp | 12 +++--- src/osgPlugins/x/types.h | 12 +++--- 7 files changed, 67 insertions(+), 60 deletions(-) diff --git a/src/osgPlugins/x/ReaderWriterDirectX.cpp b/src/osgPlugins/x/ReaderWriterDirectX.cpp index 5f17a75c6..55b3f7912 100644 --- a/src/osgPlugins/x/ReaderWriterDirectX.cpp +++ b/src/osgPlugins/x/ReaderWriterDirectX.cpp @@ -62,12 +62,13 @@ public: } virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const; + virtual ReadResult readNode(std::istream& fin, const osgDB::ReaderWriter::Options* options) const; private: - osg::Group * convertFromDX(DX::Object & obj, bool switchHands, bool flipTexture, float creaseAngle, + osg::Group * convertFromDX(DX::Object & obj, bool switchToLeftHanded, bool flipTexture, float creaseAngle, const osgDB::ReaderWriter::Options * options) const; - osg::Geode * convertFromDX(DX::Mesh & mesh, bool switchHands, bool flipTexture, float creaseAngle, + osg::Geode * convertFromDX(DX::Mesh & mesh, bool switchToLeftHanded, bool flipTexture, float creaseAngle, const osgDB::ReaderWriter::Options * options) const; }; @@ -84,11 +85,11 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string& std::string fileName = osgDB::findDataFile( file, options ); if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; - osg::notify(osg::INFO) << "ReaderWriterDirectX::readNode(" << fileName.c_str() << ")\n"; + osg::notify(osg::INFO) << "ReaderWriterDirectX::readNode(" << fileName << ")\n"; - // Load DirectX mesh - DX::Object obj; - if (obj.load(fileName.c_str()) == false) { + osgDB::ifstream fin(fileName.c_str()); + if (fin.bad()) { + osg::notify(osg::WARN) << "ReaderWriterDirectX failed to read '" << fileName.c_str() << "'\n"; return ReadResult::ERROR_IN_READING_FILE; } @@ -96,17 +97,28 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string& osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->setDatabasePath(osgDB::getFilePath(fileName)); + return readNode(fin, local_opt.get()); +} + +osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(std::istream& fin, const osgDB::ReaderWriter::Options* options) const +{ + DX::Object obj; + if (obj.load(fin) == false) { + osg::notify(osg::WARN) << "ReaderWriterDirectX failed to read stream" << std::endl; + return ReadResult::ERROR_IN_READING_FILE; + } + // Options? bool flipTexture = true; - bool switchHands = true; // when true: swap y and z for incoming files + bool switchToLeftHanded = true; // when true: swap y and z for incoming files float creaseAngle = 80.0f; if (options) { const std::string option = options->getOptionString(); - if(option.find("rightHanded") != std::string::npos) { - switchHands=false; + if (option.find("rightHanded") != std::string::npos) { + switchToLeftHanded = false; } - if(option.find("leftHanded") != std::string::npos) { - switchHands=true; + if (option.find("leftHanded") != std::string::npos) { + switchToLeftHanded = true; } if (option.find("flipTexture") != std::string::npos) { flipTexture = false; @@ -117,16 +129,18 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string& } // Convert to osg::Group - osg::Group* group = convertFromDX(obj, switchHands, flipTexture, creaseAngle, local_opt.get()); + osg::Group* group = convertFromDX(obj, switchToLeftHanded, flipTexture, creaseAngle, options); if (!group) { + osg::notify(osg::WARN) << "ReaderWriterDirectX failed to convert\n"; return ReadResult::ERROR_IN_READING_FILE; } return group; } + // Convert DirectX object -osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj, bool switchHands, +osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj, bool switchToLeftHanded, bool flipTexture, float creaseAngle, const osgDB::ReaderWriter::Options * options) const { @@ -135,7 +149,7 @@ osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj, bool switchHan for (unsigned int i = 0; i < obj.getNumMeshes(); ++i) { //std::cerr << "converting mesh " << i << std::endl; DX::Mesh & mesh = *obj.getMesh(i); - osg::Geode * geode = convertFromDX(mesh, switchHands, flipTexture, creaseAngle, options); + osg::Geode * geode = convertFromDX(mesh, switchToLeftHanded, flipTexture, creaseAngle, options); if (!geode) { return 0; } @@ -146,7 +160,7 @@ osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj, bool switchHan } // Convert DirectX mesh to osg::Geode -osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh, bool switchHands, +osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh, bool switchToLeftHanded, bool flipTexture, float creaseAngle, const osgDB::ReaderWriter::Options * options) const { @@ -308,13 +322,13 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh, bool switchHands // Convert CW to CCW order unsigned int jj = (j > 0 ? np - j : j); - if(!switchHands) jj=j; + if(!switchToLeftHanded) jj=j; // Vertices unsigned int vi = faces[i][jj]; if (vertexArray) { const DX::Vector & v = mesh.getVertices()[vi]; - if(switchHands)// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup + if(switchToLeftHanded)// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup vertexArray->push_back(osg::Vec3(v.x,v.z,v.y)); else vertexArray->push_back(osg::Vec3(v.x,v.y,v.z)); @@ -324,7 +338,7 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh, bool switchHands unsigned int ni = meshNormals->faceNormals[i][jj]; if (normalArray) { const DX::Vector& n = meshNormals->normals[ni]; - if(switchHands)// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup + if(switchToLeftHanded)// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup normalArray->push_back(osg::Vec3(n.x,n.z,n.y)); else normalArray->push_back(osg::Vec3(n.x,n.y,n.z)); @@ -335,7 +349,7 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh, bool switchHands const DX::Coords2d& tc = (*meshTexCoords)[vi]; osg::Vec2 uv; if (flipTexture){ - if(switchHands) + if(switchToLeftHanded) uv.set(tc.u, 1.0f - tc.v); // Image is upside down else uv.set(1.0f - tc.u, 1.0f - tc.v); // Image is 180 degrees diff --git a/src/osgPlugins/x/directx.cpp b/src/osgPlugins/x/directx.cpp index 58787d33d..86f4261ef 100644 --- a/src/osgPlugins/x/directx.cpp +++ b/src/osgPlugins/x/directx.cpp @@ -59,20 +59,21 @@ void Object::clear() _meshes.clear(); } -bool Object::load(const char* filename) +bool Object::load(std::istream& fin) { - if (!filename) + // read header + char buf[256]; + if (fin.getline(buf, sizeof(buf)) == 0) { + osg::notify(osg::WARN) << "Failed to read DirectX header\n"; return false; - - osgDB::ifstream fin(filename); - if (fin.bad()) { - osg::notify(osg::WARN) << "Object::load: Unable to open: " << filename << endl; + } + if (strstr(buf, "xof") == 0) { + osg::notify(osg::WARN) << "No 'xof' found in DirectX header\n"; return false; } + // read sections parseSection(fin); - fin.close(); - return true; } @@ -107,7 +108,7 @@ Material * Object::findMaterial(const std::string & name) **********************************************************************/ // Parse section -void Object::parseSection(ifstream& fin) +void Object::parseSection(std::istream& fin) { char buf[256]; vector token; @@ -152,14 +153,9 @@ void Object::parseSection(ifstream& fin) parseSection(fin); } else { - //cerr << "!!! Begin section " << token[0] << endl; + osg::notify(osg::DEBUG_INFO) << "!!! Begin section " << token[0] << endl; parseSection(fin); } } } } - -// Parse frame -void Object::parseFrame(ifstream& /*fin*/) -{ -} diff --git a/src/osgPlugins/x/directx.h b/src/osgPlugins/x/directx.h index 54444d74d..2d8f0d0f0 100644 --- a/src/osgPlugins/x/directx.h +++ b/src/osgPlugins/x/directx.h @@ -50,12 +50,12 @@ namespace DX { } /** - * Load model from file + * Load model from stream. * Discards old data. * @param filename Filename. * @return false if the model could not be loaded, else true. */ - bool load(const char* filename); + bool load(std::istream& fin); /** * Generate per-vertex normals for the entire model. @@ -83,7 +83,7 @@ namespace DX { Material * findMaterial(const std::string & name); /// Parse section until '}'; recurse as needed. - void parseSection(std::ifstream& fin); + void parseSection(std::istream& fin); private: // dgm - keep list of materials global to the file @@ -94,9 +94,6 @@ namespace DX { /// Clear object. void clear(); - - /// Parse frame. - void parseFrame(std::ifstream& fin); }; } // namespace diff --git a/src/osgPlugins/x/mesh.cpp b/src/osgPlugins/x/mesh.cpp index 5923b5927..e8c0661ea 100644 --- a/src/osgPlugins/x/mesh.cpp +++ b/src/osgPlugins/x/mesh.cpp @@ -168,7 +168,7 @@ bool Mesh::generateNormals(float /*creaseAngle*/) } // Parse 'Mesh' -void Mesh::parseMesh(ifstream& fin) +void Mesh::parseMesh(std::istream& fin) { char buf[256]; vector token; @@ -226,7 +226,7 @@ void Mesh::parseMesh(ifstream& fin) } // Parse 'MeshMaterialList' -void Mesh::parseMeshMaterialList(ifstream& fin) +void Mesh::parseMeshMaterialList(std::istream& fin) { char buf[256]; vector token; @@ -293,7 +293,7 @@ void Mesh::parseMeshMaterialList(ifstream& fin) } // Parse 'MeshNormals' -void Mesh::parseMeshNormals(ifstream& fin) +void Mesh::parseMeshNormals(std::istream& fin) { char buf[256]; vector token; @@ -345,7 +345,7 @@ void Mesh::parseMeshNormals(ifstream& fin) } // Read 'MeshTextureCoords' -void Mesh::readMeshTexCoords(ifstream& fin) +void Mesh::readMeshTexCoords(std::istream& fin) { char buf[256]; vector token; diff --git a/src/osgPlugins/x/mesh.h b/src/osgPlugins/x/mesh.h index 53c2cc822..fdca4245f 100644 --- a/src/osgPlugins/x/mesh.h +++ b/src/osgPlugins/x/mesh.h @@ -74,7 +74,7 @@ namespace DX { } /// Parse 'Mesh'. - void parseMesh(std::ifstream& fin); + void parseMesh(std::istream& fin); private: Object * _obj; @@ -92,13 +92,13 @@ namespace DX { MeshMaterialList* _materialList; /// Parse 'MeshNormals'. - void parseMeshNormals(std::ifstream& fin); + void parseMeshNormals(std::istream& fin); /// Parse 'MeshMaterialList'. - void parseMeshMaterialList(std::ifstream& fin); + void parseMeshMaterialList(std::istream& fin); /// Read 'MeshTextureCoords'. - void readMeshTexCoords(std::ifstream& fin); + void readMeshTexCoords(std::istream& fin); }; } // namespace diff --git a/src/osgPlugins/x/types.cpp b/src/osgPlugins/x/types.cpp index fa108ab9b..caf33dc93 100644 --- a/src/osgPlugins/x/types.cpp +++ b/src/osgPlugins/x/types.cpp @@ -51,7 +51,7 @@ namespace DX { } // Read 'TextureFilename' - void readTexFilename(ifstream & fin, TextureFilename & texture) + void readTexFilename(istream & fin, TextureFilename & texture) { char buf[256]; vector token; @@ -82,7 +82,7 @@ namespace DX { } // Read 'Coords2d' - void readCoords2d(ifstream & fin, vector & v, unsigned int count) + void readCoords2d(istream & fin, vector & v, unsigned int count) { char buf[256]; vector token; @@ -107,7 +107,7 @@ namespace DX { } // Read 'Vector' - void readVector(ifstream & fin, vector & v, unsigned int count) + void readVector(istream & fin, vector & v, unsigned int count) { char buf[256]; vector token; @@ -133,7 +133,7 @@ namespace DX { } // Parse 'Material' - void parseMaterial(ifstream & fin, Material & material) + void parseMaterial(istream & fin, Material & material) { char buf[256]; vector token; @@ -190,7 +190,7 @@ namespace DX { } // Read index list - void readIndexList(ifstream & fin, vector & v, unsigned int count) + void readIndexList(istream & fin, vector & v, unsigned int count) { char buf[256]; vector token; @@ -213,7 +213,7 @@ namespace DX { } // Read 'MeshFace' - void readMeshFace(ifstream & fin, vector & v, unsigned int count) + void readMeshFace(istream & fin, vector & v, unsigned int count) { char buf[256]; vector token; diff --git a/src/osgPlugins/x/types.h b/src/osgPlugins/x/types.h index c01b7175d..33768c530 100644 --- a/src/osgPlugins/x/types.h +++ b/src/osgPlugins/x/types.h @@ -109,22 +109,22 @@ namespace DX { extern void tokenize(const std::string& str, std::vector& tokens, const std::string& delimiters = " \t\r\n;,"); /// Parse 'Material'. - extern void parseMaterial(std::ifstream& fin, Material& material); + extern void parseMaterial(std::istream& fin, Material& material); /// Read 'TextureFilename'. - extern void readTexFilename(std::ifstream& fin, TextureFilename& texture); + extern void readTexFilename(std::istream& fin, TextureFilename& texture); /// Read 'Coords2d'. - extern void readCoords2d(std::ifstream& fin, std::vector& v, unsigned int count); + extern void readCoords2d(std::istream& fin, std::vector& v, unsigned int count); // Read 'Vector' - extern void readVector(std::ifstream& fin, std::vector& v, unsigned int count); + extern void readVector(std::istream& fin, std::vector& v, unsigned int count); /// Read index list. - extern void readIndexList(std::ifstream& fin, std::vector& v, unsigned int count); + extern void readIndexList(std::istream& fin, std::vector& v, unsigned int count); /// Read 'MeshFace'. - extern void readMeshFace(std::ifstream& fin, std::vector& v, unsigned int count); + extern void readMeshFace(std::istream& fin, std::vector& v, unsigned int count); } // namespace