static unsigned int ConvertOpenCOLLADAMeshVertexDataToGLTFMeshAttributes(const COLLADAFW::MeshVertexData &vertexData, GLTF::IndexSetToMeshAttributeHashmap &meshAttributes) { // The following are OpenCOLLADA fmk issues preventing doing a totally generic processing of sources //1. "set"(s) other than texCoord don't have valid input infos //2. not the original id in the source std::string name; size_t length, elementsCount; size_t stride = 0; size_t size = 0; size_t byteOffset = 0; size_t inputLength = 0; size_t setCount = vertexData.getNumInputInfos(); bool unpatchedOpenCOLLADA = (setCount == 0); // reliable heuristic to know if the input have not been set if (unpatchedOpenCOLLADA) setCount = 1; for (size_t indexOfSet = 0 ; indexOfSet < setCount ; indexOfSet++) { if (!unpatchedOpenCOLLADA) { name = vertexData.getName(indexOfSet); size = vertexData.getStride(indexOfSet); inputLength = vertexData.getLength(indexOfSet); } else { // for unpatched version of OpenCOLLADA we need this work-around. name = GLTF::GLTFUtils::generateIDForType("buffer").c_str(); size = 3; //only normal and positions should reach this code inputLength = vertexData.getLength(0); } //name is the id length = inputLength ? inputLength : vertexData.getValuesCount(); elementsCount = length / size; unsigned char *sourceData = 0; size_t sourceSize = 0; GLTF::ComponentType componentType = GLTF::NOT_AN_ELEMENT_TYPE; switch (vertexData.getType()) { case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { componentType = GLTF::FLOAT; stride = sizeof(float) * size; const COLLADAFW::FloatArray* array = vertexData.getFloatValues(); sourceData = (unsigned char*)array->getData() + byteOffset; sourceSize = length * sizeof(float); byteOffset += sourceSize; //Doh! - OpenCOLLADA store all sets contiguously in the same array } break; case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { /* sourceType = DOUBLE; const DoubleArray& array = vertexData.getDoubleValues()[indexOfSet]; const size_t count = array.getCount(); sourceData = (void*)array.getData(); sourceSize = count * sizeof(double); */ // Warning if can't make "safe" conversion } break; default: case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: //FIXME report error break; } // FIXME: the source could be shared, store / retrieve it here shared_ptr <GLTFBufferView> cvtBufferView = createBufferViewWithAllocatedBuffer(name, sourceData, 0, sourceSize, false); shared_ptr <GLTFMeshAttribute> cvtMeshAttribute(new GLTFMeshAttribute()); cvtMeshAttribute->setBufferView(cvtBufferView); cvtMeshAttribute->setComponentsPerAttribute(size); cvtMeshAttribute->setByteStride(stride); cvtMeshAttribute->setComponentType(componentType); cvtMeshAttribute->setCount(elementsCount); meshAttributes[(unsigned int)indexOfSet] = cvtMeshAttribute; } return (unsigned int)setCount; }
static unsigned int __ConvertOpenCOLLADAMeshVertexDataToGLTFAccessors(const COLLADAFW::MeshVertexData &vertexData, GLTFMesh* mesh, GLTF::Semantic semantic, size_t allowedComponentsPerAttribute, shared_ptr<GLTFProfile> profile) { // The following are OpenCOLLADA fmk issues preventing doing a totally generic processing of sources //1. "set"(s) other than texCoord don't have valid input infos //2. not the original id in the source std::string id; size_t length, elementsCount; size_t stride = 0; size_t componentsPerElement = 0; size_t byteOffset = 0; size_t inputLength = 0; size_t setCount = vertexData.getNumInputInfos(); bool unpatchedOpenCOLLADA = (setCount == 0); // reliable heuristic to know if the input have not been set if (unpatchedOpenCOLLADA) setCount = 1; for (size_t indexOfSet = 0 ; indexOfSet < setCount ; indexOfSet++) { bool meshAttributeOwnsBuffer = false; if (!unpatchedOpenCOLLADA) { id = vertexData.getName(indexOfSet); componentsPerElement = vertexData.getStride(indexOfSet); inputLength = vertexData.getLength(indexOfSet); } else { // for unpatched version of OpenCOLLADA we need this work-around. id = GLTF::GLTFUtils::generateIDForType("buffer").c_str(); componentsPerElement = 3; //only normal and positions should reach this code inputLength = vertexData.getLength(0); } length = inputLength ? inputLength : vertexData.getValuesCount(); elementsCount = length / componentsPerElement; unsigned char *sourceData = 0; size_t sourceSize = 0; GLTF::ComponentType componentType = GLTF::NOT_AN_ELEMENT_TYPE; switch (vertexData.getType()) { case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { componentType = GLTF::FLOAT; stride = sizeof(float) * componentsPerElement; const COLLADAFW::FloatArray* array = vertexData.getFloatValues(); sourceData = (unsigned char*)array->getData() + byteOffset; sourceSize = length * sizeof(float); byteOffset += sourceSize; //Doh! - OpenCOLLADA store all sets contiguously in the same array } break; case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { //FIXME: handle this /* sourceType = DOUBLE; const DoubleArray& array = vertexData.getDoubleValues()[indexOfSet]; const size_t count = array.getCount(); sourceData = (void*)array.getData(); sourceSize = length * sizeof(double); */ // Warning if can't make "safe" conversion } break; default: case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: //FIXME report error break; } //FIXME: this is assuming float if (allowedComponentsPerAttribute != componentsPerElement) { sourceSize = elementsCount * sizeof(float) * allowedComponentsPerAttribute; float *adjustedSource = (float*)malloc(sourceSize); float *originalSource = (float*)sourceData; size_t adjustedStride = sizeof(float) * allowedComponentsPerAttribute; if (allowedComponentsPerAttribute < componentsPerElement) { for (size_t i = 0 ; i < elementsCount ; i++) { for (size_t j= 0 ; j < allowedComponentsPerAttribute ; j++) { adjustedSource[(i*allowedComponentsPerAttribute) + j] = originalSource[(i*componentsPerElement) + j]; } } } else { //FIXME: unlikely but should be taken care of } //Free source before replacing it if (meshAttributeOwnsBuffer) { free(sourceData); } componentsPerElement = allowedComponentsPerAttribute; meshAttributeOwnsBuffer = true; sourceData = (unsigned char*)adjustedSource; stride = adjustedStride; } // FIXME: the source could be shared, store / retrieve it here shared_ptr <GLTFBufferView> cvtBufferView = createBufferViewWithAllocatedBuffer(id, sourceData, 0, sourceSize, meshAttributeOwnsBuffer); shared_ptr <GLTFAccessor> cvtMeshAttribute(new GLTFAccessor(profile, profile->getGLTypeForComponentType(componentType, componentsPerElement))); cvtMeshAttribute->setBufferView(cvtBufferView); cvtMeshAttribute->setByteStride(stride); cvtMeshAttribute->setCount(elementsCount); mesh->setMeshAttribute(semantic, indexOfSet, cvtMeshAttribute); } return (unsigned int)setCount; }