From: Fl_GUI Date: Sun, 6 Jul 2025 15:41:54 +0000 (+0200) Subject: touch to squint X-Git-Url: https://git.openfl.eu/?a=commitdiff_plain;ds=inline;p=gummi.git touch to squint --- diff --git a/meson.build b/meson.build index 6f6d999..52b7af9 100644 --- a/meson.build +++ b/meson.build @@ -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, diff --git a/src/animator.cc b/src/animator.cc index ddd2d3e..cdf7a0a 100644 --- a/src/animator.cc +++ b/src/animator.cc @@ -3,44 +3,26 @@ #include -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; } diff --git a/src/animator.h b/src/animator.h index f5bf8f7..19b636b 100644 --- a/src/animator.h +++ b/src/animator.h @@ -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; +}; diff --git a/src/eye.cc b/src/eye.cc index 77979b6..d295b7e 100644 --- a/src/eye.cc +++ b/src/eye.cc @@ -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; diff --git a/src/eye.h b/src/eye.h index b9599a6..b217bf6 100644 --- 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(); diff --git a/src/main.cc b/src/main.cc index a665431..11cb80b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -3,10 +3,11 @@ #include #include +#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 index 0000000..8295545 --- /dev/null +++ b/src/state.cc @@ -0,0 +1,90 @@ +#include "state.h" + +#define GLFW_INCLUDE_NONE +#include +#include +#include + +#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 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(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 index 0000000..e8bf727 --- /dev/null +++ b/src/state.h @@ -0,0 +1,2 @@ +void initState(); +void updateState(double deltaTime); diff --git a/src/window.cc b/src/window.cc new file mode 100644 index 0000000..6931f51 --- /dev/null +++ b/src/window.cc @@ -0,0 +1,4 @@ +#include "window.h" + +GLFWwindow* window; + diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..db5adfc --- /dev/null +++ b/src/window.h @@ -0,0 +1,7 @@ +#pragma once +#include + +#define SCREENWIDTH 800 +#define SCREENHEIGHT 480 + +extern GLFWwindow* window;