📄 converttoinventor.cpp
字号:
template<typename fieldClass, typename fieldItemType>bool ivApplicateIntType(const osg::Array *array, fieldClass &field, int startIndex, int stopIndex, int numItemsUntilMinusOne){ if (field.isOfType(fieldClass::getClassTypeId())) { switch (array->getType()) { case osg::Array::ByteArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, int8_t> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::UByteArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, uint8_t> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::ShortArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, int16_t> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::UShortArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, uint16_t> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::IntArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, int32_t> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::UIntArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, uint32_t> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::FloatArrayType: osgArray2ivMField_template<fieldClass, fieldItemType, float> (array, field, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::Vec4bArrayType: // FIXME: should signed values be handled differently? Like -128..127? case osg::Array::Vec4ubArrayType: osgArray2ivMField_pack_template<fieldClass, fieldItemType, GLubyte, 4> (array, field, 1, 255, 0, startIndex, stopIndex, numItemsUntilMinusOne); return true; case osg::Array::Vec4ArrayType: osgArray2ivMField_pack_template<fieldClass, fieldItemType, float, 4> (array, field, 255.f, 255.f, 0.f, startIndex, stopIndex, numItemsUntilMinusOne); return true; } } return false;}static void osgArray2ivMField(const osg::Array *array, SoMField &field, int startIndex = 0, int stopIndex = 0, int numItemsUntilMinusOne = 0){ if (field.isOfType(SoMFFloat::getClassTypeId())) { switch (array->getType()) { case osg::Array::FloatArrayType: osgArray2ivMField_template<SoMFFloat, float, float> (array, (SoMFFloat&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; } } else if (ivApplicateIntType<SoMFInt32, int32_t>(array, (SoMFInt32&) field, startIndex, stopIndex, numItemsUntilMinusOne)) return; else if (ivApplicateIntType<SoMFUInt32,uint32_t>(array, (SoMFUInt32&)field, startIndex, stopIndex, numItemsUntilMinusOne)) return; else if (ivApplicateIntType<SoMFShort, int16_t>(array, (SoMFShort&) field, startIndex, stopIndex, numItemsUntilMinusOne)) return; else if (ivApplicateIntType<SoMFUShort,uint16_t>(array, (SoMFUShort&)field, startIndex, stopIndex, numItemsUntilMinusOne)) return; else if (field.isOfType(SoMFVec2f::getClassTypeId())) { switch (array->getType()) { case osg::Array::Vec2ArrayType: osgArray2ivMField_composite_template<SoMFVec2f, SbVec2f, float, 2> (array, (SoMFVec2f&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; } } else if (field.isOfType(SoMFVec3f::getClassTypeId())) { switch (array->getType()) { case osg::Array::Vec3ArrayType: osgArray2ivMField_composite_template<SoMFVec3f, SbVec3f, float, 3> (array, (SoMFVec3f&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; case osg::Array::Vec2ArrayType: osgArray2ivMField_composite_template<SoMFVec3f, SbVec3f, float, 2> (array, (SoMFVec3f&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; } } else if (field.isOfType(SoMFVec4f::getClassTypeId())) { switch (array->getType()) { case osg::Array::Vec4ArrayType: osgArray2ivMField_composite_template<SoMFVec4f, SbVec4f, float, 4> (array, (SoMFVec4f&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; } } else if (field.isOfType(SoMFColor::getClassTypeId())) { switch (array->getType()) { case osg::Array::Vec3ArrayType: osgArray2ivMField_composite_template<SoMFColor, SbColor, float, 3> (array, (SoMFColor&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; case osg::Array::Vec4ArrayType: osgArray2ivMField_composite_template<SoMFColor, SbColor, float, 4> (array, (SoMFColor&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; case osg::Array::Vec4ubArrayType: osgArray2ivMField_composite_template<SoMFColor, SbColor, GLubyte, 4> (array, (SoMFColor&)field, startIndex, stopIndex, numItemsUntilMinusOne); return; } }; osg::notify(osg::WARN) << "IvWriter: No direct conversion for array. " << "The file may be broken." << std::endl;}template<typename variableType, typename indexType>bool ivDeindex(variableType *dest, const variableType *src, const int srcNum, const indexType *indices, const int numToProcess){ for (int i=0; i<numToProcess; i++) { int index = indices[i]; if (index<0 || index>=srcNum) return false; dest[i] = src[index]; } return true;}template<typename variableType>bool ivDeindex(variableType *dest, const variableType *src, const int srcNum, const osg::Array *indices, const int numToProcess){ if (int(indices->getNumElements()) < numToProcess) { assert(0 && "Something is wrong: indices array is shorter than numToProcess."); return false; } switch (indices->getType()) { case osg::Array::ByteArrayType: case osg::Array::UByteArrayType: return ivDeindex<variableType, GLbyte>(dest, src, srcNum, (GLbyte*)indices->getDataPointer(), numToProcess); break; case osg::Array::ShortArrayType: case osg::Array::UShortArrayType: return ivDeindex<variableType, GLshort>(dest, src, srcNum, (GLshort*)indices->getDataPointer(), numToProcess); break; case osg::Array::IntArrayType: case osg::Array::UIntArrayType: return ivDeindex<variableType, GLint>(dest, src, srcNum, (GLint*)indices->getDataPointer(), numToProcess); break; default: assert(0 && "Index of strange type."); return false; }}template<typename variableType, typename fieldType>bool ivProcessArray(const osg::Array *indices, const osg::Array *drawElemIndices, fieldType *destField, const fieldType *srcField, int startIndex, int numToProcess){ bool ok = true; if (indices || drawElemIndices) { // "deindex" original data if (indices && !drawElemIndices) ok = ivDeindex<variableType>(destField->startEditing(), srcField->getValues(startIndex), srcField->getNum(), indices, numToProcess); else if (!indices && drawElemIndices) ok = ivDeindex<variableType>(destField->startEditing(), srcField->getValues(startIndex), srcField->getNum(), drawElemIndices, numToProcess); else { osg::notify(osg::WARN) << "IvWriter: NOT IMPLEMENTED" << std::endl; assert(0); // FIXME: } destField->finishEditing(); if (!ok) osg::notify(osg::WARN) << "IvWriter: Can not deindex - bug in model: index out of range." << std::endl; } else { // copy required part of original data const variableType *src = srcField->getValues(startIndex); assert(startIndex+numToProcess <= srcField->getNum() && "Index out of bounds."); variableType *dest = destField->startEditing(); for (int i=0; i<numToProcess; i++) *(dest++) = *(src++); destField->finishEditing(); } return ok;}static void processIndices(const osg::Array *indices, const osg::Array *drawElemIndices, SoMFInt32 &ivIndices, int startIndex, int stopIndex, int numItemsUntilMinusOne){ if (indices || drawElemIndices) { if (indices && !drawElemIndices) osgArray2ivMField(indices, ivIndices, startIndex, stopIndex, numItemsUntilMinusOne); else if (!indices && drawElemIndices) osgArray2ivMField(drawElemIndices, ivIndices, startIndex, stopIndex, numItemsUntilMinusOne); else { osg::notify(osg::WARN) << "IvWriter: NOT IMPLEMENTED" << std::endl; assert(0); // FIXME: } } else { int num = stopIndex-startIndex; if (numItemsUntilMinusOne != 0 && num >= 1) num += (num-1)/numItemsUntilMinusOne; ivIndices.setNum(num); int32_t *a = ivIndices.startEditing(); if (numItemsUntilMinusOne <= 0) for (int i=0,j=startIndex; j<stopIndex; i++,j++) a[i] = j; else for (int i=0,j=startIndex,k=0; j<stopIndex; i++) if (k==numItemsUntilMinusOne) { a[i]=-1; k=0; } else { a[i] = j; j++; k++; } ivIndices.finishEditing(); }}static void postProcessDrawArrayLengths(const osg::DrawArrayLengths *drawArrayLengths, SoMFInt32 *field){ int origNum = field->getNum(); int newNum = origNum + drawArrayLengths->size()-1; field->setNum(newNum); int32_t *a = field->startEditing(); int32_t *src = a + origNum; int32_t *dst = a + newNum; for (osg::DrawArrayLengths::const_reverse_iterator primItr = drawArrayLengths->rbegin(); primItr!=drawArrayLengths->rend()-1; ++primItr) { int c = *primItr; src -= c; dst -= c; memmove(dst, src, sizeof(int32_t)*c); dst--; *dst = -1; } field->finishEditing();}static void postProcessField(const SbIntList &runLengths, osg::PrimitiveSet::Mode primType, SoMFInt32 *field, osg::Geometry::AttributeBinding binding){ if (binding==osg::Geometry::BIND_OFF || binding==osg::Geometry::BIND_OVERALL || binding==osg::Geometry::BIND_PER_PRIMITIVE_SET) return; // make copy of array const int32_t *fieldArray = field->getValues(0); int origNum = field->getNum(); int32_t *tmpArray = new int32_t[origNum]; memcpy(tmpArray, fieldArray, origNum*sizeof(int32_t)); // compute new number of indices int newNum = origNum; const int l = runLengths.getLength(); switch (binding) { case osg::Geometry::BIND_PER_VERTEX: for (int i=0; i<l; i++) newNum += (runLengths[i]-3)*3; break; case osg::Geometry::BIND_PER_PRIMITIVE: for (int i=0; i<l; i++) newNum += runLengths[i]-3; break; default: assert(0); } // process indices field->setNum(newNum); int32_t *src = tmpArray; int32_t *dst = field->startEditing(); int32_t *dst2 = dst; switch (binding) { case osg::Geometry::BIND_PER_VERTEX: for (int i=0; i<l; i++) { int c = runLengths[i]; *(dst++) = *(src++); *(dst++) = *(src++); *(dst++) = *(src++); bool even = true; int32_t first = *(src-3); for (int j=3; j<c; j++) { *(dst++) = -1; if (primType==osg::PrimitiveSet::TRIANGLE_STRIP) { if (even) { *(dst++) = *(src-1); *(dst++) = *(src-2); } else { *(dst++) = *(src-2); *(dst++) = *(src-1); } even = !even; } else if (primType==osg::PrimitiveSet::TRIANGLE_FAN) { *(dst++) = first; *(dst++) = *(src-1); } // FIXME: are QUADS, QUAD_STRIP, and POLYGON requiring some handling here as well? PCJohn-2007-08-25 else { *(dst++) = *(src-2); *(dst++) = *(src-1); } *(dst++) = *(src++); } src++; // skip -1 if (i != l-1) *(dst++) = -1; } break; case osg::Geometry::BIND_PER_PRIMITIVE: for (int i=0; i<l; i++,src++) { int c = runLengths[i]; *(dst++) = *(src); for (int j=3; j<c; j++) *(dst++) = *(src); } break; default: assert(0); } assert(dst2+newNum == dst && "Something wrong in the loop."); field->finishEditing(); // free resources
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -