📄 converttoinventor.cpp
字号:
osgMaterial->getSpecularFrontAndBack() ? osg::Material::FRONT_AND_BACK : osg::Material::FRONT).ptr()); ((SoMaterial*)ivState->ivMaterial)->emissiveColor.setValue(osgMaterial->getEmission( osgMaterial->getEmissionFrontAndBack() ? osg::Material::FRONT_AND_BACK : osg::Material::FRONT).ptr()); ((SoMaterial*)ivState->ivMaterial)->shininess.setValue(osgMaterial->getShininess( osgMaterial->getShininessFrontAndBack() ? osg::Material::FRONT_AND_BACK : osg::Material::FRONT)); ((SoMaterial*)ivState->ivMaterial)->transparency.setValue(1.f - osgMaterial->getDiffuse( osgMaterial->getDiffuseFrontAndBack() ? osg::Material::FRONT_AND_BACK : osg::Material::FRONT).a()); } // note on "headlight": // OSG is using HEADLIGHT or SKY_LIGHT. In both cases it sets these defaults: // osg::LightModel::ambientIntensity(0.1, 0.1, 0.1, 1.0); // osg::Light::num(0) // osg::Light::ambient(0,0,0,1) // osg::Light::diffuse(0.8,0.8,0.8, 1) // osg::Light::specular(1,1,1,1) // // Inventor uses different settings: // SoEnvironment::ambientIntensity(0.2) // SoEnvironment::ambientColor(1,1,1) // SoDirectionalLight::intensity(1) // SoDirectionalLight::color(1,1,1) // // note on Inventor light handling: // ambient is set to 0,0,0,1 // diffuse to color*intensity // specular to color*intensity #ifdef __COIN__ // // Handle transparency // // OSG supports GL_BLEND and GL_ALPHA_TEST // Related classes: BlendFunc, BlendEquation, BlendColor, AlphaFunc // // Inventor is more difficult and not so robust. According to Inventor 2.1 standard, // just SoMaterial::transparency, SoTexture2 with alpha channel carry transparency information // that is controlled by SoGLRenderAction::transparency type that is set to SCREEN_DOOR by default // (dither pattern). So, if the user does not select better transparency type, there is no // possiblity to control transparency type from file format. // // However, SoTransparencyType node was introduced to overcome this historical limitation // because transparency was performance expensive long time ago. // Support by different Inventor branches: // // SGI Inventor: no // Coin: since 2.0 // TGS Inventor: since 5.0 // // Alpha test was introduced in TGS 4.0, but as SoGLRenderArea::setAlphaTest. So, no direct // control in the file format. // // Conclusion: // - Alpha test is not supported and all pixels will be drawn // - Blending - current strategy is following: // ADD x BLEND - ADD is used if destination-blending-factor is GL_ONE // DELAYED rendering is used if transparency bin is used by OSG // SORTED_OBJECT is used if ... // updateMode(ivState->osgBlendEnabled, ss->getMode(GL_BLEND)); ivState->osgBlendFunc = dynamic_cast<const osg::BlendFunc*>(ss->getAttribute(osg::StateAttribute::BLENDFUNC)); if (useIvExtensions) if (ivState->osgBlendEnabled != ivPrevState->osgBlendEnabled || ivState->osgBlendFunc != ivPrevState->osgBlendFunc || (ivState->osgBlendFunc && ivPrevState->osgBlendFunc && ivState->osgBlendFunc->getDestinationRGB() != ivPrevState->osgBlendFunc->getDestinationRGB())) { const SoTransparencyType::Type transparencyTable[8] = { SoTransparencyType::BLEND, SoTransparencyType::ADD, SoTransparencyType::DELAYED_BLEND, SoTransparencyType::DELAYED_ADD, // FIXME: add sorted modes and test previous four }; int index = 0; if (!ivState->osgBlendFunc) index |= 0; else index = (ivState->osgBlendFunc->getDestinationRGB() == osg::BlendFunc::ONE) ? 1 : 0; index |= (ss->getRenderingHint() == osg::StateSet::TRANSPARENT_BIN) ? 2 : 0; SoTransparencyType *ivTransparencyType = new SoTransparencyType; ivTransparencyType->value = transparencyTable[index]; ivState->ivHead->addChild(ivTransparencyType); } #endif } // ref Inventor nodes that are required when processing Drawables if (ivState->ivTexture) ivState->ivTexture->ref(); if (ivState->ivMaterial) ivState->ivMaterial->ref(); return ivState;}void ConvertToInventor::popInventorState(){ InventorState *ivState = &ivStack.top(); // unref Inventor nodes if (ivState->ivTexture) ivState->ivTexture->unref(); if (ivState->ivMaterial) ivState->ivMaterial->unref(); ivStack.pop();}static bool processPrimitiveSet(const osg::Geometry *g, const osg::PrimitiveSet *pset, osg::UIntArray *drawElemIndices, bool needSeparateTriangles, int elementsCount, int primSize, const int startIndex, int stopIndex, int &normalIndex, int &colorIndex, SoNode *ivCoords, SoNormal *ivNormals, SoNode *ivMaterial, SoNode *ivTexCoords, SoNode *ivTexture, SoShape *shape, SoSeparator *&indexedRoot, SoSeparator *&nonIndexedRoot){ bool ok = true; const osg::DrawArrayLengths *drawArrayLengths = (elementsCount == -1) ? dynamic_cast<const osg::DrawArrayLengths*>(pset) : NULL; int drawArrayLengthsElems; if (drawArrayLengths) { // compute elementsCount elementsCount = 0; drawArrayLengthsElems = 0; for (osg::DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); primItr!=drawArrayLengths->end(); ++primItr, drawArrayLengthsElems++) elementsCount += *primItr; // update stopIndex stopIndex = startIndex + elementsCount; } // NonIndexed data for nonIndexed shapes SoNode *nonIndexedCoords = NULL; SoNode *nonIndexedTexCoords = NULL; SoNormal *nonIndexedNormals = NULL; SoNode *nonIndexedMaterial = NULL; // Normal indexing int normalStart = g->getNormalBinding() == osg::Geometry::BIND_PER_VERTEX ? startIndex : normalIndex; int numNormalsUsed; switch (g->getNormalBinding()) { case osg::Geometry::BIND_OFF: // FIXME: what is meaning of OFF value? case osg::Geometry::BIND_OVERALL: numNormalsUsed = 0; break; case osg::Geometry::BIND_PER_PRIMITIVE_SET: numNormalsUsed = 1; break; case osg::Geometry::BIND_PER_PRIMITIVE: numNormalsUsed = primSize!=0 ? (stopIndex-startIndex)/primSize : (drawArrayLengths ? drawArrayLengths->size() : 1); break; case osg::Geometry::BIND_PER_VERTEX: numNormalsUsed = stopIndex-startIndex; break; } normalIndex += numNormalsUsed; // Color indexing int colorStart = g->getColorBinding() == osg::Geometry::BIND_PER_VERTEX ? startIndex : colorIndex; int numColorsUsed; switch (g->getColorBinding()) { case osg::Geometry::BIND_OFF: case osg::Geometry::BIND_OVERALL: numColorsUsed = 0; break; case osg::Geometry::BIND_PER_PRIMITIVE_SET: numColorsUsed = 1; break; case osg::Geometry::BIND_PER_PRIMITIVE: numColorsUsed = primSize!=0 ? (stopIndex-startIndex)/primSize : (drawArrayLengths ? drawArrayLengths->size() : 1); break; case osg::Geometry::BIND_PER_VERTEX: numColorsUsed = stopIndex-startIndex; break; } colorIndex += numColorsUsed; if (shape->isOfType(SoIndexedShape::getClassTypeId())) { // Convert to SoIndexedShape processIndices(g->getVertexIndices(), drawElemIndices, ((SoIndexedShape*)shape)->coordIndex, startIndex, stopIndex, primSize); if (ivNormals) processIndices(g->getNormalIndices(), drawElemIndices, ((SoIndexedShape*)shape)->normalIndex, normalStart, normalStart+(numNormalsUsed==0 ? 1 : numNormalsUsed), g->getNormalBinding()==osg::Geometry::BIND_PER_VERTEX ? primSize : 0); if (ivMaterial) processIndices(g->getColorIndices(), drawElemIndices, ((SoIndexedShape*)shape)->materialIndex, colorStart, colorStart+(numColorsUsed==0 ? 1 : numColorsUsed), g->getColorBinding()==osg::Geometry::BIND_PER_VERTEX ? primSize : 0); if (ivTexCoords && !ivTexCoords->isOfType(SoTextureCoordinateFunction::getClassTypeId())) processIndices(g->getTexCoordIndices(0), drawElemIndices, ((SoIndexedShape*)shape)->textureCoordIndex, startIndex, stopIndex, primSize); // Post-processing for DrawArrayLengths if (drawArrayLengths && primSize==0 && drawArrayLengths->size()>=2) { postProcessDrawArrayLengths(drawArrayLengths, &((SoIndexedShape*)shape)->coordIndex); if (ivNormals && g->getNormalBinding()==osg::Geometry::BIND_PER_VERTEX) postProcessDrawArrayLengths(drawArrayLengths, &((SoIndexedShape*)shape)->normalIndex); if (ivMaterial && g->getColorBinding()==osg::Geometry::BIND_PER_VERTEX) postProcessDrawArrayLengths(drawArrayLengths, &((SoIndexedShape*)shape)->materialIndex); if (ivTexCoords && !ivTexCoords->isOfType(SoTextureCoordinateFunction::getClassTypeId())) postProcessDrawArrayLengths(drawArrayLengths, &((SoIndexedShape*)shape)->textureCoordIndex); } if (needSeparateTriangles) postProcessTriangleSeparation((SoIndexedShape*)shape, (osg::PrimitiveSet::Mode)pset->getMode(), g->getNormalBinding(), g->getColorBinding()); } else { // Convert to SoNonIndexedShape assert(shape->isOfType(SoNonIndexedShape::getClassTypeId()) && "Shape must be non-indexed."); int i,n = stopIndex-startIndex; // create alternate coordinates if (ivCoords->isOfType(SoCoordinate4::getClassTypeId())) { nonIndexedCoords = new SoCoordinate4; if (ok) { ((SoCoordinate4*)nonIndexedCoords)->point.setNum(n); ok = ivProcessArray<SbVec4f,SoMFVec4f>(g->getVertexIndices(), drawElemIndices, &((SoCoordinate4*)nonIndexedCoords)->point, &((SoCoordinate4*)ivCoords)->point, startIndex, n); } } else { nonIndexedCoords = new SoCoordinate3; if (ok) { ((SoCoordinate3*)nonIndexedCoords)->point.setNum(n); ok = ivProcessArray<SbVec3f,SoMFVec3f>(g->getVertexIndices(), drawElemIndices, &((SoCoordinate3*)nonIndexedCoords)->point, &((SoCoordinate3*)ivCoords)->point, startIndex, n); } } // create alternate texture coordinates if (ivTexCoords) if (ivTexCoords->isOfType(SoTextureCoordinate2::getClassTypeId())) { nonIndexedTexCoords = new SoTextureCoordinate2; if (ok) { ((SoTextureCoordinate2*)nonIndexedTexCoords)->point.setNum(n); ok = ivProcessArray<SbVec2f,SoMFVec2f>(g->getTexCoordIndices(0), drawElemIndices, &((SoTextureCoordinate2*)nonIndexedTexCoords)->point, &((SoTextureCoordinate2*)ivTexCoords)->point, startIndex, n); } } else#ifdef __COIN__ if (ivTexCoords->isOfType(SoTextureCoordinate3::getClassTypeId())) { nonIndexedTexCoords = new SoTextureCoordinate3; if (ok) { ((SoTextureCoordinate3*)nonIndexedTexCoords)->point.setNum(n); ok = ivProcessArray<SbVec3f,SoMFVec3f>(g->getTexCoordIndices(0), drawElemIndices, &((SoTextureCoordinate3*)nonIndexedTexCoords)->point, &((SoTextureCoordinate3*)ivCoords)->point, startIndex, n); } } else#endif // __COIN__ nonIndexedTexCoords = ivTexCoords; // create alternate normals if (ivNormals) { nonIndexedNormals = new SoNormal; if (ok) { nonIndexedNormals->vector.setNum(numNormalsUsed==0 ? 1 : numNormalsUsed); ok = ivProcessArray<SbVec3f,SoMFVec3f>(g->getNormalIndices(), g->getNormalBinding()==osg::Geometry::BIND_PER_VERTEX ? drawElemIndices : NULL, &nonIndexedNormals->vector, &ivNormals->vector, normalStart, numNormalsUsed==0 ? 1 : numNormalsUsed); } } // create alternate material if (ivMaterial) { SoMFColor *dstColorField; if (ivMaterial->isOfType(SoMaterial::getClassTypeId())) { nonIndexedMaterial = new SoMaterial; dstColorField = &((SoMaterial*)nonIndexedMaterial)->diffuseColor; } else { nonIndexedMaterial = new SoBaseColor; dstColorField = &((SoBaseColor*)nonIndexedMaterial)->rgb; } if (ok) { // FIXME: diffuse only? SoMFColor *srcColorField = (ivMaterial->isOfType(SoMaterial::getClassTypeId())) ? &((SoMaterial*)ivMaterial)->diffuseColor : &((SoBaseColor*)ivMaterial)->rgb; dstColorField->setNum(numColorsUsed==0 ? 1 : numColorsUsed); ok = ivProcessArray<SbColor,SoMFColor>(g->getColorIndices(), g->getColorBinding()==osg::Geometry::BIND_PER_VERTEX ? drawElemIndices : NULL, dstColorField, srcColorField, colorStart, numColorsUsed==0 ? 1 : numColorsUsed); } } if (shape->isOfType(SoPointSet::getClassTypeId())) ((SoPointSet*)shape)->numPoints.setValue(elementsCount); else if (shape->isOfType(SoLineSet::getClassTypeId())) { switch (pset->getMode()) { case GL_LINES: assert(elementsCount % 2 == 0 && "elementsCount is not multiple of 2."); n = elementsCount/2; ((SoLineSet*)shape)->numVertices.setNum(n); for (i=0; i<n; i++) ((SoLineSet*)shape)->numVertices.set1Value(i, 2); break; case GL_LINE_STRIP: if (drawArrayLengths) { ((SoLineSet*)shape)->numVertices.setNum(drawArrayLengthsElems); int i=0; for (osg::DrawArrayLengths::const_iterator primItr=drawArrayLengths->begin(); primItr!=drawArrayLengths->end(); ++primItr, i++) ((SoLineSet*)shape)->numVertices.set1Value(i, *primItr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -