📄 converttoinventor.cpp
字号:
//// ConvertToInventor converts OSG scene graph to Inventor or VRML 1 scene graph//// It requires OSG and Inventor compatible library, such as Coin,// SGI Inventor , or TGS Inventor.////// Autor: PCJohn (peciva _at fit.vutbr.cz)//// License: public domain////// THIS SOFTWARE IS NOT COPYRIGHTED//// This source code is offered for use in the public domain.// You may use, modify or distribute it freely.//// This source code is distributed in the hope that it will be useful but// WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY// DISCLAIMED. This includes but is not limited to warranties of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.//// If you find the source code useful, authors will kindly welcome// if you give them credit and keep their names with their source code,// but you are not forced to do so.//#include <osg/BlendFunc>#include <osg/Billboard>#include <osg/Geode>#include <osg/Geometry>#include <osg/Group>#include <osg/LightModel>#include <osg/LOD>#include <osg/Material>#include <osg/MatrixTransform>#include <osg/Node>#include <osg/NodeVisitor>#include <osg/PositionAttitudeTransform>#include <osg/PrimitiveSet>#include <osg/ShapeDrawable>#include <osg/TexEnv>#include <osg/TexGen>#include <Inventor/nodes/SoBaseColor.h>#include <Inventor/nodes/SoCoordinate3.h>#include <Inventor/nodes/SoCoordinate4.h>#include <Inventor/nodes/SoCube.h>#include <Inventor/nodes/SoCone.h>#include <Inventor/nodes/SoCylinder.h>#include <Inventor/nodes/SoFaceSet.h>#include <Inventor/nodes/SoIndexedFaceSet.h>#include <Inventor/nodes/SoIndexedLineSet.h>#include <Inventor/nodes/SoIndexedTriangleStripSet.h>#include <Inventor/nodes/SoLightModel.h>#include <Inventor/nodes/SoLineSet.h>#include <Inventor/nodes/SoLOD.h>#include <Inventor/nodes/SoLevelOfDetail.h>#include <Inventor/nodes/SoMaterial.h>#include <Inventor/nodes/SoMatrixTransform.h>#include <Inventor/nodes/SoNode.h>#include <Inventor/nodes/SoNormal.h>#include <Inventor/nodes/SoNormalBinding.h>#include <Inventor/nodes/SoPointSet.h>#include <Inventor/nodes/SoSeparator.h>#include <Inventor/nodes/SoShapeHints.h>#include <Inventor/nodes/SoSphere.h>#include <Inventor/nodes/SoTexture2.h>#include <Inventor/nodes/SoTextureCoordinate2.h>#include <Inventor/nodes/SoTextureCoordinateEnvironment.h>#include <Inventor/nodes/SoTransform.h>#include <Inventor/nodes/SoTranslation.h>#include <Inventor/nodes/SoTriangleStripSet.h>#include <Inventor/fields/SoFields.h>#ifdef __COIN__#include <Inventor/nodes/SoTextureCoordinate3.h>#include <Inventor/nodes/SoTransparencyType.h>#include <Inventor/VRMLnodes/SoVRMLBillboard.h>#endif#include "ConvertToInventor.h"#include <assert.h>#define DEBUG_IV_WRITER 1// Considerations for VRML1 support://// SoSeparator: supported (only renderCulling field)// SoCoordinate3: supported// SoCoordinate4: no -> conversion to Coordinate3 required <---- missing// SoTextureCoordinate2: supported// SoTextureCoordinate3: no - 3D textures not supported by VRML1// SoTextureCoordinateEnvironment no <- should texturing be disabled in this case?// SoTextureCoordinateBinding: no -> indexing is probably mandatory// SoNormal: supported// SoNormalBinding: supported (all modes supported, including non-indexed modes)// SoMaterial: supported// SoMaterialBinding: supported (all modes supported, including non-indexed modes)// SoBaseColor: no -> using SoMaterial instead// SoPointSet: supported// SoLineSet: no -> using SoIndexedListSet instead// SoIndexedLineSet: supported// SoIndexedTriangleStripSet: no -> using SoIndexedFaceSet instead// SoTriangleStripSet: no -> using SoIndexedFaceSet instead// SoMatrixTransform: supported// SoTransform: supported// SoTransparencyType: no <---- missing// SoShapeHints: supported// SoCone,SoCube,SoCylinder,SoSphere supported// SoTranslation supported// SoLightModel: ?// SoLOD: supported// SoLevelOfDetail: no// Node list from VRML1 documentation:// shape nodes: AsciiText, Cone, Cube, Cylinder, IndexedFaceSet, IndexedLineSet, PointSet, Sphere// properties nodes: Coordinate3, FontStyle, Info, Material, MaterialBinding, Normal, NormalBinding,// Texture2, Texture2Transform, TextureCoordinate2, ShapeHints// transformantion nodes: MatrixTransform, Rotation, Scale, Transform, Translation// group nodes: Separator, Switch, WWWAnchor, LOD// cameras: OrthographicCamera, PerspectiveCamera// lights: DirectionalLight, PointLight, SpotLight// others: WWWInlineConvertToInventor::ConvertToInventor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN){ // Enable/disable using of some extensions introduced by TGS and Coin. // // For instance, GL_REPLACE texturing mode is extension // and it will not be used if extensions are not enabled.#ifdef __COIN__ useIvExtensions = true;#else useIvExtensions = false;#endif vrml1Conversion = false; uniqueIdGenerator = 1; // Scene root ivRoot = new SoSeparator; ivRoot->ref(); // OSG -> Inventor coordinate system conversion SoMatrixTransform *mt = new SoMatrixTransform; mt->matrix.setValue(1.f, 0.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); ivRoot->addChild(mt);#if 0 // Setting everything to defaults may not be correct option // because the user may want to have model whose material,etc. // will be specified up in the scene graph and he may, for instance, // reuse the model with different materials. // However, I am not sure anyway. PCJohn-2007-08-27 // OSG defaults to: Inventor defaults to: // GL_LIGHTING enabled enabled SoLightModel *lm = new SoLightModel; lm->model = SoLightModel::PHONG; ivRoot->addChild(lm); // OSG defaults to: Inventor defaults to: // lighting: one side one side lighting // frontFace: COUNTER_CLOCKWISE COUNTER_CLOCKWISE // culling: DISABLED DISABLED // faceCulling: GL_BACK GL_BACK SoShapeHints *sh = new SoShapeHints; sh->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING; ivRoot->addChild(sh); // Make sure texturing is OFF ivRoot->addChild(new SoTexture2D); // Put default material ivRoot->addChild(new SoMaterial);#endif // initialize Inventor state stack ivStack.push(InventorState::createTopLevelState(ivRoot));}ConvertToInventor::~ConvertToInventor(){ assert(ivStack.size() == 1 && "Not all InventorStates were popped from ivStack."); if (ivRoot) ivRoot->unref();}SoNode* ConvertToInventor::getIvSceneGraph() const{ return ivRoot;}void ConvertToInventor::apply(osg::Node &node){#ifdef DEBUG_IV_WRITER osg::notify(osg::INFO) << "IvWriter: node traversed" << std::endl;#endif traverse(node);}template<typename fieldClass, typename ivType, typename osgType>void osgArray2ivMField_template(const osg::Array *array, fieldClass &field, int startIndex = 0, int stopIndex = 0, int numItemsUntilMinusOne = 0){ int i,num = array->getNumElements(); if (startIndex!=0 || stopIndex!=0) { num = stopIndex - startIndex; assert(stopIndex >= startIndex); assert(startIndex >= 0 && stopIndex >= 0); assert(stopIndex <= int(array->getNumElements())); } // update num if numItemsUntilMinusOne > 0 if (numItemsUntilMinusOne > 0 && num >= 1) num += (num-1) / numItemsUntilMinusOne; field.setNum(num); ivType *a = field.startEditing(); osgType *ptr = (osgType*)array->getDataPointer() + startIndex; if (numItemsUntilMinusOne <= 0) for (i=0; i<num; i++, ptr++) a[i] = ivType(*ptr); else { int z; for (i=0, z=0; i<num; i++) if (z == numItemsUntilMinusOne) { a[i] = -1; z = 0; } else { a[i] = ivType(*ptr); ptr++; z++; } } field.finishEditing();}template<typename ivType, typename osgType, int shift>void osgArray2ivMField_composite_template_worker(ivType *dest, osgType *src, int num, int numItemsUntilMinusOne = 0){ for (int i=0; i<num; i++, src+=shift) dest[i] = ivType(src);}template<>void osgArray2ivMField_composite_template_worker<SbColor, GLubyte, 4>(SbColor *dest, GLubyte *src, int num, int numItemsUntilMinusOne){ for (int i=0; i<num; i++, src+=4) dest[i].setValue(src[0]/255.f, src[1]/255.f, src[2]/255.f);}template<>void osgArray2ivMField_composite_template_worker<SbVec3f, float, 2>(SbVec3f *dest, float *src, int num, int numItemsUntilMinusOne){ for (int i=0; i<num; i++, src+=2) dest[i].setValue(src[0], src[1], 0.f);}template<typename fieldClass, typename ivType, typename osgType, int shift>void osgArray2ivMField_composite_template(const osg::Array *array, fieldClass &field, int startIndex = 0, int stopIndex = 0, int numItemsUntilMinusOne = 0){ int num = array->getNumElements(); if (startIndex!=0 || stopIndex!=0) { num = stopIndex - startIndex; assert(stopIndex >= startIndex); assert(startIndex >= 0 && stopIndex >= 0); assert(stopIndex <= int(array->getNumElements())); } assert(numItemsUntilMinusOne <= 0 && "Composite template must have numItemsUntilMinusOne set to 0."); field.setNum(num); ivType *a = field.startEditing(); osgType *ptr = (osgType*)array->getDataPointer() + startIndex; osgArray2ivMField_composite_template_worker<ivType, osgType, shift>(a, ptr, num, 0); field.finishEditing();}template<typename fieldClass, typename ivType, typename osgType, int numComponents>void osgArray2ivMField_pack_template(const osg::Array *array, fieldClass &field, osgType mul, osgType max, osgType min, int startIndex = 0, int stopIndex = 0, int numItemsUntilMinusOne = 0){ int i,num = array->getNumElements(); if (startIndex!=0 || stopIndex!=0) { num = stopIndex - startIndex; assert(stopIndex >= startIndex); assert(startIndex >= 0 && stopIndex >= 0); assert(stopIndex <= int(array->getNumElements())); } assert(numItemsUntilMinusOne <= 0 && "Pack template must have numItemsUntilMinusOne set to 0."); field.setNum(num); ivType *a = field.startEditing(); osgType *ptr = (osgType*)array->getDataPointer() + startIndex; for (i=0; i<num; i++, ptr++) { a[i] = ivType(0); for (int j=0; j<numComponents; j++) { osgType tmp = ptr[j]*mul; if (tmp > max) tmp = max; if (tmp < min) tmp = min; a[i] |= ivType(tmp) << (((numComponents-1)*8)-(j*8)); } } field.finishEditing();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -