📄 converttoinventor.cpp
字号:
delete tmpArray;}static void postProcessTriangleSeparation(SoIndexedShape *shape, osg::PrimitiveSet::Mode primType, osg::Geometry::AttributeBinding normalBinding, osg::Geometry::AttributeBinding colorBinding){ // compute runLengths SbIntList runLengths; const int32_t *a = shape->coordIndex.getValues(0); int origNum = shape->coordIndex.getNum(); int l = 0; for (int i=0; i<origNum; i++,a++) { if (*a == -1) { runLengths.append(l); l = 0; } else l++; } if (l != 0) // append final l if field is not finished by -1 runLengths.append(l); postProcessField(runLengths, primType, &shape->coordIndex, osg::Geometry::BIND_PER_VERTEX); postProcessField(runLengths, primType, &shape->normalIndex, normalBinding); postProcessField(runLengths, primType, &shape->materialIndex, colorBinding); bool notUseTexCoords = shape->textureCoordIndex.getNum()==0 || (shape->textureCoordIndex.getNum()==1 && shape->textureCoordIndex[0] == -1); if (!notUseTexCoords) postProcessField(runLengths, primType, &shape->textureCoordIndex, osg::Geometry::BIND_PER_VERTEX);}static SoMaterialBinding* createMaterialBinding(const osg::Geometry *g, bool isMaterialIndexed){ SoMaterialBinding *materialBinding = new SoMaterialBinding; switch (g->getColorBinding()) { case osg::Geometry::BIND_OFF: // OFF means use material from state set (if any) for whole geometry case osg::Geometry::BIND_OVERALL: case osg::Geometry::BIND_PER_PRIMITIVE_SET: materialBinding->value = SoMaterialBinding::OVERALL; break; case osg::Geometry::BIND_PER_PRIMITIVE: materialBinding->value = (isMaterialIndexed) ? SoMaterialBinding::PER_PART_INDEXED : SoMaterialBinding::PER_PART; break; case osg::Geometry::BIND_PER_VERTEX: materialBinding->value = (isMaterialIndexed) ? SoMaterialBinding::PER_VERTEX_INDEXED : SoMaterialBinding::PER_VERTEX; break; default: assert(0); } return materialBinding;}static SoNormalBinding* createNormalBinding(const osg::Geometry *g, bool areNormalsIndexed){ // Convert normal binding SoNormalBinding *normalBinding = new SoNormalBinding; switch (g->getNormalBinding()) { case osg::Geometry::BIND_OFF: // FIXME: what to do with BIND_OFF value? case osg::Geometry::BIND_OVERALL: case osg::Geometry::BIND_PER_PRIMITIVE_SET: normalBinding->value = SoNormalBinding::OVERALL; break; case osg::Geometry::BIND_PER_PRIMITIVE: normalBinding->value = (areNormalsIndexed) ? SoNormalBinding::PER_PART_INDEXED : SoNormalBinding::PER_PART; break; case osg::Geometry::BIND_PER_VERTEX: normalBinding->value = (areNormalsIndexed) ? SoNormalBinding::PER_VERTEX_INDEXED : SoNormalBinding::PER_VERTEX; break; default: assert(0); } return normalBinding;}static SoTextureCoordinateBinding* createTexCoordBinding(SbBool useIndexing){ SoTextureCoordinateBinding *b = new SoTextureCoordinateBinding; b->value.setValue(useIndexing ? SoTextureCoordinateBinding::PER_VERTEX_INDEXED : SoTextureCoordinateBinding::PER_VERTEX); return b;}static SoTexture2::Model convertTexEnvMode(osg::TexEnv::Mode osgMode, bool useIvExtensions){ switch (osgMode) { case GL_MODULATE: return SoTexture2::MODULATE; case GL_REPLACE: return (SoTexture2::Model)(useIvExtensions ? GL_REPLACE : GL_MODULATE); case GL_BLEND: return SoTexture2::BLEND; case GL_DECAL: return SoTexture2::DECAL; default: assert(0); return SoTexture2::MODULATE; }}static SoTexture2::Wrap convertTextureWrap(osg::Texture::WrapMode osgWrap){ // notes on support of CLAMP_TO_BORDER, CLAMP_TO_EDGE, and MIRRORED_REPEAT: // original SGI Inventor: no // Coin: no (until current version Coin 2.5.0b3) // TGS Inventor: introduced in TGS Inventor 5.0 (available in SoTexture class) // note: Coin (since 2.0) uses CLAMP_TO_EDGE for rendering if SoTexture2::CLAMP is specified. switch (osgWrap) { case osg::Texture::CLAMP: case osg::Texture::CLAMP_TO_BORDER: case osg::Texture::CLAMP_TO_EDGE: return SoTexture2::CLAMP; case osg::Texture::REPEAT: case osg::Texture::MIRROR: return SoTexture2::REPEAT; default: assert(0); return SoTexture2::REPEAT; }}static void setSoTransform(SoTransform *tr, const osg::Vec3 &translation, const osg::Quat &rotation, const osg::Vec3 &scale = osg::Vec3(1.,1.,1.)){ tr->translation.setValue(translation.ptr()); tr->rotation.setValue(rotation.x(), rotation.y(), rotation.z(), rotation.w()); tr->scaleFactor.setValue(scale.ptr()); //tr->scaleCenter.setValue(osg::Vec3f(node.getPivotPoint())); <- testing required on this line}static bool updateMode(bool &flag, const osg::StateAttribute::GLModeValue value){ if (value & osg::StateAttribute::INHERIT) return flag; else return (flag = (value & osg::StateAttribute::ON));}ConvertToInventor::InventorState* ConvertToInventor::createInventorState(const osg::StateSet *ss){ // Push on stack const InventorState *ivPrevState = &ivStack.top(); ivStack.push(*ivPrevState); InventorState *ivState = &ivStack.top(); // Inventor graph ivState->ivHead = new SoSeparator; ivPrevState->ivHead->addChild(ivState->ivHead); if (ss) { // // Lighting // // enable/disable lighting updateMode(ivState->osgLighting, ss->getMode(GL_LIGHTING)); if (ivState->osgLighting != ivPrevState->osgLighting) { SoLightModel *lm = new SoLightModel; lm->model = (ivState->osgLighting) ? SoLightModel::PHONG : SoLightModel::BASE_COLOR; ivState->ivHead->addChild(lm); } // two-sided lighting const osg::LightModel *osgLM = dynamic_cast<const osg::LightModel*>(ss->getAttribute(osg::StateAttribute::LIGHTMODEL)); if (osgLM) ivState->osgTwoSided = osgLM->getTwoSided(); // front face const osg::FrontFace *osgFF = dynamic_cast<const osg::FrontFace*>(ss->getAttribute(osg::StateAttribute::FRONTFACE)); if (osgFF) ivState->osgFrontFace = osgFF->getMode(); // face culling updateMode(ivState->osgCullFaceEnabled, ss->getMode(GL_CULL_FACE)); const osg::CullFace *osgCF = dynamic_cast<const osg::CullFace*>(ss->getAttribute(osg::StateAttribute::CULLFACE)); if (osgCF) ivState->osgCullFace = osgCF->getMode(); // detect state change if (ivState->osgTwoSided != ivPrevState->osgTwoSided || ivState->osgFrontFace != ivPrevState->osgFrontFace || ivState->osgCullFaceEnabled != ivPrevState->osgCullFaceEnabled || ivState->osgCullFace != ivPrevState->osgCullFace) { // new SoShapeHints SoShapeHints *sh = new SoShapeHints; if (ivState->osgTwoSided) { // warn if face culling is on if (ivState->osgCullFaceEnabled) osg::notify(osg::WARN) << "IvWriter: Using face culling and two-sided lighting together! " "Ignoring face culling." << std::endl; // set two-sided lighting and backface culling off sh->vertexOrdering = ivState->osgFrontFace==osg::FrontFace::COUNTER_CLOCKWISE ? SoShapeHints::COUNTERCLOCKWISE : SoShapeHints::CLOCKWISE; sh->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; } else { // set one-sided lighting and backface optionally if (ivState->osgCullFaceEnabled) { // determine vertex ordering bool ccw = ivState->osgFrontFace==osg::FrontFace::COUNTER_CLOCKWISE; if (ivState->osgCullFace != osg::CullFace::BACK) ccw = !ccw; if (ccw) // Warn if culling the lit faces while rendering unlit faces. // Inventor does not support this setup and it lits the unculled faces only. osg::notify(osg::WARN) << "IvWriter: Culling was set in a way that one-sided lighting will lit the culled sides of faces. " "Using lighting on correct faces." << std::endl; // face culling on sh->vertexOrdering = ccw ? SoShapeHints::COUNTERCLOCKWISE : SoShapeHints::CLOCKWISE; sh->shapeType = SoShapeHints::SOLID; } else // no face culling sh->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; } ivState->ivHead->addChild(sh); } // // Texturing // // FIXME: handle 1D and 3D textures // get OSG state ivState->osgTexture = dynamic_cast<const osg::Texture*>(ss->getTextureAttribute(0, osg::StateAttribute::TEXTURE)); ivState->osgTexEnv = dynamic_cast<const osg::TexEnv*>(ss->getTextureAttribute(0, osg::StateAttribute::TEXENV)); updateMode(ivState->osgTexture2Enabled, ss->getTextureMode(0, GL_TEXTURE_2D)); // detect state changes if (ivState->osgTexture2Enabled != ivPrevState->osgTexture2Enabled || ivState->osgTexture != ivPrevState->osgTexture || ivState->osgTexEnv != ivPrevState->osgTexEnv) { if (!ivState->osgTexture2Enabled || ivState->osgTexture==NULL || ivState->osgTexture->getImage(0)==NULL) // empty texture disables texturing ivState->ivTexture = new SoTexture2; else { // reuse texture if possible ivState->ivTexture = ivTexturesMap[ivState->osgTexture][ivState->osgTexEnv]; // if nothing for reusing, create new if (!ivState->ivTexture) { // create texture ivState->ivTexture = new SoTexture2; ivTexturesMap[ivState->osgTexture][ivState->osgTexEnv] = ivState->ivTexture; // texture file name const std::string &textureName = ivState->osgTexture->getImage(0)->getFileName(); ivState->ivTexture->filename.setValue(textureName.c_str()); // FIXME: handle inlined texture data in the files // wrap ivState->ivTexture->wrapS.setValue(convertTextureWrap( ivState->osgTexture->getWrap(osg::Texture::WRAP_S))); ivState->ivTexture->wrapT.setValue(convertTextureWrap( ivState->osgTexture->getWrap(osg::Texture::WRAP_T))); // texture environment if (ivState->osgTexEnv) { ivState->ivTexture->model.setValue(convertTexEnvMode( ivState->osgTexEnv->getMode(), useIvExtensions)); osg::Vec4 color = ivState->osgTexEnv->getColor(); ivState->ivTexture->blendColor.setValue(color.r(), color.g(), color.b()); } // notes on support of borderColor and borderWidth: // original SGI Inventor: no // Coin: no (until current version 2.5.0b3) // TGS Inventor: introduced in version 5.0 (as SoTexture::borderColor) // FIXME: implement support for texture filtering } } } // Texture coordinate generation updateMode(ivState->osgTexGenS, ss->getTextureMode(0, GL_TEXTURE_GEN_S)); updateMode(ivState->osgTexGenT, ss->getTextureMode(0, GL_TEXTURE_GEN_T)); ivState->osgTexGen = dynamic_cast<const osg::TexGen*>(ss->getTextureAttribute(0, osg::StateAttribute::TEXGEN)); // Material parameters const osg::Material *osgMaterial = dynamic_cast<const osg::Material*>(ss->getAttribute(osg::StateAttribute::MATERIAL)); if (osgMaterial) ivState->osgMaterial = osgMaterial; if (ivState->osgMaterial != ivPrevState->osgMaterial) { ivState->ivMaterial = new SoMaterial; assert(ivState->osgMaterial); // Warn if using two side materials // FIXME: The geometry can be probably doubled, or some estimation can be made // whether only front or back faces are used. if (ivState->osgMaterial->getAmbientFrontAndBack() == false || ivState->osgMaterial->getDiffuseFrontAndBack() == false || ivState->osgMaterial->getSpecularFrontAndBack() == false || ivState->osgMaterial->getEmissionFrontAndBack() == false || ivState->osgMaterial->getShininessFrontAndBack() == false) osg::notify(osg::WARN) << "IvWriter: Model contains different materials for front and " "back faces. This is not handled properly. Using front material only." << std::endl; // Convert colors // OSG represents colors by: Vec3, Vec4,Vec4ub // Inventor by: uint32 (RGBA, by SoPackedColor), SbColor (Vec3f, by SoMaterial and SoBaseColor) // note: Inventor can use DIFFUSE component inside a shape only. Material is set for whole shape. // Although SoMaterial is used only, SoPackedColor may bring some possibilities on per-vertex // alpha and SoBaseColor may be useful on pre-lit scene. if (ivState->osgMaterial->getColorMode() != osg::Material::DIFFUSE && ivState->osgMaterial->getColorMode() != osg::Material::OFF) { if (ivState->osgMaterial->getColorMode() == osg::Material::AMBIENT_AND_DIFFUSE) osg::notify(osg::WARN) << "IvWriter: The model is using AMBIENT_AND_DIFFUSE material " "mode while Inventor supports DIFFUSE mode only. " "The model colors may not much exactly." << std::endl; else osg::notify(osg::WARN) << "IvWriter: The model is not using DIFFUSE material mode and " "Inventor supports DIFFUSE mode only. " "The model colors may not be correct." << std::endl; } // Convert material components // FIXME: Transparency can be specified for each component in OSG // and just globally in Inventor. // Solutions? It can be averaged or just diffuse can be used. ((SoMaterial*)ivState->ivMaterial)->ambientColor.setValue(osgMaterial->getAmbient( osgMaterial->getAmbientFrontAndBack() ? osg::Material::FRONT_AND_BACK : osg::Material::FRONT).ptr()); ((SoMaterial*)ivState->ivMaterial)->diffuseColor.setValue(osgMaterial->getDiffuse( osgMaterial->getDiffuseFrontAndBack() ? osg::Material::FRONT_AND_BACK : osg::Material::FRONT).ptr()); ((SoMaterial*)ivState->ivMaterial)->specularColor.setValue(osgMaterial->getSpecular(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -