From 20da8e55a8f2a7b63362286c2a4c00dd48fa1b0c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 25 Oct 2008 13:17:22 +0000 Subject: [PATCH] From Jim Vaughan, - Matrix transform nodes were stripped out, and the vertices and normals of each node were transposed by the modelling matrix. My change preserves the matrix transform nodes, so that models can still be articulated by changing the matrices. - Lights were copied from the COIN scenegraph to the OSG scenegraph, but they were not associated with a LightSource node. My change for this creates a Group and adds a LightSource for each Light. - If VRML textures have names, the name is now copied to -- Form Robert Osfild, changed SbString to std::string usage M Inventor/ConvertFromInventor.h M Inventor/ConvertFromInventor.cpp --- .../Inventor/ConvertFromInventor.cpp | 223 ++++++++++++++++-- src/osgPlugins/Inventor/ConvertFromInventor.h | 13 + 2 files changed, 212 insertions(+), 24 deletions(-) diff --git a/src/osgPlugins/Inventor/ConvertFromInventor.cpp b/src/osgPlugins/Inventor/ConvertFromInventor.cpp index 58ba59556..6756864f7 100644 --- a/src/osgPlugins/Inventor/ConvertFromInventor.cpp +++ b/src/osgPlugins/Inventor/ConvertFromInventor.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -39,9 +40,14 @@ #include #include #include +#include +#include #ifdef __COIN__ #include +#include +#include +#include #endif #include "GroupSoLOD.h" @@ -49,6 +55,7 @@ #include #include #include +#include #ifdef __linux #include #endif @@ -61,6 +68,10 @@ ConvertFromInventor::ConvertFromInventor() { numPrimitives = 0; + transformInfoName = ""; + appearanceName = ""; + inAppearanceWithNoTexture = false; + lightGroup = NULL; } /////////////////////////////////////////// ConvertFromInventor::~ConvertFromInventor() @@ -98,6 +109,9 @@ osg::Node* ConvertFromInventor::convert(SoNode* rootIVNode) #ifdef __COIN__ cbAction.addPreCallback(SoVRMLImageTexture::getClassTypeId(), preVRMLImageTexture, this); + cbAction.addPreCallback(SoVRMLAppearance::getClassTypeId(), + preVRMLAppearance, this); + cbAction.addPreCallback(SoInfo::getClassTypeId(), preInfo, this); #endif cbAction.addPreCallback(SoLight::getClassTypeId(), preLight, this); cbAction.addPreCallback(SoRotor::getClassTypeId(), preRotor, this); @@ -245,42 +259,25 @@ ConvertFromInventor::postShape(void* data, SoCallbackAction* action, // Create a new Geometry osg::ref_ptr geometry = new osg::Geometry; - // Get the modeling matrix - osg::Matrix modelMat; - modelMat.set((float *)action->getModelMatrix().getValue()); - // Tranform the vertices based on the modeling matrix osg::ref_ptr coords = new osg::Vec3Array(thisPtr->vertices.size()); for (unsigned int i = 0; i < thisPtr->vertices.size(); i++) - (*coords)[i] = modelMat.preMult(thisPtr->vertices[i]); - + (*coords)[i] = thisPtr->vertices[i]; geometry->setVertexArray(coords.get()); - - // Normals need to be transformed using the transpose of the inverse - // modeling matrix - osg::Matrix invModelMat; - invModelMat.invert(modelMat); - thisPtr->transposeMatrix(invModelMat); - - // Tranform the normals based on the modeling matrix osg::ref_ptr norms = NULL; if (thisPtr->normalBinding == osg::Geometry::BIND_OVERALL) { norms = new osg::Vec3Array(1); const SbVec3f &norm = action->getNormal(0); (*norms)[0].set(norm[0], norm[1], norm[2]); - (*norms)[0] = invModelMat.transform3x3((*norms)[0],invModelMat); - (*norms)[0].normalize(); } else { norms = new osg::Vec3Array(thisPtr->normals.size()); for (unsigned int i = 0; i < thisPtr->normals.size(); i++) { - (*norms)[i] = invModelMat.transform3x3(thisPtr->normals[i], - invModelMat); - (*norms)[i].normalize(); + (*norms)[i] = thisPtr->normals[i]; } } geometry->setNormalArray(norms.get()); @@ -360,6 +357,11 @@ ConvertFromInventor::postShape(void* data, SoCallbackAction* action, osg::ref_ptr geode = new osg::Geode; geode->addDrawable(geometry.get()); + // copy name + std::string name = stateSet->getName(); + if (name != "") { + geode->setName(name); + } // Add geode to scenegraph thisPtr->groupStack.top()->addChild(geode.get()); @@ -383,6 +385,40 @@ ConvertFromInventor::preTexture(void* data, SoCallbackAction *, return SoCallbackAction::CONTINUE; } +////////////////////////////////////////////////////////////////////////////////// +SoCallbackAction::Response +ConvertFromInventor::preVRMLAppearance(void* data, SoCallbackAction* action, + const SoNode* node) +{ +#ifdef DEBUG_IV_PLUGIN + osg::notify(osg::INFO) << "preVRMLAppearance() " + << node->getTypeId().getName().getString() << std::endl; +#endif + +#ifdef __COIN__ + ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); + + // If there is a VRML appearance node without a texture node, then + // we push a NULL texture onto the stack + bool foundTex = false; + SoChildList *kids = node->getChildren(); + for (int i=0; igetLength(); i++) { + SoNode* kid = (SoNode*)kids->get(i); + if (kid->isOfType(SoVRMLMaterial::getClassTypeId())) { + thisPtr->appearanceName = kid->getName(); + } + if (kid->isOfType(SoVRMLTexture::getClassTypeId())) { + foundTex = true; + } + } + if (!foundTex) { + thisPtr->soTexStack.push(NULL); + thisPtr->inAppearanceWithNoTexture = true; + } +#endif + return SoCallbackAction::CONTINUE; +} + ////////////////////////////////////////////////////////////////////////////////// SoCallbackAction::Response ConvertFromInventor::preVRMLImageTexture(void* data, SoCallbackAction* action, @@ -432,6 +468,9 @@ ConvertFromInventor::preLight(void* data, SoCallbackAction* action, osg::ref_ptr osgLight = new osg::Light; osgLight->setLightNum(lightNum++); + + const char* name = ivLight->getName().getString(); + osgLight->setName(name); // Get color and intensity SbVec3f lightColor = ivLight->color.getValue(); @@ -487,6 +526,17 @@ ConvertFromInventor::preLight(void* data, SoCallbackAction* action, thisPtr->lightStack.push(lightList); } + // add a light source node to the scene graph + osg::ref_ptr ls = new osg::LightSource(); + ls->setLight(osgLight.get()); + ls->setName(ivLight->getName().getString()); + if (thisPtr->lightGroup == NULL) { + thisPtr->lightGroup = new osg::Group; + thisPtr->lightGroup->setName("IvLightGroup"); + thisPtr->_root->addChild(thisPtr->lightGroup.get()); + } + thisPtr->lightGroup->addChild(ls.get()); + return SoCallbackAction::CONTINUE; } /////////////////////////////////////////////////////////////////////////////////////// @@ -518,6 +568,11 @@ ConvertFromInventor::getStateSet(SoCallbackAction* action) } stateSet->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON); + + // propogate name + std::string name = texture->getName(); + if (name != "") + stateSet->setName(name); // Set the texture environment osg::ref_ptr texEnv = new osg::TexEnv; @@ -667,6 +722,7 @@ ConvertFromInventor::getStateSet(SoCallbackAction* action) material->setColorMode(osg::Material::DIFFUSE); stateSet->setAttributeAndModes(material.get(), osg::StateAttribute::ON); + stateSet->setName(appearanceName.getString()); stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); #if 0 @@ -709,6 +765,9 @@ ConvertFromInventor::convertIVTexToOSGTex(const SoNode* soNode, // Copy the texture image data from the inventor texture memcpy(osgImageData, soImageData, soSize[0] * soSize[1] * soNC); + // Copy the name + std::string name = soNode->getName().getString(); + // File name std::string fileName; if (soNode->isOfType(SoTexture2::getClassTypeId())) @@ -739,6 +798,9 @@ ConvertFromInventor::convertIVTexToOSGTex(const SoNode* soNode, // Create the osg::Texture2D osg::Texture2D *osgTex = new osg::Texture2D; osgTex->setImage(osgImage.get()); + if (name != "") { + osgTex->setName(name); + } static std::map texWrapMap; static bool firstTime = true; @@ -775,25 +837,81 @@ ConvertFromInventor::convertIVTexToOSGTex(const SoNode* soNode, } /////////////////////////////////////////////////////////////////// SoCallbackAction::Response -ConvertFromInventor::preGroup(void* data, SoCallbackAction*, +ConvertFromInventor::preInfo(void* data, SoCallbackAction* action, + const SoNode* node) +{ +#ifdef DEBUG_IV_PLUGIN + osg::notify(osg::INFO) << "preInfo() " + << node->getTypeId().getName().getString() << std::endl; +#endif + ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); + SoInfo* info = (SoInfo*)node; + thisPtr->transformInfoName = info->string.getValue(); + + return SoCallbackAction::CONTINUE; +} + +/////////////////////////////////////////////////////////////////// +SoCallbackAction::Response +ConvertFromInventor::preGroup(void* data, SoCallbackAction* action, const SoNode* node) { #ifdef DEBUG_IV_PLUGIN osg::notify(osg::INFO) << "preGroup() " << node->getTypeId().getName().getString() << std::endl; #endif - ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); // Create a new Group or LOD and add it to the stack osg::ref_ptr group; - if (node->isOfType(SoLOD::getClassTypeId())) + if (node->isOfType(SoLOD::getClassTypeId())) { group = new osg::LOD; - else + } + else { group = new osg::Group; + } + thisPtr->groupStack.top()->addChild(group.get()); thisPtr->groupStack.push(group.get()); + + // handle transform nodes + if (node->isOfType(SoTransform::getClassTypeId())) { + SoTransform* t = (SoTransform*)node; + SbVec3f axis, center, trans, scale; + float angle; + center = t->center.getValue(); + t->rotation.getValue(axis, angle); + trans = t->translation.getValue(); + scale = t->scaleFactor.getValue(); + std::string name = t->getName().getString(); + + thisPtr->addMatrixTransform(name, axis, angle, center, trans, scale); + } +#ifdef __COIN__ + if (node->isOfType(SoVRMLTransform::getClassTypeId())) { + std::string name; + if (thisPtr->transformInfoName != "") { + name = std::string("INFO_"); + name += thisPtr->transformInfoName.getString(); + name += "_trans"; + } + else { + name = node->getName(); + } + + SoVRMLTransform* vt = (SoVRMLTransform*)node; + SbVec3f axis, center, trans, scale; + float angle; + + center = vt->center.getValue(); + vt->rotation.getValue(axis, angle); + trans = vt->translation.getValue(); + scale = vt->scale.getValue(); + + thisPtr->addMatrixTransform(name, axis, angle, center, trans, scale); + } +#endif if (node->isOfType(SoSeparator::getClassTypeId())) { if (thisPtr->soTexStack.size()) @@ -822,7 +940,6 @@ ConvertFromInventor::postGroup(void* data, SoCallbackAction* action, osg::notify(osg::INFO) << "postGroup() " << node->getTypeId().getName().getString() << std::endl; #endif - ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); // Pop all the groups that are Transforms @@ -1046,6 +1163,64 @@ void ConvertFromInventor::addVertex(SoCallbackAction* action, textureCoords.push_back(osg::Vec2(texCoord[0], texCoord[1])); } //////////////////////////////////////////////////////////////////////////// +void ConvertFromInventor::addMatrixTransform(const std::string& name, SbVec3f axis, float angle, SbVec3f center, SbVec3f trans, SbVec3f scale) +{ + osg::Matrix mat; + if (trans.length() != 0.0 || name != "") + { + mat.makeIdentity(); + mat.setTrans(trans[0], trans[1], trans[2]); + osg::ref_ptr mt = new osg::MatrixTransform(mat); + if (name != "") { + std::string name2 = name; + name2 += "_t"; + mt->setName(name2); + } + groupStack.top()->addChild(mt.get()); + groupStack.push(mt.get()); + } + + if (center.length() != 0.0) { + mat.makeIdentity(); + mat.setTrans(center[0], center[1], center[2]); + osg::ref_ptr mt = new osg::MatrixTransform(mat); + groupStack.top()->addChild(mt.get()); + groupStack.push(mt.get()); + } + + if (angle != 0.0 || name != "") + { + osg::Quat q(angle, osg::Vec3f(axis[0], axis[1], axis[2])); + mat.makeIdentity(); + mat.setRotate(q); + osg::ref_ptr mt = new osg::MatrixTransform(mat); + if (name != "") { + std::string name2 = name; + name2 += "_r"; + mt->setName(name2); + } + groupStack.top()->addChild(mt.get()); + groupStack.push(mt.get()); + } + + if (center.length() != 0.0) { + center.negate(); + mat.makeIdentity(); + mat.setTrans(center[0], center[1], center[2]); + osg::ref_ptr mt = new osg::MatrixTransform(mat); + groupStack.top()->addChild(mt.get()); + groupStack.push(mt.get()); + } + + if (scale[0] != 1.0 || scale[1] != 1.0 || scale[2] != 1.0) { + mat.makeIdentity(); + mat.makeScale(scale[0], scale[1], scale[2]); + osg::ref_ptr smt = new osg::MatrixTransform(mat); + groupStack.top()->addChild(smt.get()); + groupStack.push(smt.get()); + } +} +//////////////////////////////////////////////////////////////////////////// void ConvertFromInventor::addTriangleCB(void* data, SoCallbackAction* action, const SoPrimitiveVertex* v0, const SoPrimitiveVertex* v1, diff --git a/src/osgPlugins/Inventor/ConvertFromInventor.h b/src/osgPlugins/Inventor/ConvertFromInventor.h index fd9cdf3b2..8eba8a7ab 100644 --- a/src/osgPlugins/Inventor/ConvertFromInventor.h +++ b/src/osgPlugins/Inventor/ConvertFromInventor.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,12 @@ class ConvertFromInventor ///\param node The current VRMLImageTexture node static SoCallbackAction::Response preVRMLImageTexture(void* data, SoCallbackAction* action, const SoNode* node); + static SoCallbackAction::Response preVRMLAppearance(void* data, + SoCallbackAction* action, const SoNode* node); + static SoCallbackAction::Response postVRMLAppearance(void* data, + SoCallbackAction* action, const SoNode* node); + static SoCallbackAction::Response preInfo(void* data, + SoCallbackAction* action, const SoNode* node); static void addTriangleCB(void* data, SoCallbackAction* action, const SoPrimitiveVertex *v0, @@ -61,7 +68,11 @@ class ConvertFromInventor const SoPrimitiveVertex *v0); private: + SbString transformInfoName; + SbName appearanceName; + bool inAppearanceWithNoTexture; + void addMatrixTransform(const std::string& name, SbVec3f axis, float angle, SbVec3f center, SbVec3f trans, SbVec3f scale); void addVertex(SoCallbackAction* action, const SoPrimitiveVertex* v, int index); @@ -112,6 +123,8 @@ class ConvertFromInventor std::stack lightStack; osg::ref_ptr _root;/// lightGroup; }; #endif