Пример #1
0
 shared_ptr <MeshAttributeVector> GLTFMesh::meshAttributes() {
     shared_ptr <MeshAttributeVector> meshAttributes(new MeshAttributeVector());
     vector <GLTF::Semantic> allSemantics = this->allSemantics();
     std::map<string, unsigned int> semanticAndSetToIndex;
     
     for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
         GLTF::Semantic semantic = allSemantics[i];
         size_t attributesCount = this->getMeshAttributesCountForSemantic(semantic);
         for (size_t j = 0 ; j < attributesCount ; j++) {
             shared_ptr <GLTF::GLTFAccessor> selectedMeshAttribute = this->getMeshAttribute(semantic, j);
             unsigned int indexSet = j;
             std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
             unsigned int size = (unsigned int)meshAttributes->size();
             semanticAndSetToIndex[semanticIndexSetKey] = size;
             
             meshAttributes->push_back(selectedMeshAttribute);
         }
     }
     return meshAttributes;
 }
Пример #2
0
 shared_ptr <MeshAttributeVector> GLTFMesh::meshAttributes() {
     shared_ptr <MeshAttributeVector> meshAttributes(new MeshAttributeVector());
     vector <GLTF::Semantic> allSemantics = this->allSemantics();
     std::map<string, unsigned int> semanticAndSetToIndex;
     
     for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
         IndexSetToMeshAttributeHashmap& indexSetToMeshAttribute = this->getMeshAttributesForSemantic(allSemantics[i]);
         IndexSetToMeshAttributeHashmap::const_iterator meshAttributeIterator;
         for (meshAttributeIterator = indexSetToMeshAttribute.begin() ; meshAttributeIterator != indexSetToMeshAttribute.end() ; meshAttributeIterator++) {
             //(*it).first;             // the key value (of type Key)
             //(*it).second;            // the mapped value (of type T)
             shared_ptr <GLTF::GLTFMeshAttribute> selectedMeshAttribute = (*meshAttributeIterator).second;
             unsigned int indexSet = (*meshAttributeIterator).first;
             GLTF::Semantic semantic = allSemantics[i];
             std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
             unsigned int size = (unsigned int)meshAttributes->size();
             semanticAndSetToIndex[semanticIndexSetKey] = size;
             
             meshAttributes->push_back(selectedMeshAttribute);
         }
     }
     return meshAttributes;
 }
Пример #3
0
bool JSONMesh::buildUniqueIndexes()
{
    unsigned int startIndex = 1; // begin at 1 because the hashtable will return 0 when the element is not present
    unsigned int endIndex = 0;
    unsigned int primitiveCount = (unsigned int)_primitives.size();
    unsigned int maxVertexAttributes = 0;

    if (primitiveCount == 0) {
        // FIXME: report error
        return false;
    }

    //in _allOriginalAccessors we'll get the flattened list of all the accessors as a vector.
    //fill semanticAndSetToIndex with key: (semantic, indexSet) value: index in _allOriginalAccessors vector.
    _allOriginalAccessors.clear();
    vector <JSONExport::Semantic> allSemantics = this->allSemantics();
    std::map<string, unsigned int> semanticAndSetToIndex;

    for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
        IndexSetToAccessorHashmap& indexSetToAccessor = this->getAccessorsForSemantic(allSemantics[i]);
        IndexSetToAccessorHashmap::const_iterator accessorIterator;
        for (accessorIterator = indexSetToAccessor.begin() ; accessorIterator != indexSetToAccessor.end() ; accessorIterator++) {
            //(*it).first;             // the key value (of type Key)
            //(*it).second;            // the mapped value (of type T)
            shared_ptr <JSONExport::JSONAccessor> selectedAccessor = (*accessorIterator).second;
            unsigned int indexSet = (*accessorIterator).first;
            JSONExport::Semantic semantic = allSemantics[i];
            std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
            unsigned int size = _allOriginalAccessors.size();
            semanticAndSetToIndex[semanticIndexSetKey] = size;

            //printf("set %d for key: %s\n",size, semanticIndexSetKey.c_str());

            _allOriginalAccessors.push_back(selectedAccessor);
        }
    }

    maxVertexAttributes = _allOriginalAccessors.size();

    vector <shared_ptr<JSONExport::JSONPrimitiveRemapInfos> > allPrimitiveRemapInfos;

    if (primitiveCount > 0) {
        //build a array that maps the accessors that the indices points to with the index of the indice.

        JSONExport::RemappedMeshIndexesHashmap remappedMeshIndexesMap;
        for (unsigned int i = 0 ; i < primitiveCount ; i++) {
            std::vector< shared_ptr<JSONExport::JSONIndices> > allIndices = this->_primitives[i]->allIndices();
            unsigned int* indicesInRemapping = (unsigned int*)malloc(sizeof(unsigned int) * allIndices.size());

            for (unsigned int k = 0 ; k < allIndices.size() ; k++) {
                JSONExport::Semantic semantic = allIndices[k]->getSemantic();
                unsigned int indexSet = allIndices[k]->getIndexOfSet();
                std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
                unsigned int idx = semanticAndSetToIndex[semanticIndexSetKey];

                //printf("git %d for key: %s\n",idx, semanticIndexSetKey.c_str());

                indicesInRemapping[k] = idx;
            }

            shared_ptr<JSONExport::JSONPrimitiveRemapInfos> primitiveRemapInfos = this->_primitives[i]->buildUniqueIndexes(remappedMeshIndexesMap, indicesInRemapping, startIndex, endIndex);

            free(indicesInRemapping);

            if (primitiveRemapInfos.get()) {
                startIndex = endIndex;
                allPrimitiveRemapInfos.push_back(primitiveRemapInfos);
            } else {
                // FIXME: report error
                return false;
            }
        }


    } else {

        return false;
    }

    // we are using WebGL for rendering, this involve OpenGL/ES where only float are supported.
    // now we got not only the uniqueIndexes but also the number of different indexes, i.e the number of vertex attributes count
    // we can allocate the buffer to hold vertex attributes
    unsigned int vertexCount = endIndex - 1;

    for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
        IndexSetToAccessorHashmap& indexSetToAccessor = this->getAccessorsForSemantic(allSemantics[i]);
        IndexSetToAccessorHashmap::const_iterator accessorIterator;

        //FIXME: consider turn this search into a method for mesh
        for (accessorIterator = indexSetToAccessor.begin() ; accessorIterator != indexSetToAccessor.end() ; accessorIterator++) {
            //(*it).first;             // the key value (of type Key)
            //(*it).second;            // the mapped value (of type T)
            shared_ptr <JSONExport::JSONAccessor> selectedAccessor = (*accessorIterator).second;

            size_t sourceSize = vertexCount * selectedAccessor->getElementByteLength();
            void* sourceData = malloc(sourceSize);

            shared_ptr <JSONExport::JSONBuffer> referenceBuffer = selectedAccessor->getBuffer();
            shared_ptr <JSONExport::JSONDataBuffer> remappedBuffer(new JSONExport::JSONDataBuffer(referenceBuffer->getID(), sourceData, sourceSize, true));
            shared_ptr <JSONExport::JSONAccessor> remappedAccessor(new JSONExport::JSONAccessor(selectedAccessor.get()));
            remappedAccessor->setBuffer(remappedBuffer);
            remappedAccessor->setCount(vertexCount);

            indexSetToAccessor[(*accessorIterator).first] = remappedAccessor;

            _allRemappedAccessors.push_back(remappedAccessor);
        }
    }

    /*
    if (_allOriginalAccessors.size() != allIndices.size()) {
        // FIXME: report error
        return false;
    }
    */
    for (unsigned int i = 0 ; i < primitiveCount ; i++) {
        if (!_primitives[i]->_remapVertexes(this->_allOriginalAccessors , this->_allRemappedAccessors, allPrimitiveRemapInfos[i])) {
            // FIXME: report error
            return false;
        }
    }

    if (endIndex > 65535) {
        //The mesh should be split but we do not handle this feature yet
        printf("WARNING: mesh has more than 65535 vertex, splitting has to be done for GL/ES \n");
        return false; //for now return false as splitting is not implemented
    }

    return true;
}
Пример #4
0
shared_ptr <GLTFMesh> createUnifiedIndexesMeshFromMesh(GLTFMesh *sourceMesh, std::vector< shared_ptr<IndicesVector> > &vectorOfIndicesVector)
{
    MeshAttributeVector originalMeshAttributes;
    MeshAttributeVector remappedMeshAttributes;
    shared_ptr <GLTFMesh> targetMesh(new GLTFMesh(*sourceMesh));

    PrimitiveVector sourcePrimitives = sourceMesh->getPrimitives();
    PrimitiveVector targetPrimitives = targetMesh->getPrimitives();

    size_t startIndex = 0;
    size_t endIndex = 0;
    size_t primitiveCount = sourcePrimitives.size();
    unsigned int maxVertexAttributes = 0;

    if (primitiveCount == 0) {
        // FIXME: report error
        //return 0;
    }

    //in originalMeshAttributes we'll get the flattened list of all the meshAttributes as a vector.
    //fill semanticAndSetToIndex with key: (semantic, indexSet) value: index in originalMeshAttributes vector.
    vector <GLTF::Semantic> allSemantics = sourceMesh->allSemantics();
    std::map<string, unsigned int> semanticAndSetToIndex;

    for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
        IndexSetToMeshAttributeHashmap& indexSetToMeshAttribute = sourceMesh->getMeshAttributesForSemantic(allSemantics[i]);
        IndexSetToMeshAttributeHashmap::const_iterator meshAttributeIterator;
        for (meshAttributeIterator = indexSetToMeshAttribute.begin() ; meshAttributeIterator != indexSetToMeshAttribute.end() ; meshAttributeIterator++) {
            //(*it).first;             // the key value (of type Key)
            //(*it).second;            // the mapped value (of type T)
            shared_ptr <GLTF::GLTFMeshAttribute> selectedMeshAttribute = (*meshAttributeIterator).second;
            unsigned int indexSet = (*meshAttributeIterator).first;
            GLTF::Semantic semantic = allSemantics[i];
            std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
            unsigned int size = (unsigned int)originalMeshAttributes.size();
            semanticAndSetToIndex[semanticIndexSetKey] = size;

            originalMeshAttributes.push_back(selectedMeshAttribute);
        }
    }

    maxVertexAttributes = (unsigned int)originalMeshAttributes.size();

    vector <shared_ptr<GLTF::GLTFPrimitiveRemapInfos> > allPrimitiveRemapInfos;

    //build a array that maps the meshAttributes that the indices points to with the index of the indice.
    GLTF::RemappedMeshIndexesHashmap remappedMeshIndexesMap;
    for (unsigned int i = 0 ; i < primitiveCount ; i++) {
        shared_ptr<IndicesVector>  allIndicesSharedPtr = vectorOfIndicesVector[i];
        IndicesVector *allIndices = allIndicesSharedPtr.get();
        unsigned int* indicesInRemapping = (unsigned int*)malloc(sizeof(unsigned int) * allIndices->size());


        VertexAttributeVector vertexAttributes = sourcePrimitives[i]->getVertexAttributes();
        for (unsigned int k = 0 ; k < allIndices->size() ; k++) {
            GLTF::Semantic semantic = vertexAttributes[k]->getSemantic();
            unsigned int indexSet = vertexAttributes[k]->getIndexOfSet();
            std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
            unsigned int idx = semanticAndSetToIndex[semanticIndexSetKey];
            indicesInRemapping[k] = idx;
        }

        shared_ptr<GLTF::GLTFPrimitiveRemapInfos> primitiveRemapInfos = __BuildPrimitiveUniqueIndexes(targetPrimitives[i], *allIndices, remappedMeshIndexesMap, indicesInRemapping, startIndex, maxVertexAttributes, endIndex);

        free(indicesInRemapping);

        if (primitiveRemapInfos.get()) {
            startIndex = endIndex;
            allPrimitiveRemapInfos.push_back(primitiveRemapInfos);
        } else {
            // FIXME: report error
            //return NULL;
        }
    }

    // now we got not only the uniqueIndexes but also the number of different indexes, i.e the number of vertex attributes count
    // we can allocate the buffer to hold vertex attributes
    unsigned int vertexCount = endIndex;
    //just allocate it now, will be filled later
    unsigned int* remapTableForPositions = (unsigned int*)malloc(sizeof(unsigned int) * vertexCount);
    targetMesh->setRemapTableForPositions(remapTableForPositions);

    for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
        Semantic semantic = allSemantics[i];
        IndexSetToMeshAttributeHashmap& indexSetToMeshAttribute = sourceMesh->getMeshAttributesForSemantic(semantic);
        IndexSetToMeshAttributeHashmap& destinationIndexSetToMeshAttribute = targetMesh->getMeshAttributesForSemantic(semantic);
        IndexSetToMeshAttributeHashmap::const_iterator meshAttributeIterator;

        //FIXME: consider turn this search into a method for mesh
        for (meshAttributeIterator = indexSetToMeshAttribute.begin() ; meshAttributeIterator != indexSetToMeshAttribute.end() ; meshAttributeIterator++) {
            //(*it).first;             // the key value (of type Key)
            //(*it).second;            // the mapped value (of type T)
            shared_ptr <GLTF::GLTFMeshAttribute> selectedMeshAttribute = (*meshAttributeIterator).second;

            size_t sourceSize = vertexCount * selectedMeshAttribute->getVertexAttributeByteLength();
            void* sourceData = malloc(sourceSize);

            shared_ptr <GLTFBufferView> referenceBufferView = selectedMeshAttribute->getBufferView();
            shared_ptr <GLTFBufferView> remappedBufferView = createBufferViewWithAllocatedBuffer(referenceBufferView->getID(), sourceData, 0, sourceSize, true);

            shared_ptr <GLTFMeshAttribute> remappedMeshAttribute(new GLTFMeshAttribute(selectedMeshAttribute.get()));
            remappedMeshAttribute->setBufferView(remappedBufferView);
            remappedMeshAttribute->setCount(vertexCount);

            destinationIndexSetToMeshAttribute[(*meshAttributeIterator).first] = remappedMeshAttribute;

            remappedMeshAttributes.push_back(remappedMeshAttribute);
        }
    }

    /*
     if (_allOriginalMeshAttributes.size() != allIndices.size()) {
     // FIXME: report error
     return false;
     }
     */

    for (unsigned int i = 0 ; i < primitiveCount ; i++) {
        shared_ptr<IndicesVector>  allIndicesSharedPtr = vectorOfIndicesVector[i];
        IndicesVector *allIndices = allIndicesSharedPtr.get();
        unsigned int* indicesInRemapping = (unsigned int*)calloc(sizeof(unsigned int) * (*allIndices).size(), 1);
        VertexAttributeVector vertexAttributes = sourcePrimitives[i]->getVertexAttributes();

        for (unsigned int k = 0 ; k < (*allIndices).size() ; k++) {
            GLTF::Semantic semantic = vertexAttributes[k]->getSemantic();
            unsigned int indexSet = vertexAttributes[k]->getIndexOfSet();
            std::string semanticIndexSetKey = keyWithSemanticAndSet(semantic, indexSet);
            unsigned int idx = semanticAndSetToIndex[semanticIndexSetKey];
            indicesInRemapping[k] = idx;
        }

        bool status = __RemapPrimitiveVertices(targetPrimitives[i],
                                               (*allIndices),
                                               originalMeshAttributes ,
                                               remappedMeshAttributes,
                                               indicesInRemapping,
                                               allPrimitiveRemapInfos[i],
                                               remapTableForPositions);
        free(indicesInRemapping);

        if (!status) {
            // FIXME: report error
            //return NULL;
        }
    }

    return targetMesh;
}