X-Git-Url: http://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=model.cpp;h=efc7f222b9db70856e362cf50b15549b5d5c4d27;hp=0bb58372e521095542c3e3b2f3b1e6a5be2913b5;hb=610bb8ddab4ec871cadfed0a0b66695b8fea41a4;hpb=be8759aec179d6d7bed58732134673870c596b4f diff --git a/model.cpp b/model.cpp index 0bb5837..efc7f22 100644 --- a/model.cpp +++ b/model.cpp @@ -12,7 +12,6 @@ glm::mat4 aiMatrixToMat4(aiMatrix4x4 from) { return to; } - Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) { std::vector vertices, normals, tangents, bitangents; @@ -132,8 +131,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 +143,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 +171,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,19 +224,17 @@ void Model::Node::draw( const std::vector &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; for (auto child: children) { - //set to parent transforms boneTransforms[std::string(ai.mName.C_Str())] = m; } @@ -253,19 +253,18 @@ void Model::Node::draw( const std::vector &meshes, 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); @@ -337,15 +336,35 @@ Model::Model(const std::string &path, Program p): program(p) { std::string nodeName = pair.first; if (!animMap->count(nodeName)) (*animMap)[nodeName] = std::vector(); - (*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); }