diff --git a/src/osgPlugins/Inventor/ConvertFromInventor.cpp b/src/osgPlugins/Inventor/ConvertFromInventor.cpp index 1e5649471..a5c1e47af 100644 --- a/src/osgPlugins/Inventor/ConvertFromInventor.cpp +++ b/src/osgPlugins/Inventor/ConvertFromInventor.cpp @@ -35,12 +35,11 @@ #include #include #include +#include +#include #include #include #include -#ifdef USE_COIN -#include -#endif #include "GroupSoLOD.h" @@ -58,7 +57,6 @@ ConvertFromInventor::ConvertFromInventor() { numPrimitives = 0; - _hasVRMLImageTexture = false; } /////////////////////////////////////////// ConvertFromInventor::~ConvertFromInventor() @@ -69,7 +67,7 @@ osg::Node* ConvertFromInventor::convert(SoNode* rootIVNode) { // Transformation matrix for converting Inventor coordinate system to OSG // coordinate system - osg::Matrix ivToOSGMat(osg::Matrix(1.0, 0.0, 0.0, 0.0, + osg::Matrix ivToOSGMat(osg::Matrix(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0)); @@ -85,12 +83,16 @@ osg::Node* ConvertFromInventor::convert(SoNode* rootIVNode) // Create callback actions for the inventor nodes // These callback functions perform the conversion + // note: if one class is derived from the other and both callbacks + // are registered, both functions will be called SoCallbackAction cbAction; cbAction.addPreCallback(SoShape::getClassTypeId(), preShape, this); cbAction.addPostCallback(SoShape::getClassTypeId(), postShape, this); cbAction.addPreCallback(SoGroup::getClassTypeId(), preGroup, this); cbAction.addPostCallback(SoGroup::getClassTypeId(), postGroup, this); cbAction.addPreCallback(SoTexture2::getClassTypeId(), preTexture, this); + cbAction.addPreCallback(SoVRMLImageTexture::getClassTypeId(), + preVRMLImageTexture, this); cbAction.addPreCallback(SoLight::getClassTypeId(), preLight, this); cbAction.addPreCallback(SoRotor::getClassTypeId(), preRotor, this); cbAction.addPreCallback(SoPendulum::getClassTypeId(), prePendulum, this); @@ -98,48 +100,31 @@ osg::Node* ConvertFromInventor::convert(SoNode* rootIVNode) cbAction.addTriangleCallback(SoShape::getClassTypeId(), addTriangleCB, this); cbAction.addLineSegmentCallback(SoShape::getClassTypeId(), addLineSegmentCB, this); - cbAction.addPointCallback(SoShape::getClassTypeId(), addPointCB, this); - -#ifdef USE_COIN - //callback for VRMLImageTextures - cbAction.addPreCallback(SoVRMLImageTexture::getClassTypeId(), - _vrmlImageTextureAction,this); -#endif + // Traverse the inventor scene graph cbAction.apply(rootIVNode); - // Pop the root osg node - groupStack.pop(); + // Pop all the groups that are Transforms + // Verify that the last transform is _root . + assert(groupStack.size() > 0 && "groupStack underflow."); + osg::ref_ptr group = groupStack.top(); + while (strcmp(group->className(), "MatrixTransform") == 0) + { + groupStack.pop(); + if (groupStack.empty()) break; + group = groupStack.top(); + } + assert(group.get() == _root.get() && "groupStack error"); + assert(groupStack.size() == 0 && "groupStack is not empty after traversal."); + assert(soTexStack.size() == 0 && "soTexStack was left at inconsistent state."); + + assert(lightStack.size() == 1 && "lightStack was left at inconsistent state."); lightStack.pop(); return _root.get(); } -#ifdef USE_COIN -////////////////////////////////////////////////////////////////////////////////// -SoCallbackAction::Response -ConvertFromInventor::_vrmlImageTextureAction(void* data, SoCallbackAction* action, - const SoNode* node) -{ -#ifdef DEBUG_IV_PLUGIN - osg::notify(osg::INFO) << "_vrmlImageTextureAction() " - << node->getTypeId().getName().getString() << std::endl; -#endif - ///The converter data - ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); - - - SoVRMLImageTexture* vit = (SoVRMLImageTexture*)(node); - if(vit) - { - //convert the SoVRMLImageTexture to an osg::Texture - thisPtr->_setVRMLImageTexture(vit,action); - } - - return SoCallbackAction::CONTINUE; -} -#endif /////////////////////////////////////////////////////////////////// SoCallbackAction::Response ConvertFromInventor::preShape(void* data, SoCallbackAction* action, @@ -316,31 +301,15 @@ ConvertFromInventor::postShape(void* data, SoCallbackAction* action, geometry->setColorBinding(thisPtr->colorBinding); -#if 0 // original code - // BUG: if default texture coordinates are used in Inventor model, - // the texture is not shown in OSG - if (!(thisPtr->textureCoords.empty()) && action->getNumTextureCoordinates()>0) - { - - osg::notify(osg::NOTICE)<<"tex coords found"<textureCoords.empty())/* && action->getNumTextureCoordinates()>0*/) // BUG: That was avoiding using of automatic texture coordinate generation of IV. - -#else // improved code - if (thisPtr->textureCoords.empty()) - osg::notify(osg::NOTICE)<<"tex coords not found"<getNumTextureCoordinates()>0) - osg::notify(osg::DEBUG_INFO)<<"tex coords found"<soTexStack.size()) - thisPtr->soTexStack.pop() ; - thisPtr->soTexStack.push((SoTexture2 *)node) ; + thisPtr->soTexStack.pop(); + thisPtr->soTexStack.push(node); return SoCallbackAction::CONTINUE; } +////////////////////////////////////////////////////////////////////////////////// +SoCallbackAction::Response +ConvertFromInventor::preVRMLImageTexture(void* data, SoCallbackAction* action, + const SoNode* node) +{ +#ifdef DEBUG_IV_PLUGIN + osg::notify(osg::INFO) << "preVRMLImageTexture() " + << node->getTypeId().getName().getString() << std::endl; +#endif + + ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); + + if (thisPtr->soTexStack.size()) + thisPtr->soTexStack.pop(); + thisPtr->soTexStack.push(node); + + return SoCallbackAction::CONTINUE; +} ////////////////////////////////////////////////////////////////// void ConvertFromInventor::transformLight(SoCallbackAction* action, const SbVec3f& vec, @@ -497,7 +484,8 @@ ConvertFromInventor::preLight(void* data, SoCallbackAction* action, return SoCallbackAction::CONTINUE; } /////////////////////////////////////////////////////////////////////////////////////// - osg::ref_ptr ConvertFromInventor::getStateSet(SoCallbackAction* action) +osg::ref_ptr +ConvertFromInventor::getStateSet(SoCallbackAction* action) { osg::ref_ptr stateSet = new osg::StateSet; @@ -629,47 +617,10 @@ ConvertFromInventor::preLight(void* data, SoCallbackAction* action, // Convert the IV texture to OSG texture if any osg::ref_ptr texture; -#ifdef USE_COIN - if(_hasVRMLImageTexture) - { - ///VRMLImageTexture - texture = _getConvertedVRMLImageTexture(); - _hasVRMLImageTexture = false; - stateSet->setTextureAttributeAndModes(0,texture.get(), osg::StateAttribute::ON); - - // Set the texture environment - osg::ref_ptr texEnv = new osg::TexEnv; - switch (action->getTextureModel()) - { - case SoTexture2::MODULATE: - texEnv->setMode(osg::TexEnv::MODULATE); - break; - case SoTexture2::DECAL: - texEnv->setMode(osg::TexEnv::DECAL); - break; - case SoTexture2::BLEND: - texEnv->setMode(osg::TexEnv::BLEND); - break; - -#ifdef USE_COIN -// This check is a very crude Coin detector. -// SGI's Inventor does not have REPLACE mode, but the Coin 3D library does. - case SoTexture2::REPLACE: - texEnv->setMode(osg::TexEnv::REPLACE); - break; -#endif - } - stateSet->setTextureAttributeAndModes(0,texEnv.get(),osg::StateAttribute::ON); - stateSet->setAttributeAndModes(new osg::ShadeModel()); - - } - else -#endif if (soTexStack.top()) { - osg::notify(osg::NOTICE)<<"Have texture"< tex; + osg::notify(osg::INFO)<<"Have texture"<setMode(osg::TexEnv::BLEND); break; -#ifdef USE_COIN -// This check is a very crude Coin detector. +#ifdef __COIN__ // SGI's Inventor does not have REPLACE mode, but the Coin 3D library does. +// Coin supports REPLACE since 2.2 release, TGS Inventor from 4.0. case SoTexture2::REPLACE: texEnv->setMode(osg::TexEnv::REPLACE); break; @@ -708,127 +659,61 @@ ConvertFromInventor::preLight(void* data, SoCallbackAction* action, } stateSet->setTextureAttributeAndModes(0,texEnv.get(),osg::StateAttribute::ON); } - else - { - // fallback because many inventor models don't appear to have any SoTexture2.. - SbVec2s soTexSize; - int soTexNC; - const unsigned char* texImage = action->getTextureImage(soTexSize, soTexNC); - if (texImage) - { - osg::notify(osg::NOTICE)<<"Image data found soTexSize[0]="< "; - if (str[0]=='\"') str.erase(str.begin()); - if (str[str.size()-1]=='\"') str.erase(str.begin()+str.size()-1); - osg::notify(osg::INFO) << str << std::endl; - osgTexImage->setFileName(str); -#endif - - GLenum formats[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA}; - osgTexImage->setImage(soTexSize[0], soTexSize[1], 0, soTexNC, - formats[soTexNC-1], GL_UNSIGNED_BYTE, imageData, - osg::Image::USE_NEW_DELETE/*, -1*/); // BUG: -1 have to be removed (definitely WRONG packing!) It causes crashes of GLU. - - // Create the osg texture - texture = new osg::Texture2D; - texture->setImage(osgTexImage.get()); - - static std::map texWrapMap2; - static bool firstTime2 = true; - if (firstTime2) - { - texWrapMap2[SoTexture2::CLAMP] = osg::Texture2D::CLAMP; - texWrapMap2[SoTexture2::REPEAT] = osg::Texture2D::REPEAT; - firstTime2 = false; - } - // Set texture wrap mode - texture->setWrap(osg::Texture2D::WRAP_S,texWrapMap2[action->getTextureWrapS()]); - texture->setWrap(osg::Texture2D::WRAP_T,texWrapMap2[action->getTextureWrapT()]); - - stateSet->setTextureAttributeAndModes(0,texture.get(), osg::StateAttribute::ON); - - // Set the texture environment - osg::ref_ptr texEnv = new osg::TexEnv; - switch (action->getTextureModel()) - { - case SoTexture2::MODULATE: - texEnv->setMode(osg::TexEnv::MODULATE); - break; - case SoTexture2::DECAL: - texEnv->setMode(osg::TexEnv::DECAL); - break; - case SoTexture2::BLEND: - texEnv->setMode(osg::TexEnv::BLEND); - break; - - #ifdef USE_COIN - // This check is a very crude Coin detector. - // SGI's Inventor does not have REPLACE mode, but the Coin 3D library does. - case SoTexture2::REPLACE: - texEnv->setMode(osg::TexEnv::REPLACE); - break; - #endif - } - stateSet->setTextureAttributeAndModes(0,texEnv.get(),osg::StateAttribute::ON); - } - } return stateSet; } //////////////////////////////////////////////////////////////////// -osg::Texture2D* -ConvertFromInventor::convertIVTexToOSGTex(SoTexture2* soTex, +osg::Texture2D* +ConvertFromInventor::convertIVTexToOSGTex(const SoNode* soNode, SoCallbackAction* action) { - osg::notify(osg::NOTICE)<<"convertIVTexToOSGTex"<getTypeId().getName().getString()<image.getValue(soTexSize, soTexNC); - if (!texImage) + const unsigned char* soImageData = action->getTextureImage(soSize, soNC); + if (!soImageData) { + osg::notify(osg::WARN) << "IV import warning: Error while loading texture data." << std::endl; return NULL; - + } + // Allocate memory for image data - unsigned char* imageData = new unsigned char[soTexSize[0] * soTexSize[1] * - soTexNC]; - + unsigned char* osgImageData = new unsigned char[soSize[0] * soSize[1] * soNC]; + // Copy the texture image data from the inventor texture - memcpy(imageData, texImage, soTexSize[0] * soTexSize[1] * soTexNC); + memcpy(osgImageData, soImageData, soSize[0] * soSize[1] * soNC); - // Create the osg image - osg::ref_ptr osgTexImage = new osg::Image; - SbString iv_string; - soTex->filename.get(iv_string); - std::string str(iv_string.getString()); - osg::notify(osg::INFO) << str << " -> "; - if (str[0]=='\"') str.erase(str.begin()); - if (str[str.size()-1]=='\"') str.erase(str.begin()+str.size()-1); - osg::notify(osg::INFO) << str << std::endl; - osgTexImage->setFileName(str); + // File name + std::string fileName; + if (soNode->isOfType(SoTexture2::getClassTypeId())) + fileName = ((SoTexture2*)soNode)->filename.getValue().getString(); + else + if (soNode->isOfType(SoVRMLImageTexture::getClassTypeId())) + fileName = ((SoVRMLImageTexture*)soNode)->url.getNum() >= 1 ? + ((SoVRMLImageTexture*)soNode)->url.getValues(0)[0].getString() : ""; + else + osg::notify(osg::WARN) << "IV import warning: Unsupported texture type: " + << soNode->getTypeId().getName().getString() << std::endl; + + osg::notify(osg::INFO) << fileName << " -> "; + if (fileName[0]=='\"') fileName.erase(fileName.begin()); + if (fileName.size() > 0 && fileName[fileName.size()-1]=='\"') + fileName.erase(fileName.begin()+fileName.size()-1); + osg::notify(osg::INFO) << fileName << std::endl; + + // Create the osg::Image + osg::ref_ptr osgImage = new osg::Image; + osgImage->setFileName(fileName); GLenum formats[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA}; - osgTexImage->setImage(soTexSize[0], soTexSize[1], 0, soTexNC, - formats[soTexNC-1], GL_UNSIGNED_BYTE, imageData, - osg::Image::USE_NEW_DELETE/*, -1*/); // BUG: -1 have to be removed (definitely WRONG packing!) It causes crashes of GLU. + osgImage->setImage(soSize[0], soSize[1], 0, soNC, formats[soNC-1], + GL_UNSIGNED_BYTE, osgImageData, osg::Image::USE_NEW_DELETE); - // Create the osg texture - osg::ref_ptr osgTex = new osg::Texture2D; - osgTex->setImage(osgTexImage.get()); + // Create the osg::Texture2D + osg::Texture2D *osgTex = new osg::Texture2D; + osgTex->setImage(osgImage.get()); static std::map texWrapMap; static bool firstTime = true; @@ -840,14 +725,28 @@ ConvertFromInventor::convertIVTexToOSGTex(SoTexture2* soTex, } // Set texture wrap mode - osgTex->setWrap(osg::Texture2D::WRAP_S,texWrapMap[action->getTextureWrapS()]); - osgTex->setWrap(osg::Texture2D::WRAP_T,texWrapMap[action->getTextureWrapT()]); + if (soNode->isOfType(SoVRMLImageTexture::getClassTypeId())) { + // It looks like there is a high probability of bug in Coin (investigated on version 2.4.6). + // action->getTextureWrap() returns correct value on SoTexture2 (SoTexture2::CLAMP = 0x2900, + // and REPEAT = 0x2901), but SoVRMLImageTexture returns incorrect value of + // SoGLImage::REPEAT = 0, CLAMP = 1, CLAMP_TO_EDGE = 2). + // So, let's not use action and try to get correct value directly from texture node. + // PCJohn-2007-04-22 + osgTex->setWrap(osg::Texture2D::WRAP_S, ((SoVRMLImageTexture*)soNode)->repeatS.getValue() ? + osg::Texture2D::REPEAT : osg::Texture2D::CLAMP_TO_EDGE); + osgTex->setWrap(osg::Texture2D::WRAP_T, ((SoVRMLImageTexture*)soNode)->repeatT.getValue() ? + osg::Texture2D::REPEAT : osg::Texture2D::CLAMP_TO_EDGE); + } else { + // Proper way to determine wrap mode + osgTex->setWrap(osg::Texture2D::WRAP_S, texWrapMap[action->getTextureWrapS()]); + osgTex->setWrap(osg::Texture2D::WRAP_T, texWrapMap[action->getTextureWrapT()]); + } - return osgTex.get(); + return osgTex; } /////////////////////////////////////////////////////////////////// SoCallbackAction::Response -ConvertFromInventor::preGroup(void* data, SoCallbackAction* action, +ConvertFromInventor::preGroup(void* data, SoCallbackAction*, const SoNode* node) { #ifdef DEBUG_IV_PLUGIN @@ -857,12 +756,12 @@ ConvertFromInventor::preGroup(void* data, SoCallbackAction* action, ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); - // Handle SoLOD nodes - if (node->getTypeId() == GroupSoLOD::getClassTypeId()) - return preLOD(data, action, node); - - // Create a new group and add it to the stack - osg::ref_ptr group = new osg::Group; + // Create a new Group or LOD and add it to the stack + osg::ref_ptr group; + if (node->isOfType(SoLOD::getClassTypeId())) + group = new osg::LOD; + else + group = new osg::Group; thisPtr->groupStack.top()->addChild(group.get()); thisPtr->groupStack.push(group.get()); @@ -883,9 +782,13 @@ ConvertFromInventor::preGroup(void* data, SoCallbackAction* action, } ////////////////////////////////////////////////////////////// SoCallbackAction::Response -ConvertFromInventor::postGroup(void* data, SoCallbackAction *, +ConvertFromInventor::postGroup(void* data, SoCallbackAction* action, const SoNode* node) { + // Handle SoLOD nodes specially + if (node->isOfType(SoLOD::getClassTypeId())) + return postLOD(data, action, node); + #ifdef DEBUG_IV_PLUGIN osg::notify(osg::INFO) << "postGroup() " << node->getTypeId().getName().getString() << std::endl; @@ -893,19 +796,16 @@ ConvertFromInventor::postGroup(void* data, SoCallbackAction *, ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); - // Pop all the groups that are Transforms and add it - // to the corresponding parent group + // Pop all the groups that are Transforms osg::ref_ptr group = thisPtr->groupStack.top(); while (strcmp(group->className(), "MatrixTransform") == 0) { thisPtr->groupStack.pop(); - thisPtr->groupStack.top()->addChild(group.get()); group = thisPtr->groupStack.top(); } - // Pop the group from the stack and add it to it's parent + // Pop the group from the stack thisPtr->groupStack.pop(); - thisPtr->groupStack.top()->addChild(group.get()); // Pop the state if the group is a Separator if (node->isOfType(SoSeparator::getClassTypeId())) @@ -918,36 +818,50 @@ ConvertFromInventor::postGroup(void* data, SoCallbackAction *, } //////////////////////////////////////////////////////////// SoCallbackAction::Response -ConvertFromInventor::preLOD(void* data, SoCallbackAction *, - const SoNode* node) +ConvertFromInventor::postLOD(void* data, SoCallbackAction *, + const SoNode* node) { #ifdef DEBUG_IV_PLUGIN - osg::notify(osg::INFO) << "preLOD() " + osg::notify(osg::INFO) << "postLOD() " << node->getTypeId().getName().getString() << std::endl; #endif ConvertFromInventor* thisPtr = (ConvertFromInventor *) (data); - // Inventor LOD node + // Inventor and OSG LOD node SoLOD *ivLOD = (SoLOD *) node; - - // Create a new LOD and add it to the stack - osg::ref_ptr lod = new osg::LOD; - thisPtr->groupStack.push(lod.get()); - thisPtr->groupStack.top()->addChild(lod.get()); + osg::LOD *lod = dynamic_cast(thisPtr->groupStack.top()); // Get the center of LOD and set it SbVec3f ivCenter = ivLOD->center.getValue(); lod->setCenter(osg::Vec3(ivCenter[0], ivCenter[1], ivCenter[2])); + // Verify the number of children and range values + int num = thisPtr->groupStack.top()->getNumChildren(); + if (ivLOD->range.getNum()+1 != num && !(num == 0 && ivLOD->range.getNum() == 0)) { + osg::notify(osg::WARN) << "IV import warning: SoLOD does not " + << "contain correct data in range field." << std::endl; + if (ivLOD->range.getNum()+1 < num) { + thisPtr->groupStack.top()->removeChildren(ivLOD->range.getNum() + 1, + num - ivLOD->range.getNum() - 1); + num = ivLOD->range.getNum() + 1; + } + } + // Get the ranges and set it - // lod->setRange(0, 0.0); - lod->setRange(0, 0.0, ivLOD->range[0]); - for (int i = 1; i < ivLOD->getChildren()->getLength(); i++) - lod->setRange(i, ivLOD->range[i-1], ivLOD->range[i]); - - lod->setRange(ivLOD->getChildren()->getLength(), - ivLOD->range[ivLOD->getChildren()->getLength()],FLT_MAX); + if (num > 0) { + if (num == 1) + lod->setRange(0, 0.0, FLT_MAX); + else { + lod->setRange(0, 0.0, ivLOD->range[0]); + for (int i = 1; i < num-2; i++) + lod->setRange(i, ivLOD->range[i-1], ivLOD->range[i]); + lod->setRange(num-1, ivLOD->range[num-2], FLT_MAX); + } + } + + // Pop the group from the stack + thisPtr->groupStack.pop(); return SoCallbackAction::CONTINUE; } @@ -983,8 +897,8 @@ ConvertFromInventor::preRotor(void* data, SoCallbackAction *, rotorTransform->setUpdateCallback(rotorCallback.get()); // Push the rotor transform onto the group stack - thisPtr->groupStack.push(rotorTransform.get()); thisPtr->groupStack.top()->addChild(rotorTransform.get()); + thisPtr->groupStack.push(rotorTransform.get()); return SoCallbackAction::CONTINUE; } @@ -1020,8 +934,8 @@ ConvertFromInventor::prePendulum(void* data, SoCallbackAction *, pendulumTransform->setUpdateCallback(pendulumCallback); // Push the pendulum transform onto the group stack - thisPtr->groupStack.push(pendulumTransform.get()); thisPtr->groupStack.top()->addChild(pendulumTransform.get()); + thisPtr->groupStack.push(pendulumTransform.get()); return SoCallbackAction::CONTINUE; } @@ -1056,8 +970,8 @@ ConvertFromInventor::preShuttle(void* data, SoCallbackAction *, shuttleTransform->setUpdateCallback(shuttleCallback); // Push the shuttle transform onto the group stack - thisPtr->groupStack.push(shuttleTransform.get()); thisPtr->groupStack.top()->addChild(shuttleTransform.get()); + thisPtr->groupStack.push(shuttleTransform.get()); return SoCallbackAction::CONTINUE; } @@ -1151,74 +1065,3 @@ void ConvertFromInventor::addPointCB(void* data, SoCallbackAction* action, thisPtr->numPrimitives++; thisPtr->primitiveType = osg::PrimitiveSet::POINTS; } -#ifdef USE_COIN -////////////////////////////////////////////////////////////////////// -void ConvertFromInventor::_setVRMLImageTexture(const SoVRMLImageTexture* vit, - SoCallbackAction* /*action*/) -{ - _hasVRMLImageTexture = true; - ///Coin API to extract VRML97 ImageTexture - int nComponents = 1; - SbImage* vitImage = (SbImage*)vit->getImage(); - SbString filename; - filename = vit->url.getValues(0)[0]; - vitImage->readFile(filename); - - SbVec2s dimensions; - dimensions[0] = 2; - dimensions[1] = 2; - const unsigned char* dataPtr = vitImage->getValue(dimensions,nComponents); - - unsigned char* data = new unsigned char[dimensions[0]* - dimensions[1]* - nComponents]; - - ///Is this effiecient??? - memcpy(data, dataPtr, dimensions[0]*dimensions[1]*nComponents); - - GLenum format = GL_RGBA; - switch (nComponents) - { - case 1: - format = GL_LUMINANCE; - break; - case 2: - format = GL_LUMINANCE_ALPHA; - break; - case 3: - format = GL_RGB; - break; - case 4: - default: - format = GL_RGBA; - break; - }; - - osg::ref_ptr image = new osg::Image(); - image->setImage(dimensions[0], dimensions[1], 1, nComponents, - format, GL_UNSIGNED_BYTE, const_cast(data), - osg::Image::USE_NEW_DELETE); - - - osg::ref_ptr texture = new osg::Texture2D(); - texture->setImage(image.get()); - - osg::Texture::WrapMode smode = (vit->repeatS.getValue())?(osg::Texture::REPEAT):(osg::Texture::CLAMP); - osg::Texture::WrapMode tmode = (vit->repeatT.getValue())?(osg::Texture::REPEAT):(osg::Texture::CLAMP); - - // Set texture wrap mode - texture->setWrap(osg::Texture2D::WRAP_S,smode); - texture->setWrap(osg::Texture2D::WRAP_T,tmode); - _currentVRMLImageTexture = texture; - _currentVRMLImageTexture->dirtyTextureObject(); -} -//////////////////////////////////////////////////////////////////// -osg::Texture2D* ConvertFromInventor::_getConvertedVRMLImageTexture() -{ - if(_currentVRMLImageTexture.valid()) - { - return _currentVRMLImageTexture.get(); - } - return 0; -} -#endif diff --git a/src/osgPlugins/Inventor/ConvertFromInventor.h b/src/osgPlugins/Inventor/ConvertFromInventor.h index e32451ab0..fd9cdf3b2 100644 --- a/src/osgPlugins/Inventor/ConvertFromInventor.h +++ b/src/osgPlugins/Inventor/ConvertFromInventor.h @@ -6,28 +6,18 @@ #include #include #include - #include - -#ifdef COIN_SOCALLBACKACTION_H - #define USE_COIN 1 -#endif - -#ifdef USE_COIN - #include -#endif - #include #include -class ConvertFromInventor +class ConvertFromInventor { public: ConvertFromInventor(); ~ConvertFromInventor(); - - osg::Node* convert(SoNode* rootIVNode); - + + osg::Node* convert(SoNode* rootIVNode); + private: // Callback functions for converting inventor scene graph to osg @@ -51,7 +41,13 @@ class ConvertFromInventor SoCallbackAction* action, const SoNode* node); static SoCallbackAction::Response preShuttle(void* data, SoCallbackAction* action, const SoNode* node); - static SoCallbackAction::Response preLOD(void* data, + static SoCallbackAction::Response postLOD(void* data, + SoCallbackAction* action, const SoNode* node); + ///Callback for VRMLImageTexture + ///\param data The pointer to ConvertFromInventor object + ///\param action The action handling class + ///\param node The current VRMLImageTexture node + static SoCallbackAction::Response preVRMLImageTexture(void* data, SoCallbackAction* action, const SoNode* node); static void addTriangleCB(void* data, SoCallbackAction* action, @@ -63,41 +59,23 @@ class ConvertFromInventor const SoPrimitiveVertex *v1); static void addPointCB(void* data, SoCallbackAction* action, const SoPrimitiveVertex *v0); -#ifdef USE_COIN - ///Callback to intercept VRMLImageTexture(s) - ///\param data The node data - ///\param action The callback handling class - ///\param node The current VRMLImageTexture node - static SoCallbackAction::Response - _vrmlImageTextureAction(void* data, - SoCallbackAction* action, - const SoNode* node); - ///Set the SVRMLImageTexture for the current node - ///\param texture The found texture - ///\param action The callback action - void _setVRMLImageTexture(const SoVRMLImageTexture* texture, - SoCallbackAction* action); - - ///Get the currently converted texture - osg::Texture2D* _getConvertedVRMLImageTexture(); -#endif - + private: void addVertex(SoCallbackAction* action, const SoPrimitiveVertex* v, int index); - osg::ref_ptr getStateSet(SoCallbackAction* action); + osg::ref_ptr getStateSet(SoCallbackAction* action); - osg::Texture2D* convertIVTexToOSGTex(SoTexture2* soTex, - SoCallbackAction* action); + osg::Texture2D* convertIVTexToOSGTex(const SoNode* soNode, + SoCallbackAction* action); void transformLight(SoCallbackAction* action, const SbVec3f& vec, osg::Vec3& transVec); // OSG doesn't seem to have a transpose function for matrices void transposeMatrix(osg::Matrix& mat); - + private: // Normal and color binding @@ -121,11 +99,12 @@ class ConvertFromInventor // Stack of group nodes (used to build the scene graph) std::stack groupStack; // Stack of texture nodes (used for attaching the right texture to the - // geosets) - std::stack soTexStack; + // geosets). Supported types are SoTexture2 and SoVRMLImageTexture for now. + std::stack soTexStack; - // For avoiding duplication of same texture objects - std::map ivToOsgTexMap; + // Mapping from SoTexture2 and SoVRMLImageTexture to already converted + // osg::Texture2D - avoids duplication of same texture objects + std::map ivToOsgTexMap; // Stack to maintain the list of lights at each level of the // scenegraph @@ -133,8 +112,6 @@ class ConvertFromInventor std::stack lightStack; osg::ref_ptr _root;/// _currentVRMLImageTexture;/// #include #include +#include #include "ConvertFromInventor.h" #include "GroupSoLOD.h" @@ -44,6 +45,9 @@ ReaderWriterIV::readNode(const std::string& file, // Initial GroupSoLOD node GroupSoLOD::initClass(); + // Disable delayed loading of VRML textures + SoVRMLImageTexture::setDelayFetchURL(FALSE); + // Open the file SoInput input; if (!input.openFile(fileName.data()))