From Sukender, "I had some conflicts when updating but they seem resolved now. Attached files (four files) are against rev. 11200. Changelog:

- Replaced exceptions with assert() or OSG_NOTIFY
- Replaced osg::notify() with OSG_NOTIFY
- Changed braces and tabs to fit OSG coding convention
- Cleaned a few things in code (names, added deallocations upon error)"
This commit is contained in:
Robert Osfield 2010-03-11 16:53:35 +00:00
parent 6c07be375c
commit 4dcf21d707
4 changed files with 340 additions and 206 deletions

View File

@ -94,15 +94,18 @@ osg::Matrix copyLib3dsMatrixToOsgMatrix(const Lib3dsMatrix mat)
return osgMatrix; 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]); 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]); 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]); return osg::Quat(quat[0], quat[1], quat[2], quat[3]);
} }
@ -225,22 +228,22 @@ ReaderWriter3DS::ReaderWriter3DS()
setByteOrder(); setByteOrder();
#if 0 #if 0
osg::notify(osg::NOTICE)<<"3DS reader sizes:"<<std::endl; OSG_NOTIFY(osg::NOTICE)<<"3DS reader sizes:"<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsBool)="<<sizeof(Lib3dsBool)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsBool)="<<sizeof(Lib3dsBool)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsByte)="<<sizeof(Lib3dsByte)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsByte)="<<sizeof(Lib3dsByte)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsWord)="<<sizeof(Lib3dsWord)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsWord)="<<sizeof(Lib3dsWord)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsDword)="<<sizeof(Lib3dsDword)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsDword)="<<sizeof(Lib3dsDword)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsIntb)="<<sizeof(Lib3dsIntb)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsIntb)="<<sizeof(Lib3dsIntb)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsIntw)="<<sizeof(Lib3dsIntw)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsIntw)="<<sizeof(Lib3dsIntw)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsIntd)="<<sizeof(Lib3dsIntd)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsIntd)="<<sizeof(Lib3dsIntd)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsFloat)="<<sizeof(Lib3dsFloat)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsFloat)="<<sizeof(Lib3dsFloat)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsDouble)="<<sizeof(Lib3dsDouble)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsDouble)="<<sizeof(Lib3dsDouble)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsVector)="<<sizeof(Lib3dsVector)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsVector)="<<sizeof(Lib3dsVector)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsTexel)="<<sizeof(Lib3dsTexel)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsTexel)="<<sizeof(Lib3dsTexel)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsQuat)="<<sizeof(Lib3dsQuat)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsQuat)="<<sizeof(Lib3dsQuat)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsMatrix)="<<sizeof(Lib3dsMatrix)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsMatrix)="<<sizeof(Lib3dsMatrix)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsRgb)="<<sizeof(Lib3dsRgb)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsRgb)="<<sizeof(Lib3dsRgb)<<std::endl;
osg::notify(osg::NOTICE)<<" sizeof(Lib3dsRgba)="<<sizeof(Lib3dsRgba)<<std::endl; OSG_NOTIFY(osg::NOTICE)<<" sizeof(Lib3dsRgba)="<<sizeof(Lib3dsRgba)<<std::endl;
#endif #endif
} }
@ -253,7 +256,8 @@ ReaderWriter3DS::ReaderObject::ReaderObject(const osgDB::ReaderWriter::Options*
checkForEspilonIdentityMatrices(false), checkForEspilonIdentityMatrices(false),
restoreMatrixTransformsNoMeshes(false) restoreMatrixTransformsNoMeshes(false)
{ {
if (options) { if (options)
{
std::istringstream iss(options->getOptionString()); std::istringstream iss(options->getOptionString());
std::string opt; std::string opt;
while (iss >> opt) while (iss >> opt)
@ -272,7 +276,8 @@ ReaderWriter3DS::ReaderObject::ReaderObject(const osgDB::ReaderWriter::Options*
/** /**
These print methods for 3ds hacking These print methods for 3ds hacking
*/ */
void pad(int level) { void pad(int level)
{
for(int i=0;i<level;i++) std::cout<<" "; for(int i=0;i<level;i++) std::cout<<" ";
} }
void print(Lib3dsMesh *mesh,int level); void print(Lib3dsMesh *mesh,int level);
@ -280,42 +285,56 @@ void print(Lib3dsUserData *user,int level);
void print(Lib3dsMeshInstanceNode *object,int level); void print(Lib3dsMeshInstanceNode *object,int level);
void print(Lib3dsNode *node, int level); void print(Lib3dsNode *node, int level);
void print(Lib3dsMatrix matrix,int level) { void print(Lib3dsMatrix matrix,int level)
{
pad(level); cout << matrix[0][0] <<" "<< matrix[0][1] <<" "<< matrix[0][2] <<" "<< matrix[0][3] << endl; pad(level); cout << matrix[0][0] <<" "<< matrix[0][1] <<" "<< matrix[0][2] <<" "<< matrix[0][3] << endl;
pad(level); cout << matrix[1][0] <<" "<< matrix[1][1] <<" "<< matrix[1][2] <<" "<< matrix[1][3] << endl; pad(level); cout << matrix[1][0] <<" "<< matrix[1][1] <<" "<< matrix[1][2] <<" "<< matrix[1][3] << endl;
pad(level); cout << matrix[2][0] <<" "<< matrix[2][1] <<" "<< matrix[2][2] <<" "<< matrix[2][3] << endl; pad(level); cout << matrix[2][0] <<" "<< matrix[2][1] <<" "<< matrix[2][2] <<" "<< matrix[2][3] << endl;
pad(level); cout << matrix[3][0] <<" "<< matrix[3][1] <<" "<< matrix[3][2] <<" "<< matrix[3][3] << endl; pad(level); cout << matrix[3][0] <<" "<< matrix[3][1] <<" "<< matrix[3][2] <<" "<< matrix[3][3] << endl;
} }
void print(Lib3dsMesh *mesh,int level) { void print(Lib3dsMesh *mesh,int level)
if (mesh) { {
if (mesh)
{
pad(level); cout << "mesh name " << mesh->name << endl; pad(level); cout << "mesh name " << mesh->name << endl;
print(mesh->matrix,level); print(mesh->matrix,level);
} else { }
else
{
pad(level); cout << "no mesh " << endl; pad(level); cout << "no mesh " << endl;
} }
} }
void print(Lib3dsUserData *user,int level) { void print(Lib3dsUserData *user,int level)
if (user) { {
if (user)
{
pad(level); cout << "user data" << endl; pad(level); cout << "user data" << endl;
//print(user->mesh,level+1); //print(user->mesh,level+1);
} else { }
else
{
pad(level); cout << "no user data" << endl; pad(level); cout << "no user data" << endl;
} }
} }
void print(Lib3dsMeshInstanceNode *object,int level) { void print(Lib3dsMeshInstanceNode *object,int level)
if (object) { {
if (object)
{
pad(level); cout << "objectdata instance [" << object->instance_name << "]" << endl; 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 << "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 << "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 << "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; 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; 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 name [" << node->name << "]" << endl;
pad(level); cout << "node id " << node->user_id << 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; pad(level); cout << "node matrix:" << endl;
print(node->matrix,level+1); 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; pad(level); cout << "mesh instance data:" << endl;
print(reinterpret_cast<Lib3dsMeshInstanceNode *>(node),level+1); print(reinterpret_cast<Lib3dsMeshInstanceNode *>(node),level+1);
} else { }
else
{
pad(level); cout << "node is not a mesh instance (not handled)" << endl; pad(level); cout << "node is not a mesh instance (not handled)" << endl;
} }
print(&node->user_ptr,level); 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); 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 // 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 // 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 // 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<FaceList> MaterialFaceMap; typedef std::vector<FaceList> MaterialFaceMap;
MaterialFaceMap materialFaceMap; MaterialFaceMap materialFaceMap;
unsigned int numMaterials = drawStateMap.size(); unsigned int numMaterials = drawStateMap.size();
@ -394,16 +418,19 @@ osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,
FaceList defaultMaterialFaceList; FaceList defaultMaterialFaceList;
for (unsigned int i=0; i<mesh->nfaces; ++i) for (unsigned int i=0; i<mesh->nfaces; ++i)
{ {
if (mesh->faces[i].material>=0) { if (mesh->faces[i].material>=0)
{
materialFaceMap[mesh->faces[i].material].push_back(i); materialFaceMap[mesh->faces[i].material].push_back(i);
} }
else else
{
defaultMaterialFaceList.push_back(i); defaultMaterialFaceList.push_back(i);
} }
}
if (materialFaceMap.empty() && defaultMaterialFaceList.empty()) if (materialFaceMap.empty() && defaultMaterialFaceList.empty())
{ {
osg::notify(osg::NOTICE)<<"Warning : no triangles assigned to mesh '"<<mesh->name<<"'"<< std::endl; OSG_NOTIFY(osg::NOTICE)<<"Warning : no triangles assigned to mesh '"<<mesh->name<<"'"<< std::endl;
//osg::notify(osg::INFO) << "No material assigned to mesh '" << mesh->name << "'" << std::endl; //OSG_NOTIFY(osg::INFO) << "No material assigned to mesh '" << mesh->name << "'" << std::endl;
return NULL; return NULL;
} }
else else
@ -472,8 +499,10 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L
bool pivoted = pivot.x()!=0 || pivot.y()!=0 || pivot.z()!=0; bool pivoted = pivot.x()!=0 || pivot.y()!=0 || pivot.z()!=0;
osg::Matrix meshMat; osg::Matrix meshMat;
if (mesh) { if (mesh)
if (!noMatrixTransforms) { {
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 // 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) { if (!pivoted) {
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)); meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix));
@ -492,21 +521,27 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L
} }
bool isOsgNodeMatrixIdentity = false; bool isOsgNodeMatrixIdentity = false;
if (osgNodeMatrix.isIdentity() || (checkForEspilonIdentityMatrices && isIdentityEquivalent(osgNodeMatrix, MATRIX_EPSILON))) { if (osgNodeMatrix.isIdentity() || (checkForEspilonIdentityMatrices && isIdentityEquivalent(osgNodeMatrix, MATRIX_EPSILON)))
{
isOsgNodeMatrixIdentity = true; isOsgNodeMatrixIdentity = true;
} }
//if (node->childs != NULL || pivoted || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) { //if (node->childs != NULL || pivoted || (!isOsgNodeMatrixIdentity && !noMatrixTransforms))
if (node->childs != NULL || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) { if (node->childs != NULL || (!isOsgNodeMatrixIdentity && !noMatrixTransforms))
if (isOsgNodeMatrixIdentity || noMatrixTransforms) { {
if (isOsgNodeMatrixIdentity || noMatrixTransforms)
{
group = new osg::Group; group = new osg::Group;
} else { }
else
{
group = new osg::MatrixTransform(osgNodeMatrix); group = new osg::MatrixTransform(osgNodeMatrix);
} }
} }
if (group) { if (group)
{
if (strcmp(node->name, "$$$DUMMY") == 0) if (strcmp(node->name, "$$$DUMMY") == 0)
{ {
if (node->type == LIB3DS_NODE_MESH_INSTANCE) if (node->type == LIB3DS_NODE_MESH_INSTANCE)
@ -516,32 +551,42 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L
group->setName(node->name); group->setName(node->name);
// Handle all children of this node for hierarchical assemblies // 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)); group->addChild(processNode(drawStateMap,f,p));
} }
} else { }
else
{
assert(node->childs == NULL); // Else we must have a group to put childs into assert(node->childs == NULL); // Else we must have a group to put childs into
} }
// Handle mesh // Handle mesh
if (mesh) { if (mesh)
{
osg::Matrix * meshAppliedMatPtr = NULL; osg::Matrix * meshAppliedMatPtr = NULL;
if (!meshMat.isIdentity() && !(checkForEspilonIdentityMatrices && isIdentityEquivalent(meshMat, MATRIX_EPSILON))) { if (!meshMat.isIdentity() && !(checkForEspilonIdentityMatrices && isIdentityEquivalent(meshMat, MATRIX_EPSILON)))
{
meshAppliedMatPtr = &meshMat; meshAppliedMatPtr = &meshMat;
} }
if(group) { if (group)
{
// add our geometry to group (where our children already are) // add our geometry to group (where our children already are)
// creates geometry under modifier node // creates geometry under modifier node
processMesh(drawStateMap,group,mesh,meshAppliedMatPtr); processMesh(drawStateMap,group,mesh,meshAppliedMatPtr);
return group; return group;
} else { }
else
{
// didnt use group for children // didnt use group for children
// return a ptr directly to the Geode for this mesh // return a ptr directly to the Geode for this mesh
return processMesh(drawStateMap,NULL,mesh,meshAppliedMatPtr); return processMesh(drawStateMap,NULL,mesh,meshAppliedMatPtr);
} }
} else { }
else
{
// no mesh for this node - probably a camera or something of that persuasion // no mesh for this node - probably a camera or something of that persuasion
//cout << "no mesh for object " << node->name << endl; //cout << "no mesh for object " << node->name << endl;
return group; // we have no mesh, but we might have children 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<std::istream*>(self); std::istream *f = reinterpret_cast<std::istream*>(self);
ios_base::seekdir o = ios_base::beg; ios_base::seekdir o = ios_base::beg;
if (origin == LIB3DS_SEEK_CUR) o = ios_base::cur; 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; 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<std::ostream*>(self); std::ostream *f = reinterpret_cast<std::ostream*>(self);
ios_base::seekdir o = ios_base::beg; ios_base::seekdir o = ios_base::beg;
if (origin == LIB3DS_SEEK_CUR) o = ios_base::cur; 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; return f->fail() ? -1 : 0;
} }
static long filei_tell_func(void *self) { static long filei_tell_func(void *self)
{
std::istream *f = reinterpret_cast<std::istream*>(self); std::istream *f = reinterpret_cast<std::istream*>(self);
return f->tellg(); return f->tellg();
} }
static long fileo_tell_func(void *self) { static long fileo_tell_func(void *self)
{
std::ostream *f = reinterpret_cast<std::ostream*>(self); std::ostream *f = reinterpret_cast<std::ostream*>(self);
return f->tellp(); 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<std::istream*>(self); std::istream *f = reinterpret_cast<std::istream*>(self);
f->read(reinterpret_cast<char*>(buffer), size); f->read(reinterpret_cast<char*>(buffer), size);
return f->gcount(); 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<std::ostream*>(self); std::ostream *f = reinterpret_cast<std::ostream*>(self);
f->write(static_cast<const char*>(buffer), size); f->write(static_cast<const char*>(buffer), size);
return f->fail() ? 0 : 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_WARN) l = osg::NOTICE;
else if (level == LIB3DS_LOG_INFO) l = osg::INFO; else if (level == LIB3DS_LOG_INFO) l = osg::INFO;
else if (level == LIB3DS_LOG_DEBUG) l = osg::DEBUG_INFO; else if (level == LIB3DS_LOG_DEBUG) l = osg::DEBUG_INFO;
osg::notify(l) << msg << std::endl; OSG_NOTIFY(l) << msg << std::endl;
} }
@ -699,7 +750,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriter3DS::constructFrom3dsFile(Lib3dsFile
{ {
int level=0; int level=0;
std::cout << "NODE TRAVERSAL of 3ds file "<<f->name<<std::endl; std::cout << "NODE TRAVERSAL of 3ds file "<<f->name<<std::endl;
for(Lib3dsNode *node=f->nodes; node; node=node->next) { for(Lib3dsNode *node=f->nodes; node; node=node->next)
{
print(node,level+1); print(node,level+1);
} }
std::cout << "MESH TRAVERSAL of 3ds file "<<f->name<<std::endl; std::cout << "MESH TRAVERSAL of 3ds file "<<f->name<<std::endl;
@ -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 // 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? // 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) { if (f->nodes == NULL)
osg::notify(osg::WARN)<<"Warning: in 3ds loader: file has no nodes, traversing by meshes instead"<< std::endl; {
OSG_NOTIFY(osg::WARN)<<"Warning: in 3ds loader: file has no nodes, traversing by meshes instead"<< std::endl;
traverse_nodes=true; traverse_nodes=true;
} }
osg::Node* group = NULL; osg::Node* group = NULL;
if (traverse_nodes) { // old method if (traverse_nodes) // old method
{
group = new osg::Group(); group = new osg::Group();
for (int imesh=0; imesh<f->nmeshes; ++imesh) { for (int imesh=0; imesh<f->nmeshes; ++imesh)
{
reader.processMesh(drawStateMap,group->asGroup(),f->meshes[imesh],NULL); reader.processMesh(drawStateMap,group->asGroup(),f->meshes[imesh],NULL);
} }
} else { // new method }
else
{ // new method
Lib3dsNode *node=f->nodes; Lib3dsNode *node=f->nodes;
if (!node->next) if (!node->next)
{
group = reader.processNode(drawStateMap,f,node); group = reader.processNode(drawStateMap,f,node);
}
else else
{ {
group = new osg::Group(); group = new osg::Group();
for(; node; node=node->next) { for(; node; node=node->next)
{
group->asGroup()->addChild(reader.processNode(drawStateMap,f,node)); group->asGroup()->addChild(reader.processNode(drawStateMap,f,node));
} }
} }
@ -743,7 +803,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriter3DS::constructFrom3dsFile(Lib3dsFile
if (osg::getNotifyLevel()>=osg::INFO) 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)); PrintVisitor pv(osg::notify(osg::NOTICE));
group->accept(pv); group->accept(pv);
} }
@ -902,14 +962,14 @@ osg::Texture2D* ReaderWriter3DS::ReaderObject::createTexture(Lib3dsTextureMap *
{ {
if (texture && *(texture->name)) if (texture && *(texture->name))
{ {
osg::notify(osg::INFO)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl; OSG_NOTIFY(osg::INFO)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl;
std::string fileName = osgDB::findFileInDirectory(texture->name,_directory,osgDB::CASE_INSENSITIVE); std::string fileName = osgDB::findFileInDirectory(texture->name,_directory,osgDB::CASE_INSENSITIVE);
if (fileName.empty()) if (fileName.empty())
{ {
// file not found in .3ds file's directory, so we'll look in the datafile path list. // 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); fileName = osgDB::findDataFile(texture->name,options, osgDB::CASE_INSENSITIVE);
osg::notify(osg::INFO)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl; OSG_NOTIFY(osg::INFO)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl;
} }
if (fileName.empty()) if (fileName.empty())
@ -918,30 +978,33 @@ osg::Texture2D* ReaderWriter3DS::ReaderObject::createTexture(Lib3dsTextureMap *
{ {
// if 3DS file is loaded from http, just attempt to load texture from same location. // if 3DS file is loaded from http, just attempt to load texture from same location.
fileName = _directory + "/" + texture->name; fileName = _directory + "/" + texture->name;
} else { }
osg::notify(osg::WARN) << "texture '"<<texture->name<<"' not found"<< std::endl; else
{
OSG_NOTIFY(osg::WARN) << "texture '"<<texture->name<<"' not found"<< std::endl;
return NULL; return NULL;
} }
} }
if (label) osg::notify(osg::DEBUG_INFO) << label; if (label) { OSG_NOTIFY(osg::DEBUG_INFO) << label; }
else osg::notify(osg::DEBUG_INFO) << "texture name"; else { OSG_NOTIFY(osg::DEBUG_INFO) << "texture name"; }
osg::notify(osg::DEBUG_INFO) << " '"<<texture->name<<"'"<< std::endl;
osg::notify(osg::DEBUG_INFO) << " texture flag "<<texture->flags<< std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << " '"<<texture->name<<"'"<< std::endl;
osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_DECALE "<<((texture->flags)&LIB3DS_TEXTURE_DECALE)<< std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << " texture flag "<<texture->flags<< std::endl;
osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_MIRROR "<<((texture->flags)&LIB3DS_TEXTURE_MIRROR)<< std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_DECALE "<<((texture->flags)&LIB3DS_TEXTURE_DECALE)<< std::endl;
osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_NEGATE "<<((texture->flags)&LIB3DS_TEXTURE_NEGATE)<< std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_MIRROR "<<((texture->flags)&LIB3DS_TEXTURE_MIRROR)<< 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_NEGATE "<<((texture->flags)&LIB3DS_TEXTURE_NEGATE)<< 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_NO_TILE "<<((texture->flags)&LIB3DS_TEXTURE_NO_TILE)<< 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_SUMMED_AREA "<<((texture->flags)&LIB3DS_TEXTURE_SUMMED_AREA)<< std::endl;
osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_TINT "<<((texture->flags)&LIB3DS_TEXTURE_TINT)<< 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_IGNORE_ALPHA "<<((texture->flags)&LIB3DS_TEXTURE_IGNORE_ALPHA)<< std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_TINT "<<((texture->flags)&LIB3DS_TEXTURE_TINT)<< std::endl;
osg::notify(osg::DEBUG_INFO) << " LIB3DS_TEXTURE_RGB_TINT "<<((texture->flags)&LIB3DS_TEXTURE_RGB_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> osg_image = osgDB::readRefImageFile(fileName.c_str(), options); //Absolute Path osg::ref_ptr<osg::Image> osg_image = osgDB::readRefImageFile(fileName.c_str(), options); //Absolute Path
if (!osg_image.valid()) if (!osg_image.valid())
{ {
osg::notify(osg::NOTICE) << "Warning: Cannot create texture "<<texture->name<< std::endl; OSG_NOTIFY(osg::NOTICE) << "Warning: Cannot create texture "<<texture->name<< std::endl;
return NULL; return NULL;
} }
if (osg_image->getFileName().empty()) // it should be done in OSG with osgDB::readRefImageFile(fileName.c_str()); 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); std::string ext = osgDB::getLowerCaseFileExtension(fileName);
if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; 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(); Lib3dsFile * file3ds = lib3ds_file_new();
if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE); if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE);
try {
osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false; if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false;
if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false; if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false;
} catch (...) {
lib3ds_file_free(file3ds);
throw;
}
lib3ds_file_free(file3ds); lib3ds_file_free(file3ds);
return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE); 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 { 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; {
//OSG_NOTIFY(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl;
std::string optFileName; std::string optFileName;
if (options) { if (options)
{
optFileName = options->getPluginStringData("STREAM_FILENAME"); optFileName = options->getPluginStringData("STREAM_FILENAME");
} }
return doWriteNode(node, fout, options, optFileName); 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<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileNamelib3ds)); 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); if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE);
bool ok = true; bool ok = true;
try {
if (!createFileObject(node, file3ds, fileNamelib3ds, local_opt.get())) ok = false; if (!createFileObject(node, file3ds, fileNamelib3ds, local_opt.get())) ok = false;
if (ok && !lib3ds_file_write(file3ds, &io)) ok = false; if (ok && !lib3ds_file_write(file3ds, &io)) ok = false;
} catch (...) {
lib3ds_file_free(file3ds);
throw;
}
lib3ds_file_free(file3ds); lib3ds_file_free(file3ds);
return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE); return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE);
//return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::FILE_NOT_HANDLED); //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())); WriterNodeVisitor w(file3ds, fileName, options, osgDB::getFilePath(node.getName()));
const_cast<osg::Node &>(node).accept(w); // Ugly const_cast<> for visitor... const_cast<osg::Node &>(node).accept(w); // Ugly const_cast<> for visitor...
if (!w.suceedLastApply()) if (!w.succeeded()) return false;
return false;
w.writeMaterials(); w.writeMaterials();
return true; //w.good(); return w.succeeded();
} }

View File

@ -1,4 +1,5 @@
#include "WriterCompareTriangle.h" #include "WriterCompareTriangle.h"
#include <assert.h>
WriterCompareTriangle::WriterCompareTriangle(const osg::Geode & geode, unsigned int nbVertices) : geode(geode) 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 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 x by " << nbVerticesX << std::endl
<< "Cutting y by " << nbVerticesY << std::endl << "Cutting y by " << nbVerticesY << std::endl
<< "Cutting z by " << nbVerticesZ << std::endl; << "Cutting z by " << nbVerticesZ << std::endl;
@ -128,7 +129,8 @@ WriterCompareTriangle::inWhichBox(const osg::BoundingBox::value_type x,
return i; 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 { int WriterCompareTriangle::inWhichBox(const osg::BoundingBox::vec_type & point) const {

View File

@ -25,7 +25,8 @@
void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix) 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][0] = osg_matrix.ptr()[row*4+0];
lib3ds_matrix[row][1] = osg_matrix.ptr()[row*4+1]; lib3ds_matrix[row][1] = osg_matrix.ptr()[row*4+1];
lib3ds_matrix[row][2] = osg_matrix.ptr()[row*4+2]; 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[0] = osg_vector[0];
lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[1] = osg_vector[1];
lib3ds_vector[2] = osg_vector[2]; 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[0] = osg_vector[0];
lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[1] = osg_vector[1];
lib3ds_vector[2] = osg_vector[2]; 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[0] = osg_vector[0];
lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[1] = osg_vector[1];
lib3ds_vector[2] = osg_vector[2]; 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[0] = osg_vector[0];
lib3ds_vector[1] = osg_vector[1]; lib3ds_vector[1] = osg_vector[1];
lib3ds_vector[2] = osg_vector[2]; 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[0] = osg_quat[3]; // Not sure
//lib3ds_vector[1] = osg_quat[0]; //lib3ds_vector[1] = osg_quat[0];
//lib3ds_vector[2] = osg_quat[1]; //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<float>(-angle); lib3ds_vector[3] = static_cast<float>(-angle);
} }
std::string getFileName(const std::string & path) { std::string getFileName(const std::string & path)
{
unsigned int slashPos = path.find_last_of("/\\"); unsigned int slashPos = path.find_last_of("/\\");
if (slashPos == std::string::npos) return path; if (slashPos == std::string::npos) return path;
return path.substr(slashPos+1); 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). /// 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 // 012345678901
// ABCDEFGH.ABC // ABCDEFGH.ABC
if (s.find_first_of("/\\") != std::string::npos) return false; // It should not be a path, but a filename 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). /// 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(); unsigned int len = s.length();
if (len >= 64 || len == 0) return false; if (len >= 64 || len == 0) return false;
if (extendedFilePaths) return true; // Extended paths are simply those that fits the 64 bytes buffer! 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 */ /** 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: public:
PrimitiveIndexWriter(osg::Geometry * geo, PrimitiveIndexWriter(osg::Geometry * geo,
ListTriangle & listTriangles, ListTriangle & listTriangles,
@ -340,7 +350,7 @@ void PrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
case(GL_LINE_LOOP): case(GL_LINE_LOOP):
//break; //break;
default: 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; break;
} }
} }
@ -361,7 +371,8 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg
{ {
//static unsigned int s_objmaterial_id = 0; //static unsigned int s_objmaterial_id = 0;
//++s_objmaterial_id; //++s_objmaterial_id;
if (mat) { if (mat)
{
assert(stateset); assert(stateset);
diffuse = mat->getDiffuse(osg::Material::FRONT); diffuse = mat->getDiffuse(osg::Material::FRONT);
ambient = mat->getAmbient(osg::Material::FRONT); ambient = mat->getAmbient(osg::Material::FRONT);
@ -370,24 +381,30 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg
transparency = 1-diffuse.w(); transparency = 1-diffuse.w();
name = writerNodeVisitor.getUniqueName(mat->getName(),"mat"); name = writerNodeVisitor.getUniqueName(mat->getName(),"mat");
osg::StateAttribute * attribute = stateset->getAttribute(osg::StateAttribute::CULLFACE); osg::StateAttribute * attribute = stateset->getAttribute(osg::StateAttribute::CULLFACE);
if (!attribute) { if (!attribute)
{
double_sided = true; double_sided = true;
} else { }
else
{
assert(dynamic_cast<osg::CullFace *>(attribute)); assert(dynamic_cast<osg::CullFace *>(attribute));
osg::CullFace::Mode mode = static_cast<osg::CullFace *>(attribute)->getMode(); osg::CullFace::Mode mode = static_cast<osg::CullFace *>(attribute)->getMode();
if (mode == osg::CullFace::BACK) double_sided = false; if (mode == osg::CullFace::BACK) double_sided = false;
else if (mode == osg::CullFace::FRONT) { else if (mode == osg::CullFace::FRONT)
osg::notify(osg::WARN) << "3DS Writer: Reversed face (culled FRONT) not supported yet." << std::endl; {
OSG_NOTIFY(osg::WARN) << "3DS Writer: Reversed face (culled FRONT) not supported yet." << std::endl;
double_sided = false; double_sided = false;
} }
else { else
{
assert(mode == osg::CullFace::FRONT_AND_BACK); 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; double_sided = false;
} }
} }
} }
if (tex) { if (tex)
{
osg::Image* img = tex->getImage(0); osg::Image* img = tex->getImage(0);
if(img) if(img)
{ {
@ -397,7 +414,8 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg
} }
} }
if (name.empty()) { if (name.empty())
{
std::stringstream ss; std::stringstream ss;
ss << "m" << index; ss << "m" << index;
name = ss.str(); name = ss.str();
@ -465,7 +483,7 @@ WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & f
const osgDB::ReaderWriter::Options* options, const osgDB::ReaderWriter::Options* options,
const std::string & srcDirectory) : const std::string & srcDirectory) :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_suceedLastApply(true), _succeeded(true),
_srcDirectory(srcDirectory), _srcDirectory(srcDirectory),
file3ds(file3ds), file3ds(file3ds),
_currentStateSet(new osg::StateSet()), _currentStateSet(new osg::StateSet()),
@ -479,7 +497,8 @@ WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & f
if (!fileName.empty()) if (!fileName.empty())
_directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front(); _directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front();
if (options) { if (options)
{
std::istringstream iss(options->getOptionString()); std::istringstream iss(options->getOptionString());
std::string opt; std::string opt;
while (iss >> opt) while (iss >> opt)
@ -523,12 +542,14 @@ void WriterNodeVisitor::writeMaterials()
oss << "Image_" << _imageCount++ << ".rgb"; oss << "Image_" << _imageCount++ << ".rgb";
path = oss.str(); path = oss.str();
} }
else { else
{
path = getPathRelative(_srcDirectory, mat.image->getFileName()); path = getPathRelative(_srcDirectory, mat.image->getFileName());
} }
path = convertExt(path, _extendedFilePaths); path = convertExt(path, _extendedFilePaths);
if(!is3DSpath(path, _extendedFilePaths)) { if(!is3DSpath(path, _extendedFilePaths))
{
path = getUniqueName(path, "", true); path = getUniqueName(path, "", true);
//path = osgDB::getSimpleFileName(path); //path = osgDB::getSimpleFileName(path);
} }
@ -546,24 +567,26 @@ void WriterNodeVisitor::writeMaterials()
if (mat.texture_transparency) tex.flags |= LIB3DS_TEXTURE_ALPHA_SOURCE; if (mat.texture_transparency) tex.flags |= LIB3DS_TEXTURE_ALPHA_SOURCE;
if (mat.texture_no_tile) tex.flags |= LIB3DS_TEXTURE_NO_TILE; if (mat.texture_no_tile) tex.flags |= LIB3DS_TEXTURE_NO_TILE;
} }
if (!suceedLastApply()) if (!succeeded())
return; return;
lib3ds_file_insert_material(file3ds, mat3ds, itr->second.index); lib3ds_file_insert_material(file3ds, mat3ds, itr->second.index);
break; // Ugly thing (3) 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) { 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. 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 // Tests if default name is valid and unique
bool defaultIs83 = is83(_defaultValue); bool defaultIs83 = is83(_defaultValue);
bool defaultIsValid = nameIsPath ? is3DSpath(_defaultValue, _extendedFilePaths) : defaultIs83; bool defaultIsValid = nameIsPath ? is3DSpath(_defaultValue, _extendedFilePaths) : defaultIs83;
if (defaultIsValid && _nameMap.find(_defaultValue) == _nameMap.end()) { if (defaultIsValid && _nameMap.find(_defaultValue) == _nameMap.end())
{
_nameMap.insert(_defaultValue); _nameMap.insert(_defaultValue);
return _defaultValue; return _defaultValue;
} }
@ -610,18 +633,23 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, c
} }
unsigned int searchStart = 0; unsigned int searchStart = 0;
if (pairPrefix != _mapPrefix.end()) { if (pairPrefix != _mapPrefix.end())
{
searchStart = pairPrefix->second; searchStart = pairPrefix->second;
} }
for(unsigned int i = searchStart; i <= max_val; ++i) { for(unsigned int i = searchStart; i <= max_val; ++i)
{
std::stringstream ss; std::stringstream ss;
ss << defaultPrefix << i; ss << defaultPrefix << i;
const std::string & res = ss.str(); const std::string & res = ss.str();
if (_nameMap.find(res) == _nameMap.end()) { if (_nameMap.find(res) == _nameMap.end())
if (pairPrefix != _mapPrefix.end()) { {
if (pairPrefix != _mapPrefix.end())
{
pairPrefix->second = i + 1; pairPrefix->second = i + 1;
} else { } else
{
_mapPrefix.insert(std::pair<std::string, unsigned int>(defaultPrefix, i + 1)); _mapPrefix.insert(std::pair<std::string, unsigned int>(defaultPrefix, i + 1));
} }
_nameMap.insert(res); _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); if (defaultPrefix.length()>1) return getUniqueName(_defaultValue, defaultPrefix.substr(0, defaultPrefix.length()-1), nameIsPath);
// Try with default prefix if not arleady done // Try with default prefix if not arleady done
if (defaultPrefix != std::string("_")) return getUniqueName(_defaultValue, "_", nameIsPath); 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) int WriterNodeVisitor::processStateSet(osg::StateSet* ss)
{ {
MaterialMap::const_iterator itr = _materialMap.find(ss); MaterialMap::const_iterator itr = _materialMap.find(ss);
if (itr != _materialMap.end()) { if (itr != _materialMap.end())
{
assert(itr->second.index>=0); assert(itr->second.index>=0);
return itr->second.index; return itr->second.index;
} }
@ -671,7 +704,8 @@ WriterNodeVisitor::getMeshIndexForGeometryIndex(MapIndices & index_vert,
unsigned int drawable_n) unsigned int drawable_n)
{ {
MapIndices::iterator itIndex = index_vert.find(std::pair<unsigned int, unsigned int>(index, drawable_n)); MapIndices::iterator itIndex = index_vert.find(std::pair<unsigned int, unsigned int>(index, drawable_n));
if (itIndex == index_vert.end()) { if (itIndex == index_vert.end())
{
unsigned int indexMesh = index_vert.size(); unsigned int indexMesh = index_vert.size();
index_vert.insert(std::make_pair(std::pair<unsigned int, unsigned int>(index, drawable_n), indexMesh)); index_vert.insert(std::make_pair(std::pair<unsigned int, unsigned int>(index, drawable_n), indexMesh));
return indexMesh; return indexMesh;
@ -687,9 +721,8 @@ WriterNodeVisitor::buildMesh(osg::Geode & geo,
bool texcoords, bool texcoords,
Lib3dsMesh * mesh) Lib3dsMesh * mesh)
{ {
osg::notify(osg::DEBUG_INFO) << "Building Mesh" << std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << "Building Mesh" << std::endl;
assert(mesh);
if (!mesh) throw "Allocation error"; // TODO
// Write points // Write points
assert(index_vert.size() <= MAX_VERTICES); assert(index_vert.size() <= MAX_VERTICES);
@ -700,7 +733,12 @@ WriterNodeVisitor::buildMesh(osg::Geode & geo,
osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry(); osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry();
assert(g->getVertexArray()); assert(g->getVertexArray());
if (g->getVertexArray()->getType() != osg::Array::Vec3ArrayType) 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<osg::Vec3Array *>(g->getVertexArray()); const osg::Vec3Array & vecs= *static_cast<osg::Vec3Array *>(g->getVertexArray());
copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first]*mat); 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) for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end(); ++it)
{ {
osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry(); osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry();
osg::Array * array = g->getTexCoordArray(0); osg::Array * texarray = g->getTexCoordArray(0);
if(array) if (texarray)
{ {
if (g->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType) if (g->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType)
throw "Texture coords array is not Vec2. Not implemented"; // TODO {
const osg::Vec2Array & vecs= *static_cast<osg::Vec2Array *>(array); OSG_NOTIFY(osg::FATAL) << "Texture coords array is not Vec2. Not implemented" << std::endl;
_succeeded = false;
return;
}
const osg::Vec2Array & vecs= *static_cast<osg::Vec2Array *>(texarray);
mesh->texcos[it->second][0] = vecs[it->first.first][0]; mesh->texcos[it->second][0] = vecs[it->first.first][0];
mesh->texcos[it->second][1] = vecs[it->first.first][1]; 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(); osg::Geometry *g = geo.getDrawable( i )->asGeometry();
assert(g->getVertexArray()); assert(g->getVertexArray());
if (g->getVertexArray()->getType() != osg::Array::Vec3ArrayType) 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<osg::Vec3Array *>(g->getVertexArray()); const osg::Vec3Array & vecs= *static_cast<osg::Vec3Array *>(g->getVertexArray());
numVertice += vecs.getNumElements(); numVertice += vecs.getNumElements();
} }
@ -752,12 +799,19 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo,
ListTriangle & listTriangles, ListTriangle & listTriangles,
bool texcoords) 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 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_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 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 // Test if the mesh will be split and needs sorting
if (nbVerticesRemaining >= MAX_VERTICES || nbTrianglesRemaining >= MAX_FACES) 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); WriterCompareTriangle cmp(geo, nbVerticesRemaining);
std::sort(listTriangles.begin(), listTriangles.end(), cmp); std::sort(listTriangles.begin(), listTriangles.end(), cmp);
} }
MapIndices index_vert;
unsigned int numFace = 0; // Current face index 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 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 // Finnish mesh
lib3ds_mesh_resize_faces (mesh, numFace); lib3ds_mesh_resize_faces (mesh, numFace);
//lib3ds_mesh_resize_vertices() will be called in buildMesh() //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 // "Reset" values and start over a new mesh
index_vert.clear(); index_vert.clear();
@ -789,7 +849,12 @@ WriterNodeVisitor::buildFaces(osg::Geode & geo,
// [Sukender: An optimisation here would take too much time I think.] // [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()); 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_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 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.index[2] = getMeshIndexForGeometryIndex(index_vert, it->first.t3, it->second);
face.material = it->first.material; 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 void
@ -811,19 +882,33 @@ WriterNodeVisitor::createListTriangle(osg::Geometry * geo,
unsigned int nbVertices = 0; unsigned int nbVertices = 0;
{ {
if (geo->getVertexArray() && geo->getVertexArray()->getType() != osg::Array::Vec3ArrayType) 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<osg::Vec3Array *>(geo->getVertexArray()) : NULL; const osg::Vec3Array * vecs = geo->getVertexArray() ? static_cast<osg::Vec3Array *>(geo->getVertexArray()) : NULL;
if (vecs) if (vecs)
{ {
nbVertices = geo->getVertexArray()->getNumElements(); nbVertices = geo->getVertexArray()->getNumElements();
// Texture coords // Texture coords
if (geo->getTexCoordArray(0) && geo->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType) 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<osg::Vec2Array *>(geo->getTexCoordArray(0)) : NULL; const osg::Vec2Array * texvecs = geo->getTexCoordArray(0) ? static_cast<osg::Vec2Array *>(geo->getTexCoordArray(0)) : NULL;
if (texvecs) if (texvecs)
{ {
unsigned int nb = geo->getTexCoordArray(0)->getNumElements(); 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; 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()); pushStateSet(node.getStateSet());
//_nameStack.push_back(node.getName()); //_nameStack.push_back(node.getName());
unsigned int count = node.getNumDrawables(); unsigned int count = node.getNumDrawables();
@ -864,22 +939,24 @@ void WriterNodeVisitor::apply( osg::Geode &node ) {
if ( g != NULL ) if ( g != NULL )
{ {
pushStateSet(g->getStateSet()); pushStateSet(g->getStateSet());
createListTriangle(g, listTriangles, texcoords, i); createListTriangle(g, listTriangles, texcoords, i); // May set _succeded to false
popStateSet(g->getStateSet()); popStateSet(g->getStateSet());
if (!succeeded()) break;
} }
} }
if (count > 0) if (succeeded() && count > 0)
{ {
osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) ); osg::Matrix mat( osg::computeLocalToWorld(getNodePath()) );
buildFaces(node, mat, listTriangles, texcoords); buildFaces(node, mat, listTriangles, texcoords); // May set _succeded to false
} }
popStateSet(node.getStateSet()); popStateSet(node.getStateSet());
//_nameStack.pop_back(); //_nameStack.pop_back();
if (suceedLastApply()) if (succeeded())
traverse(node); traverse(node);
} }
void WriterNodeVisitor::apply( osg::Billboard &node ) { void WriterNodeVisitor::apply( osg::Billboard &node )
{
// TODO Does not handle Billboards' points yet // TODO Does not handle Billboards' points yet
pushStateSet(node.getStateSet()); pushStateSet(node.getStateSet());
@ -888,7 +965,7 @@ void WriterNodeVisitor::apply( osg::Billboard &node ) {
unsigned int count = node.getNumDrawables(); unsigned int count = node.getNumDrawables();
ListTriangle listTriangles; ListTriangle listTriangles;
bool texcoords = false; 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()) ); osg::Matrix m( osg::computeLocalToWorld(getNodePath()) );
for ( unsigned int i = 0; i < count; i++ ) for ( unsigned int i = 0; i < count; i++ )
{ {
@ -900,15 +977,17 @@ void WriterNodeVisitor::apply( osg::Billboard &node ) {
pushStateSet(g->getStateSet()); pushStateSet(g->getStateSet());
createListTriangle(g, listTriangles, texcoords, i); 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 osg::Matrix currentBillBoardMat(osg::Matrix::translate(node.getPosition(i)) * m); // TODO handle rotation
apply3DSMatrixNode(node, currentBillBoardMat, "bil"); // Add a 3DS matrix node 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); traverse(node);
_cur3dsNode = parent; _cur3dsNode = parent;
popStateSet(node.getStateSet()); popStateSet(node.getStateSet());
@ -921,7 +1000,7 @@ void WriterNodeVisitor::apply(osg::Group &node)
pushStateSet(node.getStateSet()); pushStateSet(node.getStateSet());
Lib3dsMeshInstanceNode * parent = _cur3dsNode; Lib3dsMeshInstanceNode * parent = _cur3dsNode;
apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "grp"); apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "grp");
if (suceedLastApply()) if (succeeded())
traverse(node); traverse(node);
_cur3dsNode = parent; _cur3dsNode = parent;
popStateSet(node.getStateSet()); popStateSet(node.getStateSet());
@ -932,7 +1011,7 @@ void WriterNodeVisitor::apply(osg::MatrixTransform &node)
pushStateSet(node.getStateSet()); pushStateSet(node.getStateSet());
Lib3dsMeshInstanceNode * parent = _cur3dsNode; Lib3dsMeshInstanceNode * parent = _cur3dsNode;
apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "mtx"); apply3DSMatrixNode(node, osg::computeLocalToWorld(getNodePath()), "mtx");
if (suceedLastApply()) if (succeeded())
traverse(node); traverse(node);
_cur3dsNode = parent; _cur3dsNode = parent;
popStateSet(node.getStateSet()); popStateSet(node.getStateSet());

View File

@ -58,8 +58,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
const osgDB::ReaderWriter::Options* options, const osgDB::ReaderWriter::Options* options,
const std::string & srcDirectory); const std::string & srcDirectory);
bool suceedLastApply() const; bool succeeded() const { return _succeeded; }
void failedApply();
virtual void apply(osg::Geode &node); virtual void apply(osg::Geode &node);
virtual void apply(osg::Billboard &node); virtual void apply(osg::Billboard &node);
@ -145,8 +144,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
* Calculate the number of vertices in the geode. * Calculate the number of vertices in the geode.
* \return the number of vertices in the geode. * \return the number of vertices in the geode.
*/ */
unsigned int unsigned int calcVertices(osg::Geode & geo);
calcVertices(osg::Geode & geo);
/** /**
* Build a mesh * 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); void apply3DSMatrixNode(osg::Node &node, const osg::Matrix & m, const char * const prefix);
bool _suceedLastApply; bool _succeeded;
std::string _directory; std::string _directory;
std::string _srcDirectory; std::string _srcDirectory;
Lib3dsFile * file3ds; Lib3dsFile * file3ds;