X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=blendshapes.cpp;fp=blendshapes.cpp;h=8611f6289fb7cd83b024071bc9f88a0d9e45feee;hp=0000000000000000000000000000000000000000;hb=d2a4cfcd292f5bc422a025d43855e5f4f21fb161;hpb=b472351f3c80cec8c7e9ec30cb4c113c947c0ff7 diff --git a/blendshapes.cpp b/blendshapes.cpp new file mode 100644 index 0000000..8611f62 --- /dev/null +++ b/blendshapes.cpp @@ -0,0 +1,55 @@ +#include +#include +#include "blendshapes.hpp" +#include "util.hpp" + +void createBlendshapes(std::vector blendshapes, std::string neutral, Program p, Blendshapes *res) { + + Assimp::Importer importer; + unsigned int ppFlags = aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals; + importer.ReadFile(neutral, ppFlags); + const aiScene *scene = importer.GetOrphanedScene(); + + res->model = new Model(scene, p); + + assert(scene->mNumMeshes == 1); + + const aiMesh *neutralMesh = scene->mMeshes[0]; + res->neutral = std::vector(neutralMesh->mNumVertices); + res->deltas = std::vector>(blendshapes.size()); + for (int i = 0; i < neutralMesh->mNumVertices; i++) + res->neutral[i] = aiVector3DToVec3(neutralMesh->mVertices[i]); + + for (int i = 0; i < blendshapes.size(); i++) { + auto fp = blendshapes[i]; + const aiScene *blendshape = importer.ReadFile(fp, ppFlags); + if (blendshape->mNumMeshes != 1) { + std::cerr << "Too many or too little meshes for the blendshape " << fp << std::endl; + abort(); + } + aiMesh *mesh = blendshape->mMeshes[0]; + std::vector meshDeltas(mesh->mNumVertices); + assert(mesh->mNumVertices == neutralMesh->mNumVertices); + for (int j = 0; j < mesh->mNumVertices; j++) { + glm::vec3 d = aiVector3DToVec3(mesh->mVertices[j]) - aiVector3DToVec3(neutralMesh->mVertices[j]); + meshDeltas[j] = d; + } + res->deltas[i] = meshDeltas; + } + +} + +void interpolateBlendshapes(Blendshapes *b, std::vector weights) { + assert(weights.size() == b->deltas.size()); + const Model::Mesh mesh = b->model->meshes[0]; + + for (int i = 0; i < mesh.ai.mNumVertices; i++) { + glm::vec3 pos = b->neutral[i]; + for (int j = 0; j < b->deltas.size(); j++) { + pos += b->deltas[j][i] * weights[j]; + } + mesh.ai.mVertices[i] = vec3ToaiVector3D(pos); + } + + mesh.updatePosBuffer(); +}