@bitefoundry/retrieviewer 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ASSET-PROVENANCE.md +43 -0
- package/ASSETS-LICENSE.md +58 -0
- package/ATTRIBUTION.md +54 -0
- package/EMBEDDING.md +96 -0
- package/INSTALLING.md +107 -0
- package/LICENSE +16 -0
- package/LICENSE-CODE +21 -0
- package/PLUGIN.md +110 -0
- package/PUPPY-MEMORY.md +57 -0
- package/PUPPY-Q5-COMPARISON.md +73 -0
- package/README.md +61 -2
- package/RELEASING.md +61 -0
- package/THIRD-PARTY-NOTICES.md +17 -0
- package/TRADEMARKS.md +21 -0
- package/braille.mjs +45 -0
- package/examples/bridge.py +62 -0
- package/examples/embed.mjs +15 -0
- package/examples/live.mjs +40 -0
- package/examples/plugin.mjs +21 -0
- package/integrations/opencode/runtime.mjs +195 -0
- package/integrations/opencode/tui.tsx +59 -0
- package/locomotion-core.mjs +21 -0
- package/locomotion-puppy.animal +0 -0
- package/package.json +125 -4
- package/pet-q5-manifest.json +118 -0
- package/puppy-clean.mjs +51 -0
- package/puppy-companion-interactions-v3-q5.bin.gz +0 -0
- package/puppy-companion-interactions-v3.json +1 -0
- package/puppy-companion-life.mjs +182 -0
- package/puppy-companion-objects.mjs +30 -0
- package/puppy-companion-sprites.mjs +14 -0
- package/puppy-continuous.mjs +57 -0
- package/puppy-face.mjs +46 -0
- package/puppy-frame-predictive.mjs +147 -0
- package/puppy-frame-store.mjs +108 -0
- package/puppy-mouth-anchor.json +1 -0
- package/puppy-mouth-anchor.mjs +33 -0
- package/puppy-paper-actions-v9-q5.bin.gz +0 -0
- package/puppy-paper-actions-v9.json +1 -0
- package/puppy-paper-actions.mjs +48 -0
- package/puppy-paper-approach-q5.bin.gz +0 -0
- package/puppy-paper-approach.json +1 -0
- package/puppy-paper-area.mjs +15 -0
- package/puppy-paper-arrival-seat-q5.bin.gz +0 -0
- package/puppy-paper-arrival-seat.json +1 -0
- package/puppy-paper-behaviors-q5.bin.gz +0 -0
- package/puppy-paper-behaviors.json +1 -0
- package/puppy-paper-behaviors.mjs +8 -0
- package/puppy-paper-contact.mjs +103 -0
- package/puppy-paper-director.mjs +21 -0
- package/puppy-paper-paw-transport.mjs +76 -0
- package/puppy-paper-rear-gallop-q5.bin.gz +0 -0
- package/puppy-paper-rear-gallop.json +1 -0
- package/puppy-paper-seat-q5.bin.gz +0 -0
- package/puppy-paper-seat.json +14 -0
- package/puppy-paper-seat.mjs +13 -0
- package/puppy-paper-trick-timing.mjs +58 -0
- package/puppy-paper-world.mjs +108 -0
- package/puppy-paper.mjs +271 -0
- package/puppy-stable-meta.json +1606 -0
- package/puppy-stable.mjs +72 -0
- package/puppy-stride-meta.json +343 -0
- package/puppy-stride-tweens-q5.bin.gz +0 -0
- package/puppy-zoomies.mjs +27 -0
- package/puppy-zoomies30.mjs +12 -0
- package/retrieviewer-cli.mjs +81 -0
- package/retrieviewer-config.mjs +49 -0
- package/retrieviewer-install.mjs +157 -0
- package/retrieviewer-plugin.d.mts +44 -0
- package/retrieviewer-plugin.mjs +97 -0
- package/retrieviewer-stdio.mjs +38 -0
- package/retrieviewer.d.mts +85 -0
- package/retrieviewer.mjs +142 -0
- package/vendor/procedural-animals/LICENSE +21 -0
- package/vendor/procedural-animals/package.json +40 -0
- package/vendor/procedural-animals/src/animal.js +146 -0
- package/vendor/procedural-animals/src/bake.js +51 -0
- package/vendor/procedural-animals/src/build.js +81 -0
- package/vendor/procedural-animals/src/core/build/coatKit.js +121 -0
- package/vendor/procedural-animals/src/core/build/featherCards.js +189 -0
- package/vendor/procedural-animals/src/core/build/finEdges.js +85 -0
- package/vendor/procedural-animals/src/core/build/furSlope.js +115 -0
- package/vendor/procedural-animals/src/core/build/mesh.js +67 -0
- package/vendor/procedural-animals/src/core/build/pipeline.js +272 -0
- package/vendor/procedural-animals/src/core/build/seams.js +183 -0
- package/vendor/procedural-animals/src/core/build/warp.js +112 -0
- package/vendor/procedural-animals/src/core/build/weights.js +393 -0
- package/vendor/procedural-animals/src/core/math/vec.js +81 -0
- package/vendor/procedural-animals/src/core/motion/actions.js +800 -0
- package/vendor/procedural-animals/src/core/motion/bird.js +3063 -0
- package/vendor/procedural-animals/src/core/motion/birdActions.js +1059 -0
- package/vendor/procedural-animals/src/core/motion/common.js +158 -0
- package/vendor/procedural-animals/src/core/motion/index.js +22 -0
- package/vendor/procedural-animals/src/core/motion/quadruped.js +2875 -0
- package/vendor/procedural-animals/src/core/motion/snake.js +1594 -0
- package/vendor/procedural-animals/src/core/motion/spider.js +1810 -0
- package/vendor/procedural-animals/src/core/motion/swimmer.js +1047 -0
- package/vendor/procedural-animals/src/core/motion/swimmerActions.js +613 -0
- package/vendor/procedural-animals/src/core/render/animalObject.js +262 -0
- package/vendor/procedural-animals/src/core/render/coatMaterial.js +1301 -0
- package/vendor/procedural-animals/src/core/render/dqs.js +159 -0
- package/vendor/procedural-animals/src/core/render/eyes.js +676 -0
- package/vendor/procedural-animals/src/core/render/membranes.js +77 -0
- package/vendor/procedural-animals/src/core/render/skeleton.js +41 -0
- package/vendor/procedural-animals/src/core/rig/bird.js +327 -0
- package/vendor/procedural-animals/src/core/rig/quadruped.js +76 -0
- package/vendor/procedural-animals/src/core/rig/rig.js +79 -0
- package/vendor/procedural-animals/src/core/rig/snake.js +76 -0
- package/vendor/procedural-animals/src/core/rig/spider.js +110 -0
- package/vendor/procedural-animals/src/core/rig/swimmer.js +181 -0
- package/vendor/procedural-animals/src/core/sdf/eyeSocket.js +53 -0
- package/vendor/procedural-animals/src/core/sdf/mesher.js +238 -0
- package/vendor/procedural-animals/src/core/sdf/sdf.js +263 -0
- package/vendor/procedural-animals/src/index.d.ts +98 -0
- package/vendor/procedural-animals/src/index.js +29 -0
- package/vendor/procedural-animals/src/registry.js +48 -0
- package/vendor/procedural-animals/src/species/bear/behaviour.js +463 -0
- package/vendor/procedural-animals/src/species/bear/claws.js +147 -0
- package/vendor/procedural-animals/src/species/bear/coat.js +726 -0
- package/vendor/procedural-animals/src/species/bear/index.js +139 -0
- package/vendor/procedural-animals/src/species/bear/motion.js +112 -0
- package/vendor/procedural-animals/src/species/bear/regions.js +78 -0
- package/vendor/procedural-animals/src/species/bear/rig.js +112 -0
- package/vendor/procedural-animals/src/species/bear/sculpt.js +272 -0
- package/vendor/procedural-animals/src/species/boar/behaviour.js +335 -0
- package/vendor/procedural-animals/src/species/boar/coat.js +372 -0
- package/vendor/procedural-animals/src/species/boar/index.js +110 -0
- package/vendor/procedural-animals/src/species/boar/motion.js +85 -0
- package/vendor/procedural-animals/src/species/boar/regions.js +88 -0
- package/vendor/procedural-animals/src/species/boar/rig.js +111 -0
- package/vendor/procedural-animals/src/species/boar/sculpt.js +285 -0
- package/vendor/procedural-animals/src/species/cat/behaviour.js +559 -0
- package/vendor/procedural-animals/src/species/cat/coat.js +841 -0
- package/vendor/procedural-animals/src/species/cat/index.js +211 -0
- package/vendor/procedural-animals/src/species/cat/motion.js +101 -0
- package/vendor/procedural-animals/src/species/cat/regions.js +82 -0
- package/vendor/procedural-animals/src/species/cat/rig.js +100 -0
- package/vendor/procedural-animals/src/species/cat/sculpt.js +266 -0
- package/vendor/procedural-animals/src/species/cat/whiskers.js +110 -0
- package/vendor/procedural-animals/src/species/cheetah/coat.js +427 -0
- package/vendor/procedural-animals/src/species/cheetah/index.js +51 -0
- package/vendor/procedural-animals/src/species/cheetah/joints.js +3 -0
- package/vendor/procedural-animals/src/species/cheetah/motion.js +77 -0
- package/vendor/procedural-animals/src/species/cheetah/regions.js +95 -0
- package/vendor/procedural-animals/src/species/cheetah/rig.js +66 -0
- package/vendor/procedural-animals/src/species/cheetah/sculpt.js +158 -0
- package/vendor/procedural-animals/src/species/chicken/coat.js +313 -0
- package/vendor/procedural-animals/src/species/chicken/coverts.js +320 -0
- package/vendor/procedural-animals/src/species/chicken/index.js +110 -0
- package/vendor/procedural-animals/src/species/chicken/motion.js +177 -0
- package/vendor/procedural-animals/src/species/chicken/regions.js +66 -0
- package/vendor/procedural-animals/src/species/chicken/rig.js +144 -0
- package/vendor/procedural-animals/src/species/chicken/sculpt.js +389 -0
- package/vendor/procedural-animals/src/species/chicken/wingLook.js +66 -0
- package/vendor/procedural-animals/src/species/chicken/wingStack.js +124 -0
- package/vendor/procedural-animals/src/species/cow/behaviour.js +521 -0
- package/vendor/procedural-animals/src/species/cow/coat.js +465 -0
- package/vendor/procedural-animals/src/species/cow/index.js +118 -0
- package/vendor/procedural-animals/src/species/cow/motion.js +81 -0
- package/vendor/procedural-animals/src/species/cow/regions.js +98 -0
- package/vendor/procedural-animals/src/species/cow/rig.js +116 -0
- package/vendor/procedural-animals/src/species/cow/sculpt.js +339 -0
- package/vendor/procedural-animals/src/species/crow/coat.js +145 -0
- package/vendor/procedural-animals/src/species/crow/index.js +70 -0
- package/vendor/procedural-animals/src/species/crow/joints.js +3 -0
- package/vendor/procedural-animals/src/species/crow/motion.js +101 -0
- package/vendor/procedural-animals/src/species/crow/regions.js +50 -0
- package/vendor/procedural-animals/src/species/crow/rig.js +83 -0
- package/vendor/procedural-animals/src/species/crow/sculpt.js +118 -0
- package/vendor/procedural-animals/src/species/deer/behaviour.js +513 -0
- package/vendor/procedural-animals/src/species/deer/coat.js +391 -0
- package/vendor/procedural-animals/src/species/deer/index.js +106 -0
- package/vendor/procedural-animals/src/species/deer/motion.js +97 -0
- package/vendor/procedural-animals/src/species/deer/regions.js +60 -0
- package/vendor/procedural-animals/src/species/deer/rig.js +124 -0
- package/vendor/procedural-animals/src/species/deer/sculpt.js +297 -0
- package/vendor/procedural-animals/src/species/dog/behaviour.js +521 -0
- package/vendor/procedural-animals/src/species/dog/coat.js +495 -0
- package/vendor/procedural-animals/src/species/dog/index.js +144 -0
- package/vendor/procedural-animals/src/species/dog/motion.js +118 -0
- package/vendor/procedural-animals/src/species/dog/regions.js +61 -0
- package/vendor/procedural-animals/src/species/dog/rig.js +129 -0
- package/vendor/procedural-animals/src/species/dog/sculpt.js +246 -0
- package/vendor/procedural-animals/src/species/eagle/coat.js +250 -0
- package/vendor/procedural-animals/src/species/eagle/index.js +76 -0
- package/vendor/procedural-animals/src/species/eagle/joints.js +3 -0
- package/vendor/procedural-animals/src/species/eagle/motion.js +137 -0
- package/vendor/procedural-animals/src/species/eagle/regions.js +57 -0
- package/vendor/procedural-animals/src/species/eagle/rig.js +107 -0
- package/vendor/procedural-animals/src/species/eagle/sculpt.js +137 -0
- package/vendor/procedural-animals/src/species/fish/coat.js +271 -0
- package/vendor/procedural-animals/src/species/fish/index.js +88 -0
- package/vendor/procedural-animals/src/species/fish/motion.js +92 -0
- package/vendor/procedural-animals/src/species/fish/regions.js +27 -0
- package/vendor/procedural-animals/src/species/fish/rig.js +143 -0
- package/vendor/procedural-animals/src/species/fish/sculpt.js +214 -0
- package/vendor/procedural-animals/src/species/fish/variants.js +126 -0
- package/vendor/procedural-animals/src/species/fox/behaviour.js +314 -0
- package/vendor/procedural-animals/src/species/fox/coat.js +444 -0
- package/vendor/procedural-animals/src/species/fox/index.js +120 -0
- package/vendor/procedural-animals/src/species/fox/motion.js +81 -0
- package/vendor/procedural-animals/src/species/fox/regions.js +59 -0
- package/vendor/procedural-animals/src/species/fox/rig.js +91 -0
- package/vendor/procedural-animals/src/species/fox/sculpt.js +202 -0
- package/vendor/procedural-animals/src/species/frog/behaviour.js +590 -0
- package/vendor/procedural-animals/src/species/frog/coat.js +305 -0
- package/vendor/procedural-animals/src/species/frog/index.js +97 -0
- package/vendor/procedural-animals/src/species/frog/motion.js +69 -0
- package/vendor/procedural-animals/src/species/frog/regions.js +46 -0
- package/vendor/procedural-animals/src/species/frog/rig.js +156 -0
- package/vendor/procedural-animals/src/species/frog/sculpt.js +240 -0
- package/vendor/procedural-animals/src/species/goat/behaviour.js +509 -0
- package/vendor/procedural-animals/src/species/goat/coat.js +590 -0
- package/vendor/procedural-animals/src/species/goat/index.js +149 -0
- package/vendor/procedural-animals/src/species/goat/motion.js +95 -0
- package/vendor/procedural-animals/src/species/goat/regions.js +98 -0
- package/vendor/procedural-animals/src/species/goat/rig.js +181 -0
- package/vendor/procedural-animals/src/species/goat/sculpt.js +547 -0
- package/vendor/procedural-animals/src/species/horse/coat.js +361 -0
- package/vendor/procedural-animals/src/species/horse/coatSeam.js +122 -0
- package/vendor/procedural-animals/src/species/horse/index.js +80 -0
- package/vendor/procedural-animals/src/species/horse/motion.js +245 -0
- package/vendor/procedural-animals/src/species/horse/regions.js +60 -0
- package/vendor/procedural-animals/src/species/horse/rig.js +117 -0
- package/vendor/procedural-animals/src/species/horse/sculpt.js +316 -0
- package/vendor/procedural-animals/src/species/horse/seamWeights.js +272 -0
- package/vendor/procedural-animals/src/species/lion/behaviour.js +509 -0
- package/vendor/procedural-animals/src/species/lion/coat.js +1016 -0
- package/vendor/procedural-animals/src/species/lion/index.js +111 -0
- package/vendor/procedural-animals/src/species/lion/motion.js +87 -0
- package/vendor/procedural-animals/src/species/lion/regions.js +106 -0
- package/vendor/procedural-animals/src/species/lion/rig.js +110 -0
- package/vendor/procedural-animals/src/species/lion/sculpt.js +384 -0
- package/vendor/procedural-animals/src/species/lion/whiskers.js +132 -0
- package/vendor/procedural-animals/src/species/pig/behaviour.js +575 -0
- package/vendor/procedural-animals/src/species/pig/coat.js +730 -0
- package/vendor/procedural-animals/src/species/pig/ears.js +242 -0
- package/vendor/procedural-animals/src/species/pig/index.js +161 -0
- package/vendor/procedural-animals/src/species/pig/motion.js +105 -0
- package/vendor/procedural-animals/src/species/pig/regions.js +100 -0
- package/vendor/procedural-animals/src/species/pig/rig.js +152 -0
- package/vendor/procedural-animals/src/species/pig/sculpt.js +382 -0
- package/vendor/procedural-animals/src/species/rabbit/behaviour.js +605 -0
- package/vendor/procedural-animals/src/species/rabbit/coat.js +285 -0
- package/vendor/procedural-animals/src/species/rabbit/index.js +85 -0
- package/vendor/procedural-animals/src/species/rabbit/motion.js +85 -0
- package/vendor/procedural-animals/src/species/rabbit/regions.js +48 -0
- package/vendor/procedural-animals/src/species/rabbit/rig.js +99 -0
- package/vendor/procedural-animals/src/species/rabbit/sculpt.js +148 -0
- package/vendor/procedural-animals/src/species/rat/behaviour.js +539 -0
- package/vendor/procedural-animals/src/species/rat/coat.js +341 -0
- package/vendor/procedural-animals/src/species/rat/index.js +111 -0
- package/vendor/procedural-animals/src/species/rat/motion.js +90 -0
- package/vendor/procedural-animals/src/species/rat/regions.js +92 -0
- package/vendor/procedural-animals/src/species/rat/rig.js +112 -0
- package/vendor/procedural-animals/src/species/rat/sculpt.js +163 -0
- package/vendor/procedural-animals/src/species/rat/whiskers.js +119 -0
- package/vendor/procedural-animals/src/species/shark/coat.js +383 -0
- package/vendor/procedural-animals/src/species/shark/index.js +104 -0
- package/vendor/procedural-animals/src/species/shark/motion.js +69 -0
- package/vendor/procedural-animals/src/species/shark/regions.js +34 -0
- package/vendor/procedural-animals/src/species/shark/rig.js +194 -0
- package/vendor/procedural-animals/src/species/shark/sculpt.js +343 -0
- package/vendor/procedural-animals/src/species/shark/variants.js +105 -0
- package/vendor/procedural-animals/src/species/sheep/behaviour.js +522 -0
- package/vendor/procedural-animals/src/species/sheep/coat.js +529 -0
- package/vendor/procedural-animals/src/species/sheep/index.js +152 -0
- package/vendor/procedural-animals/src/species/sheep/motion.js +86 -0
- package/vendor/procedural-animals/src/species/sheep/neck.js +41 -0
- package/vendor/procedural-animals/src/species/sheep/regions.js +62 -0
- package/vendor/procedural-animals/src/species/sheep/rig.js +163 -0
- package/vendor/procedural-animals/src/species/sheep/sculpt.js +542 -0
- package/vendor/procedural-animals/src/species/snake/coat.js +315 -0
- package/vendor/procedural-animals/src/species/snake/index.js +73 -0
- package/vendor/procedural-animals/src/species/snake/motion.js +51 -0
- package/vendor/procedural-animals/src/species/snake/regions.js +51 -0
- package/vendor/procedural-animals/src/species/snake/rig.js +108 -0
- package/vendor/procedural-animals/src/species/snake/sculpt.js +122 -0
- package/vendor/procedural-animals/src/species/spider/coat.js +279 -0
- package/vendor/procedural-animals/src/species/spider/index.js +78 -0
- package/vendor/procedural-animals/src/species/spider/motion.js +72 -0
- package/vendor/procedural-animals/src/species/spider/regions.js +87 -0
- package/vendor/procedural-animals/src/species/spider/rig.js +118 -0
- package/vendor/procedural-animals/src/species/spider/sculpt.js +182 -0
- package/vendor/procedural-animals/src/species/wolf/behaviour.js +160 -0
- package/vendor/procedural-animals/src/species/wolf/coat.js +749 -0
- package/vendor/procedural-animals/src/species/wolf/index.js +107 -0
- package/vendor/procedural-animals/src/species/wolf/motion.js +80 -0
- package/vendor/procedural-animals/src/species/wolf/regions.js +57 -0
- package/vendor/procedural-animals/src/species/wolf/rig.js +87 -0
- package/vendor/procedural-animals/src/species/wolf/sculpt.js +339 -0
- package/vendor/procedural-animals/src/worker.js +29 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Exact box-footprint minification of the authored grayscale raster, including
|
|
2
|
+
// fractional edge coverage. No temporal blur, face warp or minimum sprite size.
|
|
3
|
+
export function createPaperAreaSampler(n=320){
|
|
4
|
+
if(!Number.isInteger(n)||n<2||n>640)throw Error('Invalid area source size');
|
|
5
|
+
const pitch=n+1,sums=new Float64Array(pitch*pitch);
|
|
6
|
+
const integral=(x,y)=>{
|
|
7
|
+
x=Math.max(0,Math.min(n,x));y=Math.max(0,Math.min(n,y));
|
|
8
|
+
const ix=Math.min(n-1,Math.floor(x)),iy=Math.min(n-1,Math.floor(y)),fx=x-ix,fy=y-iy,k=iy*pitch+ix;
|
|
9
|
+
return (sums[k]*(1-fx)+sums[k+1]*fx)*(1-fy)+(sums[k+pitch]*(1-fx)+sums[k+pitch+1]*fx)*fy;
|
|
10
|
+
};
|
|
11
|
+
return{
|
|
12
|
+
prepare(image){if(image.length!==n*n*4)throw Error('Invalid area source');sums.fill(0);for(let y=0;y<n;y++){let row=0;for(let x=0;x<n;x++){row+=image[(y*n+x)*4];sums[(y+1)*pitch+x+1]=sums[y*pitch+x+1]+row;}}},
|
|
13
|
+
sample(x,y,dx,dy){if(![x,y,dx,dy].every(Number.isFinite)||Math.min(dx,dy)<=0)throw Error('Invalid area footprint');const l=x-dx/2,r=x+dx/2,t=y-dy/2,b=y+dy/2;return Math.max(0,(integral(r,b)-integral(l,b)-integral(r,t)+integral(l,t))/(dx*dy));}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"width":320,"height":320,"pairs":3,"samples":17,"bytes":5222400,"sha256":"13acb62fd573ff7ef97bcf59be80757897fe9d1784f187ab278990ff94a643b9","sourceHashes":{"puppy-paper-behaviors.bin.gz":"d8aa7d373514a66bfa39168ed1087a0a95e83caab5f2879cc7287b2911741ad1","puppy-paper-seat.bin.gz":"a863225bef502fa3d60fe97c85007a9e85b818d53e5c3b5490fddd80b0c100d9","puppy-paper-seat.json":"46540368e2cb77c9b089edd97e0231bb407e9acb0ee2b25f6dff9a5c5d45a2b2","prepare-paper-arrival-seat.py":"0b847665e4193973c98b23ab21da8cae0f49bc9009428bb2297c1337b38d0b87"},"method":"direct old brake endpoint to old frontal standing, then exact original sit edges; no run-size detour"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"width":320,"height":320,"pairs":18,"samples":9,"bytes":16588800,"sha256":"7918261fb64c57a91739729841fd84c6dd53891196c7fb76ee9c27712ab6ef5d","sourceHashes":{"puppy-behaviors16-sheet.png":"17fb15d35cd5b089bfd7762c744393fceb774bb834e11c20f82dae05cad0fdb1","puppy-paper-approach.bin.gz":"21f4015cf899f6b1b6602a8939bbe0eaa76c66cb466c6aabd77249d215ce8d7f","puppy-sitting-tweens.bin.gz":"5680d046726a1f296d02fefb713fe7f984b480d6a77e44fd4e2da5635a9d0fa9","preparer":"820b6f337f806b3f1b7eb3f974c505290e889fb5ed380881c5cb8c7dcf8f424b","prepare-paper-behavior-contacts.py":"a401a9d286aed499a80093494504c7b552fd4101199598c3800f2e5006c35d5b"},"registration":[{"cell":0,"scale":0.82,"source_bounds":[79,26,268,277],"torso_x":209.05050317546608,"ground":301,"matrix":[[0.82,0.0,-11.421412603882175],[0.0,0.82,53.18000000000001]]},{"cell":1,"scale":0.82,"source_bounds":[406,26,260,277],"torso_x":533.9745278946236,"ground":301,"matrix":[[0.82,0.0,-277.85911287359136],[0.0,0.82,53.18000000000001]]},{"cell":2,"scale":0.82,"source_bounds":[745,26,270,277],"torso_x":878.7764715289212,"ground":301,"matrix":[[0.82,0.0,-560.5967066537154],[0.0,0.82,53.18000000000001]]},{"cell":3,"scale":0.82,"source_bounds":[1086,26,272,276],"torso_x":1221.9028664916002,"ground":300,"matrix":[[0.82,0.0,-841.9603505231121],[0.0,0.82,54.00000000000003]]},{"cell":4,"scale":0.82,"source_bounds":[79,326,266,242],"torso_x":199.7053716408469,"ground":566,"matrix":[[0.82,0.0,-3.758404745494431],[0.0,0.82,-164.11999999999995]]},{"cell":5,"scale":0.82,"source_bounds":[407,326,271,238],"torso_x":541.6006246081464,"ground":562,"matrix":[[0.82,0.0,-284.11251217868005],[0.0,0.82,-160.83999999999997]]},{"cell":6,"scale":0.82,"source_bounds":[758,326,246,242],"torso_x":896.0829673295764,"ground":566,"matrix":[[0.82,0.0,-574.7880332102526],[0.0,0.82,-164.11999999999995]]},{"cell":7,"scale":0.82,"source_bounds":[1102,315,254,253],"torso_x":1222.9266568431597,"ground":566,"matrix":[[0.82,0.0,-842.7998586113908],[0.0,0.82,-164.11999999999995]]},{"cell":8,"scale":0.82,"source_bounds":[52,581,255,269],"torso_x":200.00895049442764,"ground":848,"matrix":[[0.82,0.0,-4.007339405430656],[0.0,0.82,-395.36]]},{"cell":9,"scale":0.82,"source_bounds":[404,582,255,267],"torso_x":540.8938816280412,"ground":848,"matrix":[[0.82,0.0,-283.53298293499375],[0.0,0.82,-395.36]]},{"cell":10,"scale":0.82,"source_bounds":[750,581,247,269],"torso_x":895.3536425502729,"ground":848,"matrix":[[0.82,0.0,-574.1899868912237],[0.0,0.82,-395.36]]},{"cell":11,"scale":0.82,"source_bounds":[1095,583,250,267],"torso_x":1251.2657512978315,"ground":848,"matrix":[[0.82,0.0,-866.0379160642217],[0.0,0.82,-395.36]]},{"cell":12,"scale":0.82,"source_bounds":[34,860,282,199],"torso_x":153.59616909705724,"ground":1057,"matrix":[[0.82,0.0,34.05114134041307],[0.0,0.82,-566.7399999999999]]},{"cell":13,"scale":0.82,"source_bounds":[384,863,285,196],"torso_x":505.5182454953787,"ground":1057,"matrix":[[0.82,0.0,-254.5249613062105],[0.0,0.82,-566.7399999999999]]},{"cell":14,"scale":0.82,"source_bounds":[720,896,301,163],"torso_x":846.3849797636211,"ground":1057,"matrix":[[0.82,0.0,-534.0356834061693],[0.0,0.82,-566.7399999999999]]},{"cell":15,"scale":0.82,"source_bounds":[1072,898,315,161],"torso_x":1192.851051490826,"ground":1057,"matrix":[[0.82,0.0,-818.1378622224772],[0.0,0.82,-566.7399999999999]]}],"edges":[[0,1],[1,2],[2,3],[3,0],[16,0],[0,4],[4,5],[5,6],[6,7],[7,16],[17,9],[9,17],[17,11],[11,17],[17,12],[12,13],[13,14],[14,15]],"feet":[[[{"id":"fore-left","x":139,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}],[{"id":"fore-left","x":138,"y":285,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}],[{"id":"fore-left","x":138,"y":286,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":285,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":285,"stance":false},{"id":"fore-right","x":213,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":213,"y":300,"stance":true}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":212,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":211,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":210,"y":299,"stance":true}]],[[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":210,"y":299,"stance":true}],[{"id":"fore-left","x":136,"y":286,"stance":false},{"id":"fore-right","x":211,"y":299,"stance":true}],[{"id":"fore-left","x":136,"y":286,"stance":false},{"id":"fore-right","x":211,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":212,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":213,"y":299,"stance":true}],[{"id":"fore-left","x":136,"y":286,"stance":false},{"id":"fore-right","x":213,"y":299,"stance":true}],[{"id":"fore-left","x":136,"y":285,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":true}],[{"id":"fore-left","x":135,"y":286,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":false}],[{"id":"fore-left","x":135,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":false}]],[[{"id":"fore-left","x":135,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":false}],[{"id":"fore-left","x":136,"y":285,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":false}],[{"id":"fore-left","x":136,"y":285,"stance":false},{"id":"fore-right","x":211,"y":299,"stance":false}],[{"id":"fore-left","x":136,"y":285,"stance":false},{"id":"fore-right","x":208,"y":300,"stance":false}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":198,"y":299,"stance":false}],[{"id":"fore-left","x":137,"y":287,"stance":false},{"id":"fore-right","x":187,"y":299,"stance":false}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":183,"y":300,"stance":false}],[{"id":"fore-left","x":159,"y":292,"stance":false},{"id":"fore-right","x":181,"y":299,"stance":false}],[{"id":"fore-left","x":159,"y":298,"stance":true},{"id":"fore-right","x":177,"y":300,"stance":false}]],[[{"id":"fore-left","x":159,"y":298,"stance":true},{"id":"fore-right","x":177,"y":300,"stance":false}],[{"id":"fore-left","x":159,"y":296,"stance":true},{"id":"fore-right","x":179,"y":299,"stance":false}],[{"id":"fore-left","x":159,"y":292,"stance":false},{"id":"fore-right","x":181,"y":298,"stance":false}],[{"id":"fore-left","x":137,"y":286,"stance":false},{"id":"fore-right","x":184,"y":298,"stance":false}],[{"id":"fore-left","x":138,"y":286,"stance":false},{"id":"fore-right","x":204,"y":297,"stance":false}],[{"id":"fore-left","x":138,"y":286,"stance":false},{"id":"fore-right","x":209,"y":299,"stance":false}],[{"id":"fore-left","x":138,"y":286,"stance":false},{"id":"fore-right","x":211,"y":300,"stance":false}],[{"id":"fore-left","x":139,"y":286,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":false}],[{"id":"fore-left","x":139,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}]],[[{"id":"fore-left","x":155,"y":276,"stance":false},{"id":"fore-right","x":209,"y":300,"stance":false}],[{"id":"fore-left","x":156,"y":277,"stance":false},{"id":"fore-right","x":210,"y":300,"stance":false}],[{"id":"fore-left","x":156,"y":277,"stance":false},{"id":"fore-right","x":211,"y":300,"stance":false}],[{"id":"fore-left","x":157,"y":277,"stance":false},{"id":"fore-right","x":212,"y":300,"stance":false}],[{"id":"fore-left","x":141,"y":277,"stance":false},{"id":"fore-right","x":213,"y":300,"stance":true}],[{"id":"fore-left","x":139,"y":279,"stance":false},{"id":"fore-right","x":214,"y":300,"stance":true}],[{"id":"fore-left","x":138,"y":282,"stance":false},{"id":"fore-right","x":214,"y":299,"stance":true}],[{"id":"fore-left","x":138,"y":284,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}],[{"id":"fore-left","x":139,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}]],[[{"id":"fore-left","x":139,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}],[{"id":"fore-left","x":137,"y":285,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}],[{"id":"fore-left","x":136,"y":286,"stance":false},{"id":"fore-right","x":215,"y":299,"stance":true}],[{"id":"fore-left","x":135,"y":286,"stance":false},{"id":"fore-right","x":215,"y":298,"stance":true}],[{"id":"fore-left","x":134,"y":286,"stance":false},{"id":"fore-right","x":217,"y":297,"stance":true}],[{"id":"fore-left","x":132,"y":286,"stance":false},{"id":"fore-right","x":216,"y":296,"stance":true}],[{"id":"fore-left","x":131,"y":286,"stance":false},{"id":"fore-right","x":195,"y":296,"stance":true}],[{"id":"fore-left","x":130,"y":286,"stance":false},{"id":"fore-right","x":176,"y":298,"stance":false}],[{"id":"fore-left","x":130,"y":287,"stance":false},{"id":"fore-right","x":175,"y":300,"stance":false}]],[[{"id":"fore-left","x":130,"y":287,"stance":false},{"id":"fore-right","x":175,"y":300,"stance":false}],[{"id":"fore-left","x":158,"y":297,"stance":true},{"id":"fore-right","x":173,"y":299,"stance":false}],[{"id":"fore-left","x":157,"y":298,"stance":true},{"id":"fore-right","x":171,"y":300,"stance":false}],[{"id":"fore-left","x":156,"y":298,"stance":true},{"id":"fore-right","x":170,"y":298,"stance":false}],[{"id":"fore-left","x":154,"y":299,"stance":true},{"id":"fore-right","x":170,"y":299,"stance":false}],[{"id":"fore-left","x":152,"y":299,"stance":false},{"id":"fore-right","x":169,"y":299,"stance":false}],[{"id":"fore-left","x":150,"y":299,"stance":false},{"id":"fore-right","x":170,"y":298,"stance":false}],[{"id":"fore-left","x":148,"y":299,"stance":false},{"id":"fore-right","x":170,"y":298,"stance":true}],[{"id":"fore-left","x":149,"y":299,"stance":false},{"id":"fore-right","x":169,"y":298,"stance":true}]],[[{"id":"fore-left","x":149,"y":299,"stance":false},{"id":"fore-right","x":169,"y":298,"stance":true}],[{"id":"fore-left","x":148,"y":299,"stance":false},{"id":"fore-right","x":170,"y":298,"stance":true}],[{"id":"fore-left","x":147,"y":299,"stance":false},{"id":"fore-right","x":214,"y":297,"stance":true}],[{"id":"fore-left","x":147,"y":299,"stance":false},{"id":"fore-right","x":213,"y":298,"stance":true}],[{"id":"fore-left","x":146,"y":299,"stance":false},{"id":"fore-right","x":211,"y":298,"stance":true}],[{"id":"fore-left","x":146,"y":299,"stance":false},{"id":"fore-right","x":206,"y":298,"stance":true}],[{"id":"fore-left","x":145,"y":299,"stance":false},{"id":"fore-right","x":201,"y":299,"stance":true}],[{"id":"fore-left","x":145,"y":299,"stance":true},{"id":"fore-right","x":197,"y":299,"stance":false}],[{"id":"fore-left","x":144,"y":299,"stance":true},{"id":"fore-right","x":192,"y":299,"stance":false}]],[[{"id":"fore-left","x":144,"y":299,"stance":true},{"id":"fore-right","x":192,"y":299,"stance":false}],[{"id":"fore-left","x":146,"y":299,"stance":true},{"id":"fore-right","x":194,"y":300,"stance":false}],[{"id":"fore-left","x":147,"y":299,"stance":true},{"id":"fore-right","x":196,"y":300,"stance":false}],[{"id":"fore-left","x":148,"y":299,"stance":true},{"id":"fore-right","x":198,"y":299,"stance":false}],[{"id":"fore-left","x":147,"y":299,"stance":true},{"id":"fore-right","x":200,"y":299,"stance":false}],[{"id":"fore-left","x":148,"y":299,"stance":true},{"id":"fore-right","x":202,"y":299,"stance":false}],[{"id":"fore-left","x":149,"y":299,"stance":true},{"id":"fore-right","x":204,"y":299,"stance":false}],[{"id":"fore-left","x":150,"y":299,"stance":true},{"id":"fore-right","x":206,"y":299,"stance":false}],[{"id":"fore-left","x":152,"y":299,"stance":true},{"id":"fore-right","x":209,"y":299,"stance":false}]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]]],"clips":{"walk":[0,1,2,3],"walk-enter":[4],"brake":[5,6,7,8],"finish":[9],"watch-left":[10,11],"watch-right":[12,13],"rest":[14,15,16,17]},"strideMeters":{"walk":0.12,"run":0.18,"basis":"authored matching parameter, not measured canine mocap"},"method":"Built-in imagegen; fixed-scale connected-subject extraction; grounded keys; exact existing endpoints; pinned local RIFE v4.6","contact_basis":"Authored support/swing phase masks intersected with visible source-pixel sole; image proxies, not anatomical four-paw mocap."}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{createRearSampler}from'./puppy-paper-contact.mjs';
|
|
2
|
+
export function paperBehaviorPose(state,info){
|
|
3
|
+
const list=info.clips[state.behavior];if(!list)throw Error('Unknown paper behavior');
|
|
4
|
+
const progress=state.behavior==='walk'?state.behaviorProgress%1:Math.max(0,Math.min(1,state.behaviorProgress));
|
|
5
|
+
const q=Math.min(list.length-1e-9,progress*list.length),i=Math.floor(q),blend=Math.round((q-i)*8)/8;
|
|
6
|
+
return{pair:list[i],blend};
|
|
7
|
+
}
|
|
8
|
+
export function createPaperBehaviorSampler(bytes,info){const sample=createRearSampler(bytes,info);return state=>{const p=paperBehaviorPose(state,info);return sample(p.pair,p.blend);};}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {PAPER_LIMB} from './puppy-paper-world.mjs';
|
|
2
|
+
import {grayFrameReader,isGrayFrameSource} from './puppy-frame-store.mjs';
|
|
3
|
+
const smooth=(a,b,x)=>{const t=Math.max(0,Math.min(1,(x-a)/(b-a)));return t*t*(3-2*t);};
|
|
4
|
+
|
|
5
|
+
// Image-space stance anchors. These are visible paw proxies, not engine contact targets.
|
|
6
|
+
export function createPaperFootLock({maxImageStretch=Infinity}={}){
|
|
7
|
+
if(typeof maxImageStretch!=='number'||!(maxImageStretch>1.08))throw Error('Invalid image leg stretch');
|
|
8
|
+
const anchors=new Map();let identity='',samples=0,episodes=0,rawMax=0,max=0,limited=0;
|
|
9
|
+
const blocked=new Map(),releasing=new Set();let releaseEvents=0,releasingFrames=0,releasedMax=0;
|
|
10
|
+
return{
|
|
11
|
+
update(feet,placement,key){
|
|
12
|
+
if(key!==identity){anchors.clear();blocked.clear();releasing.clear();identity=key;}
|
|
13
|
+
const {left,top,side}=placement,scale=side/320,scaleX=(placement.sideX??side)/320,pins=[],active=new Set();
|
|
14
|
+
for(const foot of feet){
|
|
15
|
+
if(!foot.stance||foot.y<245)continue;
|
|
16
|
+
if(blocked.has(foot.id)){if(blocked.get(foot.id)===foot.episode)continue;blocked.delete(foot.id);}
|
|
17
|
+
const source={x:foot.x+.5,y:foot.y+.5};
|
|
18
|
+
const x=left+source.x*scaleX,y=top+source.y*scale;active.add(foot.id);
|
|
19
|
+
let anchor=anchors.get(foot.id);
|
|
20
|
+
if(!anchor||anchor.episode!==foot.episode){anchor={x,y,episode:foot.episode,world:placement.groundFromPixel?.(x,y)??null,root:placement.root?{...placement.root}:null};anchors.set(foot.id,anchor);episodes++;}
|
|
21
|
+
// Preserve the actual ground point across raster/viewport changes. For a
|
|
22
|
+
// fixed camera this reprojects to the same point, not a root-relative toe.
|
|
23
|
+
if(anchor.world&&placement.pixelFromGround)Object.assign(anchor,placement.pixelFromGround(anchor.world));
|
|
24
|
+
let desired={x:anchor.x,y:anchor.y},gain=1;
|
|
25
|
+
if(anchor.world&&placement.root&&placement.pixelFromGround){
|
|
26
|
+
const root=placement.root,contact=anchor.root,forward={x:Math.sin(contact.heading),z:Math.cos(contact.heading)};
|
|
27
|
+
const reach=Math.sqrt(PAPER_LIMB.length**2-PAPER_LIMB.stanceHeight**2);
|
|
28
|
+
// The artwork is not a metric 3D skeleton. Register a visible-limb proxy
|
|
29
|
+
// at protracted touchdown, then translate its hip with the actual
|
|
30
|
+
// world root. Never infer a fixed hip depth from a 2D far paw's height.
|
|
31
|
+
const hip={x:anchor.world.x-forward.x*reach+root.x-contact.x,z:anchor.world.z-forward.z*reach+root.z-contact.z},dx=anchor.world.x-hip.x,dz=anchor.world.z-hip.z;
|
|
32
|
+
// Geometric reach of a .35m limb with a flexed .25m stance height.
|
|
33
|
+
// A source-pixel limit was direction/depth dependent and not physical.
|
|
34
|
+
const radius=Math.hypot(dx,dz);
|
|
35
|
+
if(radius>reach+1e-9){gain=reach/radius;desired=placement.pixelFromGround({x:hip.x+dx*gain,z:hip.z+dz*gain});}
|
|
36
|
+
}
|
|
37
|
+
const dx=(desired.x-x)/scaleX,dy=(desired.y-y)/scale,length=Math.hypot(dx,dy),sourceGain=anchor.world&&placement.root?1:length>56?56/length:1;
|
|
38
|
+
// The world reach proxy can outlive the visible lower-leg pose. Ease out
|
|
39
|
+
// that incompatible support instead of making a 60px shin span 150px.
|
|
40
|
+
// This is a source-pose contact release, not a clamped planted target.
|
|
41
|
+
const rest=Math.max(16,source.y-225),strain=Math.hypot(dx,rest+dy)/rest;
|
|
42
|
+
const strength=Number.isFinite(maxImageStretch)?1-smooth(1.08,maxImageStretch,strain):1;
|
|
43
|
+
const isReleasing=strength<1;
|
|
44
|
+
if(isReleasing&&!releasing.has(foot.id)){releaseEvents++;releasing.add(foot.id);}
|
|
45
|
+
if(!strength){anchors.delete(foot.id);blocked.set(foot.id,foot.episode);continue;}
|
|
46
|
+
const target={x:source.x+dx*sourceGain*strength,y:source.y+dy*sourceGain*strength};
|
|
47
|
+
const actual={x:Math.floor(left+target.x*scaleX)+.5,y:Math.floor(top+target.y*scale)+.5};
|
|
48
|
+
rawMax=Math.max(rawMax,Math.hypot(x-anchor.x,y-anchor.y));
|
|
49
|
+
const residual=Math.hypot(actual.x-anchor.x,actual.y-anchor.y);
|
|
50
|
+
if(isReleasing){releasingFrames++;releasedMax=Math.max(releasedMax,residual);}else max=Math.max(max,residual);
|
|
51
|
+
samples++;if(gain<1||sourceGain<1)limited++;
|
|
52
|
+
pins.push({id:foot.id,source,target,anchor:{...anchor},actual,limited:gain<1||sourceGain<1,releasing:isReleasing});
|
|
53
|
+
}
|
|
54
|
+
for(const id of anchors.keys())if(!active.has(id))anchors.delete(id);
|
|
55
|
+
const supported=new Set(feet.filter(f=>f.stance).map(f=>f.id));
|
|
56
|
+
for(const id of blocked.keys())if(!supported.has(id))blocked.delete(id);
|
|
57
|
+
for(const id of releasing)if(!supported.has(id))releasing.delete(id);
|
|
58
|
+
return pins;
|
|
59
|
+
},reset(){anchors.clear();blocked.clear();releasing.clear();identity='';},report(){return{samples,episodes,rawMax,max,limited,releaseEvents,releasingFrames,releasedMax};}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// A render frame can skip an entire swing at high cadence. Identify support
|
|
64
|
+
// episodes from the complete source schedule, not just last rendered stance.
|
|
65
|
+
// This keeps real contiguous support across the loop seam but releases a new
|
|
66
|
+
// touchdown even when no airborne picture was presented between two draws.
|
|
67
|
+
export function createPaperSupportEpisodes(labels,indices,samples,{cyclic=true}={}){
|
|
68
|
+
const step=samples-1,period=indices.length*step,ids=new Set(indices.flatMap(p=>labels[p].flatMap(f=>f.map(x=>x.id)))),starts=new Map();
|
|
69
|
+
for(const id of ids){
|
|
70
|
+
const active=Array.from({length:period+(cyclic?0:1)},(_,i)=>{const p=Math.min(indices.length-1,Math.floor(i/step)),s=i-p*step;return labels[indices[p]][s].some(f=>f.id===id&&f.stance);});
|
|
71
|
+
starts.set(id,active.map((v,i)=>{if(!v)return -1;let start=i;while(start>0&&active[start-1])start--;if(cyclic&&start===0&&active.at(-1)){let k=active.length-1;while(k>0&&active[k-1])k--;return k;}return start;}));
|
|
72
|
+
}
|
|
73
|
+
return(feet,pair,blend,phase)=>{
|
|
74
|
+
const p=indices.indexOf(pair);if(p<0)return feet;
|
|
75
|
+
const q=p*step+Math.round(blend*step),index=cyclic?q%period:Math.min(period,q),cycle=cyclic?Math.floor(phase)+Math.floor(q/period):0;
|
|
76
|
+
return feet.map(foot=>{const start=starts.get(foot.id)?.[index]??-1;return{...foot,episode:`${start}/${cycle-(cyclic&&start>index?1:0)}`};});
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Inverse, nearest-pixel leg warp; the entire head/torso above y=225 is identity.
|
|
81
|
+
// A compact support covers both the old and new toe positions to avoid a second toe.
|
|
82
|
+
export function footSourcePoint(x,y,pins){
|
|
83
|
+
if(y<=225||!pins.length)return{x,y};
|
|
84
|
+
let best=0,chosen=null;
|
|
85
|
+
for(const pin of pins){
|
|
86
|
+
const dx=pin.target.x-pin.source.x,dy=pin.target.y-pin.source.y;
|
|
87
|
+
const rx=28+2*Math.abs(dx),ry=28+2*Math.abs(dy),r2=((x-pin.target.x)/rx)**2+((y-pin.target.y)/ry)**2;
|
|
88
|
+
const weight=r2<1?(1-r2)**2*smooth(225,Math.min(245,Math.max(226,pin.target.y)),y):0;
|
|
89
|
+
if(weight>best){best=weight;chosen={dx,dy};}
|
|
90
|
+
}
|
|
91
|
+
return chosen?{x:x-chosen.dx*best,y:y-chosen.dy*best}:{x,y};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function createRearSampler(bytes,info){
|
|
95
|
+
if(!isGrayFrameSource(bytes)||info.pairs!==18||info.samples!==9||bytes.byteLength!==18*9*320*320)throw Error('Invalid rear sprite cache');
|
|
96
|
+
const frames=grayFrameReader(bytes,320,320,18*9),out=new Uint8ClampedArray(320*320*4);for(let i=3;i<out.length;i+=4)out[i]=255;
|
|
97
|
+
return(pair,blend)=>{
|
|
98
|
+
if(!Number.isInteger(pair)||pair<0||pair>=18||!Number.isFinite(blend)||blend<0||blend>1)throw Error('Invalid rear pose');
|
|
99
|
+
const frame=frames.getFrame(pair*9+Math.round(blend*8));
|
|
100
|
+
for(let j=0,i=0;i<320*320;i++,j+=4)out[j]=out[j+1]=out[j+2]=frame[i];
|
|
101
|
+
return out;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Bounded local behavior selection, independent of rendering and LLM services.
|
|
2
|
+
// Durations/energy are authored character parameters, not canine science claims.
|
|
3
|
+
export function createPaperDirector(seed=731){
|
|
4
|
+
let value=seed>>>0,energy=.85,last='',choices=0,excursions=0;
|
|
5
|
+
const random=()=>{value=(Math.imul(value,1664525)+1013904223)>>>0;return value/4294967296;};
|
|
6
|
+
return{
|
|
7
|
+
update(dt,moving,distance=0){energy=Math.max(0,Math.min(1,energy+dt*(moving?-.05:.025)-(moving?distance*.025:0)));},
|
|
8
|
+
choose({x,z,seated}){
|
|
9
|
+
choices++;
|
|
10
|
+
let candidates=seated?[{kind:'watch',weight:2},{kind:'rest',weight:energy<.45?5:.5},{kind:'wander',weight:energy*5}]:[{kind:'wander',weight:3},{kind:'come',weight:2}];
|
|
11
|
+
candidates=candidates.filter(a=>a.kind!==last);const total=candidates.reduce((n,a)=>n+a.weight,0);let pick=random()*total,selected=candidates.at(-1);
|
|
12
|
+
for(const candidate of candidates){pick-=candidate.weight;if(pick<=0){selected=candidate;break;}}
|
|
13
|
+
last=selected.kind;
|
|
14
|
+
// Alternate near/middle/far excursions; do not trap autonomous life inside
|
|
15
|
+
// the old one-meter box. Deep arrivals return before choosing another depth.
|
|
16
|
+
const depths=[-1.6,-8,-3.2];
|
|
17
|
+
const target=last==='come'?[x,.2]:[x>0?-.5:.5,z<-1?-.15:depths[excursions++%depths.length]];
|
|
18
|
+
return{kind:last,target,holdSeconds:2+random()*2,side:random()<.5?'left':'right',energy};
|
|
19
|
+
},get report(){return{energy,last,choices};}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Bounded per-limb paw transport (inverse map, canonical 320px source space).
|
|
2
|
+
// Source ownership: x-Voronoi strips fixed once from the original foot x
|
|
3
|
+
// positions. Inside a strip every source row below y=225 is translated as a
|
|
4
|
+
// whole, x'=x+dx*g(y), y'=y+dy*gy(y): row widths (toes, shin) never stretch in
|
|
5
|
+
// x, g reaches 1 at the toe top so the toe block is rigid, and only the shin
|
|
6
|
+
// shears/bends. y<=225 is exact identity. A target that no layer claims from
|
|
7
|
+
// inside its own strip returns null (vacated or torn background), never a
|
|
8
|
+
// copy of the old toe.
|
|
9
|
+
const TORSO=226,TOE_RIGID=8,MIN_SPAN=4,FOLD_MARGIN=.9;
|
|
10
|
+
const smooth=t=>t<=0?0:t>=1?1:t*t*(3-2*t);
|
|
11
|
+
const finite=v=>typeof v==='number'&&Number.isFinite(v);
|
|
12
|
+
const depthRank=id=>/near/.test(id)?0:/far/.test(id)?2:1;
|
|
13
|
+
|
|
14
|
+
export function createPawTransport(feet,pins,{opaque=null}={}){
|
|
15
|
+
const list=[],seen=new Set();
|
|
16
|
+
for(const foot of Array.isArray(feet)?feet:[]){
|
|
17
|
+
if(!foot||typeof foot.id!=='string'||seen.has(foot.id)||!finite(foot.x)||!finite(foot.y))continue;
|
|
18
|
+
seen.add(foot.id);list.push(foot);
|
|
19
|
+
}
|
|
20
|
+
const pinById=new Map();
|
|
21
|
+
for(const pin of Array.isArray(pins)?pins:[]){
|
|
22
|
+
if(!pin||!seen.has(pin.id)||pinById.has(pin.id))continue;
|
|
23
|
+
const s=pin.source,t=pin.target;
|
|
24
|
+
if(!s||!t||![s.x,s.y,t.x,t.y].every(finite))continue;
|
|
25
|
+
pinById.set(pin.id,pin);
|
|
26
|
+
}
|
|
27
|
+
const limited=[],degenerate=[];
|
|
28
|
+
const identity=(x,y)=>finite(x)&&finite(y)?{x,y}:null;
|
|
29
|
+
if(!pinById.size||!list.length)return Object.assign(identity,{layers:[],limited,degenerate});
|
|
30
|
+
// Strips from original foot centers, sorted by (x,id) so input order is irrelevant.
|
|
31
|
+
const byX=[...list].sort((a,b)=>a.x-b.x||(a.id<b.id?-1:1));
|
|
32
|
+
const layers=byX.map((foot,i)=>{
|
|
33
|
+
const cx=foot.x+.5,lo=i?(byX[i-1].x+.5+cx)/2:-Infinity,hi=i<byX.length-1?(cx+byX[i+1].x+.5)/2:Infinity;
|
|
34
|
+
if(!(cx>=lo&&cx<hi))degenerate.push(foot.id);
|
|
35
|
+
const pin=pinById.get(foot.id),dx=pin?pin.target.x-pin.source.x:0;let dy=pin?pin.target.y-pin.source.y:0;
|
|
36
|
+
const toeTop=Math.max(TORSO+MIN_SPAN,(pin?pin.source.y:foot.y+.5)-TOE_RIGID),span=toeTop-TORSO;
|
|
37
|
+
// Vertical profile: smoothstep, blended toward a linear ramp when a negative
|
|
38
|
+
// dy would fold it (max slope 1.5/span vs 1/span). Beyond even the linear
|
|
39
|
+
// limit the vertical shift is clamped and the pin reported as limited.
|
|
40
|
+
let a=0;
|
|
41
|
+
if(dy<0){
|
|
42
|
+
const k=FOLD_MARGIN*span/-dy;
|
|
43
|
+
if(k<1){a=1;dy=-FOLD_MARGIN*span;limited.push(foot.id);}else if(k<1.5)a=Math.min(1,3-2*k);
|
|
44
|
+
}
|
|
45
|
+
return{id:foot.id,lo,hi,dx,dy,toeTop,span,a,active:!!pin,rank:depthRank(foot.id),y:foot.y,lastY:NaN,lastSy:NaN};
|
|
46
|
+
});
|
|
47
|
+
const gx=(L,s)=>smooth((s-TORSO)/L.span);
|
|
48
|
+
const gy=(L,s)=>{const t=(s-TORSO)/L.span;return t<=0?0:t>=1?1:(1-L.a)*smooth(t)+L.a*t;};
|
|
49
|
+
// Monotone vertical inverse; the renderer walks rows, so cache per layer.
|
|
50
|
+
const invY=(L,y)=>{
|
|
51
|
+
if(L.dy===0)return y;
|
|
52
|
+
if(y>=L.toeTop+L.dy)return y-L.dy;
|
|
53
|
+
if(y===L.lastY)return L.lastSy;
|
|
54
|
+
let lo=TORSO,hi=L.toeTop;
|
|
55
|
+
for(let i=0;i<48&&hi-lo>1e-9;i++){const m=(lo+hi)/2;if(m+L.dy*gy(L,m)<y)lo=m;else hi=m;}
|
|
56
|
+
L.lastY=y;L.lastSy=(lo+hi)/2;return L.lastSy;
|
|
57
|
+
};
|
|
58
|
+
// Front-to-back. With an opacity predicate, true depth order with fall-through
|
|
59
|
+
// on transparent source; without one, pinned layers first so anchors stay visible.
|
|
60
|
+
const order=[...layers].sort((p,q)=>(opaque?0:(q.active-p.active))||p.rank-q.rank||q.y-p.y||(p.id<q.id?-1:1));
|
|
61
|
+
const sourcePoint=(x,y)=>{
|
|
62
|
+
if(!finite(x)||!finite(y))return null;
|
|
63
|
+
if(y<TORSO)return{x,y};
|
|
64
|
+
let fallback=null;
|
|
65
|
+
for(const L of order){
|
|
66
|
+
let sx,sy;
|
|
67
|
+
if(L.dx===0&&L.dy===0){sx=x;sy=y;}
|
|
68
|
+
else{sy=invY(L,y);sx=sy>=L.toeTop?x-L.dx:x-L.dx*gx(L,sy);}
|
|
69
|
+
if(!(sx>=L.lo&&sx<L.hi))continue;
|
|
70
|
+
if(!opaque||opaque(sx,sy))return{x:sx,y:sy};
|
|
71
|
+
fallback??={x:sx,y:sy};
|
|
72
|
+
}
|
|
73
|
+
return fallback;
|
|
74
|
+
};
|
|
75
|
+
return Object.assign(sourcePoint,{layers:order.map(({id,lo,hi,dx,dy,toeTop,active,rank})=>({id,lo,hi,dx,dy,toeTop,active,rank})),limited,degenerate});
|
|
76
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"width":320,"height":320,"samples":9,"pairs":18,"bytes":16588800,"sha256":"75972598be42314b92e64487106e3103ad477f897705dda869fc0b10cf68e256","sheet_sha256":"dcf5998027fc34cf07e404c45c86f21aba82c9e9a72b8f8748f8726f2553723f","front_cache_sha256":"15e8ef49947cec4a1dcb3393d43a2ad48125d1bcd30f01275087c3df61627392","edges":[[8,9],[9,10],[10,11],[11,12],[12,0],[0,1],[1,2],[2,3],[3,4],[4,5],[5,6],[6,7],[7,0],[0,13],[13,14],[14,15],[15,16],[16,8]],"away":[0,1,2,3,4],"run":[5,6,7,8,9,10,11,12],"toward":[13,14,15,16,17],"registration":[{"component":4,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,50.647021800599376],[0.0,0.6876790830945558,60.687679083094565]],"floor":300},{"component":5,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,51.53979274277823],[0.0,0.6876790830945558,61.37535816618913]],"floor":300},{"component":1,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,60.04271295801766],[0.0,0.6876790830945558,37.93982808022923]],"floor":269},{"component":2,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,53.72935945464771],[0.0,0.6876790830945558,52.25787965616047]],"floor":262},{"component":12,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,43.88160389196199],[0.0,0.6876790830945558,51.876790830945566]],"floor":285},{"component":11,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,51.41092783712841],[0.0,0.6876790830945558,60.687679083094565]],"floor":300},{"component":13,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,59.1667508659871],[0.0,0.6876790830945558,54.498567335243564]],"floor":300},{"component":14,"scale":0.6876790830945558,"matrix":[[0.6876790830945558,0.0,53.42116987656014],[0.0,0.6876790830945558,55.18624641833813]],"floor":300}],"frontFeet":[[[{"id":"hind-near","x":141,"y":265,"stance":true},{"id":"fore-far","x":212,"y":278,"stance":false},{"id":"fore-near","x":255,"y":278,"stance":false}],[{"id":"hind-near","x":140,"y":264,"stance":true},{"id":"fore-far","x":214,"y":278,"stance":false},{"id":"fore-near","x":255,"y":278,"stance":false}],[{"id":"hind-near","x":140,"y":262,"stance":true},{"id":"fore-far","x":215,"y":278,"stance":false},{"id":"fore-near","x":255,"y":278,"stance":false}],[{"id":"hind-near","x":138,"y":262,"stance":true},{"id":"fore-far","x":217,"y":277,"stance":false},{"id":"fore-near","x":255,"y":278,"stance":false}],[{"id":"hind-near","x":137,"y":261,"stance":true},{"id":"fore-far","x":220,"y":276,"stance":false},{"id":"fore-near","x":254,"y":277,"stance":false}],[{"id":"hind-near","x":135,"y":260,"stance":true},{"id":"fore-far","x":222,"y":276,"stance":false},{"id":"fore-near","x":255,"y":277,"stance":false}],[{"id":"hind-near","x":133,"y":259,"stance":true},{"id":"fore-far","x":225,"y":276,"stance":false},{"id":"fore-near","x":255,"y":276,"stance":false}],[{"id":"hind-near","x":133,"y":257,"stance":true},{"id":"fore-far","x":226,"y":276,"stance":false},{"id":"fore-near","x":256,"y":276,"stance":false}],[{"id":"hind-near","x":131,"y":255,"stance":false},{"id":"fore-far","x":227,"y":277,"stance":false},{"id":"fore-near","x":255,"y":275,"stance":false}],[{"id":"hind-near","x":130,"y":255,"stance":false},{"id":"fore-far","x":228,"y":278,"stance":false},{"id":"fore-near","x":252,"y":276,"stance":false}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":95,"y":254,"stance":false},{"id":"fore-far","x":229,"y":277,"stance":false},{"id":"fore-near","x":239,"y":277,"stance":false}],[{"id":"hind-far","x":81,"y":254,"stance":false},{"id":"hind-near","x":87,"y":258,"stance":false},{"id":"fore-far","x":232,"y":277,"stance":false},{"id":"fore-near","x":244,"y":275,"stance":false}],[{"id":"hind-far","x":81,"y":258,"stance":false},{"id":"hind-near","x":87,"y":258,"stance":false},{"id":"fore-far","x":233,"y":277,"stance":false},{"id":"fore-near","x":243,"y":277,"stance":false}],[{"id":"hind-far","x":79,"y":260,"stance":false},{"id":"hind-near","x":85,"y":260,"stance":false},{"id":"fore-far","x":233,"y":277,"stance":false},{"id":"fore-near","x":244,"y":277,"stance":false}],[{"id":"hind-far","x":78,"y":261,"stance":false},{"id":"hind-near","x":85,"y":260,"stance":false},{"id":"fore-far","x":234,"y":276,"stance":false},{"id":"fore-near","x":245,"y":277,"stance":false}],[{"id":"hind-far","x":79,"y":261,"stance":false},{"id":"hind-near","x":85,"y":261,"stance":false},{"id":"fore-far","x":234,"y":276,"stance":false},{"id":"fore-near","x":245,"y":277,"stance":false}],[{"id":"hind-far","x":78,"y":262,"stance":false},{"id":"hind-near","x":86,"y":261,"stance":false},{"id":"fore-far","x":234,"y":275,"stance":false},{"id":"fore-near","x":246,"y":277,"stance":false}]],[[{"id":"hind-far","x":78,"y":262,"stance":false},{"id":"hind-near","x":86,"y":261,"stance":false},{"id":"fore-far","x":234,"y":275,"stance":false},{"id":"fore-near","x":246,"y":277,"stance":false}],[{"id":"hind-far","x":77,"y":260,"stance":false},{"id":"hind-near","x":85,"y":258,"stance":false},{"id":"fore-far","x":234,"y":272,"stance":false},{"id":"fore-near","x":246,"y":275,"stance":false}],[{"id":"hind-far","x":76,"y":258,"stance":false},{"id":"hind-near","x":85,"y":256,"stance":false},{"id":"fore-far","x":234,"y":269,"stance":false},{"id":"fore-near","x":247,"y":273,"stance":false}],[{"id":"hind-far","x":75,"y":256,"stance":false},{"id":"hind-near","x":84,"y":254,"stance":false},{"id":"fore-far","x":233,"y":266,"stance":false},{"id":"fore-near","x":249,"y":271,"stance":false}],[{"id":"hind-far","x":74,"y":254,"stance":false},{"id":"hind-near","x":83,"y":251,"stance":false},{"id":"fore-far","x":233,"y":264,"stance":false},{"id":"fore-near","x":246,"y":270,"stance":false}],[{"id":"hind-far","x":73,"y":250,"stance":false},{"id":"hind-near","x":114,"y":246,"stance":false},{"id":"fore-far","x":234,"y":262,"stance":false},{"id":"fore-near","x":249,"y":266,"stance":false}],[{"id":"hind-far","x":71,"y":248,"stance":false},{"id":"hind-near","x":114,"y":246,"stance":false},{"id":"fore-far","x":234,"y":260,"stance":false},{"id":"fore-near","x":249,"y":266,"stance":false}],[{"id":"hind-far","x":69,"y":245,"stance":false},{"id":"hind-near","x":112,"y":244,"stance":false},{"id":"fore-far","x":228,"y":254,"stance":false},{"id":"fore-near","x":251,"y":263,"stance":false}],[{"id":"hind-far","x":67,"y":243,"stance":false},{"id":"hind-near","x":109,"y":243,"stance":false},{"id":"fore-far","x":228,"y":252,"stance":false},{"id":"fore-near","x":253,"y":262,"stance":false}],[{"id":"hind-far","x":65,"y":240,"stance":false},{"id":"hind-near","x":107,"y":242,"stance":false},{"id":"fore-far","x":226,"y":251,"stance":false},{"id":"fore-near","x":255,"y":260,"stance":false}],[{"id":"hind-far","x":63,"y":236,"stance":false},{"id":"hind-near","x":106,"y":241,"stance":false},{"id":"fore-far","x":225,"y":249,"stance":false},{"id":"fore-near","x":256,"y":257,"stance":false}],[{"id":"hind-far","x":62,"y":234,"stance":false},{"id":"hind-near","x":104,"y":240,"stance":false},{"id":"fore-far","x":225,"y":248,"stance":false},{"id":"fore-near","x":258,"y":256,"stance":false}],[{"id":"hind-far","x":60,"y":231,"stance":false},{"id":"hind-near","x":101,"y":238,"stance":false},{"id":"fore-far","x":225,"y":247,"stance":false},{"id":"fore-near","x":259,"y":254,"stance":false}],[{"id":"hind-far","x":58,"y":229,"stance":false},{"id":"hind-near","x":100,"y":238,"stance":false},{"id":"fore-far","x":224,"y":246,"stance":false},{"id":"fore-near","x":262,"y":252,"stance":false}],[{"id":"hind-far","x":58,"y":227,"stance":false},{"id":"hind-near","x":99,"y":237,"stance":false},{"id":"fore-far","x":225,"y":245,"stance":false},{"id":"fore-near","x":261,"y":251,"stance":false}],[{"id":"hind-near","x":98,"y":236,"stance":false},{"id":"fore-far","x":224,"y":244,"stance":false},{"id":"fore-near","x":263,"y":249,"stance":false}],[{"id":"hind-near","x":94,"y":235,"stance":false},{"id":"fore-far","x":224,"y":243,"stance":false},{"id":"fore-near","x":267,"y":247,"stance":false}]],[[{"id":"hind-near","x":94,"y":235,"stance":false},{"id":"fore-far","x":224,"y":243,"stance":false},{"id":"fore-near","x":267,"y":247,"stance":false}],[{"id":"hind-near","x":96,"y":235,"stance":false},{"id":"fore-far","x":224,"y":244,"stance":false},{"id":"fore-near","x":266,"y":248,"stance":false}],[{"id":"hind-near","x":98,"y":236,"stance":false},{"id":"fore-far","x":224,"y":244,"stance":false},{"id":"fore-near","x":263,"y":249,"stance":false}],[{"id":"hind-far","x":59,"y":227,"stance":false},{"id":"hind-near","x":99,"y":236,"stance":false},{"id":"fore-far","x":224,"y":244,"stance":false},{"id":"fore-near","x":265,"y":250,"stance":false}],[{"id":"hind-far","x":63,"y":228,"stance":false},{"id":"hind-near","x":101,"y":236,"stance":false},{"id":"fore-far","x":224,"y":244,"stance":false},{"id":"fore-near","x":264,"y":251,"stance":false}],[{"id":"hind-far","x":63,"y":229,"stance":false},{"id":"hind-near","x":102,"y":236,"stance":false},{"id":"fore-far","x":228,"y":246,"stance":false},{"id":"fore-near","x":267,"y":252,"stance":false}],[{"id":"hind-far","x":65,"y":231,"stance":false},{"id":"hind-near","x":103,"y":237,"stance":false},{"id":"fore-far","x":228,"y":246,"stance":false},{"id":"fore-near","x":265,"y":253,"stance":false}],[{"id":"hind-far","x":67,"y":233,"stance":false},{"id":"hind-near","x":105,"y":237,"stance":false},{"id":"fore-far","x":226,"y":248,"stance":false},{"id":"fore-near","x":283,"y":256,"stance":false}],[{"id":"hind-far","x":70,"y":235,"stance":false},{"id":"hind-near","x":107,"y":238,"stance":false},{"id":"fore-far","x":226,"y":249,"stance":false},{"id":"fore-near","x":282,"y":257,"stance":false}],[{"id":"hind-far","x":72,"y":238,"stance":false},{"id":"hind-near","x":110,"y":238,"stance":false},{"id":"fore-far","x":226,"y":250,"stance":false},{"id":"fore-near","x":281,"y":258,"stance":false}],[{"id":"hind-far","x":75,"y":240,"stance":false},{"id":"hind-near","x":110,"y":238,"stance":false},{"id":"fore-far","x":234,"y":255,"stance":false},{"id":"fore-near","x":281,"y":262,"stance":false}],[{"id":"hind-far","x":76,"y":241,"stance":false},{"id":"hind-near","x":109,"y":238,"stance":false},{"id":"fore-far","x":234,"y":257,"stance":false},{"id":"fore-near","x":282,"y":264,"stance":false}],[{"id":"hind-far","x":78,"y":243,"stance":false},{"id":"hind-near","x":85,"y":243,"stance":false},{"id":"fore-far","x":234,"y":259,"stance":false},{"id":"fore-near","x":282,"y":265,"stance":false}],[{"id":"hind-far","x":78,"y":244,"stance":false},{"id":"hind-near","x":86,"y":244,"stance":false},{"id":"fore-far","x":234,"y":261,"stance":false},{"id":"fore-near","x":286,"y":269,"stance":false}],[{"id":"hind-far","x":78,"y":245,"stance":false},{"id":"hind-near","x":85,"y":245,"stance":false},{"id":"fore-far","x":234,"y":263,"stance":false},{"id":"fore-near","x":284,"y":270,"stance":false}],[{"id":"hind-far","x":79,"y":245,"stance":false},{"id":"hind-near","x":85,"y":245,"stance":false},{"id":"fore-far","x":234,"y":265,"stance":false},{"id":"fore-near","x":290,"y":271,"stance":false}],[{"id":"hind-far","x":79,"y":247,"stance":false},{"id":"hind-near","x":86,"y":247,"stance":false},{"id":"fore-far","x":234,"y":270,"stance":false},{"id":"fore-near","x":290,"y":275,"stance":false}]],[[{"id":"hind-far","x":79,"y":247,"stance":false},{"id":"hind-near","x":86,"y":247,"stance":false},{"id":"fore-far","x":234,"y":270,"stance":false},{"id":"fore-near","x":290,"y":275,"stance":false}],[{"id":"hind-far","x":80,"y":247,"stance":false},{"id":"hind-near","x":87,"y":247,"stance":false},{"id":"fore-far","x":233,"y":270,"stance":false},{"id":"fore-near","x":289,"y":276,"stance":false}],[{"id":"hind-far","x":80,"y":248,"stance":false},{"id":"hind-near","x":87,"y":248,"stance":false},{"id":"fore-far","x":233,"y":271,"stance":false},{"id":"fore-near","x":288,"y":276,"stance":false}],[{"id":"hind-far","x":80,"y":248,"stance":false},{"id":"hind-near","x":88,"y":249,"stance":false},{"id":"fore-far","x":233,"y":272,"stance":false},{"id":"fore-near","x":287,"y":276,"stance":false}],[{"id":"hind-far","x":81,"y":249,"stance":false},{"id":"hind-near","x":88,"y":249,"stance":false},{"id":"fore-far","x":233,"y":273,"stance":false},{"id":"fore-near","x":282,"y":277,"stance":false}],[{"id":"hind-far","x":81,"y":249,"stance":false},{"id":"hind-near","x":88,"y":250,"stance":false},{"id":"fore-far","x":232,"y":274,"stance":false},{"id":"fore-near","x":285,"y":277,"stance":false}],[{"id":"hind-far","x":81,"y":249,"stance":false},{"id":"hind-near","x":89,"y":250,"stance":false},{"id":"fore-far","x":231,"y":275,"stance":false},{"id":"fore-near","x":280,"y":278,"stance":false}],[{"id":"hind-far","x":81,"y":249,"stance":false},{"id":"hind-near","x":89,"y":251,"stance":false},{"id":"fore-far","x":231,"y":276,"stance":false},{"id":"fore-near","x":278,"y":278,"stance":false}],[{"id":"hind-far","x":81,"y":249,"stance":false},{"id":"hind-near","x":90,"y":251,"stance":false},{"id":"fore-far","x":231,"y":276,"stance":false},{"id":"fore-near","x":278,"y":277,"stance":false}],[{"id":"hind-far","x":82,"y":250,"stance":false},{"id":"hind-near","x":90,"y":251,"stance":false},{"id":"fore-far","x":230,"y":277,"stance":false},{"id":"fore-near","x":278,"y":278,"stance":false}],[{"id":"hind-far","x":81,"y":248,"stance":false},{"id":"hind-near","x":90,"y":251,"stance":false},{"id":"fore-far","x":230,"y":278,"stance":false},{"id":"fore-near","x":276,"y":279,"stance":false}],[{"id":"hind-far","x":81,"y":248,"stance":false},{"id":"hind-near","x":92,"y":252,"stance":false},{"id":"fore-far","x":230,"y":278,"stance":false},{"id":"fore-near","x":274,"y":280,"stance":false}],[{"id":"hind-far","x":82,"y":249,"stance":false},{"id":"hind-near","x":93,"y":252,"stance":false},{"id":"fore-far","x":229,"y":279,"stance":false},{"id":"fore-near","x":272,"y":280,"stance":false}],[{"id":"hind-far","x":81,"y":247,"stance":false},{"id":"hind-near","x":94,"y":253,"stance":false},{"id":"fore-far","x":229,"y":280,"stance":false},{"id":"fore-near","x":267,"y":280,"stance":false}],[{"id":"hind-far","x":82,"y":249,"stance":false},{"id":"hind-near","x":95,"y":253,"stance":false},{"id":"fore-far","x":228,"y":280,"stance":false},{"id":"fore-near","x":267,"y":280,"stance":false}],[{"id":"hind-far","x":82,"y":249,"stance":false},{"id":"hind-near","x":94,"y":254,"stance":false},{"id":"fore-far","x":228,"y":280,"stance":false},{"id":"fore-near","x":267,"y":280,"stance":false}],[{"id":"hind-far","x":82,"y":248,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":228,"y":281,"stance":false},{"id":"fore-near","x":265,"y":281,"stance":false}]],[[{"id":"hind-far","x":82,"y":248,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":228,"y":281,"stance":false},{"id":"fore-near","x":265,"y":281,"stance":false}],[{"id":"hind-far","x":82,"y":247,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":228,"y":281,"stance":false},{"id":"fore-near","x":265,"y":281,"stance":false}],[{"id":"hind-far","x":82,"y":248,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":227,"y":281,"stance":false},{"id":"fore-near","x":266,"y":281,"stance":false}],[{"id":"hind-far","x":82,"y":247,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":227,"y":281,"stance":false},{"id":"fore-near","x":266,"y":281,"stance":false}],[{"id":"hind-far","x":82,"y":247,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":228,"y":282,"stance":false},{"id":"fore-near","x":265,"y":281,"stance":false}],[{"id":"hind-far","x":82,"y":247,"stance":false},{"id":"hind-near","x":97,"y":254,"stance":false},{"id":"fore-far","x":227,"y":283,"stance":false},{"id":"fore-near","x":267,"y":282,"stance":false}],[{"id":"hind-far","x":82,"y":247,"stance":false},{"id":"hind-near","x":98,"y":253,"stance":false},{"id":"fore-far","x":227,"y":283,"stance":false},{"id":"fore-near","x":267,"y":282,"stance":false}],[{"id":"hind-far","x":82,"y":247,"stance":false},{"id":"hind-near","x":98,"y":253,"stance":false},{"id":"fore-far","x":226,"y":283,"stance":false},{"id":"fore-near","x":267,"y":282,"stance":false}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":98,"y":253,"stance":false},{"id":"fore-far","x":226,"y":283,"stance":false},{"id":"fore-near","x":267,"y":282,"stance":false}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":99,"y":252,"stance":false},{"id":"fore-far","x":225,"y":283,"stance":false},{"id":"fore-near","x":268,"y":282,"stance":false}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":100,"y":252,"stance":false},{"id":"fore-far","x":223,"y":283,"stance":false},{"id":"fore-near","x":269,"y":282,"stance":false}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":100,"y":252,"stance":false},{"id":"fore-far","x":223,"y":283,"stance":true},{"id":"fore-near","x":269,"y":282,"stance":true}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":100,"y":252,"stance":false},{"id":"fore-far","x":223,"y":283,"stance":true},{"id":"fore-near","x":269,"y":282,"stance":true}],[{"id":"hind-far","x":82,"y":246,"stance":false},{"id":"hind-near","x":103,"y":251,"stance":false},{"id":"fore-far","x":222,"y":284,"stance":true},{"id":"fore-near","x":271,"y":283,"stance":true}],[{"id":"hind-far","x":82,"y":245,"stance":false},{"id":"hind-near","x":124,"y":252,"stance":false},{"id":"fore-far","x":222,"y":284,"stance":true},{"id":"fore-near","x":271,"y":283,"stance":true}],[{"id":"hind-far","x":82,"y":245,"stance":false},{"id":"hind-near","x":124,"y":252,"stance":false},{"id":"fore-far","x":222,"y":284,"stance":true},{"id":"fore-near","x":270,"y":283,"stance":true}],[{"id":"hind-far","x":82,"y":245,"stance":false},{"id":"hind-near","x":103,"y":251,"stance":false},{"id":"fore-far","x":221,"y":284,"stance":true},{"id":"fore-near","x":270,"y":283,"stance":true}]],[[{"id":"hind-far","x":82,"y":245,"stance":false},{"id":"hind-near","x":103,"y":251,"stance":false},{"id":"fore-far","x":221,"y":284,"stance":true},{"id":"fore-near","x":270,"y":283,"stance":true}],[{"id":"hind-far","x":82,"y":245,"stance":false},{"id":"hind-near","x":125,"y":252,"stance":false},{"id":"fore-far","x":221,"y":284,"stance":true},{"id":"fore-near","x":269,"y":283,"stance":true}],[{"id":"hind-near","x":126,"y":252,"stance":false},{"id":"fore-far","x":221,"y":284,"stance":true},{"id":"fore-near","x":269,"y":282,"stance":true}],[{"id":"hind-near","x":129,"y":252,"stance":false},{"id":"fore-far","x":220,"y":283,"stance":true},{"id":"fore-near","x":269,"y":282,"stance":true}],[{"id":"hind-near","x":132,"y":253,"stance":false},{"id":"fore-far","x":220,"y":283,"stance":true},{"id":"fore-near","x":269,"y":282,"stance":true}],[{"id":"hind-near","x":135,"y":254,"stance":false},{"id":"fore-far","x":221,"y":283,"stance":true},{"id":"fore-near","x":268,"y":282,"stance":true}],[{"id":"hind-near","x":136,"y":254,"stance":false},{"id":"fore-far","x":220,"y":283,"stance":true},{"id":"fore-near","x":268,"y":281,"stance":true}],[{"id":"hind-near","x":137,"y":254,"stance":false},{"id":"fore-far","x":220,"y":283,"stance":true},{"id":"fore-near","x":268,"y":281,"stance":true}],[{"id":"hind-near","x":138,"y":255,"stance":false},{"id":"fore-far","x":220,"y":282,"stance":true},{"id":"fore-near","x":267,"y":280,"stance":true}],[{"id":"hind-near","x":140,"y":256,"stance":false},{"id":"fore-far","x":221,"y":282,"stance":true},{"id":"fore-near","x":267,"y":281,"stance":true}],[{"id":"hind-near","x":141,"y":257,"stance":false},{"id":"fore-far","x":221,"y":282,"stance":true},{"id":"fore-near","x":268,"y":281,"stance":true}],[{"id":"hind-near","x":141,"y":257,"stance":false},{"id":"fore-far","x":221,"y":282,"stance":true},{"id":"fore-near","x":266,"y":279,"stance":true}],[{"id":"hind-near","x":142,"y":257,"stance":false},{"id":"fore-far","x":221,"y":282,"stance":true},{"id":"fore-near","x":266,"y":280,"stance":true}],[{"id":"hind-near","x":143,"y":258,"stance":false},{"id":"fore-far","x":221,"y":282,"stance":true},{"id":"fore-near","x":266,"y":280,"stance":true}],[{"id":"hind-near","x":143,"y":257,"stance":false},{"id":"fore-far","x":221,"y":281,"stance":true},{"id":"fore-near","x":267,"y":280,"stance":true}],[{"id":"hind-near","x":143,"y":258,"stance":false},{"id":"fore-far","x":221,"y":281,"stance":true},{"id":"fore-near","x":265,"y":279,"stance":true}],[{"id":"hind-near","x":145,"y":258,"stance":false},{"id":"fore-far","x":221,"y":281,"stance":true},{"id":"fore-near","x":265,"y":279,"stance":true}]],[[{"id":"hind-near","x":145,"y":258,"stance":false},{"id":"fore-far","x":221,"y":281,"stance":true},{"id":"fore-near","x":265,"y":279,"stance":true}],[{"id":"hind-near","x":146,"y":258,"stance":false},{"id":"fore-far","x":221,"y":279,"stance":true},{"id":"fore-near","x":264,"y":277,"stance":true}],[{"id":"hind-near","x":146,"y":258,"stance":false},{"id":"fore-far","x":221,"y":278,"stance":true},{"id":"fore-near","x":264,"y":276,"stance":true}],[{"id":"hind-near","x":146,"y":258,"stance":false},{"id":"fore-far","x":221,"y":277,"stance":false},{"id":"fore-near","x":260,"y":273,"stance":false}],[{"id":"hind-near","x":147,"y":258,"stance":false},{"id":"fore-far","x":221,"y":276,"stance":false},{"id":"fore-near","x":257,"y":272,"stance":false}],[{"id":"hind-near","x":147,"y":258,"stance":false},{"id":"fore-far","x":221,"y":275,"stance":false},{"id":"fore-near","x":253,"y":271,"stance":false}],[{"id":"hind-near","x":148,"y":258,"stance":false},{"id":"fore-far","x":221,"y":275,"stance":false},{"id":"fore-near","x":241,"y":270,"stance":false}],[{"id":"hind-near","x":148,"y":258,"stance":false},{"id":"fore-far","x":221,"y":273,"stance":false},{"id":"fore-near","x":238,"y":270,"stance":false}],[{"id":"hind-near","x":148,"y":258,"stance":false},{"id":"fore-far","x":221,"y":272,"stance":false},{"id":"fore-near","x":237,"y":269,"stance":false}],[{"id":"hind-near","x":149,"y":258,"stance":false},{"id":"fore-far","x":219,"y":271,"stance":false},{"id":"fore-near","x":237,"y":266,"stance":false}],[{"id":"hind-near","x":149,"y":258,"stance":false},{"id":"fore-far","x":219,"y":270,"stance":false},{"id":"fore-near","x":241,"y":261,"stance":false}],[{"id":"hind-near","x":149,"y":258,"stance":false},{"id":"fore-far","x":220,"y":269,"stance":false},{"id":"fore-near","x":240,"y":259,"stance":false}],[{"id":"hind-near","x":149,"y":258,"stance":false},{"id":"fore-far","x":221,"y":269,"stance":false},{"id":"fore-near","x":236,"y":261,"stance":false}],[{"id":"hind-near","x":150,"y":258,"stance":false},{"id":"fore-far","x":221,"y":268,"stance":false},{"id":"fore-near","x":240,"y":256,"stance":false}],[{"id":"hind-near","x":150,"y":258,"stance":false},{"id":"fore-far","x":221,"y":267,"stance":false},{"id":"fore-near","x":239,"y":255,"stance":false}],[{"id":"hind-near","x":150,"y":258,"stance":false},{"id":"fore-far","x":221,"y":266,"stance":false},{"id":"fore-near","x":238,"y":254,"stance":false}],[{"id":"hind-near","x":150,"y":257,"stance":false},{"id":"fore-far","x":221,"y":264,"stance":false},{"id":"fore-near","x":240,"y":252,"stance":false}]],[[{"id":"hind-near","x":150,"y":257,"stance":false},{"id":"fore-far","x":221,"y":264,"stance":false},{"id":"fore-near","x":240,"y":252,"stance":false}],[{"id":"hind-near","x":150,"y":257,"stance":false},{"id":"fore-far","x":220,"y":265,"stance":false},{"id":"fore-near","x":240,"y":253,"stance":false}],[{"id":"hind-near","x":150,"y":258,"stance":false},{"id":"fore-far","x":220,"y":266,"stance":false},{"id":"fore-near","x":241,"y":253,"stance":false}],[{"id":"hind-near","x":149,"y":259,"stance":false},{"id":"fore-far","x":219,"y":267,"stance":false},{"id":"fore-near","x":240,"y":255,"stance":false}],[{"id":"hind-near","x":149,"y":260,"stance":false},{"id":"fore-far","x":218,"y":267,"stance":false},{"id":"fore-near","x":241,"y":256,"stance":false}],[{"id":"hind-near","x":148,"y":260,"stance":false},{"id":"fore-far","x":217,"y":268,"stance":false},{"id":"fore-near","x":241,"y":258,"stance":false}],[{"id":"hind-near","x":148,"y":260,"stance":false},{"id":"fore-far","x":217,"y":269,"stance":false},{"id":"fore-near","x":242,"y":260,"stance":false}],[{"id":"hind-near","x":146,"y":261,"stance":false},{"id":"fore-far","x":215,"y":270,"stance":false},{"id":"fore-near","x":243,"y":262,"stance":false}],[{"id":"hind-near","x":146,"y":262,"stance":false},{"id":"fore-far","x":215,"y":270,"stance":false},{"id":"fore-near","x":243,"y":264,"stance":false}],[{"id":"hind-near","x":145,"y":262,"stance":false},{"id":"fore-far","x":214,"y":271,"stance":false},{"id":"fore-near","x":245,"y":265,"stance":false}],[{"id":"hind-near","x":143,"y":262,"stance":false},{"id":"fore-far","x":215,"y":271,"stance":false},{"id":"fore-near","x":247,"y":266,"stance":false}],[{"id":"hind-near","x":143,"y":263,"stance":true},{"id":"fore-far","x":213,"y":273,"stance":false},{"id":"fore-near","x":248,"y":268,"stance":false}],[{"id":"hind-near","x":143,"y":264,"stance":true},{"id":"fore-far","x":213,"y":274,"stance":false},{"id":"fore-near","x":251,"y":271,"stance":false}],[{"id":"hind-near","x":142,"y":264,"stance":true},{"id":"fore-far","x":213,"y":275,"stance":false},{"id":"fore-near","x":252,"y":273,"stance":false}],[{"id":"hind-near","x":142,"y":264,"stance":true},{"id":"fore-far","x":214,"y":276,"stance":false},{"id":"fore-near","x":254,"y":275,"stance":false}],[{"id":"hind-near","x":142,"y":264,"stance":true},{"id":"fore-far","x":214,"y":276,"stance":false},{"id":"fore-near","x":254,"y":275,"stance":false}],[{"id":"hind-near","x":141,"y":265,"stance":true},{"id":"fore-far","x":212,"y":278,"stance":false},{"id":"fore-near","x":255,"y":278,"stance":false}]]],"rearFeet":[[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[{"id":"hind-far","x":127,"y":299,"stance":true},{"id":"hind-near","x":188,"y":299,"stance":true}],[{"id":"hind-far","x":127,"y":297,"stance":true},{"id":"hind-near","x":186,"y":299,"stance":true}],[{"id":"hind-far","x":126,"y":295,"stance":true},{"id":"hind-near","x":184,"y":299,"stance":true}],[{"id":"hind-far","x":127,"y":292,"stance":true},{"id":"hind-near","x":182,"y":299,"stance":true}],[{"id":"hind-far","x":159,"y":296,"stance":true},{"id":"hind-near","x":180,"y":299,"stance":true}],[{"id":"hind-far","x":158,"y":298,"stance":true},{"id":"hind-near","x":179,"y":299,"stance":true}],[{"id":"hind-far","x":157,"y":298,"stance":true},{"id":"hind-near","x":177,"y":299,"stance":true}],[{"id":"hind-far","x":156,"y":298,"stance":true},{"id":"hind-near","x":176,"y":299,"stance":true}],[{"id":"hind-far","x":155,"y":298,"stance":false},{"id":"hind-near","x":174,"y":299,"stance":true}]],[[{"id":"hind-far","x":155,"y":298,"stance":false},{"id":"hind-near","x":174,"y":299,"stance":true}],[{"id":"hind-far","x":155,"y":293,"stance":false},{"id":"hind-near","x":173,"y":294,"stance":true}],[{"id":"hind-far","x":155,"y":289,"stance":false},{"id":"hind-near","x":171,"y":289,"stance":false}],[{"id":"hind-far","x":155,"y":285,"stance":false},{"id":"hind-near","x":171,"y":285,"stance":false}],[{"id":"hind-far","x":156,"y":280,"stance":false},{"id":"hind-near","x":166,"y":281,"stance":false}],[{"id":"hind-far","x":156,"y":276,"stance":false},{"id":"hind-near","x":167,"y":278,"stance":false}],[{"id":"hind-far","x":157,"y":273,"stance":false},{"id":"hind-near","x":165,"y":274,"stance":false}],[{"id":"hind-far","x":157,"y":270,"stance":false},{"id":"hind-near","x":166,"y":271,"stance":false}],[{"id":"hind-far","x":157,"y":266,"stance":false},{"id":"hind-near","x":165,"y":267,"stance":false}]],[[{"id":"hind-far","x":157,"y":266,"stance":false},{"id":"hind-near","x":165,"y":267,"stance":false}],[{"id":"hind-far","x":157,"y":265,"stance":false},{"id":"hind-near","x":165,"y":267,"stance":false}],[{"id":"hind-far","x":158,"y":264,"stance":false},{"id":"hind-near","x":166,"y":266,"stance":false}],[{"id":"hind-far","x":158,"y":263,"stance":false},{"id":"hind-near","x":166,"y":266,"stance":false}],[{"id":"hind-far","x":159,"y":263,"stance":false},{"id":"hind-near","x":167,"y":264,"stance":false}],[{"id":"hind-far","x":159,"y":260,"stance":false},{"id":"hind-near","x":168,"y":263,"stance":false}],[{"id":"hind-far","x":158,"y":257,"stance":false},{"id":"hind-near","x":168,"y":262,"stance":false}],[{"id":"hind-far","x":158,"y":256,"stance":false},{"id":"hind-near","x":169,"y":262,"stance":false}],[{"id":"hind-far","x":159,"y":256,"stance":false},{"id":"hind-near","x":170,"y":261,"stance":false}]],[[{"id":"hind-far","x":159,"y":256,"stance":false},{"id":"hind-near","x":170,"y":261,"stance":false}],[{"id":"hind-far","x":158,"y":257,"stance":false},{"id":"hind-near","x":169,"y":263,"stance":false}],[{"id":"hind-far","x":159,"y":262,"stance":false},{"id":"hind-near","x":168,"y":266,"stance":false}],[{"id":"hind-far","x":157,"y":266,"stance":false},{"id":"hind-near","x":168,"y":268,"stance":false}],[{"id":"hind-far","x":156,"y":271,"stance":false},{"id":"hind-near","x":170,"y":272,"stance":false}],[{"id":"hind-far","x":154,"y":276,"stance":false},{"id":"hind-near","x":171,"y":276,"stance":false}],[{"id":"hind-far","x":154,"y":277,"stance":false},{"id":"hind-near","x":172,"y":278,"stance":false}],[{"id":"hind-far","x":153,"y":280,"stance":false},{"id":"hind-near","x":172,"y":281,"stance":false}],[{"id":"hind-far","x":153,"y":283,"stance":false},{"id":"hind-near","x":172,"y":283,"stance":false}]],[[{"id":"hind-far","x":153,"y":283,"stance":false},{"id":"hind-near","x":172,"y":283,"stance":false}],[{"id":"hind-far","x":153,"y":282,"stance":false},{"id":"hind-near","x":172,"y":283,"stance":false}],[{"id":"hind-far","x":154,"y":283,"stance":false},{"id":"hind-near","x":170,"y":284,"stance":false}],[{"id":"hind-far","x":155,"y":283,"stance":false},{"id":"hind-near","x":172,"y":283,"stance":false}],[{"id":"hind-far","x":157,"y":282,"stance":false},{"id":"hind-near","x":172,"y":283,"stance":false}],[{"id":"hind-far","x":131,"y":282,"stance":false},{"id":"hind-near","x":176,"y":283,"stance":false}],[{"id":"hind-far","x":135,"y":289,"stance":false},{"id":"hind-near","x":175,"y":283,"stance":false}],[{"id":"hind-far","x":132,"y":295,"stance":false},{"id":"hind-near","x":175,"y":283,"stance":false}],[{"id":"hind-far","x":131,"y":299,"stance":false},{"id":"hind-near","x":176,"y":284,"stance":false}]],[[{"id":"hind-far","x":131,"y":299,"stance":false},{"id":"hind-near","x":176,"y":284,"stance":false}],[{"id":"hind-far","x":133,"y":297,"stance":false},{"id":"hind-near","x":176,"y":286,"stance":false}],[{"id":"hind-far","x":131,"y":295,"stance":false},{"id":"hind-near","x":175,"y":288,"stance":false}],[{"id":"hind-far","x":130,"y":293,"stance":false},{"id":"hind-near","x":175,"y":289,"stance":false}],[{"id":"hind-far","x":130,"y":290,"stance":false},{"id":"hind-near","x":174,"y":290,"stance":false}],[{"id":"hind-far","x":158,"y":292,"stance":false},{"id":"hind-near","x":173,"y":293,"stance":false}],[{"id":"hind-far","x":158,"y":295,"stance":false},{"id":"hind-near","x":174,"y":296,"stance":false}],[{"id":"hind-far","x":157,"y":297,"stance":false},{"id":"hind-near","x":175,"y":298,"stance":false}],[{"id":"hind-far","x":157,"y":298,"stance":false},{"id":"hind-near","x":176,"y":300,"stance":false}]],[[{"id":"hind-far","x":157,"y":298,"stance":false},{"id":"hind-near","x":176,"y":300,"stance":false}],[{"id":"hind-far","x":158,"y":298,"stance":false},{"id":"hind-near","x":178,"y":299,"stance":false}],[{"id":"hind-far","x":159,"y":298,"stance":false},{"id":"hind-near","x":178,"y":299,"stance":false}],[{"id":"hind-far","x":159,"y":297,"stance":false},{"id":"hind-near","x":179,"y":299,"stance":false}],[{"id":"hind-far","x":128,"y":290,"stance":false},{"id":"hind-near","x":180,"y":299,"stance":false}],[{"id":"hind-far","x":128,"y":293,"stance":false},{"id":"hind-near","x":181,"y":299,"stance":false}],[{"id":"hind-far","x":126,"y":295,"stance":false},{"id":"hind-near","x":183,"y":298,"stance":false}],[{"id":"hind-far","x":126,"y":297,"stance":false},{"id":"hind-near","x":184,"y":298,"stance":false}],[{"id":"hind-far","x":125,"y":299,"stance":false},{"id":"hind-near","x":186,"y":298,"stance":false}]],[[{"id":"hind-far","x":125,"y":299,"stance":false},{"id":"hind-near","x":186,"y":298,"stance":false}],[{"id":"hind-far","x":125,"y":299,"stance":false},{"id":"hind-near","x":186,"y":298,"stance":false}],[{"id":"hind-far","x":125,"y":299,"stance":false},{"id":"hind-near","x":186,"y":298,"stance":false}],[{"id":"hind-far","x":126,"y":299,"stance":false},{"id":"hind-near","x":186,"y":298,"stance":false}],[{"id":"hind-far","x":126,"y":299,"stance":true},{"id":"hind-near","x":186,"y":299,"stance":false}],[{"id":"hind-far","x":126,"y":299,"stance":true},{"id":"hind-near","x":187,"y":299,"stance":false}],[{"id":"hind-far","x":127,"y":299,"stance":true},{"id":"hind-near","x":187,"y":299,"stance":true}],[{"id":"hind-far","x":127,"y":299,"stance":true},{"id":"hind-near","x":188,"y":299,"stance":true}],[{"id":"hind-far","x":127,"y":299,"stance":true},{"id":"hind-near","x":188,"y":299,"stance":true}]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]],[[],[],[],[],[],[],[],[],[]]],"method":"reference-preserving rear bounding keys; fixed isotropic clip scale; authored hind support/swing schedule; exact old side endpoints","sourceHashes":{"puppy-rear-gallop8-sheet.png":"900d5d4dcba32a749d96cba673f25c829fb77076a7d821fce8215f82c506b8d8","puppy-paper-rear.bin.gz":"19c86a6c8cf0114cdf22f766c55c568573d5345e0b754eac438803407ee078bc","puppy-paper-rear.json":"427fdfb7c5ee3492750f6d44b88d941e19178eaf851ec41a3b1860a196072121","prepare-paper-rear-gallop.py":"2b806247934954b9dbc5003e8c77dc417d0a290d8666d41d534012b3d1947e71"}}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"width": 320,
|
|
3
|
+
"height": 320,
|
|
4
|
+
"pairs": 3,
|
|
5
|
+
"samples": 17,
|
|
6
|
+
"bytes": 5222400,
|
|
7
|
+
"sha256": "613dbeeeaec11804e80db0216922c8f62294745514ee6283bdce61a6d784dd5e",
|
|
8
|
+
"sourceHashes": {
|
|
9
|
+
"puppy-paper-approach.bin.gz": "21f4015cf899f6b1b6602a8939bbe0eaa76c66cb466c6aabd77249d215ce8d7f",
|
|
10
|
+
"puppy-sitting-tweens.bin.gz": "5680d046726a1f296d02fefb713fe7f984b480d6a77e44fd4e2da5635a9d0fa9",
|
|
11
|
+
"preparer": "baf88cc94f684f097ec3bbab3bce676d3229c0e336f39ebde36e42d9940e9b02"
|
|
12
|
+
},
|
|
13
|
+
"method": "Existing approach run0 -> existing frontal standing -> reversed original sit preparation; pinned offline RIFE v4.6"
|
|
14
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {grayFrameReader,isGrayFrameSource} from './puppy-frame-store.mjs';
|
|
2
|
+
// Exact cached samples; no live crossfade. Reverse the same path to stand up.
|
|
3
|
+
export function createPaperSeatSampler(bytes,info){
|
|
4
|
+
const stride=320*320;
|
|
5
|
+
if(!isGrayFrameSource(bytes)||info.width!==320||info.height!==320||info.pairs!==3||info.samples!==17||bytes.byteLength!==3*17*stride)throw Error('Invalid paper sitting cache');
|
|
6
|
+
const frames=grayFrameReader(bytes,320,320,3*17),out=new Uint8ClampedArray(stride*4);for(let i=3;i<out.length;i+=4)out[i]=255;
|
|
7
|
+
return progress=>{
|
|
8
|
+
if(!Number.isFinite(progress)||progress<0||progress>1)throw Error('Invalid paper sitting progress');
|
|
9
|
+
const q=progress*3,pair=Math.min(2,Math.floor(q)),sample=Math.round((q-pair)*16),frame=frames.getFrame(pair*17+sample);
|
|
10
|
+
for(let i=0,j=0;i<stride;i++,j+=4)out[j]=out[j+1]=out[j+2]=frame[i];
|
|
11
|
+
return out;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {validatePaperActionInfo} from './puppy-paper-actions.mjs';
|
|
2
|
+
|
|
3
|
+
// Art-directed "snappy" trick timing (a staging choice, not measured animal
|
|
4
|
+
// behaviour): short windup, fast active rotation, brief settle. Pure helper that
|
|
5
|
+
// maps action age (s) to the clip progress paperActionPose already consumes.
|
|
6
|
+
// Phase boundaries sit exactly on v5 weighted edge boundaries, located by key
|
|
7
|
+
// name: windup ends after the first edge arriving at `enter`; settle starts at
|
|
8
|
+
// the last edge leaving `exit`. seconds = [windup, active, settle].
|
|
9
|
+
export const SNAPPY_TRICK_PROFILES=Object.freeze({
|
|
10
|
+
spin:Object.freeze({enter:'spin0',exit:'spin15',seconds:Object.freeze([.1,.72,.14])}),
|
|
11
|
+
roll:Object.freeze({enter:'bridge6',exit:'bridge6',seconds:Object.freeze([.56,.86,.62])}),
|
|
12
|
+
'roll-down':Object.freeze({enter:'bridge6',exit:'bridge6',seconds:Object.freeze([.32,.86,.62])}),
|
|
13
|
+
});
|
|
14
|
+
export const TRICK_PHASES=Object.freeze(['windup','active','settle']);
|
|
15
|
+
const fail=m=>{throw Error(`Invalid trick timing: ${m}`);};
|
|
16
|
+
|
|
17
|
+
// Clip edges as key names plus cumulative weighted progress at every edge boundary.
|
|
18
|
+
export function trickClipEdges(name,info){
|
|
19
|
+
validatePaperActionInfo(info);
|
|
20
|
+
const list=info.clips[name],weights=info.weights?.[name]??list.map(()=>1),{keyOrder,edges}=info;
|
|
21
|
+
if(!Array.isArray(keyOrder)||!Array.isArray(edges)||edges.length<info.pairs)fail('missing keyOrder/edges');
|
|
22
|
+
const keys=list.map(p=>{const e=edges[p];if(!Array.isArray(e)||e.length!==2||!e.every(k=>Number.isInteger(k)&&typeof keyOrder[k]==='string'))fail(`edge ${p}`);return[keyOrder[e[0]],keyOrder[e[1]]];});
|
|
23
|
+
for(let i=1;i<keys.length;i++)if(edges[list[i-1]][1]!==edges[list[i]][0])fail(`${name} chain breaks at edge ${i}`);
|
|
24
|
+
const total=weights.reduce((a,b)=>a+b,0),bounds=[0];let sum=0;
|
|
25
|
+
for(let i=0;i<weights.length-1;i++){sum+=weights[i];bounds.push(sum/total);}bounds.push(1);
|
|
26
|
+
return{list,keys,bounds};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createTrickTiming(name,info,profile=SNAPPY_TRICK_PROFILES[name]){
|
|
30
|
+
if(!profile||typeof profile.enter!=='string'||typeof profile.exit!=='string')fail(`profile for ${name}`);
|
|
31
|
+
const s=profile.seconds;if(!Array.isArray(s)||s.length!==3||!s.every(v=>typeof v==='number'&&Number.isFinite(v)&&v>0))fail('seconds');
|
|
32
|
+
const {list,keys,bounds}=trickClipEdges(name,info);
|
|
33
|
+
const first=keys.findIndex(k=>k[1]===profile.enter),last=keys.findLastIndex(k=>k[0]===profile.exit);
|
|
34
|
+
if(first<0)fail(`no edge arrives at ${profile.enter}`);if(last<0)fail(`no edge leaves ${profile.exit}`);
|
|
35
|
+
// Edge index ranges [from,to] per phase; every phase owns at least one edge.
|
|
36
|
+
const ranges=[[0,first],[first+1,last-1],[last,list.length-1]];
|
|
37
|
+
if(!ranges.every(([a,b])=>a<=b))fail(`${name} phases need at least one edge each`);
|
|
38
|
+
const T=[0,s[0],s[0]+s[1],s[0]+s[1]+s[2]],P=[0,bounds[first+1],bounds[last],1];
|
|
39
|
+
// Monotone cubic Hermite (Fritsch-Butland): zero speed at both ends, harmonic
|
|
40
|
+
// mean of adjacent secants inside, so progress is C1 across phase boundaries.
|
|
41
|
+
const d=[0,1,2].map(i=>(P[i+1]-P[i])/(T[i+1]-T[i])),m=[0,2*d[0]*d[1]/(d[0]+d[1]),2*d[1]*d[2]/(d[1]+d[2]),0];
|
|
42
|
+
const duration=T[3];
|
|
43
|
+
const progressAt=age=>{
|
|
44
|
+
if(typeof age!=='number'||!Number.isFinite(age))fail('age');
|
|
45
|
+
if(age<=0)return 0;if(age>=duration)return 1;
|
|
46
|
+
const i=age<T[1]?0:age<T[2]?1:2,h=T[i+1]-T[i],u=(age-T[i])/h,u2=u*u,u3=u2*u;
|
|
47
|
+
const p=(2*u3-3*u2+1)*P[i]+(u3-2*u2+u)*h*m[i]+(-2*u3+3*u2)*P[i+1]+(u3-u2)*h*m[i+1];
|
|
48
|
+
return Math.max(P[i],Math.min(P[i+1],p));
|
|
49
|
+
};
|
|
50
|
+
const phases=Object.freeze(TRICK_PHASES.map((phase,i)=>Object.freeze({phase,start:T[i],end:T[i+1],progressStart:P[i],progressEnd:P[i+1],
|
|
51
|
+
firstEdge:ranges[i][0],lastEdge:ranges[i][1],fromKey:keys[ranges[i][0]][0],toKey:keys[ranges[i][1]][1]})));
|
|
52
|
+
return Object.freeze({name,duration,phases,progressAt});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Timings for every profiled clip present in this action cache (e.g. v5 info).
|
|
56
|
+
export function createSnappyTrickTimings(info,profiles=SNAPPY_TRICK_PROFILES){
|
|
57
|
+
return Object.freeze(Object.fromEntries(Object.keys(profiles).filter(n=>Object.prototype.hasOwnProperty.call(info?.clips??{},n)).map(n=>[n,createTrickTiming(n,info,profiles[n])])));
|
|
58
|
+
}
|