Update shader errors, add back brdffrag
[opengl.git] / model.cpp
index 0bb58372e521095542c3e3b2f3b1e6a5be2913b5..a11a0745dd9d4b8d41da1c8a3809fa34384e1037 100644 (file)
--- a/model.cpp
+++ b/model.cpp
@@ -1,17 +1,8 @@
 #include "model.hpp"
 #include <iostream>
-#include <assimp/postprocess.h>
 #include <assimp/quaternion.h>
 #include <glm/gtc/type_ptr.hpp>
 
-glm::mat4 aiMatrixToMat4(aiMatrix4x4 from) {
-       glm::mat4 to;
-       for (int i = 0; i < 4; i++)
-               for (int j = 0; j < 4; j++)
-                       to[i][j] = from[j][i];
-       return to;
-}
-
 
 Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) {
 
@@ -132,8 +123,7 @@ Model::Node::Node(const aiNode &node, GLuint progId, AnimMap *am): ai(node), pro
        }
 }
 
-glm::mat4 lerp(const aiNodeAnim *anim, const float tick) {
-       
+glm::mat4 lerpPosition(const aiNodeAnim *anim, const float tick) {
        if (anim->mNumPositionKeys == 0) return glm::mat4(1.f);
 
        int yIndex = -1;
@@ -145,8 +135,10 @@ glm::mat4 lerp(const aiNodeAnim *anim, const float tick) {
                }
        }
        aiVector3D lerpPos;
-       if (yIndex < 1) {
+       if (yIndex == 0) {
                lerpPos = anim->mPositionKeys[0].mValue;
+       } else if (yIndex == -1) {
+               lerpPos = anim->mPositionKeys[anim->mNumPositionKeys - 1].mValue;
        } else {
                auto X = anim->mPositionKeys[yIndex - 1];
                auto Y = anim->mPositionKeys[yIndex];
@@ -171,6 +163,8 @@ glm::mat4 lerpRotation(const aiNodeAnim *anim, const float tick) {
        aiQuaternion result;
        if (yIndex < 1) {
                result = anim->mRotationKeys[0].mValue;
+       } else if (yIndex == -1) {
+               result = anim->mRotationKeys[anim->mNumRotationKeys - 1].mValue;
        } else {
 
                auto X = anim->mRotationKeys[yIndex - 1];
@@ -222,21 +216,19 @@ void Model::Node::draw(   const std::vector<Mesh> &meshes,
                for (const Animation anim: animMap->at(std::string(ai.mName.C_Str()))) {
                        float t = fmod(tick, anim.duration);
                        for (const aiNodeAnim *nodeAnim: anim.nodeAnims) {
-                               animTrans *= lerp(nodeAnim, t);
+                               animTrans *= lerpPosition(nodeAnim, t);
                                animTrans *= lerpRotation(nodeAnim, t);
                                animTrans *= lerpScaling(nodeAnim, t);
                        }
                }
-               /* std::cerr << std::string(ai.mName.C_Str()) << animTrans[0][0] << std::endl; */
        }
        
 
-       glm::mat4 m = parentTrans * animTrans * aiMatrixToMat4(ai.mTransformation) * model;
+       glm::mat4 m = parentTrans * animTrans * aiMatrixToMat4(ai.mTransformation);
 
-       for (auto child: children) {
-               //set to parent transforms
-               boneTransforms[std::string(ai.mName.C_Str())] = m;
-       }
+       /* for (auto child: children) { */
+       /*      boneTransforms[std::string(ai.mName.C_Str())] = m; */
+       /* } */
        
        for (unsigned int i: meshIndices) {
                const Mesh &mesh = meshes[i];
@@ -250,24 +242,27 @@ void Model::Node::draw(   const std::vector<Mesh> &meshes,
 
                        std::string nodeName = pair.first;
                        unsigned int boneId = pair.second.first;
+                       // This is actually an inverse-bind matrix
+                       // i.e. position of the mesh in bone space
+                       // so no need to inverse again!
+                       // https://github.com/assimp/assimp/pull/1803/files
                        glm::mat4 boneOffset = pair.second.second;
 
                        glm::mat4 boneTrans(1.f);
-                       if (boneTransforms.count(nodeName)) boneTrans = boneTransforms[nodeName];
-                       int j = 0;
+                       /* if (boneTransforms.count(nodeName)) { */
+                       /*      std::cerr << "got bone transform from map" << std::endl; */
+                       /*      boneTrans = boneTransforms[nodeName]; */
+                       /* } */
                        for (const Animation anim: animMap->at(nodeName)) {
                                float t = fmod(tick, anim.duration);
                                for (const aiNodeAnim *nodeAnim: anim.nodeAnims) {
-                                       boneTrans = boneTrans * lerp(nodeAnim, t);
+                                       boneTrans = boneTrans * lerpPosition(nodeAnim, t);
                                        boneTrans = boneTrans * lerpRotation(nodeAnim, t);
-                                       /* boneTrans = boneTrans * lerpScaling(nodeAnim, t); */
-                                       j++;
+                                       boneTrans = boneTrans * lerpScaling(nodeAnim, t);
                                }
                        }
-                       assert(j == 1);
-
 
-                       boneTrans = boneTrans * glm::inverse(boneOffset);
+                       boneTrans = boneTrans * boneOffset;
 
 
                        std::string boneLocStr = "bones[" + std::to_string(boneId) + "]";
@@ -297,16 +292,9 @@ void Model::Node::draw(    const std::vector<Mesh> &meshes,
        for (Node *child: children) child->draw(meshes, materials, skybox, tick, m, boneTransforms);
 }
 
-Model::Model(const std::string &path, Program p): program(p) {
+Model::Model(const aiScene *scene, Program p): program(p) {
        glUseProgram(p.progId);
 
-       const aiScene *scene = importer.ReadFile(path, 
-                       aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_FlipUVs);
-       if (!scene) {
-               std::cerr << importer.GetErrorString() << std::endl;
-               exit(1);
-       }
-
        for (int i = 0; i < scene->mNumMeshes; i++) {
                const aiMesh *mesh = scene->mMeshes[i];
                meshes.push_back(Mesh(mesh, p.progId));
@@ -315,7 +303,7 @@ Model::Model(const std::string &path, Program p): program(p) {
        // TODO: handle default material inserted at the end by assimp
        for (unsigned int i = 0; i < scene->mNumMaterials - 1; i++) {
                const aiMaterial &material = *scene->mMaterials[i];
-               materials.push_back(Material(material, p.progId));
+               materials.push_back(Material(material, *scene, p.progId));
        }
 
        AnimMap *animMap = new AnimMap();
@@ -337,15 +325,35 @@ Model::Model(const std::string &path, Program p): program(p) {
                        std::string nodeName = pair.first;
 
                        if (!animMap->count(nodeName)) (*animMap)[nodeName] = std::vector<const Animation>();
-                       (*animMap)[nodeName].push_back({ 7500, pair.second });
+                       (*animMap)[nodeName].push_back({ aiAnim->mDuration, pair.second });
                }
        }
 
        root = new Node(*(scene->mRootNode), p.progId, animMap);
 }
 
+/* void Model::calcBoneTransforms(aiNode &node, glm::mat4 parentTrans = glm::mat4(1), BoneTransforms boneTrans = BoneTransforms()) { */
+/*     glm::mat4 animTrans(1.f); */
+/*     if (animMap->count(std::string(ai.mName.C_Str()))) { */
+/*             for (const Animation anim: animMap->at(std::string(ai.mName.C_Str()))) { */
+/*                     float t = fmod(tick, anim.duration); */
+/*                     for (const aiNodeAnim *nodeAnim: anim.nodeAnims) { */
+/*                             animTrans *= lerpPosition(nodeAnim, t); */
+/*                             animTrans *= lerpRotation(nodeAnim, t); */
+/*                             animTrans *= lerpScaling(nodeAnim, t); */
+/*                     } */
+/*             } */
+/*     } */
+       
+
+/*     glm::mat4 m = parentTrans * animTrans * aiMatrixToMat4(ai.mTransformation) * model; */
+/* } */
+
 void Model::draw(Skybox skybox, const float tick) const {
        glUseProgram(program.progId);
+
+       
+
        root->draw(meshes, materials, skybox, tick);
 }