예제 #1
0
bool CPeripheralAddon::SetIgnoredPrimitives(const CPeripheral* device, const PrimitiveVector& primitives)
{
  if (!m_bProvidesButtonMaps)
    return false;

  PERIPHERAL_ERROR retVal;

  ADDON::Joystick joystickInfo;
  GetJoystickInfo(device, joystickInfo);

  JOYSTICK_INFO joystickStruct;
  joystickInfo.ToStruct(joystickStruct);

  JOYSTICK_DRIVER_PRIMITIVE* addonPrimitives = nullptr;
  ADDON::DriverPrimitives::ToStructs(primitives, &addonPrimitives);

  try
  {
    LogError(retVal = m_pStruct->SetIgnoredPrimitives(&joystickStruct,
        primitives.size(), addonPrimitives), "SetIgnoredPrimitives()");
  }
  catch (std::exception &e)
  {
    LogException(e, "SetIgnoredPrimitives()"); return false;
  }

  ADDON::DriverPrimitives::FreeStructs(primitives.size(), addonPrimitives);

  return retVal == PERIPHERAL_NO_ERROR;
}
void copySubsystem( ESMoL::Subsystem inputSubSubsystem, ESMoL::Subsystem outputSubsystem, bool deep ) {

	ESMoL::Subsystem outputSubSubsystem = ESMoL::Subsystem::Create( outputSubsystem );
	UdmEngine::copyBlock( inputSubSubsystem, outputSubSubsystem );
	copyPorts( inputSubSubsystem, outputSubSubsystem );

	PrimitiveVector primitiveVector = inputSubSubsystem.Primitive_kind_children();
	for( PrimitiveVector::iterator pmvItr = primitiveVector.begin() ; pmvItr != primitiveVector.end() ; ++pmvItr ) {

		ESMoL::Primitive primitive = *pmvItr;
		ESMoL::Block block = UdmEngine::copy( primitive, outputSubSubsystem );
		if ( primitive.BlockType() == "S-Function" ) {
			ConnectorRefVector connectorRefVector = primitive.ConnectorRef_kind_children();
			if ( !connectorRefVector.empty() ) {
				ESMoL::ConnectorRef inputConnectorRef = connectorRefVector.back();
				ESMoL::ConnectorRef outputConnectorRef = ESMoL::ConnectorRef::Create( block );
				outputConnectorRef.name() = inputConnectorRef.name();
				ESMoL::TransConnector inputTransConnector = inputConnectorRef.ref();
				TransConnectorMap::iterator tcmItr = getTransConnectorMap().find( inputTransConnector );
				if ( tcmItr != getTransConnectorMap().end() ) outputConnectorRef.ref() = tcmItr->second;
			}
		}
		copyPorts( primitive, block );
	}

	SubsystemVector sub3systemVector = inputSubSubsystem.Subsystem_kind_children();
	for( SubsystemVector::iterator ssvItr = sub3systemVector.begin() ; ssvItr != sub3systemVector.end() ; ++ssvItr ) {

		ESMoL::Subsystem inputSub3system = *ssvItr;
		if ( deep ) copySubsystem( inputSub3system, outputSubSubsystem );
		else        flattenSubsystem( inputSub3system, outputSubSubsystem );
	}
}
예제 #3
0
 shared_ptr <GLTF::JSONObject> serializeMesh(GLTFMesh* mesh, void *context)
 {
     shared_ptr <GLTF::JSONObject> meshObject(new GLTF::JSONObject());
     
     meshObject->setString("name", mesh->getName());
     
     //primitives
     shared_ptr <GLTF::JSONArray> primitivesArray(new GLTF::JSONArray());
     meshObject->setValue("primitives", primitivesArray);
     
     PrimitiveVector primitives = mesh->getPrimitives();
     unsigned int primitivesCount =  (unsigned int)primitives.size();
     for (unsigned int i = 0 ; i < primitivesCount ; i++) {
         shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];
         
         void *primitiveContext[2];
         
         primitiveContext[0] = mesh;
         primitiveContext[1] = context;
         
         shared_ptr <GLTF::JSONObject> primitiveObject = serializePrimitive(primitive.get(), primitiveContext);
         
         primitivesArray->appendValue(primitiveObject);
     }
             
     return meshObject;
 }
예제 #4
0
파일: GLTFWriter.cpp 프로젝트: rcpage3/glTF
 shared_ptr <GLTF::JSONObject> serializeMesh(GLTFMesh* mesh, void *context)
 {
     shared_ptr <GLTF::JSONObject> meshObject(new GLTF::JSONObject());
     
     meshObject->setString("name", mesh->getName());
     
     //primitives
     shared_ptr <GLTF::JSONArray> primitivesArray(new GLTF::JSONArray());
     meshObject->setValue("primitives", primitivesArray);
     
     //meshAttributes
     shared_ptr <GLTF::JSONObject> meshAttributesObject(new GLTF::JSONObject());
     meshObject->setValue("attributes", meshAttributesObject);
     
     shared_ptr <MeshAttributeVector> allMeshAttributes = mesh->meshAttributes();
     
     PrimitiveVector primitives = mesh->getPrimitives();
     unsigned int primitivesCount =  (unsigned int)primitives.size();
     for (unsigned int i = 0 ; i < primitivesCount ; i++) {
         
         shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];
         shared_ptr <GLTF::GLTFIndices> uniqueIndices =  primitive->getUniqueIndices();
         
         void *primitiveContext[2];
         
         primitiveContext[0] = mesh;
         primitiveContext[1] = context;
         
         shared_ptr <GLTF::JSONObject> primitiveObject = serializePrimitive(primitive.get(), primitiveContext);
         
         primitivesArray->appendValue(primitiveObject);
     }
     
     vector <GLTF::Semantic> allSemantics = mesh->allSemantics();
     for (unsigned int i = 0 ; i < allSemantics.size() ; i++) {
         GLTF::Semantic semantic = allSemantics[i];
         
         GLTF::IndexSetToMeshAttributeHashmap::const_iterator meshAttributeIterator;
         GLTF::IndexSetToMeshAttributeHashmap& indexSetToMeshAttribute = mesh->getMeshAttributesForSemantic(semantic);
         
         //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> meshAttribute = (*meshAttributeIterator).second;
             
             shared_ptr <GLTF::JSONObject> meshAttributeObject = serializeMeshAttribute(meshAttribute.get(), context);
             
             meshAttributesObject->setValue(meshAttribute->getID(), meshAttributeObject);
         }
     }
     
     return meshObject;
 }
예제 #5
0
파일: GLTFWriter.cpp 프로젝트: nil84/glTF
shared_ptr <GLTF::JSONObject> serializeMesh(GLTFMesh* mesh, void *context)
{
    shared_ptr <GLTF::JSONObject> meshObject(new GLTF::JSONObject());

    meshObject->setString("name", mesh->getName());

    //primitives
    shared_ptr <GLTF::JSONArray> primitivesArray(new GLTF::JSONArray());
    meshObject->setValue("primitives", primitivesArray);

    PrimitiveVector primitives = mesh->getPrimitives();
    unsigned int primitivesCount =  (unsigned int)primitives.size();
    for (unsigned int i = 0 ; i < primitivesCount ; i++) {
        shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];

        void *primitiveContext[2];

        primitiveContext[0] = mesh;
        primitiveContext[1] = context;

        shared_ptr <GLTF::JSONObject> primitiveObject = serializePrimitive(primitive.get(), primitiveContext);

        primitivesArray->appendValue(primitiveObject);
    }

    if (mesh->getExtensions()->getKeysCount() > 0) {
        meshObject->setValue("extensions", mesh->getExtensions());
        if (mesh->getExtensions()->contains("won-compression")) {
            shared_ptr<JSONObject> compressionObject = static_pointer_cast<JSONObject>(mesh->getExtensions()->getValue("won-compression"));
            if (compressionObject->contains("compressedData")) {
                shared_ptr<JSONObject> compressionData = compressionObject->getObject("compressedData");
                GLTFBufferView *bufferView = (GLTFBufferView*)((void**)context)[0];
                compressionData->setString("bufferView", bufferView->getID());
            }

        }

        if (mesh->getExtensions()->contains("Open3DGC-compression")) {
            shared_ptr<JSONObject> compressionObject = static_pointer_cast<JSONObject>(mesh->getExtensions()->getValue("Open3DGC-compression"));
            if (compressionObject->contains("compressedData")) {
                shared_ptr<JSONObject> compressionData = compressionObject->getObject("compressedData");
                GLTFBufferView *bufferView = (GLTFBufferView*)((void**)context)[0];
                compressionData->setString("bufferView", bufferView->getID());
            }

        }
    }

    return meshObject;
}
예제 #6
0
 //All these limitations will be fixed in coming iterations:
 //Do we have only triangles, only one set of texcoord and no skinning ?
 //TODO:Also check that the same buffer is not shared by 2 different semantics or set
 bool canEncodeOpen3DGCMesh(shared_ptr <GLTFMesh> mesh)
 {
     PrimitiveVector primitives = mesh->getPrimitives();
     unsigned int primitivesCount =  (unsigned int)primitives.size();
     
     for (unsigned int i = 0 ; i < primitivesCount ; i++) {
         shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];
         if (primitive->getType() != "TRIANGLES") {
             return false;
         }
     }
     
     return true;
 }
예제 #7
0
bool CPeripheralAddon::GetIgnoredPrimitives(const CPeripheral* device, PrimitiveVector& primitives)
{
  if (!m_bProvidesButtonMaps)
    return false;

  PERIPHERAL_ERROR retVal;

  ADDON::Joystick joystickInfo;
  GetJoystickInfo(device, joystickInfo);

  JOYSTICK_INFO joystickStruct;
  joystickInfo.ToStruct(joystickStruct);

  unsigned int primitiveCount = 0;
  JOYSTICK_DRIVER_PRIMITIVE* pPrimitives = nullptr;

  LogError(retVal = m_pStruct->GetIgnoredPrimitives(&joystickStruct, &primitiveCount,
                                                      &pPrimitives), "GetIgnoredPrimitives()");
  if (retVal == PERIPHERAL_NO_ERROR)
  {
    for (unsigned int i = 0; i < primitiveCount; i++)
      primitives.emplace_back(pPrimitives[i]);

    m_pStruct->FreePrimitives(primitiveCount, pPrimitives);

    return true;
  }

  return false;

}
bool isStateMachine( ESMoL::Subsystem subsystem ) {
	ESMoL::Primitive sFunction;

	PrimitiveVector primitiveVector = subsystem.Primitive_kind_children();
	for( PrimitiveVector::iterator pmvItr = primitiveVector.begin() ; pmvItr != primitiveVector.end() ; ++pmvItr ) {

		ESMoL::Primitive primitive = *pmvItr;
		if ( primitive.BlockType() == "S-Function" ) {
			sFunction = primitive;
			break;
		}
	}

	if ( sFunction == Udm::null ) return false;

	ConnectorRefVector connectorRefVector = sFunction.ConnectorRef_kind_children();
	return !connectorRefVector.empty();
}
void flattenSubsystem( ESMoL::Subsystem inputSubsystem, ESMoL::Subsystem outputSubsystem ) {
	
	PrimitiveVector primitiveVector = inputSubsystem.Primitive_kind_children();
	for( PrimitiveVector::iterator pmvItr = primitiveVector.begin() ; pmvItr != primitiveVector.end() ; ++pmvItr ) {

		ESMoL::Primitive primitive = *pmvItr;
		ESMoL::Block block = UdmEngine::copy( primitive, outputSubsystem );
		copyPorts( primitive, block );
	}

	SubsystemVector subSubsystemVector = inputSubsystem.Subsystem_kind_children();
	for( SubsystemVector::iterator ssvItr = subSubsystemVector.begin() ; ssvItr != subSubsystemVector.end() ; ++ssvItr ) {

		ESMoL::Subsystem inputSubSubsystem = *ssvItr;
		if (  isStateMachine( inputSubSubsystem )  )                  copySubsystem( inputSubSubsystem, outputSubsystem );
		else if (  isConditionActionSubsystem( inputSubSubsystem )  ) copySubsystem( inputSubSubsystem, outputSubsystem, false );
		else                                                          flattenSubsystem( inputSubSubsystem, outputSubsystem );
	}
}
예제 #10
0
    bool GLTFMesh::writeAllBuffers(std::ofstream& verticesOutputStream, std::ofstream& indicesOutputStream)
    {
        typedef map<std::string , shared_ptr<GLTF::GLTFBuffer> > IDToBufferDef;
        IDToBufferDef IDToBuffer;
        
        shared_ptr <AccessorVector> allAccessors = this->accessors();
        
        shared_ptr <GLTFBufferView> dummyBuffer(new GLTFBufferView());
        
        PrimitiveVector primitives = this->getPrimitives();
        unsigned int primitivesCount =  (unsigned int)primitives.size();
        for (unsigned int i = 0 ; i < primitivesCount ; i++) {            
            shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];            
            shared_ptr <GLTF::GLTFIndices> uniqueIndices = primitive->getUniqueIndices();
            
            /*
                Convert the indices to unsigned short and write the blob 
             */
            unsigned int indicesCount = (unsigned int)uniqueIndices->getCount();
            
            shared_ptr <GLTFBufferView> indicesBufferView = uniqueIndices->getBufferView();
            unsigned char* uniqueIndicesBufferPtr = (unsigned char*)indicesBufferView->getBuffer()->getData();
            uniqueIndicesBufferPtr += indicesBufferView->getByteOffset();
            
            unsigned int* uniqueIndicesBuffer = (unsigned int*) uniqueIndicesBufferPtr;
            if (indicesCount <= 0) {
                // FIXME: report error
            } else {
                size_t indicesLength = sizeof(unsigned short) * indicesCount;
                unsigned short* ushortIndices = (unsigned short*)calloc(indicesLength, 1);
                for (unsigned int idx = 0 ; idx < indicesCount ; idx++) {
                    ushortIndices[idx] = (unsigned short)uniqueIndicesBuffer[idx];
                }
                    
                uniqueIndices->setByteOffset(static_cast<size_t>(indicesOutputStream.tellp()));
                indicesOutputStream.write((const char*)ushortIndices, indicesLength);
                
                //now that we wrote to the stream we can release the buffer.
                uniqueIndices->setBufferView(dummyBuffer);
                
                free(ushortIndices);
            }
        }
        
        for (unsigned int j = 0 ; j < allAccessors->size() ; j++) {
            shared_ptr <GLTFAccessor> accessor = (*allAccessors)[j];
            shared_ptr <GLTFBufferView> bufferView = accessor->getBufferView();
            shared_ptr <GLTFBuffer> buffer = bufferView->getBuffer();
            
            if (!bufferView.get()) {
                // FIXME: report error
                return false;
            }
                        
            if (!IDToBuffer[bufferView->getBuffer()->getID().c_str()].get()) {
                // FIXME: this should be internal to accessor when a Data buffer is set
                // for this, add a type to buffers , and check this type in setBuffer , then call computeMinMax
                accessor->computeMinMax();
                
                accessor->setByteOffset(static_cast<size_t>(verticesOutputStream.tellp()));
                verticesOutputStream.write((const char*)(static_pointer_cast <GLTFBuffer> (buffer)->getData()), buffer->getByteLength());

                //now that we wrote to the stream we can release the buffer.
                accessor->setBufferView(dummyBuffer);
                
                IDToBuffer[bufferView->getBuffer()->getID().c_str()] = buffer;
            } 
        }
                
        return true;
    }
예제 #11
0
bool createMeshesWithMaximumIndicesCountFromMeshIfNeeded(GLTFMesh *sourceMesh, unsigned int maxiumIndicesCount, MeshVector &meshes)
{
    bool splitNeeded = false;

    //First, check every primitive indices count to figure out if we really need to split anything at all.
    //TODO: what about making a sanity check, to ensure we don't have points not referenced by any primitive. (I wonder if that's would be considered compliant with the SPEC. need to check.
    PrimitiveVector primitives = sourceMesh->getPrimitives();

    for (size_t i = 0 ; i < primitives.size() ; i++) {
        if (primitives[i]->getIndices()->getCount() >= maxiumIndicesCount) {
            splitNeeded = true;
            break;
        }
    }

    if (!splitNeeded)
        return false;

    SubMeshContext *subMesh = NULL;

    bool stillHavePrimitivesElementsToBeProcessed = false;
    bool primitiveCompleted = false;

    int *allNextPrimitiveIndices = (int*)calloc(primitives.size(), sizeof(int));
    unsigned int meshIndex = 0;
    for (size_t i = 0 ; i < primitives.size() ; i++) {
        if (allNextPrimitiveIndices[i] == -1)
            continue;

        if (subMesh == 0) {
            subMesh = __CreateSubMeshContext();
            meshes.push_back(subMesh->targetMesh);
            std::string meshID = "";
            std::string meshName = "";

            meshID += sourceMesh->getID();
            meshName += sourceMesh->getName();
            if (meshIndex) {
                meshID += "-"+ GLTFUtils::toString(meshIndex);
                meshName += "-"+ GLTFUtils::toString(meshIndex);
            }
            subMesh->targetMesh->setID(meshID);
            subMesh->targetMesh->setName(meshName);

            stillHavePrimitivesElementsToBeProcessed = false;
            meshIndex++;
        }

        shared_ptr <GLTFPrimitive> targetPrimitive;
        //when we are done with a primitive we mark its nextIndice with a -1

        targetPrimitive = shared_ptr <GLTFPrimitive> (new GLTFPrimitive((*primitives[i])));

        unsigned int nextPrimitiveIndex = (unsigned int)allNextPrimitiveIndices[i];

        shared_ptr<GLTFPrimitive> &primitive = primitives[i];
        shared_ptr<GLTFIndices> indices = primitive->getIndices();

        unsigned int* indicesPtr = (unsigned int*)indices->getBufferView()->getBufferDataByApplyingOffset();
        unsigned int* targetIndicesPtr = (unsigned int*)malloc(indices->getBufferView()->getBuffer()->getByteLength());

        //sub meshes are built this way [ and it is not optimal yet (*)]:
        //each primitive is iterated through all its triangles/lines/...
        //When the indices count in indexToRemappedIndex is >= maxiumIndicesCount then we try the next primitive.
        /*
            we could continue walking through a primitive even if the of maximum indices has been reached, because, for instance the next say, triangles could be within the already remapped indices. That said, not doing so should produce meshes that have more chances to have adjacent triangles. Need more experimentation about this. Having 2 modes would ideal.
         */


        //Different iterators type will be needed for these types
        /*
         type = "TRIANGLES";
         type = "LINES";
         type = "LINE_STRIP";
         type = "TRIANGLES";
         type = "TRIANGLE_FANS";
         type = "TRIANGLE_STRIPS";
         type = "POINTS";
         */
        size_t j = 0;
        unsigned int primitiveCount = 0;
        unsigned int targetIndicesCount = 0;
        if (primitive->getType() == "TRIANGLES") {
            unsigned int indicesPerElementCount = 3;
            primitiveCount = indices->getCount() / indicesPerElementCount;
            for (j = nextPrimitiveIndex ; j < primitiveCount ; j++) {
                unsigned int *indicesPtrAtPrimitiveIndex = indicesPtr + (j * indicesPerElementCount);
                //will we still have room to store coming indices from this mesh ?
                //note: this is tied to the policy described above in (*)
                size_t currentSize = subMesh->indexToRemappedIndex.size();
                if ((currentSize + indicesPerElementCount) < maxiumIndicesCount) {
                    __PushAndRemapIndicesInSubMesh(subMesh, indicesPtrAtPrimitiveIndex, indicesPerElementCount);

                    //build the indices for the primitive to be added to the subMesh
                    targetIndicesPtr[targetIndicesCount] = subMesh->indexToRemappedIndex[indicesPtrAtPrimitiveIndex[0]];
                    targetIndicesPtr[targetIndicesCount + 1] = subMesh->indexToRemappedIndex[indicesPtrAtPrimitiveIndex[1]];
                    targetIndicesPtr[targetIndicesCount + 2] = subMesh->indexToRemappedIndex[indicesPtrAtPrimitiveIndex[2]];

                    targetIndicesCount += indicesPerElementCount;

                    nextPrimitiveIndex++;
                } else {
                    allNextPrimitiveIndices[i] = -1;
                    primitiveCompleted = true;
                    break;
                }
            }
        }

        allNextPrimitiveIndices[i] = nextPrimitiveIndex;

        if (targetIndicesCount > 0) {
            //FIXME: here targetIndices takes too much memory
            //To avoid this we would need to make a smaller copy.
            //In our case not sure if that's really a problem since this buffer won't be around for too long, as each buffer is deallocated once the callback from OpenCOLLADA to handle geomery has completed.

            shared_ptr <GLTFBufferView> targetBufferView = createBufferViewWithAllocatedBuffer(targetIndicesPtr, 0,targetIndicesCount * sizeof(unsigned int), true);

            shared_ptr <GLTFIndices> indices(new GLTFIndices(targetBufferView, targetIndicesCount));
            targetPrimitive->setIndices(indices);

            subMesh->targetMesh->appendPrimitive(targetPrimitive);
        } else {
            if (targetIndicesPtr)
                free(targetIndicesPtr);
        }

        if (j < primitiveCount)
            stillHavePrimitivesElementsToBeProcessed = true;

        //did we process the last primitive ?
        if (primitiveCompleted || (((i + 1) == primitives.size()))) {
            __RemapSubMesh(subMesh, sourceMesh);
            if (stillHavePrimitivesElementsToBeProcessed) {
                //loop again and build new mesh
                i = -1;
                delete subMesh;
                subMesh = 0;
            }
        }
    }

    free(allNextPrimitiveIndices);

    return true;
}
예제 #12
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;
}
예제 #13
0
    void encodeOpen3DGCMesh(shared_ptr <GLTFMesh> mesh,
                            shared_ptr<JSONObject> floatAttributeIndexMapping,
                            const GLTFConverterContext& converterContext)
    {
        o3dgc::SC3DMCEncodeParams params;
        o3dgc::IndexedFaceSet <unsigned short> ifs;

        //setup options
        int qcoord    = 12;
        int qtexCoord = 10;
        int qnormal   = 10;
        int qcolor   = 10;
        int qWeights = 8;
        
        GLTFOutputStream *outputStream = converterContext._compressionOutputStream;
        size_t bufferOffset = outputStream->length();
        
        O3DGCSC3DMCPredictionMode floatAttributePrediction = O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION;
        
        unsigned int nFloatAttributes = 0;
        
        PrimitiveVector primitives = mesh->getPrimitives();
        unsigned int primitivesCount =  (unsigned int)primitives.size();
        unsigned int allIndicesCount = 0;
        unsigned int allTrianglesCount = 0;
        
        std::vector <unsigned int> trianglesPerPrimitive;
        
        //First run through primitives to gather the number of indices and infer the number of triangles.
        for (unsigned int i = 0 ; i < primitivesCount ; i++) {
            shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];
            shared_ptr <GLTF::GLTFIndices> uniqueIndices = primitive->getUniqueIndices();
            unsigned int indicesCount = (unsigned int)(uniqueIndices->getCount());
            //FIXME: assumes triangles, but we are guarded from issues by canEncodeOpen3DGCMesh
            allIndicesCount += indicesCount;
            trianglesPerPrimitive.push_back(indicesCount / 3);
        }
        
        //Then we setup the matIDs array and at the same time concatenate all triangle indices
        unsigned long *primitiveIDs = (unsigned long*)malloc(sizeof(unsigned long) * (allIndicesCount / 3));
        unsigned long *primitiveIDsPtr = primitiveIDs;
        unsigned short* allConcatenatedIndices = (unsigned short*)malloc(allIndicesCount * sizeof(unsigned short));
        unsigned short* allConcatenatedIndicesPtr = allConcatenatedIndices;
        
        for (unsigned int i = 0 ; i < trianglesPerPrimitive.size() ; i++) {
            unsigned int trianglesCount = trianglesPerPrimitive[i];
            for (unsigned int j = 0 ; j < trianglesCount ; j++) {
                primitiveIDsPtr[j] = i;
            }
            primitiveIDsPtr += trianglesCount;
            allTrianglesCount += trianglesCount;
            shared_ptr<GLTF::GLTFPrimitive> primitive = primitives[i];
            shared_ptr <GLTF::GLTFIndices> uniqueIndices = primitive->getUniqueIndices();
            unsigned int indicesCount = (unsigned int)(uniqueIndices->getCount());
            unsigned int* indicesPtr = (unsigned int*)uniqueIndices->getBufferView()->getBufferDataByApplyingOffset();
            for (unsigned int j = 0 ; j < indicesCount ; j++) {
                allConcatenatedIndicesPtr[j] = indicesPtr[j];
            }
            allConcatenatedIndicesPtr += indicesCount;
        }
        
        //FIXME:Open3DGC SetNCoordIndex is not a good name here (file against o3dgc)
        ifs.SetNCoordIndex(allTrianglesCount);
        ifs.SetCoordIndex((unsigned short * const ) allConcatenatedIndices);
        ifs.SetIndexBufferID(primitiveIDs);
        
        size_t vertexCount = 0;
        
        std::vector <GLTF::Semantic> semantics = mesh->allSemantics();
        for (unsigned int i = 0 ; i < semantics.size() ; i ++) {
            GLTF::Semantic semantic  = semantics[i];
            
            size_t attributesCount = mesh->getMeshAttributesCountForSemantic(semantic);
            
            for (size_t j = 0 ; j < attributesCount ; j++) {
                shared_ptr <GLTFMeshAttribute> meshAttribute = mesh->getMeshAttribute(semantic, j);
                vertexCount = meshAttribute->getCount();
                size_t componentsPerAttribute = meshAttribute->getComponentsPerAttribute();
                char *buffer = (char*)meshAttribute->getBufferView()->getBufferDataByApplyingOffset();
                switch (semantic) {
                    case POSITION:
                        params.SetCoordQuantBits(qcoord);
                        params.SetCoordPredMode(floatAttributePrediction);
                        ifs.SetNCoord(vertexCount);
                        ifs.SetCoord((Real * const)buffer);
                        break;
                    case NORMAL:
                        params.SetNormalQuantBits(qnormal);
                        params.SetNormalPredMode(O3DGC_SC3DMC_SURF_NORMALS_PREDICTION);
                        ifs.SetNNormal(vertexCount);
                        ifs.SetNormal((Real * const)buffer);
                        break;
                    case TEXCOORD:
                        params.SetFloatAttributeQuantBits(nFloatAttributes, qtexCoord);
                        params.SetFloatAttributePredMode(nFloatAttributes, floatAttributePrediction);
                        ifs.SetNFloatAttribute(nFloatAttributes, vertexCount);
                        ifs.SetFloatAttributeDim(nFloatAttributes, componentsPerAttribute);
                        ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD);
                        ifs.SetFloatAttribute(nFloatAttributes, (Real * const)buffer);
                        floatAttributeIndexMapping->setUnsignedInt32(meshAttribute->getID(), nFloatAttributes);
                        nFloatAttributes++;
                        break;
                    case COLOR:
                        params.SetFloatAttributeQuantBits(nFloatAttributes, qcolor);
                        params.SetFloatAttributePredMode(nFloatAttributes, floatAttributePrediction);
                        ifs.SetNFloatAttribute(nFloatAttributes, vertexCount);
                        ifs.SetFloatAttributeDim(nFloatAttributes, componentsPerAttribute);
                        ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_COLOR);
                        ifs.SetFloatAttribute(nFloatAttributes, (Real * const)buffer);
                        floatAttributeIndexMapping->setUnsignedInt32(meshAttribute->getID(), nFloatAttributes);
                        nFloatAttributes++;
                        break;
                    case WEIGHT:
                        params.SetFloatAttributeQuantBits(nFloatAttributes, qWeights);
                        params.SetFloatAttributePredMode(nFloatAttributes, O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION);
                        ifs.SetNFloatAttribute(nFloatAttributes, vertexCount);
                        ifs.SetFloatAttributeDim(nFloatAttributes, componentsPerAttribute);
                        ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_WEIGHT);
                        ifs.SetFloatAttribute(nFloatAttributes, (Real * const)buffer);
                        floatAttributeIndexMapping->setUnsignedInt32(meshAttribute->getID(), nFloatAttributes);
                        nFloatAttributes++;
                        break;
                    case JOINT:
                        /*
                         params.SetIntAttributePredMode(nIntAttributes, O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION);
                         ifs.SetNIntAttribute(nIntAttributes, jointIDs.size() / numJointsPerVertex);
                         ifs.SetIntAttributeDim(nIntAttributes, numJointsPerVertex);
                         ifs.SetIntAttributeType(nIntAttributes, O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID);
                         ifs.SetIntAttribute(nIntAttributes, (long * const ) & (jointIDs[0]));
                         nIntAttributes++;
                         */
                        params.SetFloatAttributeQuantBits(nFloatAttributes, 10);
                        params.SetFloatAttributePredMode(nFloatAttributes, O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION);
                        ifs.SetNFloatAttribute(nFloatAttributes, vertexCount);
                        ifs.SetFloatAttributeDim(nFloatAttributes, componentsPerAttribute);
                        ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_UNKOWN);
                        ifs.SetFloatAttribute(nFloatAttributes, (Real * const)buffer);
                        floatAttributeIndexMapping->setUnsignedInt32(meshAttribute->getID(), nFloatAttributes);
                        nFloatAttributes++;
                        break;
                    default:
                        break;
                }
            }
        }
        
        params.SetNumFloatAttributes(nFloatAttributes);
        ifs.SetNumFloatAttributes(nFloatAttributes);
        shared_ptr<JSONObject> compressionObject = static_pointer_cast<JSONObject>(mesh->getExtensions()->createObjectIfNeeded("Open3DGC-compression"));
        
        ifs.ComputeMinMax(O3DGC_SC3DMC_MAX_ALL_DIMS);
        BinaryStream bstream(vertexCount * 8);
        SC3DMCEncoder <unsigned short> encoder;
        shared_ptr<JSONObject> compressedData(new JSONObject());
        compressedData->setInt32("verticesCount", vertexCount);
        compressedData->setInt32("indicesCount", allIndicesCount);
        //Open3DGC binary is disabled
        params.SetStreamType(converterContext.compressionMode == "binary" ? O3DGC_STREAM_TYPE_BINARY : O3DGC_STREAM_TYPE_ASCII);
#if DUMP_O3DGC_OUTPUT
        static int dumpedId = 0;
        COLLADABU::URI outputURI(converterContext.outputFilePath.c_str());
        std::string outputFilePath = outputURI.getPathDir() + GLTFUtils::toString(dumpedId) + ".txt";
        dumpedId++;
        SaveIFS(outputFilePath, ifs);
#endif
        encoder.Encode(params, ifs, bstream);
        
        compressedData->setString("mode", converterContext.compressionMode);
        compressedData->setUnsignedInt32("count", bstream.GetSize());
        compressedData->setUnsignedInt32("type", converterContext.profile->getGLenumForString("UNSIGNED_BYTE"));
        compressedData->setUnsignedInt32("byteOffset", bufferOffset);
        compressedData->setValue("floatAttributesIndexes", floatAttributeIndexMapping);
        
        compressionObject->setValue("compressedData", compressedData);
        
        //testDecode(mesh, bstream);
        outputStream->write((const char*)bstream.GetBuffer(0), bstream.GetSize());
        
        if (ifs.GetCoordIndex()) {
            free(ifs.GetCoordIndex());
        }
        
        if (primitiveIDs) {
            free(primitiveIDs);
        }
    }