src/GLTFLoader.cpp
std::vector<AnimatedMesh> LoadAnimatedMeshes(cgltf_data* data)
{
   std::vector<AnimatedMesh> animatedMeshes;

   // Loop over the array of nodes of the glTF file
   unsigned int numNodes = static_cast<unsigned int>(data->nodes_count);
   for (unsigned int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex)
   {
      // This function only loads animated meshes, so the node must contain a mesh and a skin for us to process it
      cgltf_node* currNode = &data->nodes[nodeIndex];
      if (currNode->mesh == nullptr || currNode->skin == nullptr)
      {
         continue;
      }

      // Loop over the array of mesh primitives of the current node
      unsigned int numPrimitives = static_cast<unsigned int>(currNode->mesh->primitives_count);
      for (unsigned int primitiveIndex = 0; primitiveIndex < numPrimitives; ++primitiveIndex)
      {
         // Get the current mesh primitive
         cgltf_primitive* currPrimitive = &currNode->mesh->primitives[primitiveIndex];

         // Create an AnimatedMesh for the current mesh primitive
         animatedMeshes.push_back(AnimatedMesh());
         AnimatedMesh& currMesh = animatedMeshes[animatedMeshes.size() - 1];

         // Loop over the attributes of the current mesh primitive
         unsigned int numAttributes = static_cast<unsigned int>(currPrimitive->attributes_count);
         for (unsigned int attributeIndex = 0; attributeIndex < numAttributes; ++attributeIndex)
         {
            // Get the current attribute
            cgltf_attribute* attribute = &currPrimitive->attributes[attributeIndex];
            // Read the values of the current attribute and store them in the current mesh
            GLTFHelpers::StoreValuesOfAttributeInAnimatedMesh(*attribute, currNode->skin, data->nodes, numNodes, currMesh);
         }

         // If the current mesh primitive has a set of indices, store them too
         if (currPrimitive->indices != nullptr)
         {
            unsigned int indexCount = static_cast<unsigned int>(currPrimitive->indices->count);

            // Get the vector that will store the indices of the current mesh
            std::vector<unsigned int>& indices = currMesh.GetIndices();
            indices.resize(indexCount);

            // Loop over the indices of the current mesh primitive
            for (unsigned int i = 0; i < indexCount; ++i)
            {
               indices[i] = static_cast<unsigned int>(cgltf_accessor_read_index(currPrimitive->indices, i));
            }
         }

         // TODO: Perhaps we shouldn't do this here. The user should choose when this is done
         // Once we are done loading the current mesh, we load its VBOs with the data that we read
         currMesh.LoadBuffers();
      }
   }

   return animatedMeshes;
}
// A glTF file may contain an array of meshes
// Each mesh may contain multiple mesh primitives, which refer to the geometry data that is required to render a mesh
// Each mesh primitive consists of:
// - A rendering mode (e.g. POINTS, LINES or TRIANGLES)
// - A set of indices
// - The attributes of the vertices
// - The material that should be used for rendering
// This function loads the meshes of nodes that also refer to skins
// In other words, it loads animated meshes
A glTF file may contain an array of meshes
Each mesh may contain multiple mesh primitives, which refer to the geometry data that is required to render a mesh
Each mesh primitive consists of:
A rendering mode
A set of indices
The attributes of the vertices
The material that should be used for rendering
This function loads the meshes of nodes that also refer to skins
In other words, it loads animated meshes
A glTF file may contain an array of meshes Each mesh may contain multiple mesh primitives which refer to the geometry data that is required to render a mesh Each mesh primitive consists of : A rendering mode A set of indices The attributes of the vertices The material that should be used for rendering This function loads the meshes of nodes that also refer to skins In other words it loads animated meshes
std::vector<AnimatedMesh> LoadAnimatedMeshes(cgltf_data* data)
{
   std::vector<AnimatedMesh> animatedMeshes;
   unsigned int numNodes = static_cast<unsigned int>(data->nodes_count);
   for (unsigned int nodeIndex = 0; nodeIndex < numNodes; ++nodeIndex)
   {
      cgltf_node* currNode = &data->nodes[nodeIndex];
      if (currNode->mesh == nullptr || currNode->skin == nullptr)
      {
         continue;
      }
      unsigned int numPrimitives = static_cast<unsigned int>(currNode->mesh->primitives_count);
      for (unsigned int primitiveIndex = 0; primitiveIndex < numPrimitives; ++primitiveIndex)
      {
         cgltf_primitive* currPrimitive = &currNode->mesh->primitives[primitiveIndex];
         animatedMeshes.push_back(AnimatedMesh());
         AnimatedMesh& currMesh = animatedMeshes[animatedMeshes.size() - 1];
         unsigned int numAttributes = static_cast<unsigned int>(currPrimitive->attributes_count);
         for (unsigned int attributeIndex = 0; attributeIndex < numAttributes; ++attributeIndex)
         {
            cgltf_attribute* attribute = &currPrimitive->attributes[attributeIndex];
            GLTFHelpers::StoreValuesOfAttributeInAnimatedMesh(*attribute, currNode->skin, data->nodes, numNodes, currMesh);
         }
         if (currPrimitive->indices != nullptr)
         {
            unsigned int indexCount = static_cast<unsigned int>(currPrimitive->indices->count);
            std::vector<unsigned int>& indices = currMesh.GetIndices();
            indices.resize(indexCount);
            for (unsigned int i = 0; i < indexCount; ++i)
            {
               indices[i] = static_cast<unsigned int>(cgltf_accessor_read_index(currPrimitive->indices, i));
            }
         }
         currMesh.LoadBuffers();
      }
   }
   return animatedMeshes;
}
std :: vector < AnimatedMesh > LoadAnimatedMeshes ( cgltf_data * data ) { std :: vector < AnimatedMesh > animatedMeshes ; unsigned int numNodes = static_cast < unsigned int > ( data -> nodes_count ) ; for ( unsigned int nodeIndex = 0 ; nodeIndex < numNodes ; ++ nodeIndex ) { cgltf_node * currNode = & data -> nodes [ nodeIndex ] ; if ( currNode -> mesh == nullptr || currNode -> skin == nullptr ) { continue ; } unsigned int numPrimitives = static_cast < unsigned int > ( currNode -> mesh -> primitives_count ) ; for ( unsigned int primitiveIndex = 0 ; primitiveIndex < numPrimitives ; ++ primitiveIndex ) { cgltf_primitive * currPrimitive = & currNode -> mesh -> primitives [ primitiveIndex ] ; animatedMeshes . push_back ( AnimatedMesh ( ) ) ; AnimatedMesh & currMesh = animatedMeshes [ animatedMeshes . size ( ) - 1 ] ; unsigned int numAttributes = static_cast < unsigned int > ( currPrimitive -> attributes_count ) ; for ( unsigned int attributeIndex = 0 ; attributeIndex < numAttributes ; ++ attributeIndex ) { cgltf_attribute * attribute = & currPrimitive -> attributes [ attributeIndex ] ; GLTFHelpers :: StoreValuesOfAttributeInAnimatedMesh ( * attribute , currNode -> skin , data -> nodes , numNodes , currMesh ) ; } if ( currPrimitive -> indices != nullptr ) { unsigned int indexCount = static_cast < unsigned int > ( currPrimitive -> indices -> count ) ; std :: vector < unsigned int > & indices = currMesh . GetIndices ( ) ; indices . resize ( indexCount ) ; for ( unsigned int i = 0 ; i < indexCount ; ++ i ) { indices [ i ] = static_cast < unsigned int > ( cgltf_accessor_read_index ( currPrimitive -> indices , i ) ) ; } } currMesh . LoadBuffers ( ) ; } } return animatedMeshes ; }
A glTF file may contain an array of meshes
Each mesh may contain multiple mesh primitives, which refer to the geometry data that is required to render a mesh
Each mesh primitive consists of:
 A rendering mode (e.g.
A glTF file may contain an array of meshes Each mesh may contain multiple mesh primitives which refer to the geometry data that is required to render a mesh Each mesh primitive consists of : A rendering mode ( e . g .
// Loop over the array of nodes of the glTF file // This function only loads animated meshes, so the node must contain a mesh and a skin for us to process it // Loop over the array of mesh primitives of the current node // Get the current mesh primitive // Create an AnimatedMesh for the current mesh primitive // Loop over the attributes of the current mesh primitive // Get the current attribute // Read the values of the current attribute and store them in the current mesh // If the current mesh primitive has a set of indices, store them too // Get the vector that will store the indices of the current mesh // Loop over the indices of the current mesh primitive // TODO: Perhaps we shouldn't do this here. The user should choose when this is done // Once we are done loading the current mesh, we load its VBOs with the data that we read