diff --git a/src/osgPlugins/3ds/ReaderWriter3DS.cpp b/src/osgPlugins/3ds/ReaderWriter3DS.cpp index 1cbc7bfa8..6e716c5da 100644 --- a/src/osgPlugins/3ds/ReaderWriter3DS.cpp +++ b/src/osgPlugins/3ds/ReaderWriter3DS.cpp @@ -94,15 +94,18 @@ osg::Matrix copyLib3dsMatrixToOsgMatrix(const Lib3dsMatrix mat) return osgMatrix; } -void copyLib3dsVec3ToOsgVec3(osg::Vec3f osgVec, const float vertices[3]) { +void copyLib3dsVec3ToOsgVec3(osg::Vec3f osgVec, const float vertices[3]) +{ return osgVec.set(vertices[0], vertices[1], vertices[2]); } -osg::Vec3f copyLib3dsVec3ToOsgVec3(const float vertices[3]) { +osg::Vec3f copyLib3dsVec3ToOsgVec3(const float vertices[3]) +{ return osg::Vec3f(vertices[0], vertices[1], vertices[2]); } -osg::Quat copyLib3dsQuatToOsgQuat(const float quat[4]) { +osg::Quat copyLib3dsQuatToOsgQuat(const float quat[4]) +{ return osg::Quat(quat[0], quat[1], quat[2], quat[3]); } @@ -225,22 +228,22 @@ ReaderWriter3DS::ReaderWriter3DS() setByteOrder(); #if 0 - osg::notify(osg::NOTICE)<<"3DS reader sizes:"<name << endl; print(mesh->matrix,level); - } else { + } + else + { pad(level); cout << "no mesh " << endl; } } -void print(Lib3dsUserData *user,int level) { - if (user) { +void print(Lib3dsUserData *user,int level) +{ + if (user) + { pad(level); cout << "user data" << endl; //print(user->mesh,level+1); - } else { + } + else + { pad(level); cout << "no user data" << endl; } } -void print(Lib3dsMeshInstanceNode *object,int level) { - if (object) { +void print(Lib3dsMeshInstanceNode *object,int level) +{ + if (object) + { pad(level); cout << "objectdata instance [" << object->instance_name << "]" << endl; pad(level); cout << "pivot " << object->pivot[0] <<" "<< object->pivot[1] <<" "<< object->pivot[2] << endl; pad(level); cout << "pos " << object->pos[0] <<" "<< object->pos[1] <<" "<< object->pos[2] << endl; pad(level); cout << "scl " << object->scl[0] <<" "<< object->scl[1] <<" "<< object->scl[2] << endl; pad(level); cout << "rot " << object->rot[0] <<" "<< object->rot[1] <<" "<< object->rot[2] <<" "<< object->rot[3] << endl; - } else { + } + else + { pad(level); cout << "no object data" << endl; } } -void print(Lib3dsNode *node, int level) { +void print(Lib3dsNode *node, int level) +{ pad(level); cout << "node name [" << node->name << "]" << endl; pad(level); cout << "node id " << node->user_id << endl; @@ -323,16 +342,20 @@ void print(Lib3dsNode *node, int level) { pad(level); cout << "node matrix:" << endl; print(node->matrix,level+1); - if (node->type == LIB3DS_NODE_MESH_INSTANCE) { + if (node->type == LIB3DS_NODE_MESH_INSTANCE) + { pad(level); cout << "mesh instance data:" << endl; print(reinterpret_cast(node),level+1); - } else { + } + else + { pad(level); cout << "node is not a mesh instance (not handled)" << endl; } print(&node->user_ptr,level); - for(Lib3dsNode *child=node->childs; child; child=child->next) { + for(Lib3dsNode *child=node->childs; child; child=child->next) + { print(child,level+1); } @@ -386,7 +409,8 @@ void ReaderWriter3DS::ReaderObject::addDrawableFromFace(osg::Geode * geode, Face // Transforms points by matrix if 'matrix' is not NULL // Creates a Geode and Geometry (as parent,child) and adds the Geode to 'parent' parameter iff 'parent' is non-NULL // Returns ptr to the Geode -osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, const osg::Matrix * matrix) { +osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, const osg::Matrix * matrix) +{ typedef std::vector MaterialFaceMap; MaterialFaceMap materialFaceMap; unsigned int numMaterials = drawStateMap.size(); @@ -394,16 +418,19 @@ osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap, FaceList defaultMaterialFaceList; for (unsigned int i=0; infaces; ++i) { - if (mesh->faces[i].material>=0) { + if (mesh->faces[i].material>=0) + { materialFaceMap[mesh->faces[i].material].push_back(i); } else + { defaultMaterialFaceList.push_back(i); + } } if (materialFaceMap.empty() && defaultMaterialFaceList.empty()) { - osg::notify(osg::NOTICE)<<"Warning : no triangles assigned to mesh '"<name<<"'"<< std::endl; - //osg::notify(osg::INFO) << "No material assigned to mesh '" << mesh->name << "'" << std::endl; + OSG_NOTIFY(osg::NOTICE)<<"Warning : no triangles assigned to mesh '"<name<<"'"<< std::endl; + //OSG_NOTIFY(osg::INFO) << "No material assigned to mesh '" << mesh->name << "'" << std::endl; return NULL; } else @@ -472,8 +499,10 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L bool pivoted = pivot.x()!=0 || pivot.y()!=0 || pivot.z()!=0; osg::Matrix meshMat; - if (mesh) { - if (!noMatrixTransforms) { + if (mesh) + { + if (!noMatrixTransforms) + { // There can be a transform directly on a mesh instance (= as if a osg::MatrixTransform and a osg::Geode were merged together) in object->pos/rot/scl if (!pivoted) { meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)); @@ -492,21 +521,27 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L } bool isOsgNodeMatrixIdentity = false; - if (osgNodeMatrix.isIdentity() || (checkForEspilonIdentityMatrices && isIdentityEquivalent(osgNodeMatrix, MATRIX_EPSILON))) { + if (osgNodeMatrix.isIdentity() || (checkForEspilonIdentityMatrices && isIdentityEquivalent(osgNodeMatrix, MATRIX_EPSILON))) + { isOsgNodeMatrixIdentity = true; } - //if (node->childs != NULL || pivoted || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) { - if (node->childs != NULL || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) { - if (isOsgNodeMatrixIdentity || noMatrixTransforms) { + //if (node->childs != NULL || pivoted || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) + if (node->childs != NULL || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) + { + if (isOsgNodeMatrixIdentity || noMatrixTransforms) + { group = new osg::Group; - } else { + } + else + { group = new osg::MatrixTransform(osgNodeMatrix); } } - if (group) { + if (group) + { if (strcmp(node->name, "$$$DUMMY") == 0) { if (node->type == LIB3DS_NODE_MESH_INSTANCE) @@ -516,32 +551,42 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L group->setName(node->name); // Handle all children of this node for hierarchical assemblies - for (Lib3dsNode *p=node->childs; p!=NULL; p=p->next) { + for (Lib3dsNode *p=node->childs; p!=NULL; p=p->next) + { group->addChild(processNode(drawStateMap,f,p)); } - } else { + } + else + { assert(node->childs == NULL); // Else we must have a group to put childs into } // Handle mesh - if (mesh) { + if (mesh) + { osg::Matrix * meshAppliedMatPtr = NULL; - if (!meshMat.isIdentity() && !(checkForEspilonIdentityMatrices && isIdentityEquivalent(meshMat, MATRIX_EPSILON))) { + if (!meshMat.isIdentity() && !(checkForEspilonIdentityMatrices && isIdentityEquivalent(meshMat, MATRIX_EPSILON))) + { meshAppliedMatPtr = &meshMat; } - if(group) { + if (group) + { // add our geometry to group (where our children already are) // creates geometry under modifier node processMesh(drawStateMap,group,mesh,meshAppliedMatPtr); return group; - } else { + } + else + { // didnt use group for children // return a ptr directly to the Geode for this mesh return processMesh(drawStateMap,NULL,mesh,meshAppliedMatPtr); } - } else { + } + else + { // no mesh for this node - probably a camera or something of that persuasion //cout << "no mesh for object " << node->name << endl; return group; // we have no mesh, but we might have children @@ -549,7 +594,8 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L } -static long filei_seek_func(void *self, long offset, Lib3dsIoSeek origin) { +static long filei_seek_func(void *self, long offset, Lib3dsIoSeek origin) +{ std::istream *f = reinterpret_cast(self); ios_base::seekdir o = ios_base::beg; if (origin == LIB3DS_SEEK_CUR) o = ios_base::cur; @@ -559,7 +605,8 @@ static long filei_seek_func(void *self, long offset, Lib3dsIoSeek origin) { return f->fail() ? -1 : 0; } -static long fileo_seek_func(void *self, long offset, Lib3dsIoSeek origin) { +static long fileo_seek_func(void *self, long offset, Lib3dsIoSeek origin) +{ std::ostream *f = reinterpret_cast(self); ios_base::seekdir o = ios_base::beg; if (origin == LIB3DS_SEEK_CUR) o = ios_base::cur; @@ -569,24 +616,28 @@ static long fileo_seek_func(void *self, long offset, Lib3dsIoSeek origin) { return f->fail() ? -1 : 0; } -static long filei_tell_func(void *self) { +static long filei_tell_func(void *self) +{ std::istream *f = reinterpret_cast(self); return f->tellg(); } -static long fileo_tell_func(void *self) { +static long fileo_tell_func(void *self) +{ std::ostream *f = reinterpret_cast(self); return f->tellp(); } -static size_t filei_read_func(void *self, void *buffer, size_t size) { +static size_t filei_read_func(void *self, void *buffer, size_t size) +{ std::istream *f = reinterpret_cast(self); f->read(reinterpret_cast(buffer), size); return f->gcount(); } -static size_t fileo_write_func(void *self, const void *buffer, size_t size) { +static size_t fileo_write_func(void *self, const void *buffer, size_t size) +{ std::ostream *f = reinterpret_cast(self); f->write(static_cast(buffer), size); return f->fail() ? 0 : size; @@ -600,7 +651,7 @@ static void fileio_log_func(void *self, Lib3dsLogLevel level, int indent, const else if (level == LIB3DS_LOG_WARN) l = osg::NOTICE; else if (level == LIB3DS_LOG_INFO) l = osg::INFO; else if (level == LIB3DS_LOG_DEBUG) l = osg::DEBUG_INFO; - osg::notify(l) << msg << std::endl; + OSG_NOTIFY(l) << msg << std::endl; } @@ -699,11 +750,12 @@ osgDB::ReaderWriter::ReadResult ReaderWriter3DS::constructFrom3dsFile(Lib3dsFile { int level=0; std::cout << "NODE TRAVERSAL of 3ds file "<name<nodes; node; node=node->next) { + for(Lib3dsNode *node=f->nodes; node; node=node->next) + { print(node,level+1); } std::cout << "MESH TRAVERSAL of 3ds file "<name<nmeshes; ++imesh) { + for (int imesh=0; imeshnmeshes; ++imesh){ print(f->meshes[imesh],level+1); } } @@ -715,26 +767,34 @@ osgDB::ReaderWriter::ReadResult ReaderWriter3DS::constructFrom3dsFile(Lib3dsFile // MIKEC: have found 3ds files with NO node structure - only meshes, for this case we fall back to the old traverse-by-meshes code // Loading and re-exporting these files from 3DS produces a file with correct node structure, so perhaps these are not 100% conformant? - if (f->nodes == NULL) { - osg::notify(osg::WARN)<<"Warning: in 3ds loader: file has no nodes, traversing by meshes instead"<< std::endl; + if (f->nodes == NULL) + { + OSG_NOTIFY(osg::WARN)<<"Warning: in 3ds loader: file has no nodes, traversing by meshes instead"<< std::endl; traverse_nodes=true; } osg::Node* group = NULL; - if (traverse_nodes) { // old method + if (traverse_nodes) // old method + { group = new osg::Group(); - for (int imesh=0; imeshnmeshes; ++imesh) { + for (int imesh=0; imeshnmeshes; ++imesh) + { reader.processMesh(drawStateMap,group->asGroup(),f->meshes[imesh],NULL); } - } else { // new method + } + else + { // new method Lib3dsNode *node=f->nodes; if (!node->next) + { group = reader.processNode(drawStateMap,f,node); + } else { group = new osg::Group(); - for(; node; node=node->next) { + for(; node; node=node->next) + { group->asGroup()->addChild(reader.processNode(drawStateMap,f,node)); } } @@ -743,7 +803,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriter3DS::constructFrom3dsFile(Lib3dsFile if (osg::getNotifyLevel()>=osg::INFO) { - osg::notify(osg::NOTICE) << "Final OSG node structure looks like this:"<< endl; + OSG_NOTIFY(osg::NOTICE) << "Final OSG node structure looks like this:"<< endl; PrintVisitor pv(osg::notify(osg::NOTICE)); group->accept(pv); } @@ -902,14 +962,14 @@ osg::Texture2D* ReaderWriter3DS::ReaderObject::createTexture(Lib3dsTextureMap * { if (texture && *(texture->name)) { - osg::notify(osg::INFO)<<"texture->name="<name<<", _directory="<<_directory<name="<name<<", _directory="<<_directory<name,_directory,osgDB::CASE_INSENSITIVE); if (fileName.empty()) { // file not found in .3ds file's directory, so we'll look in the datafile path list. fileName = osgDB::findDataFile(texture->name,options, osgDB::CASE_INSENSITIVE); - osg::notify(osg::INFO)<<"texture->name="<name<<", _directory="<<_directory<name="<name<<", _directory="<<_directory<name; - } else { - osg::notify(osg::WARN) << "texture '"<name<<"' not found"<< std::endl; + } + else + { + OSG_NOTIFY(osg::WARN) << "texture '"<name<<"' not found"<< std::endl; return NULL; } } - if (label) osg::notify(osg::DEBUG_INFO) << label; - else osg::notify(osg::DEBUG_INFO) << "texture name"; - osg::notify(osg::DEBUG_INFO) << " '"<name<<"'"<< std::endl; - osg::notify(osg::DEBUG_INFO) << " texture flag "<flags<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_DECALE "<<((texture->flags)&LIB3DS_TEXTURE_DECALE)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_MIRROR "<<((texture->flags)&LIB3DS_TEXTURE_MIRROR)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_NEGATE "<<((texture->flags)&LIB3DS_TEXTURE_NEGATE)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_NO_TILE "<<((texture->flags)&LIB3DS_TEXTURE_NO_TILE)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_SUMMED_AREA "<<((texture->flags)&LIB3DS_TEXTURE_SUMMED_AREA)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_ALPHA_SOURCE "<<((texture->flags)&LIB3DS_TEXTURE_ALPHA_SOURCE)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_TINT "<<((texture->flags)&LIB3DS_TEXTURE_TINT)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_IGNORE_ALPHA "<<((texture->flags)&LIB3DS_TEXTURE_IGNORE_ALPHA)<< std::endl; - osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_RGB_TINT "<<((texture->flags)&LIB3DS_TEXTURE_RGB_TINT)<< std::endl; + if (label) { OSG_NOTIFY(osg::DEBUG_INFO) << label; } + else { OSG_NOTIFY(osg::DEBUG_INFO) << "texture name"; } + + OSG_NOTIFY(osg::DEBUG_INFO) << " '"<name<<"'"<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " texture flag "<flags<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_DECALE "<<((texture->flags)&LIB3DS_TEXTURE_DECALE)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_MIRROR "<<((texture->flags)&LIB3DS_TEXTURE_MIRROR)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_NEGATE "<<((texture->flags)&LIB3DS_TEXTURE_NEGATE)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_NO_TILE "<<((texture->flags)&LIB3DS_TEXTURE_NO_TILE)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_SUMMED_AREA "<<((texture->flags)&LIB3DS_TEXTURE_SUMMED_AREA)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_ALPHA_SOURCE "<<((texture->flags)&LIB3DS_TEXTURE_ALPHA_SOURCE)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_TINT "<<((texture->flags)&LIB3DS_TEXTURE_TINT)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_IGNORE_ALPHA "<<((texture->flags)&LIB3DS_TEXTURE_IGNORE_ALPHA)<< std::endl; + OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_RGB_TINT "<<((texture->flags)&LIB3DS_TEXTURE_RGB_TINT)<< std::endl; osg::ref_ptr osg_image = osgDB::readRefImageFile(fileName.c_str(), options); //Absolute Path if (!osg_image.valid()) { - osg::notify(osg::NOTICE) << "Warning: Cannot create texture "<name<< std::endl; + OSG_NOTIFY(osg::NOTICE) << "Warning: Cannot create texture "<name<< std::endl; return NULL; } if (osg_image->getFileName().empty()) // it should be done in OSG with osgDB::readRefImageFile(fileName.c_str()); @@ -1070,7 +1133,8 @@ osg::StateSet* ReaderWriter3DS::ReaderObject::createStateSet(Lib3dsMaterial *mat } -osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,const std::string& fileName,const Options* options) const { +osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,const std::string& fileName,const Options* options) const +{ std::string ext = osgDB::getLowerCaseFileExtension(fileName); if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; @@ -1083,16 +1147,10 @@ osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& nod Lib3dsFile * file3ds = lib3ds_file_new(); if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE); - try { - osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; - local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); - - if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false; - if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false; - } catch (...) { - lib3ds_file_free(file3ds); - throw; - } + osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); + if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false; + if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false; lib3ds_file_free(file3ds); return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE); @@ -1100,17 +1158,20 @@ osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& nod } -osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,std::ostream& fout,const Options* options) const { - //osg::notify(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl; +osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,std::ostream& fout,const Options* options) const +{ + //OSG_NOTIFY(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl; std::string optFileName; - if (options) { + if (options) + { optFileName = options->getPluginStringData("STREAM_FILENAME"); } return doWriteNode(node, fout, options, optFileName); } -osgDB::ReaderWriter::WriteResult ReaderWriter3DS::doWriteNode(const osg::Node& node,std::ostream& fout, const Options* options, const std::string & fileNamelib3ds) const { +osgDB::ReaderWriter::WriteResult ReaderWriter3DS::doWriteNode(const osg::Node& node,std::ostream& fout, const Options* options, const std::string & fileNamelib3ds) const +{ osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileNamelib3ds)); @@ -1126,26 +1187,20 @@ osgDB::ReaderWriter::WriteResult ReaderWriter3DS::doWriteNode(const osg::Node& n if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE); bool ok = true; - try { - if (!createFileObject(node, file3ds, fileNamelib3ds, local_opt.get())) ok = false; - if (ok && !lib3ds_file_write(file3ds, &io)) ok = false; - - } catch (...) { - lib3ds_file_free(file3ds); - throw; - } + if (!createFileObject(node, file3ds, fileNamelib3ds, local_opt.get())) ok = false; + if (ok && !lib3ds_file_write(file3ds, &io)) ok = false; lib3ds_file_free(file3ds); return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE); //return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::FILE_NOT_HANDLED); } -bool ReaderWriter3DS::createFileObject(const osg::Node& node, Lib3dsFile * file3ds,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const { +bool ReaderWriter3DS::createFileObject(const osg::Node& node, Lib3dsFile * file3ds,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const +{ WriterNodeVisitor w(file3ds, fileName, options, osgDB::getFilePath(node.getName())); const_cast(node).accept(w); // Ugly const_cast<> for visitor... - if (!w.suceedLastApply()) - return false; + if (!w.succeeded()) return false; w.writeMaterials(); - return true; //w.good(); + return w.succeeded(); } diff --git a/src/osgPlugins/3ds/WriterCompareTriangle.cpp b/src/osgPlugins/3ds/WriterCompareTriangle.cpp index 2e485ed85..d2ffcb4c0 100644 --- a/src/osgPlugins/3ds/WriterCompareTriangle.cpp +++ b/src/osgPlugins/3ds/WriterCompareTriangle.cpp @@ -1,4 +1,5 @@ #include "WriterCompareTriangle.h" +#include WriterCompareTriangle::WriterCompareTriangle(const osg::Geode & geode, unsigned int nbVertices) : geode(geode) { @@ -50,7 +51,7 @@ void WriterCompareTriangle::cutscene(int nbVertices, const osg::BoundingBox & sc setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cutting the scene in too many blocs - osg::notify(osg::INFO) + OSG_NOTIFY(osg::INFO) << "Cutting x by " << nbVerticesX << std::endl << "Cutting y by " << nbVerticesY << std::endl << "Cutting z by " << nbVerticesZ << std::endl; @@ -119,16 +120,17 @@ WriterCompareTriangle::inWhichBox(const osg::BoundingBox::value_type x, for (unsigned int i = 0; i < boxList.size(); ++i) { if (x >= boxList[i].xMin() && - x < boxList[i].xMax() && + x < boxList[i].xMax() && y >= boxList[i].yMin() && - y < boxList[i].yMax() && + y < boxList[i].yMax() && z >= boxList[i].zMin() && - z < boxList[i].zMax()) + z < boxList[i].zMax()) { return i; } } - throw "Point is not in any blocs"; + assert(false && "Point is not in any blocs"); + return 0; } int WriterCompareTriangle::inWhichBox(const osg::BoundingBox::vec_type & point) const { diff --git a/src/osgPlugins/3ds/WriterNodeVisitor.cpp b/src/osgPlugins/3ds/WriterNodeVisitor.cpp index 6707b534a..5325c3e9d 100644 --- a/src/osgPlugins/3ds/WriterNodeVisitor.cpp +++ b/src/osgPlugins/3ds/WriterNodeVisitor.cpp @@ -25,7 +25,8 @@ void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix) { - for(int row=0; row<4; ++row) { + for(int row=0; row<4; ++row) + { lib3ds_matrix[row][0] = osg_matrix.ptr()[row*4+0]; lib3ds_matrix[row][1] = osg_matrix.ptr()[row*4+1]; lib3ds_matrix[row][2] = osg_matrix.ptr()[row*4+2]; @@ -33,29 +34,34 @@ void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& } } -inline void copyOsgVectorToLib3dsVector(Lib3dsVector lib3ds_vector, const osg::Vec3f& osg_vector) { +inline void copyOsgVectorToLib3dsVector(Lib3dsVector lib3ds_vector, const osg::Vec3f& osg_vector) +{ lib3ds_vector[0] = osg_vector[0]; lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[2] = osg_vector[2]; } -inline void copyOsgVectorToLib3dsVector(Lib3dsVector lib3ds_vector, const osg::Vec3d& osg_vector) { +inline void copyOsgVectorToLib3dsVector(Lib3dsVector lib3ds_vector, const osg::Vec3d& osg_vector) +{ lib3ds_vector[0] = osg_vector[0]; lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[2] = osg_vector[2]; } -inline void copyOsgColorToLib3dsColor(Lib3dsVector lib3ds_vector, const osg::Vec4f& osg_vector) { +inline void copyOsgColorToLib3dsColor(Lib3dsVector lib3ds_vector, const osg::Vec4f& osg_vector) +{ lib3ds_vector[0] = osg_vector[0]; lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[2] = osg_vector[2]; } -inline void copyOsgColorToLib3dsColor(Lib3dsVector lib3ds_vector, const osg::Vec4d& osg_vector) { +inline void copyOsgColorToLib3dsColor(Lib3dsVector lib3ds_vector, const osg::Vec4d& osg_vector) +{ lib3ds_vector[0] = osg_vector[0]; lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[2] = osg_vector[2]; } -inline void copyOsgQuatToLib3dsQuat(float lib3ds_vector[4], const osg::Quat& osg_quat) { +inline void copyOsgQuatToLib3dsQuat(float lib3ds_vector[4], const osg::Quat& osg_quat) +{ //lib3ds_vector[0] = osg_quat[3]; // Not sure //lib3ds_vector[1] = osg_quat[0]; //lib3ds_vector[2] = osg_quat[1]; @@ -69,7 +75,8 @@ inline void copyOsgQuatToLib3dsQuat(float lib3ds_vector[4], const osg::Quat& osg lib3ds_vector[3] = static_cast(-angle); } -std::string getFileName(const std::string & path) { +std::string getFileName(const std::string & path) +{ unsigned int slashPos = path.find_last_of("/\\"); if (slashPos == std::string::npos) return path; return path.substr(slashPos+1); @@ -77,7 +84,8 @@ std::string getFileName(const std::string & path) { /// Checks if a filename (\b not path) is 8.3 (an empty name is never 8.3, and a path is never 8.3). -bool is83(const std::string & s) { +bool is83(const std::string & s) +{ // 012345678901 // ABCDEFGH.ABC if (s.find_first_of("/\\") != std::string::npos) return false; // It should not be a path, but a filename @@ -92,7 +100,8 @@ bool is83(const std::string & s) { } /// Tests if the given string is a path supported by 3DS format (8.3, 63 chars max). -bool is3DSpath(const std::string & s, bool extendedFilePaths) { +bool is3DSpath(const std::string & s, bool extendedFilePaths) +{ unsigned int len = s.length(); if (len >= 64 || len == 0) return false; if (extendedFilePaths) return true; // Extended paths are simply those that fits the 64 bytes buffer! @@ -112,7 +121,8 @@ bool is3DSpath(const std::string & s, bool extendedFilePaths) { /** writes all primitives of a primitive-set out to a stream, decomposes quads to triangles, line-strips to lines etc */ -class PrimitiveIndexWriter : public osg::PrimitiveIndexFunctor { +class PrimitiveIndexWriter : public osg::PrimitiveIndexFunctor +{ public: PrimitiveIndexWriter(osg::Geometry * geo, ListTriangle & listTriangles, @@ -340,7 +350,7 @@ void PrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count) case(GL_LINE_LOOP): //break; default: - osg::notify(osg::WARN) << "3DS WriterNodeVisitor: can't handle mode " << mode << std::endl; + OSG_NOTIFY(osg::WARN) << "3DS WriterNodeVisitor: can't handle mode " << mode << std::endl; break; } } @@ -361,7 +371,8 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg { //static unsigned int s_objmaterial_id = 0; //++s_objmaterial_id; - if (mat) { + if (mat) + { assert(stateset); diffuse = mat->getDiffuse(osg::Material::FRONT); ambient = mat->getAmbient(osg::Material::FRONT); @@ -370,24 +381,30 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg transparency = 1-diffuse.w(); name = writerNodeVisitor.getUniqueName(mat->getName(),"mat"); osg::StateAttribute * attribute = stateset->getAttribute(osg::StateAttribute::CULLFACE); - if (!attribute) { + if (!attribute) + { double_sided = true; - } else { + } + else + { assert(dynamic_cast(attribute)); osg::CullFace::Mode mode = static_cast(attribute)->getMode(); if (mode == osg::CullFace::BACK) double_sided = false; - else if (mode == osg::CullFace::FRONT) { - osg::notify(osg::WARN) << "3DS Writer: Reversed face (culled FRONT) not supported yet." << std::endl; + else if (mode == osg::CullFace::FRONT) + { + OSG_NOTIFY(osg::WARN) << "3DS Writer: Reversed face (culled FRONT) not supported yet." << std::endl; double_sided = false; } - else { + else + { assert(mode == osg::CullFace::FRONT_AND_BACK); - osg::notify(osg::WARN) << "3DS Writer: Invisible face (culled FRONT_AND_BACK) not supported yet." << std::endl; + OSG_NOTIFY(osg::WARN) << "3DS Writer: Invisible face (culled FRONT_AND_BACK) not supported yet." << std::endl; double_sided = false; } } } - if (tex) { + if (tex) + { osg::Image* img = tex->getImage(0); if(img) { @@ -397,7 +414,8 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg } } - if (name.empty()) { + if (name.empty()) + { std::stringstream ss; ss << "m" << index; name = ss.str(); @@ -465,7 +483,7 @@ WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & f const osgDB::ReaderWriter::Options* options, const std::string & srcDirectory) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _suceedLastApply(true), + _succeeded(true), _srcDirectory(srcDirectory), file3ds(file3ds), _currentStateSet(new osg::StateSet()), @@ -479,7 +497,8 @@ WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & f if (!fileName.empty()) _directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front(); - if (options) { + if (options) + { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) @@ -523,12 +542,14 @@ void WriterNodeVisitor::writeMaterials() oss << "Image_" << _imageCount++ << ".rgb"; path = oss.str(); } - else { + else + { path = getPathRelative(_srcDirectory, mat.image->getFileName()); } path = convertExt(path, _extendedFilePaths); - if(!is3DSpath(path, _extendedFilePaths)) { + if(!is3DSpath(path, _extendedFilePaths)) + { path = getUniqueName(path, "", true); //path = osgDB::getSimpleFileName(path); } @@ -546,24 +567,26 @@ void WriterNodeVisitor::writeMaterials() if (mat.texture_transparency) tex.flags |= LIB3DS_TEXTURE_ALPHA_SOURCE; if (mat.texture_no_tile) tex.flags |= LIB3DS_TEXTURE_NO_TILE; } - if (!suceedLastApply()) + if (!succeeded()) return; lib3ds_file_insert_material(file3ds, mat3ds, itr->second.index); break; // Ugly thing (3) } - if (!found) throw "Implementation error"; // Ugly thing (4) + assert(found); // Ugly thing (4) - Implementation error if !found } } -std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, const std::string & _defaultPrefix, bool nameIsPath) { - static const unsigned int MAX_PREFIX_LEGNTH = 4; - if (_defaultPrefix.length()>MAX_PREFIX_LEGNTH) throw "Default prefix is too long"; // Arbitrarily defined to 4 chars. +std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, const std::string & _defaultPrefix, bool nameIsPath) +{ + static const unsigned int MAX_PREFIX_LEGNTH = 4; // Arbitrarily defined to 4 chars + assert(_defaultPrefix.length()<=MAX_PREFIX_LEGNTH); // Default prefix is too long (implementation error) // Tests if default name is valid and unique bool defaultIs83 = is83(_defaultValue); bool defaultIsValid = nameIsPath ? is3DSpath(_defaultValue, _extendedFilePaths) : defaultIs83; - if (defaultIsValid && _nameMap.find(_defaultValue) == _nameMap.end()) { + if (defaultIsValid && _nameMap.find(_defaultValue) == _nameMap.end()) + { _nameMap.insert(_defaultValue); return _defaultValue; } @@ -610,18 +633,23 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, c } unsigned int searchStart = 0; - if (pairPrefix != _mapPrefix.end()) { + if (pairPrefix != _mapPrefix.end()) + { searchStart = pairPrefix->second; } - for(unsigned int i = searchStart; i <= max_val; ++i) { + for(unsigned int i = searchStart; i <= max_val; ++i) + { std::stringstream ss; ss << defaultPrefix << i; const std::string & res = ss.str(); - if (_nameMap.find(res) == _nameMap.end()) { - if (pairPrefix != _mapPrefix.end()) { + if (_nameMap.find(res) == _nameMap.end()) + { + if (pairPrefix != _mapPrefix.end()) + { pairPrefix->second = i + 1; - } else { + } else + { _mapPrefix.insert(std::pair(defaultPrefix, i + 1)); } _nameMap.insert(res); @@ -634,13 +662,18 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, c if (defaultPrefix.length()>1) return getUniqueName(_defaultValue, defaultPrefix.substr(0, defaultPrefix.length()-1), nameIsPath); // Try with default prefix if not arleady done if (defaultPrefix != std::string("_")) return getUniqueName(_defaultValue, "_", nameIsPath); - throw "No more names available! Is default prefix too long?"; + + // No more names + OSG_NOTIFY(osg::FATAL) << "No more names available!" << std::endl; + _succeeded = false; + return "ERROR"; } int WriterNodeVisitor::processStateSet(osg::StateSet* ss) { MaterialMap::const_iterator itr = _materialMap.find(ss); - if (itr != _materialMap.end()) { + if (itr != _materialMap.end()) + { assert(itr->second.index>=0); return itr->second.index; } @@ -671,7 +704,8 @@ WriterNodeVisitor::getMeshIndexForGeometryIndex(MapIndices & index_vert, unsigned int drawable_n) { MapIndices::iterator itIndex = index_vert.find(std::pair(index, drawable_n)); - if (itIndex == index_vert.end()) { + if (itIndex == index_vert.end()) + { unsigned int indexMesh = index_vert.size(); index_vert.insert(std::make_pair(std::pair(index, drawable_n), indexMesh)); return indexMesh; @@ -687,9 +721,8 @@ WriterNodeVisitor::buildMesh(osg::Geode & geo, bool texcoords, Lib3dsMesh * mesh) { - osg::notify(osg::DEBUG_INFO) << "Building Mesh" << std::endl; - - if (!mesh) throw "Allocation error"; // TODO + OSG_NOTIFY(osg::DEBUG_INFO) << "Building Mesh" << std::endl; + assert(mesh); // Write points assert(index_vert.size() <= MAX_VERTICES); @@ -700,7 +733,12 @@ WriterNodeVisitor::buildMesh(osg::Geode & geo, osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry(); assert(g->getVertexArray()); if (g->getVertexArray()->getType() != osg::Array::Vec3ArrayType) - throw "Vertex array is not Vec3. Not implemented"; // TODO + { + // TODO Handle double presision vertices by converting them to float with a warning + OSG_NOTIFY(osg::FATAL) << "Vertex array is not Vec3. Not implemented" << std::endl; + _succeeded = false; + return; + } const osg::Vec3Array & vecs= *static_cast(g->getVertexArray()); copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first]*mat); } @@ -711,12 +749,16 @@ WriterNodeVisitor::buildMesh(osg::Geode & geo, for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end(); ++it) { osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry(); - osg::Array * array = g->getTexCoordArray(0); - if(array) + osg::Array * texarray = g->getTexCoordArray(0); + if (texarray) { if (g->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType) - throw "Texture coords array is not Vec2. Not implemented"; // TODO - const osg::Vec2Array & vecs= *static_cast(array); + { + OSG_NOTIFY(osg::FATAL) << "Texture coords array is not Vec2. Not implemented" << std::endl; + _succeeded = false; + return; + } + const osg::Vec2Array & vecs= *static_cast(texarray); mesh->texcos[it->second][0] = vecs[it->first.first][0]; mesh->texcos[it->second][1] = vecs[it->first.first][1]; } @@ -738,7 +780,12 @@ WriterNodeVisitor::calcVertices(osg::Geode & geo) osg::Geometry *g = geo.getDrawable( i )->asGeometry(); assert(g->getVertexArray()); if (g->getVertexArray()->getType() != osg::Array::Vec3ArrayType) - throw "Vertex array is not Vec3. Not implemented"; // TODO + { + // TODO Handle double presision vertices by converting them to float with a warning + OSG_NOTIFY(osg::FATAL) << "Vertex array is not Vec3. Not implemented" << std::endl; + _succeeded = false; + return 0; + } const osg::Vec3Array & vecs= *static_cast(g->getVertexArray()); numVertice += vecs.getNumElements(); } @@ -752,12 +799,19 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo, ListTriangle & listTriangles, bool texcoords) { - MapIndices index_vert; - Lib3dsMesh *mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo").c_str() ); - if (!mesh) throw "Allocation error"; - unsigned int nbTrianglesRemaining = listTriangles.size(); - unsigned int nbVerticesRemaining = calcVertices(geo); + unsigned int nbVerticesRemaining = calcVertices(geo); // May set _succeded to false + if (!succeeded()) return; + + std::string name( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo") ); + if (!succeeded()) return; + Lib3dsMesh *mesh = lib3ds_mesh_new( name.c_str() ); + if (!mesh) + { + OSG_NOTIFY(osg::FATAL) << "Allocation error" << std::endl; + _succeeded = false; + return; + } lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block @@ -765,11 +819,12 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo, // Test if the mesh will be split and needs sorting if (nbVerticesRemaining >= MAX_VERTICES || nbTrianglesRemaining >= MAX_FACES) { - osg::notify(osg::INFO) << "Sorting elements..." << std::endl; + OSG_NOTIFY(osg::INFO) << "Sorting elements..." << std::endl; WriterCompareTriangle cmp(geo, nbVerticesRemaining); std::sort(listTriangles.begin(), listTriangles.end(), cmp); } + MapIndices index_vert; unsigned int numFace = 0; // Current face index for (ListTriangle::iterator it = listTriangles.begin(); it != listTriangles.end(); ++it) //Go through the triangle list to define meshs { @@ -779,7 +834,12 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo, // Finnish mesh lib3ds_mesh_resize_faces (mesh, numFace); //lib3ds_mesh_resize_vertices() will be called in buildMesh() - buildMesh(geo, mat, index_vert, texcoords, mesh); + buildMesh(geo, mat, index_vert, texcoords, mesh); // May set _succeded to false + if (!succeeded()) + { + lib3ds_mesh_free(mesh); + return; + } // "Reset" values and start over a new mesh index_vert.clear(); @@ -789,7 +849,12 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo, // [Sukender: An optimisation here would take too much time I think.] mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo").c_str()); - if (!mesh) throw "Allocation error"; + if (!mesh) + { + OSG_NOTIFY(osg::FATAL) << "Allocation error" << std::endl; + _succeeded = false; + return; + } lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block } @@ -799,7 +864,13 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo, face.index[2] = getMeshIndexForGeometryIndex(index_vert, it->first.t3, it->second); face.material = it->first.material; } - buildMesh(geo, mat, index_vert, texcoords, mesh); //When a Mesh is completed without restriction of vertices number + + buildMesh(geo, mat, index_vert, texcoords, mesh); // May set _succeded to false + if (!succeeded()) + { + lib3ds_mesh_free(mesh); + return; + } } void @@ -811,19 +882,33 @@ WriterNodeVisitor::createListTriangle(osg::Geometry * geo, unsigned int nbVertices = 0; { if (geo->getVertexArray() && geo->getVertexArray()->getType() != osg::Array::Vec3ArrayType) - throw "Vertex array is not Vec3. Not implemented"; // TODO + { + // TODO Handle double presision vertices by converting them to float with a warning + OSG_NOTIFY(osg::FATAL) << "Vertex array is not Vec3. Not implemented" << std::endl; + _succeeded = false; + return; + } const osg::Vec3Array * vecs = geo->getVertexArray() ? static_cast(geo->getVertexArray()) : NULL; if (vecs) { nbVertices = geo->getVertexArray()->getNumElements(); // Texture coords if (geo->getTexCoordArray(0) && geo->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType) - throw "Texture coords array is not Vec2. Not implemented"; // TODO + { + OSG_NOTIFY(osg::FATAL) << "Texture coords array is not Vec2. Not implemented" << std::endl; + _succeeded = false; + return; + } const osg::Vec2Array * texvecs = geo->getTexCoordArray(0) ? static_cast(geo->getTexCoordArray(0)) : NULL; if (texvecs) { unsigned int nb = geo->getTexCoordArray(0)->getNumElements(); - if (nb != geo->getVertexArray()->getNumElements()) throw "There are more/less texture coords than vertices!"; + if (nb != geo->getVertexArray()->getNumElements()) + { + OSG_NOTIFY(osg::FATAL) << "There are more/less texture coords than vertices (corrupted geometry)" << std::endl; + _succeeded = false; + return; + } texcoords = true; } } @@ -841,18 +926,8 @@ WriterNodeVisitor::createListTriangle(osg::Geometry * geo, } } -bool WriterNodeVisitor::suceedLastApply() const +void WriterNodeVisitor::apply( osg::Geode &node ) { - return _suceedLastApply; -} - -void WriterNodeVisitor::failedApply() -{ - _suceedLastApply = false; - osg::notify(osg::NOTICE) << "Error going through node" << std::endl; -} - -void WriterNodeVisitor::apply( osg::Geode &node ) { pushStateSet(node.getStateSet()); //_nameStack.push_back(node.getName()); unsigned int count = node.getNumDrawables(); @@ -864,22 +939,24 @@ void WriterNodeVisitor::apply( osg::Geode &node ) { if ( g != NULL ) { pushStateSet(g->getStateSet()); - createListTriangle(g, listTriangles, texcoords, i); + createListTriangle(g, listTriangles, texcoords, i); // May set _succeded to false popStateSet(g->getStateSet()); + if (!succeeded()) break; } } - if (count > 0) + if (succeeded() && count > 0) { osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) ); - buildFaces(node, mat, listTriangles, texcoords); + buildFaces(node, mat, listTriangles, texcoords); // May set _succeded to false } popStateSet(node.getStateSet()); //_nameStack.pop_back(); - if (suceedLastApply()) + if (succeeded()) traverse(node); } -void WriterNodeVisitor::apply( osg::Billboard &node ) { +void WriterNodeVisitor::apply( osg::Billboard &node ) +{ // TODO Does not handle Billboards' points yet pushStateSet(node.getStateSet()); @@ -888,7 +965,7 @@ void WriterNodeVisitor::apply( osg::Billboard &node ) { unsigned int count = node.getNumDrawables(); ListTriangle listTriangles; bool texcoords = false; - osg::notify(osg::NOTICE) << "Warning: 3DS writer is incomplete for Billboards (rotation not implemented)." << std::endl; + OSG_NOTIFY(osg::NOTICE) << "Warning: 3DS writer is incomplete for Billboards (rotation not implemented)." << std::endl; osg::Matrix m( osg::computeLocalToWorld(getNodePath()) ); for ( unsigned int i = 0; i < count; i++ ) { @@ -900,15 +977,17 @@ void WriterNodeVisitor::apply( osg::Billboard &node ) { pushStateSet(g->getStateSet()); createListTriangle(g, listTriangles, texcoords, i); - popStateSet(g->getStateSet()); + popStateSet(g->getStateSet()); // May set _succeded to false + if (!succeeded()) break; osg::Matrix currentBillBoardMat(osg::Matrix::translate(node.getPosition(i)) * m); // TODO handle rotation apply3DSMatrixNode(node, currentBillBoardMat, "bil"); // Add a 3DS matrix node - buildFaces(node, currentBillBoardMat, listTriangles, texcoords); + buildFaces(node, currentBillBoardMat, listTriangles, texcoords); // May set _succeded to false + if (!succeeded()) break; } } - if (suceedLastApply()) + if (succeeded()) traverse(node); _cur3dsNode = parent; popStateSet(node.getStateSet()); @@ -921,7 +1000,7 @@ void WriterNodeVisitor::apply(osg::Group &node) pushStateSet(node.getStateSet()); Lib3dsMeshInstanceNode * parent = _cur3dsNode; apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "grp"); - if (suceedLastApply()) + if (succeeded()) traverse(node); _cur3dsNode = parent; popStateSet(node.getStateSet()); @@ -932,7 +1011,7 @@ void WriterNodeVisitor::apply(osg::MatrixTransform &node) pushStateSet(node.getStateSet()); Lib3dsMeshInstanceNode * parent = _cur3dsNode; apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "mtx"); - if (suceedLastApply()) + if (succeeded()) traverse(node); _cur3dsNode = parent; popStateSet(node.getStateSet()); diff --git a/src/osgPlugins/3ds/WriterNodeVisitor.h b/src/osgPlugins/3ds/WriterNodeVisitor.h index ac3cd7097..d55377cf0 100644 --- a/src/osgPlugins/3ds/WriterNodeVisitor.h +++ b/src/osgPlugins/3ds/WriterNodeVisitor.h @@ -58,8 +58,7 @@ class WriterNodeVisitor: public osg::NodeVisitor const osgDB::ReaderWriter::Options* options, const std::string & srcDirectory); - bool suceedLastApply() const; - void failedApply(); + bool succeeded() const { return _succeeded; } virtual void apply(osg::Geode &node); virtual void apply(osg::Billboard &node); @@ -145,8 +144,7 @@ class WriterNodeVisitor: public osg::NodeVisitor * Calculate the number of vertices in the geode. * \return the number of vertices in the geode. */ - unsigned int - calcVertices(osg::Geode & geo); + unsigned int calcVertices(osg::Geode & geo); /** * Build a mesh @@ -197,7 +195,7 @@ class WriterNodeVisitor: public osg::NodeVisitor void apply3DSMatrixNode(osg::Node &node, const osg::Matrix & m, const char * const prefix); - bool _suceedLastApply; + bool _succeeded; std::string _directory; std::string _srcDirectory; Lib3dsFile * file3ds;