Ejemplo n.º 1
0
 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;
 }
Ejemplo n.º 2
0
    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;
    }