From 7bc196f175cf052bc2e7bd814c04252aa21ef9d2 Mon Sep 17 00:00:00 2001 From: Macoy Madson Date: Sun, 25 Sep 2022 12:43:50 -0400 Subject: [PATCH] Get bone rotation working --- .gitmodules | 3 + Dependencies/Handmade-Math | 1 + Dependencies/cakelisp | 2 +- Dependencies/gamelib | 2 +- src/VectorPuppetShow.cake | 114 ++++++++++++++++++++++++++++++------- 5 files changed, 100 insertions(+), 22 deletions(-) create mode 160000 Dependencies/Handmade-Math diff --git a/.gitmodules b/.gitmodules index b33a438..0caddc8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "Dependencies/nanosvg"] path = Dependencies/nanosvg url = gitea@macoy.me:macoy/nanosvg.git +[submodule "Dependencies/Handmade-Math"] + path = Dependencies/Handmade-Math + url = https://github.com/HandmadeMath/Handmade-Math diff --git a/Dependencies/Handmade-Math b/Dependencies/Handmade-Math new file mode 160000 index 0000000..ba5405a --- /dev/null +++ b/Dependencies/Handmade-Math @@ -0,0 +1 @@ +Subproject commit ba5405ac0fb3f899845fe47d80364e4d1fd5c866 diff --git a/Dependencies/cakelisp b/Dependencies/cakelisp index d1aa08f..951bbde 160000 --- a/Dependencies/cakelisp +++ b/Dependencies/cakelisp @@ -1 +1 @@ -Subproject commit d1aa08f1bbc68856beb699374a5cd32274757e61 +Subproject commit 951bbde2970ba796384a0938d02d7219b771cc3a diff --git a/Dependencies/gamelib b/Dependencies/gamelib index 35ee3b0..3c916b8 160000 --- a/Dependencies/gamelib +++ b/Dependencies/gamelib @@ -1 +1 @@ -Subproject commit 35ee3b08a3e4ef87a686ebcaa43c21734b06336f +Subproject commit 3c916b8cb7a05eebbee790f4b8d3480cf5f296aa diff --git a/src/VectorPuppetShow.cake b/src/VectorPuppetShow.cake index 81b0fc7..bccac32 100644 --- a/src/VectorPuppetShow.cake +++ b/src/VectorPuppetShow.cake @@ -10,7 +10,7 @@ "CHelpers.cake" ;; GameLib "Introspection.cake" "SDL.cake" "DynamicArray.cake" "Dictionary.cake" "DataBundle.cake" - "SDLFontAtlas.cake" "FreeType.cake") + "SDLFontAtlas.cake" "FreeType.cake" "Math.cake") (c-import "" &with-decls "") @@ -55,6 +55,39 @@ (return (and (< bounds-width compare-to-width) (< bounds-height compare-to-height)))) +(defstruct-local skeleton-bone + shape (addr NSVGshape) + start-position vec2 + rest-position vec2 + end-position vec2) + +(defun-local draw-bone (renderer (addr SDL_Renderer) bone (addr skeleton-bone)) + (var point-width (const int) 15) + (defstruct point-color + point (addr vec2) + color (array 3 (unsigned char))) + (var points-to-render (array point-color) + (array + (array (addr (path bone > start-position)) + (array 255 0 0)) + (array (addr (path bone > end-position)) + (array 0 255 0)) + (array (addr (path bone > rest-position)) + (array 0 0 255)))) + (each-item-addr-in-array points-to-render i point (addr point-color) + (var point-rect SDL_Rect + (array (- (type-cast (path point > point > X) int) + (/ point-width 2)) + (- (type-cast (path point > point > Y) int) + (/ point-width 2)) + point-width point-width)) + (SDL_SetRenderDrawColor renderer + (at 0 (path point > color)) + (at 1 (path point > color)) + (at 2 (path point > color)) + 255) + (SDL_RenderDrawRect renderer (addr point-rect)))) + (defun main (&return int) (comptime-cond ('Windows @@ -246,9 +279,10 @@ (var selected-shape (addr NSVGshape) null) (var selected-shape-bounds (array 4 int) (array 0)) + (var selected-bone skeleton-bone (array 0)) (var enable-fullscreen bool false) - (var view-selection bool false) + (var view-selection bool true) (var view-atlas bool false) (var view-svg bool false) (var view-puppet bool true) @@ -328,7 +362,8 @@ (var mouse-x int 0) (var mouse-y int 0) - (SDL_GetMouseState (addr mouse-x) (addr mouse-y)) + (var mouse-button-state Uint32 + (SDL_GetMouseState (addr mouse-x) (addr mouse-y))) (when (and view-atlas puppet-atlas-texture) (var atlas-rectangle SDL_Rect @@ -341,7 +376,8 @@ (set exit-reason "Failed to render atlas texture"))) ;; Start over selection to always ensure we pick the smallest shape - (set selected-shape null) + (when (bit-and mouse-button-state SDL_BUTTON_MMASK) + (set selected-shape null)) (when view-selection ;; Shape selection and debug viewing (var hovered-shape-id-buffer (array 1024 char) (array 0)) (var hovered-write-head (addr char) hovered-shape-id-buffer) @@ -399,8 +435,8 @@ (>= mouse-y (at 1 sized-bounds)) (< mouse-x (at 2 sized-bounds)) (< mouse-y (at 3 sized-bounds))) - (when (or (not selected-shape) - (is-shape-smaller sized-bounds selected-shape-bounds)) + (when (and (bit-and mouse-button-state SDL_BUTTON_MMASK) + (or (not selected-shape) (is-shape-smaller sized-bounds selected-shape-bounds))) (set selected-shape shape) (memcpy selected-shape-bounds sized-bounds (sizeof selected-shape-bounds))) (SDL_SetRenderDrawColor renderer 10 230 10 255) @@ -443,20 +479,37 @@ (when view-puppet ;; We are ever so slightly off - (var sized-bounds (array 4 float) (array 0)) - (nanosvg-get-shape-bounds-with-stroke-float shape sized-bounds) - (var to-rectangle SDL_Rect - (array (type-cast (at 0 sized-bounds) int) - (type-cast (at 1 sized-bounds) int) - (path current-rectangle > w) - (path current-rectangle > h))) - (var-static angle float -2.5f) - (var-static angle-add float 0.001f) - (set angle (+ angle angle-add)) - (when (or (> angle 2.5f) - (< angle -2.5f)) - (set angle-add (negate angle-add))) - (var rotate-center SDL_Point (array 0 0)) + (var sized-bounds (array 4 float) (array 0)) + (nanosvg-get-shape-bounds-with-stroke-float shape sized-bounds) + (var to-rectangle SDL_Rect + (array (type-cast (at 0 sized-bounds) int) + (type-cast (at 1 sized-bounds) int) + (path current-rectangle > w) + (path current-rectangle > h))) + (var rest-vector vec2 + (vec2-normalize (vec2-subtract (field selected-bone end-position) + (field selected-bone start-position)))) + (var point-at-vector vec2 + (vec2-normalize (vec2-subtract (field selected-bone rest-position) + (field selected-bone start-position)))) + (var angle float + (acosf (vec2-dot + rest-vector + point-at-vector))) + ;; We need to find the perpendicular vector to know which way we need to rotate + (var perpendicular vec2 rest-vector) + ;; In 2D we can find the perpendicular vector by swapping the axes and negating one + (var temp float (field perpendicular X)) + (set (field perpendicular X) (field perpendicular Y)) + (set (field perpendicular Y) (negate temp)) + (var sign float (vec2-dot point-at-vector perpendicular)) + (set angle (radians-to-degrees angle)) + (when (> sign 0.f) + (set angle (negate angle))) + (var rotate-center SDL_Point + (array + (type-cast (- (field selected-bone start-position X) (at 0 sized-bounds)) int) + (type-cast (- (field selected-bone start-position Y) (at 1 sized-bounds)) int))) (unless (= 0 (SDL_RenderCopyEx renderer puppet-atlas-texture (addr draw-rectangle) (addr to-rectangle) (? (= shape selected-shape) angle 0.f) @@ -466,6 +519,27 @@ (set exit-reason "Failed to render atlas texture"))) (incr current-rectangle))) + (cond + ((and (bit-and mouse-button-state SDL_BUTTON_LMASK) + (or (at SDL_SCANCODE_LCTRL (field s-key-states this-frame-states)) + (at SDL_SCANCODE_RCTRL (field s-key-states this-frame-states)))) + (set-fields selected-bone + shape selected-shape + (rest-position X) mouse-x + (rest-position Y) mouse-y)) + ((bit-and mouse-button-state SDL_BUTTON_LMASK) + (set-fields selected-bone + shape selected-shape + (start-position X) mouse-x + (start-position Y) mouse-y)) + ((bit-and mouse-button-state SDL_BUTTON_RMASK) + (set-fields selected-bone + shape selected-shape + (end-position X) mouse-x + (end-position Y) mouse-y))) + (when selected-shape + (draw-bone renderer (addr selected-bone))) + (when true ;; Debug position (var buffer (array 256 char) (array 0)) (snprintf buffer (- (array-size buffer) 1) "Mouse: %4d %4d Percent of window: %.2f %.2f"