1 #include <assimp/Importer.hpp>
2 #include <assimp/postprocess.h>
3 #include "blendshapes.hpp"
6 void createBlendshapes(std::vector<std::string> blendshapes, std::string neutral, Program p, Blendshapes *res) {
8 Assimp::Importer importer;
9 unsigned int ppFlags = aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals;
10 importer.ReadFile(neutral, ppFlags);
11 const aiScene *scene = importer.GetOrphanedScene();
13 res->model = new Model(scene, p);
15 assert(scene->mNumMeshes == 1);
17 const aiMesh *neutralMesh = scene->mMeshes[0];
18 res->neutral = std::vector<glm::vec3>(neutralMesh->mNumVertices);
19 res->deltas = std::vector<std::vector<glm::vec3>>(blendshapes.size());
20 for (int i = 0; i < neutralMesh->mNumVertices; i++)
21 res->neutral[i] = aiVector3DToVec3(neutralMesh->mVertices[i]);
23 for (int i = 0; i < blendshapes.size(); i++) {
24 auto fp = blendshapes[i];
25 const aiScene *blendshape = importer.ReadFile(fp, ppFlags);
26 if (blendshape->mNumMeshes != 1) {
27 std::cerr << "Too many or too little meshes for the blendshape " << fp << std::endl;
30 aiMesh *mesh = blendshape->mMeshes[0];
31 std::vector<glm::vec3> meshDeltas(mesh->mNumVertices);
32 assert(mesh->mNumVertices == neutralMesh->mNumVertices);
33 for (int j = 0; j < mesh->mNumVertices; j++) {
34 glm::vec3 d = aiVector3DToVec3(mesh->mVertices[j]) - aiVector3DToVec3(neutralMesh->mVertices[j]);
37 res->deltas[i] = meshDeltas;
42 void interpolateBlendshapes(Blendshapes *b, std::vector<float> weights) {
43 assert(weights.size() == b->deltas.size());
44 const Model::Mesh mesh = b->model->meshes[0];
46 for (int i = 0; i < mesh.ai.mNumVertices; i++) {
47 glm::vec3 pos = b->neutral[i];
48 for (int j = 0; j < b->deltas.size(); j++) {
49 pos += b->deltas[j][i] * weights[j];
51 mesh.ai.mVertices[i] = vec3ToaiVector3D(pos);
54 mesh.updatePosBuffer();