]> git.openfl.eu Git - gummi.git/commitdiff
touch to squint main
authorFl_GUI <flor.guilini@hotmail.com>
Sun, 6 Jul 2025 15:41:54 +0000 (17:41 +0200)
committerFl_GUI <flor.guilini@hotmail.com>
Sun, 6 Jul 2025 15:41:54 +0000 (17:41 +0200)
meson.build
src/animator.cc
src/animator.h
src/eye.cc
src/eye.h
src/main.cc
src/state.cc [new file with mode: 0644]
src/state.h [new file with mode: 0644]
src/window.cc [new file with mode: 0644]
src/window.h [new file with mode: 0644]

index 6f6d99901d1a1b527e851b713e871462da2701cf..52b7af9c48244d9c1a1a7bb9f49cb4eff9acfe4c 100644 (file)
@@ -5,7 +5,7 @@ src = 'src'
 subdir(src / 'glad')
 
 deps = [dependency('glfw3'), glad_dep]
-srcs = [src/'main.cc', src/'eye.cc', src/'log.cc', src/'mouth.cc', src/'animator.cc']
+srcs = [src/'window.cc', src/'main.cc', src/'animator.cc', src/'state.cc', src/'eye.cc', src/'log.cc', src/'mouth.cc']
 
 executable('gummi',
   sources: srcs,
index ddd2d3e4e92943ad72f4e8f9d42e3442735992ae..cdf7a0a730c344e6ba4cf4d1419a26201a37bcdb 100644 (file)
@@ -3,44 +3,26 @@
 
 #include <random>
 
-struct {
-  double blink;
-} animation;
-
-std::random_device rd;
-
-const double blinkDuration = 0.2;
-
-void blink(double dt) {
-  if (animation.blink < -1) {
-    animation.blink = blinkDuration;
-  } else if (animation.blink <= 0.0) {
-    auto roll = rd();
-    if (roll > rd.max() * 0.8)
-      animation.blink -= dt;
-  } else {
-    animation.blink -= dt;
-  }
+animator::animator(double duration) {
+  target = duration;
+  current = 0;
+}
 
-  if (animation.blink <= 0.0) {
-    eyes[0].blinkFrame = open;
-    eyes[1].blinkFrame = open;
-  } else {
-    const double frameTimings[BLINKFRAME_MAX] {blinkDuration, blinkDuration*0.6, blinkDuration*0.3, 0};
-    for (int i = open; i < BLINKFRAME_MAX; i++) {
-      auto frame = blinkDuration - animation.blink;
-      if (frameTimings[i+1] <= frame && frame <= frameTimings[i]) {
-        eyes[0].blinkFrame = (blinkFrame_t)(i+1);
-        eyes[1].blinkFrame = (blinkFrame_t)(i+1);
-      }
-    }
-  }
+void animator::update(double deltaTime) {
+  if (target > 0)
+    current += deltaTime;
+  if (target < 0)
+    current -= deltaTime;
 }
 
-void updateAnimations(double dt) {
-  blink(dt);
+double animator::getRatio() {
+  return current / target;
 }
 
-void initAnimator() {
-  animation.blink = 0.0;
+bool animator::done() {
+  if (target > 0)
+    return current >= target;
+  if (target < 0)
+    return -current >= -target;
+  return true;
 }
index f5bf8f7987eb23d588cf74686af79bbec3666e09..19b636b3844e600169009d3d3f8b6f8c491a5113 100644 (file)
@@ -1,2 +1,12 @@
-void initAnimator();
-void updateAnimations(double dt);
+class animator {
+  public:
+    animator(double duration);
+    ~animator() = default;
+
+    void update(double deltaTime);
+    double getRatio();
+    bool done();
+  private:
+    double target;
+    double current;
+};
index 77979b646475e49f340c37d0a41160360bdb745a..d295b7e189ec8ee1712173d50f021529953ce174 100644 (file)
@@ -46,6 +46,16 @@ GLuint pupilShaderProgram;
 
 eye_t eyes[2];
 
+blinkFrame_t ratioToBlink(double ratio) {
+  if (ratio > 0.6)
+    return open;
+  if (ratio > 0.3)
+    return blink_60;
+  if (ratio > 0.0)
+    return blink_30;
+  return closed;
+}
+
 void setEyeShaderProgram() {
   GLint status;
 
index b9599a6b39a254116b5016b6820e0d9b19523278..b217bf6fd9b15ba678ee27935603d648e1fc535a 100644 (file)
--- a/src/eye.h
+++ b/src/eye.h
@@ -23,6 +23,8 @@ typedef struct eye {
 
 extern eye_t eyes[2];
 
+blinkFrame_t ratioToBlink(double ratio);
+
 void initEyes();
 
 void drawEyes();
index a6654312b7a41e62d18258e1647cc4f78fe7399f..11cb80bf6287b869ca5555c27b60bd39687d721f 100644 (file)
@@ -3,10 +3,11 @@
 #include <iostream>
 #include <vector>
 
+#include "window.h"
 #include "log.h"
 #include "eye.h"
 #include "mouth.h"
-#include "animator.h"
+#include "state.h"
 
 float triangles[] = {
   -0.5,0.5,0,
@@ -82,8 +83,6 @@ void closeOnQ(GLFWwindow* window, int key, int scancode, int action, int mods) {
 }
 
 int main() {
-  GLFWwindow* window;
-
   if (!glfwInit()) {
     printf("could not initialize glfw\n");
     exit(1);
@@ -95,7 +94,7 @@ int main() {
   glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
   glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
 
-  window = glfwCreateWindow(800, 480, "gummi", NULL, NULL);
+  window = glfwCreateWindow(SCREENWIDTH, SCREENHEIGHT, "gummi", NULL, NULL);
 
   if (!window) {
     printf("could not create window\n");
@@ -120,9 +119,7 @@ int main() {
 
   useShaders();
 
-  initEyes();
-  initMouth();
-  initAnimator();
+  initState();
 
   GLuint VBOS[2];
   glGenBuffers(2, (GLuint*) &VBOS);
@@ -144,7 +141,7 @@ int main() {
     glfwPollEvents();
 
     // update
-    updateAnimations(currentTime - lastUpdateTime);
+    updateState(currentTime - lastUpdateTime);
     lastUpdateTime = currentTime;
 
     if (currentTime - lastRenderTime > targetRate) {
diff --git a/src/state.cc b/src/state.cc
new file mode 100644 (file)
index 0000000..8295545
--- /dev/null
@@ -0,0 +1,90 @@
+#include "state.h"
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#include <random>
+#include <memory>
+
+#include "animator.h"
+#include "eye.h"
+#include "mouth.h"
+#include "window.h"
+
+constexpr double irritationPerSecond = 1;
+constexpr double irritationThresh = 5;
+
+struct {
+  double leftEyeIrritate;
+  double rightEyeIrritate;
+
+  std::unique_ptr<animator> blinkAnimator;
+  std::random_device rd;
+} state;
+
+void initEyeIrritation() {
+  if (state.blinkAnimator)
+    state.blinkAnimator.release();
+
+  auto initIrr = state.rd() * 0.8 * irritationThresh / state.rd.max();
+
+  state.leftEyeIrritate = initIrr;
+  state.rightEyeIrritate = initIrr;
+  state.blinkAnimator.release();
+}
+
+void initState() {
+  initEyes();
+  initMouth();
+
+  initEyeIrritation();
+}
+
+void closeOnTouched() {
+  double x, y;
+  glfwGetCursorPos(window, &x, &y);
+  int close = 0;
+
+  if (x < SCREENWIDTH/2) {
+    close = 0;
+  } else {
+    close = 1;
+  }
+  eyes[close].blinkFrame = closed;
+  eyes[1-close].blinkFrame = blink_30;
+}
+
+void updateEyeState(double deltaTime) {
+  state.leftEyeIrritate += deltaTime*irritationPerSecond;
+  state.rightEyeIrritate += deltaTime*irritationPerSecond;
+
+  auto press = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_1);
+
+  // overwrite when touched
+  if (press == GLFW_PRESS) {
+    closeOnTouched();
+    state.leftEyeIrritate = irritationThresh*0.9;
+    state.rightEyeIrritate = irritationThresh*0.9;
+    return;
+  }
+
+  if (state.blinkAnimator) {
+    state.blinkAnimator->update(deltaTime);
+    auto blinkRatio = state.blinkAnimator->getRatio();
+    auto blinkFrame = ratioToBlink(blinkRatio);
+    eyes[0].blinkFrame = blinkFrame;
+    eyes[1].blinkFrame = blinkFrame;
+
+    if (state.blinkAnimator->done()) {
+      initEyeIrritation();
+    } 
+  } else if (state.leftEyeIrritate > irritationThresh || state.rightEyeIrritate > irritationThresh) {
+    state.blinkAnimator = std::make_unique<animator>(0.2);
+  } else {
+    eyes[0].blinkFrame = open;
+    eyes[1].blinkFrame = open;
+  }
+}
+
+void updateState(double deltaTime) {
+  updateEyeState(deltaTime);
+}
diff --git a/src/state.h b/src/state.h
new file mode 100644 (file)
index 0000000..e8bf727
--- /dev/null
@@ -0,0 +1,2 @@
+void initState();
+void updateState(double deltaTime);
diff --git a/src/window.cc b/src/window.cc
new file mode 100644 (file)
index 0000000..6931f51
--- /dev/null
@@ -0,0 +1,4 @@
+#include "window.h"
+
+GLFWwindow* window;
+
diff --git a/src/window.h b/src/window.h
new file mode 100644 (file)
index 0000000..db5adfc
--- /dev/null
@@ -0,0 +1,7 @@
+#pragma once
+#include <GLFW/glfw3.h>
+
+#define SCREENWIDTH 800
+#define SCREENHEIGHT 480
+
+extern GLFWwindow* window;