WIP on inverse kinematics
[opengl.git] / main.cpp
index 281da276905660e1e4a5935c1caf961f9c53d97f..a579adfc63ffdb71e910f63840b1a4b625bd9711 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -21,6 +21,7 @@
 #include "skybox.hpp"
 #include "image.hpp"
 #include "util.hpp"
+#include "ik.hpp"
 
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
 
@@ -101,6 +102,33 @@ void drawLight(Light &light) {
        glDrawArrays(GL_TRIANGLES, 0, 36);
 }
 
+int findNodeTrans(const struct aiNode *n, const struct aiString name, glm::mat4 *dest) {
+       if (strcmp(n->mName.data, name.data) == 0) {
+               *dest = aiMatrixToMat4(n->mTransformation);
+               return 0;
+       }
+       for (int i = 0; i < n->mNumChildren; i++) {
+               if (findNodeTrans(n->mChildren[i], name, dest) == 0) {
+                       glm::mat4 t = aiMatrixToMat4(n->mTransformation);
+                       *dest = t * *dest;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+glm::mat4 worldSpaceToModelSpace(aiNode *node, glm::mat4 m) {
+       aiNode *parent = node;
+       glm::mat4 res = m;
+       std::vector<glm::mat4> trans;
+       while (parent != nullptr) {
+               /* res = res * glm::inverse(aiMatrixToMat4(parent->mTransformation)); */
+               trans.push_back(glm::inverse(aiMatrixToMat4(parent->mTransformation)));
+               parent = parent->mParent;
+       }
+       while (!trans.empty()) { res = trans.back() * res; trans.pop_back(); }
+       return res;
+}
 
 void display() {
        glClearColor(0.5, 0.5, 0.5, 1);
@@ -140,8 +168,40 @@ void display() {
        glUniform3fv(glGetUniformLocation(pbrProg->progId, "lightPositions"), numLights, glm::value_ptr(lightPositions[0]));
        glUniform3fv(glGetUniformLocation(pbrProg->progId, "lightColors"), numLights, glm::value_ptr(lightColors[0]));
 
+       glm::vec3 targetPos(sin(d * 1.f), 0, cos(d * 1.f));
+       inverseKinematic(*sceneModel->find("Bottom Bone"), *sceneModel->find("Toppest Bone"), targetPos);
+
+       /* std::array<glm::vec3, 3> jointPositions; std::array<float, 2> jointDistances; */
+
+       /* std::array<std::string, 3> jointNames = { "Bottom Bone", "Middle Bone", "Top Bone" }; */
+       /* for (int i = 0; i < 3; i++) { */
+       /*      glm::mat4 trans; */
+       /*      findNodeTrans(&sceneModel->getRoot()->ai, aiString(jointNames[i]), &trans); */
+       /*      jointPositions[i] = glm::vec3(trans[3]); */
+
+       /*      if (i > 0) */
+       /*              jointDistances[i - 1] = glm::distance(jointPositions[i], jointPositions[i - 1]); */
+       /* } */
+
+       /* glm::vec3 targetPos(sin(d * 10.f), cos(d * 10.f), 0); */
+       /* auto newPositions = fabrik(targetPos, jointPositions, jointDistances); */
+
+       /* for (int i = 0; i < 3; i++) { */
+       /*      glm::mat4 absTrans(1); */
+       /*      findNodeTrans(&sceneModel->getRoot()->ai, aiString(jointNames[i]), */
+       /*                      &absTrans); */
+       /*      glm::mat4 newAbsTrans = absTrans; */
+       /*      newAbsTrans[3] = glm::vec4(newPositions[i], newAbsTrans[3][3]); */
+
+       /*      auto node = sceneModel->getRoot()->ai.FindNode(jointNames[i].c_str()); */
+
+       /*      auto newTrans = worldSpaceToModelSpace(node->mParent, newAbsTrans); */
+
+       /*      node->mTransformation = mat4ToaiMatrix(newTrans); */
+       /* } */
        /* sceneModel->find("Top Bone")->transform = glm::rotate(glm::mat4(1), d / 5.f, { 1, 0, 0}); */
        /* sceneModel->find("Bottom Bone")->transform = glm::rotate(glm::mat4(1), d / 3.f, { 1, 0, 0}); */
+
        sceneModel->draw(skyboxes[activeSkybox], d * 1000);
 
        for (Light &light: lights) drawLight(light);
@@ -175,20 +235,6 @@ void setupLightBuffers(GLuint progId) {
        glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
 }
 
-int findNodeTrans(struct aiNode *n, const struct aiString name, glm::mat4 *dest) {
-       if (strcmp(n->mName.data, name.data) == 0) {
-               *dest = aiMatrixToMat4(n->mTransformation);
-               return 0;
-       }
-       for (int i = 0; i < n->mNumChildren; i++) {
-               if (findNodeTrans(n->mChildren[i], name, dest) == 0) {
-                       glm::mat4 t = aiMatrixToMat4(n->mTransformation);
-                       *dest = t * *dest;
-                       return 0;
-               }
-       }
-       return 1;
-}
 
 void init() {
        initUtilProg();
@@ -206,7 +252,7 @@ void init() {
        pbrProg = new Program("pbrvert.glsl", "pbrfrag.glsl");
        glUseProgram(pbrProg->progId);
 
-       const std::string scenePath = "models/newtonsCradle.glb";
+       const std::string scenePath = "models/ik.glb";
        const aiScene *scene = importer.ReadFile(scenePath, aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_FlipUVs);
        if (!scene) {
                std::cerr << importer.GetErrorString() << std::endl;
@@ -269,6 +315,9 @@ void keyboardUp(unsigned char key, int x, int y) {
 void timer(int _) {
 #ifdef ENABLE_MOVEMENT
        float xSpeed = 0.f, ySpeed = 0.f, zSpeed = 0.f;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wchar-subscripts"
        if (keyStates['w'])
                zSpeed = 0.1f;
        if (keyStates['s'])
@@ -281,6 +330,7 @@ void timer(int _) {
                ySpeed = 0.1f;
        if (keyStates['e'])
                ySpeed = -0.1f;
+#pragma clang diagnostic pop
 
        camPos.x += xSpeed * sin(yaw) + zSpeed * cos(yaw);
        camPos.y += ySpeed;