Browse Source

Start saving skeleton data

master
Macoy Madson 4 months ago
parent
commit
4cc75e6fbd
  1. 194
      data/TestPuppet_skeleton.cakedata
  2. 174
      src/VectorPuppetShow.cake

194
data/TestPuppet_skeleton.cakedata

@ -0,0 +1,194 @@
(skeleton-data :svg-name "TestPuppet"
:bones (array (skeleton-bone :shape-id "UpperArmRight"
:start-position (vec 0.000 0.000)
:rest-position (vec 1.000 2.000)
:end-position (vec 3.000 4.000)) (skeleton-bone :shape-id "LowerArmRight"
:start-position (vec 0.000 10.000)
:rest-position (vec 10.000 10.000)
:end-position (vec 0.000 10.000)) (skeleton-bone :shape-id "Arm_Upper_Right"
:start-position (vec 435.000 255.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 247.000 252.000)) (skeleton-bone :shape-id "Arm_Lower_Right"
:start-position (vec 268.000 256.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 101.000 255.000)) (skeleton-bone :shape-id "Arm_Upper_Left"
:start-position (vec 581.000 253.000)
:rest-position (vec 846.000 254.000)
:end-position (vec 773.000 252.000)) (skeleton-bone :shape-id "Arm_Lower_Left"
:start-position (vec 758.000 256.000)
:rest-position (vec 958.000 209.000)
:end-position (vec 919.000 254.000)) (skeleton-bone :shape-id "Hand_Right"
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000)) (skeleton-bone :shape-id ""
:start-position (vec 0.000 0.000)
:rest-position (vec 0.000 0.000)
:end-position (vec 0.000 0.000))))

174
src/VectorPuppetShow.cake

@ -7,10 +7,11 @@
(import
"NanoSVG.cake"
;; Cakelisp
"CHelpers.cake"
"CHelpers.cake" "FileUtilities.cake"
;; GameLib
"Introspection.cake" "SDL.cake" "DynamicArray.cake" "Dictionary.cake" "DataBundle.cake"
"SDLFontAtlas.cake" "FreeType.cake" "Math.cake")
"SDLFontAtlas.cake" "FreeType.cake"
&with-decls "Math.cake")
(c-import "<stdio.h>"
&with-decls "<stdint.h>")
@ -55,11 +56,80 @@
(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)
(forward-declare (struct NSVGshape))
(def-introspect-struct skeleton-bone
shape (addr NSVGshape) (ignore)
shape-id (array 64 char)
start-position vec2 (override 'vec2)
rest-position vec2 (override 'vec2)
end-position vec2 (override 'vec2))
(introspect-override-register-handler 'write-s-expr
(metadata-field-has-tag field "'vec2")
write-vec2
(var vec2-write (addr vec2)
(offset-pointer-to-type struct-to-write value-offset (addr vec2)))
(var format-buffer (array 64 char) (array 0))
(snprintf-or-return-false format-buffer " (vec %.3f %.3f)" (at 0 (deref vec2-write))
(at 1 (deref vec2-write)))
(unless (write-func format-buffer 0 write-func-userdata) (return false))
(return true))
(introspect-override-register-handler 'read-s-expr
(metadata-field-has-tag field "'vec2")
read-vec2
(var vec2-read (addr vec2)
(offset-pointer-to-type struct-out value-offset (addr vec2)))
(var start-float (addr (const char)) value-argument-start)
(var axis int 0)
(each-char-in-string-const value-argument-start current-char
(when (= ' ' (deref current-char))
(set start-float (+ 1 current-char))
(set (at axis (deref vec2-read)) (atof start-float))
(incr axis))
(when (= value-argument-end current-char)
(break)))
(unless (= 2 axis)
(fprintf stderr "Failed to read 2D vector. Expected e.g. (vec 0.f 0.f)\n")
(return false))
(return true))
(introspect-override-register-handler 'free
(metadata-field-has-tag field "'vec2")
free-vec2
(return))
(def-introspect-struct skeleton-data
svg-name (array 64 char)
bones (array 64 skeleton-bone) ('array-allow-subset))
(defun-local get-skeleton-filename-from-svg-filename (svg-name (addr (const char))
filename-out (addr char)
filename-out-size size_t)
(var trimmed-svg-name (array 128 char) (array 0))
(snprintf trimmed-svg-name (- (strlen svg-name) 3) ;; .svg
"%s" svg-name)
(snprintf filename-out filename-out-size "%s_skeleton.cakedata" trimmed-svg-name))
(defun-local load-skeleton-for-svg (skeleton-out (addr skeleton-data)
svg-name (addr (const char)))
(var filename (array 2048 char) (array 0))
(get-skeleton-filename-from-svg-filename svg-name filename (sizeof filename))
(if-open-file-scoped filename "rb" in-file
(scope
(var file-contents (addr char) (read-file-into-memory in-file))
(defer (free file-contents))
(unless (read-introspect-struct-s-expr
skeleton-data--metadata
skeleton-out
file-contents
malloc
null)
(vpslog "Failed to read skeleton data\n")))
(scope
(vpslog "Could not find skeleton for SVG %s (expected %s)\n"
svg-name filename))))
(defun-local draw-bone (renderer (addr SDL_Renderer) bone (addr skeleton-bone))
(var point-width (const int) 15)
@ -88,6 +158,26 @@
255)
(SDL_RenderDrawRect renderer (addr point-rect))))
;; (defun-local find-shape-bone (shape (addr NSVGshape)
;; bone-out (addr skeleton-bone))
;; (var bone-tag (addr (const char)) "Bone_")
;; (var-static tag-length int (strlen bone-tag))
;; (each-shape-in-svg-image puppet-image bone-shape
;; (when (and (= 0 (strncmp (path bone-shape > id) bone-tag tag-length))
;; (= 0 (strncmp (+ tag-length (path bone-shape > id))
;; (path shape > id)
;; (sizeof (path shape > id)))))
;; (each-path-in-svg-shape bone-shape current-path
;; (var state int 0)
;; (each-in-range (* 2 (path current-path > npts)) point-index
;; (var point-x float (at point-index (path current-path > pts)))
;; (var point-y float (at (+ 1 point-index) (path current-path > pts)))
;; (var is-control-point bool (!= 0 (mod point-index 6)))
;; (when is-control-point
;; (continue))
;; (incr point-index)))
;; (break))))
(defun main (&return int)
(comptime-cond
('Windows
@ -195,9 +285,14 @@
(defer (when puppet-atlas-texture (SDL_DestroyTexture puppet-atlas-texture)))
(var puppet-atlas-width int 0)
(var puppet-atlas-height int 0)
(var skeleton skeleton-data (array 0))
(var svg-filename (addr (const char)) "data/TestPuppet.svg")
;; (var svg-filename (addr (const char)) "data/DoNotCheckIn.svg")
(defer
(free-introspect-struct-fields skeleton-data--metadata (addr skeleton) free))
(scope
;; (var filename (addr (const char)) "data/TestPuppet.svg")
(var filename (addr (const char)) "data/DoNotCheckIn.svg")
(var filename (addr (const char)) svg-filename)
(load-skeleton-for-svg (addr skeleton) filename)
(set puppet-image (nsvgParseFromFile filename "px" 96.0f))
(unless puppet-image
(vpslog "Failed to load SVG %s\n" filename)
@ -251,7 +346,9 @@
(set puppet-atlas-texture (SDL_CreateTextureFromSurface renderer image-surface))
(unless puppet-atlas-texture
(sdl-print-error)
(return 1)))
(return 1))
;; Make sure we have good anti-aliasing because we are going to be rotating these
(SDL_SetTextureScaleMode puppet-atlas-texture SDL_ScaleModeBest))
(nsvgRasterize rasterizer puppet-image 0.f 0.f 1.f image-buffer
(path puppet-image > width) (path puppet-image > height)
@ -279,7 +376,8 @@
(var selected-shape (addr NSVGshape) null)
(var selected-shape-bounds (array 4 int) (array 0))
(var selected-bone skeleton-bone (array 0))
(var empty-bone skeleton-bone (array 0))
(var selected-bone (addr skeleton-bone) (addr empty-bone))
(var enable-fullscreen bool false)
(var view-selection bool true)
@ -435,10 +533,22 @@
(>= mouse-y (at 1 sized-bounds))
(< mouse-x (at 2 sized-bounds))
(< mouse-y (at 3 sized-bounds)))
;; Select shape
(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)))
(memcpy selected-shape-bounds sized-bounds (sizeof selected-shape-bounds))
(each-item-addr-in-array (field skeleton bones) bone-index bone (addr skeleton-bone)
;; Assign bone to empty slot
(unless (at 0 (path bone > shape-id))
(snprintf (path bone > shape-id) (sizeof (path bone > shape-id))
"%s" (path shape > id))
(set selected-bone bone)
(break))
(when (= 0 (strncmp (path shape > id) (path bone > shape-id)
(sizeof (path bone > shape-id))))
(set selected-bone bone)
(break))))
(SDL_SetRenderDrawColor renderer 10 230 10 255)
(set hovered-write-head
(+ hovered-write-head
@ -487,11 +597,11 @@
(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))))
(vec2-normalize (vec2-subtract (path selected-bone > end-position)
(path selected-bone > start-position))))
(var point-at-vector vec2
(vec2-normalize (vec2-subtract (field selected-bone rest-position)
(field selected-bone start-position))))
(vec2-normalize (vec2-subtract (path selected-bone > rest-position)
(path selected-bone > start-position))))
(var angle float
(acosf (vec2-dot
rest-vector
@ -508,8 +618,8 @@
(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)))
(type-cast (- (path selected-bone > start-position . X) (at 0 sized-bounds)) int)
(type-cast (- (path 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)
@ -523,22 +633,22 @@
((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
(set-fields (deref 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
(set-fields (deref 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
(set-fields (deref selected-bone)
shape selected-shape
(end-position X) mouse-x
(end-position Y) mouse-y)))
(when selected-shape
(draw-bone renderer (addr selected-bone)))
(draw-bone renderer selected-bone))
(when true ;; Debug position
(var buffer (array 256 char) (array 0))
@ -551,6 +661,15 @@
10 (- true-window-height 50)
buffer))
(when selected-shape
(var buffer (array 256 char) (array 0))
(snprintf buffer (- (array-size buffer) 1) "Editing shape %s" (path selected-shape > id))
(render-string
renderer (addr (field (at body-font-index font-atlases) atlas))
(field (at body-font-index font-atlases) texture)
10 (- true-window-height 90)
buffer))
(SDL_RenderPresent renderer)
(SDL_UpdateWindowSurface window)
@ -560,6 +679,17 @@
(when exit-reason
(break)))
(scope ;; Save edited skeleton
(var filename (array 2048 char) (array 0))
(get-skeleton-filename-from-svg-filename svg-filename filename (sizeof filename))
(if-open-file-scoped filename "wb" out-file
(write-introspect-struct-s-expr
skeleton-data--metadata
(addr skeleton)
write-introspect-struct-file-writer out-file
write-introspect-struct-add-newline)
(vpslog "Failed to write skeleton to %s\n" filename)))
(when exit-reason
(vpslog "Exited reason: %s\n" exit-reason))
(return 0))

Loading…
Cancel
Save