|
|
@ -214,7 +214,7 @@ |
|
|
|
(type-cast (field end Y) int))) |
|
|
|
|
|
|
|
(defun-local debug-render-vec2-at-mouse (vec vec2 |
|
|
|
r (unsigned char) g (unsigned char) b (unsigned char)) |
|
|
|
r (unsigned char) g (unsigned char) b (unsigned char)) |
|
|
|
(unless g-debug-renderer |
|
|
|
(vpslog "Need to set g-debug-renderer to render vectors\n") |
|
|
|
(return)) |
|
|
@ -232,6 +232,21 @@ |
|
|
|
(type-cast (field target X) int) |
|
|
|
(type-cast (field target Y) int))) |
|
|
|
|
|
|
|
(defun-local debug-render-point (vec vec2 |
|
|
|
r (unsigned char) g (unsigned char) b (unsigned char)) |
|
|
|
(unless g-debug-renderer |
|
|
|
(vpslog "Need to set g-debug-renderer to render points\n") |
|
|
|
(return)) |
|
|
|
(var point-width (const int) 15) |
|
|
|
(var point-rect SDL_Rect |
|
|
|
(array (- (type-cast (field vec X) int) |
|
|
|
(/ point-width 2)) |
|
|
|
(- (type-cast (field vec Y) int) |
|
|
|
(/ point-width 2)) |
|
|
|
point-width point-width)) |
|
|
|
(SDL_SetRenderDrawColor g-debug-renderer r g b 255) |
|
|
|
(SDL_RenderDrawRect g-debug-renderer (addr point-rect))) |
|
|
|
|
|
|
|
(defun-local reset-skeleton-pose (skeleton (addr skeleton-data)) |
|
|
|
(each-item-addr-in-array (path skeleton > bones) i bone (addr skeleton-bone) |
|
|
|
(set (path bone > pose-start-position) (path bone > start-position)) |
|
|
@ -242,7 +257,9 @@ |
|
|
|
num-effectors int) |
|
|
|
;; TODO: This obviously won't work when it's time to animate |
|
|
|
(reset-skeleton-pose skeleton) |
|
|
|
(each-in-range 1 iteration-number |
|
|
|
(var num-refinements int 1) |
|
|
|
(var ease-factor float 0.f) ;; disabled |
|
|
|
(each-in-range num-refinements iteration-number |
|
|
|
(each-in-range num-effectors effector-index |
|
|
|
(var root-effector (addr skeleton-effector) (addr (at effector-index effectors))) |
|
|
|
;; The root bone's posed end is what we want to move to reach the effector position |
|
|
@ -258,7 +275,7 @@ |
|
|
|
(var bone-rotation-write-head (addr float) bone-rotations-turns) |
|
|
|
(var next-chain-effector skeleton-effector (deref root-effector)) |
|
|
|
;; TODO: This is only to catch loops, not refine the descent |
|
|
|
(var max-iterations (const int) 10) |
|
|
|
(var max-iterations (const int) 6) |
|
|
|
(var num-iterations int 0) |
|
|
|
(while (and (field next-chain-effector shape-id) |
|
|
|
(< num-iterations max-iterations)) |
|
|
@ -292,6 +309,8 @@ |
|
|
|
(get-angle-turns-between-vec2 |
|
|
|
bone-pose-position |
|
|
|
effector-target-position)) |
|
|
|
(when ease-factor |
|
|
|
(set root-angle-turns (* root-angle-turns ease-factor))) |
|
|
|
(var close-enough-turns float 0.01f) |
|
|
|
(when (< (fabs root-angle-turns) close-enough-turns) |
|
|
|
;; (vpslog "Close enough turns!\n") |
|
|
@ -305,6 +324,12 @@ |
|
|
|
(vec2-add |
|
|
|
(mat2-transform-vec2 rotation-matrix rotated-end-position) |
|
|
|
(path bone > pose-start-position))) |
|
|
|
|
|
|
|
(debug-render-point root-bone-working-end-position |
|
|
|
(+ (* num-iterations (/ 150 max-iterations)) 100) 17 17) |
|
|
|
(debug-render-line (path bone > pose-start-position) root-bone-working-end-position |
|
|
|
(+ (* num-iterations (/ 150 max-iterations)) 100) 30 30) |
|
|
|
|
|
|
|
(set (deref bone-rotation-write-head) |
|
|
|
(+ (deref bone-rotation-write-head) root-angle-turns)) |
|
|
|
(incr bone-rotation-write-head) |
|
|
@ -334,8 +359,8 @@ |
|
|
|
(var bone-turns float (at turn-index bone-rotations-turns)) |
|
|
|
(unless bone-turns |
|
|
|
(continue)) |
|
|
|
(vpslog "Rotate bone %s by %f turns\n" (path (at turn-index bone-chain) > shape-id) |
|
|
|
bone-turns) |
|
|
|
;; (vpslog "Rotate bone %s by %f turns\n" (path (at turn-index bone-chain) > shape-id) |
|
|
|
;; bone-turns) |
|
|
|
(var rotation-matrix mat2 (mat2-rotate-turns bone-turns)) |
|
|
|
(var parent-bone (addr skeleton-bone) (at turn-index bone-chain)) |
|
|
|
(var parent-pose-end-position vec2 |
|
|
@ -345,13 +370,19 @@ |
|
|
|
(vec2-subtract (path parent-bone > pose-end-position) |
|
|
|
(path parent-bone > pose-start-position))))) |
|
|
|
(set (path parent-bone > pose-end-position) parent-pose-end-position) |
|
|
|
(debug-render-line (path parent-bone > pose-start-position) |
|
|
|
(path parent-bone > pose-end-position) |
|
|
|
30 119 199) |
|
|
|
|
|
|
|
(var child-bone-index int (- turn-index 1)) |
|
|
|
(unless (>= child-bone-index 0) |
|
|
|
(break)) |
|
|
|
;; This makes the end effector get closer sometimes, but in other cases it gets further |
|
|
|
;; (set (at child-bone-index bone-rotations-turns) |
|
|
|
;; (+ (at child-bone-index bone-rotations-turns) bone-turns)) |
|
|
|
;; Commenting this makes the end bone position no longer align with the working end bone pose |
|
|
|
;; position, meaning this code is necessary to maintain synchronization between the expected |
|
|
|
;; position and the final rotated one. |
|
|
|
(set (at child-bone-index bone-rotations-turns) |
|
|
|
(+ (at child-bone-index bone-rotations-turns) bone-turns)) |
|
|
|
(var child-bone (addr skeleton-bone) (at child-bone-index bone-chain)) |
|
|
|
|
|
|
|
;; Rotate the offset between the parent's end position and the child's start position, then |
|
|
|