+ // bones
+ std::vector<VertBones> vertBones(aiMesh->mNumVertices);
+
+ std::map<unsigned int, std::vector<std::pair<unsigned int, float>>> boneWeightMap;
+
+ for (unsigned int i = 0; i < aiMesh->mNumBones; i++) {
+ aiBone *aiBone = aiMesh->mBones[i];
+
+ boneMap[std::string(aiBone->mName.C_Str())] = std::pair(i + 1, aiMatrixToMat4(aiBone->mOffsetMatrix));
+
+ for (int j = 0; j < aiBone->mNumWeights; j++) {
+ aiVertexWeight vw = aiBone->mWeights[j];
+
+ if (!boneWeightMap.count(vw.mVertexId)) boneWeightMap[vw.mVertexId] = std::vector<std::pair<unsigned int, float>>();
+ boneWeightMap[vw.mVertexId].push_back(std::pair(i + 1, vw.mWeight));
+ }
+ }
+
+ for (auto pair: boneWeightMap) {
+ unsigned int vertexId = pair.first;
+ for (int i = 0; i < pair.second.size() && i < 4; i++) {
+ unsigned int boneId = pair.second[i].first;
+ float weight = pair.second[i].second;
+ vertBones[vertexId].ids[i] = boneId;
+ vertBones[vertexId].weights[i] = weight;
+ }
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, boneVbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(VertBones) * vertBones.size(), &vertBones[0], GL_STATIC_DRAW);
+
+ GLuint boneIdLoc = glGetAttribLocation(progId, "boneIds");
+ glEnableVertexAttribArray(boneIdLoc);
+ glVertexAttribIPointer(boneIdLoc, 4, GL_INT, sizeof(VertBones), 0);
+
+ GLuint boneWeightLoc = glGetAttribLocation(progId, "boneWeights");
+ glEnableVertexAttribArray(boneWeightLoc);
+ glVertexAttribPointer(boneWeightLoc, 4, GL_FLOAT, GL_FALSE, sizeof(VertBones), (const GLvoid *)sizeof(VertBones::ids));
+}
+
+Model::Node::Node(const aiNode &node, GLuint progId, AnimMap *am): ai(node), progId(progId), animMap(am) {