⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 converttoinventor.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  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 + -