Runtime assets
Models, textures and animations prepared for use in a scene or application.
88,694 bytes (0.09 MB)
Download runtime assetsFirst-person derivative of The Caretaker, with a shared 47-joint rig, articulated opposing-thumb grips, left-hand flashlight carry and camera-framed reload.
Cabin in the Woods: PSX Horror pack
Drag to orbit after opening. The model starts stationary.
For your engine. The download is a standard glTF 2.0 binary (GLB) with PBR metallic-roughness materials. glTF stores materials, not lighting or tone mapping, so your engine decides how they read. This 3D view tone-maps with Review Neutral, the Khronos PBR Neutral construction with a smaller glare offset (0.015 instead of 0.04), at exposure 0.9. Its Tone mapping control also shows ACES and Linear, for comparison.
Models, textures and animations prepared for use in a scene or application.
88,694 bytes (0.09 MB)
Download runtime assetsModels plus Kiln source, editing metadata, materials and included revisions, so you can reopen and continue editing.
187,076 bytes (0.19 MB)
Download full kiln assets (remixable)Runtime includes the GLB and metadata sidecar. The editable ZIP contains this selected revision and its complete material closure. Parent revision identifiers are retained; earlier authoring history is deliberately not distributed in this initial pack.
Import this ZIP into Kiln’s Library, or run node kiln.mjs import asset.zip in an authoring workspace. The full model, exact source, editing metadata, preview and material resources are included so you can reopen and remix it.
Use an importing Kiln build that supports the included material schemas. Use Kiln 1.2.3 or later.
Native clips: Idle, Walk, AxeHold, AxeUse, GripAim, ShotgunFire, Reload, WalkAxe, WalkShotgun, FlashlightHold.
const meta={name:'Caretaker First-Person Arms',description:'First-person arms derived from The Caretaker full body, sharing its olive workwear, articulated hands and 47-joint rig. Includes left-hand flashlight carry, axe and shotgun grips, and a camera-framed reload. The full body remains the canonical character representation.'};
const MODE='fps-arms';
const FINGER_LENGTHS=[[.032,.024,.017],[.034,.027,.018],[.032,.025,.017],[.027,.020,.014]];
const gripDatum=weapon=>weapon==='axe'?[.061,-.095,0]:weapon==='shotgun'?[.078,-.095,0]:weapon==='flashlight'?[.061,-.095,0]:[.090,-.095,0];
function graspFrame(side,weapon){const axis=(x,y,z,a)=>new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(x,y,z),a*Math.PI/180);return weapon==='flashlight'?axis(1,0,0,270).multiply(axis(0,1,0,side*90)):weapon==='reload'?axis(1,0,0,-40).multiply(axis(0,1,0,-90)):weapon==='shotgun'?axis(0,0,1,25).multiply(axis(0,1,0,side*90)):weapon==='axe'?axis(0,1,0,20).multiply(axis(0,1,0,side*90)).multiply(axis(1,0,0,-side*90)):axis(1,0,0,side*(weapon==='reload'?(MODE==='fps-arms'?20:40):45)).multiply(axis(0,1,0,side*90));}
// Three-dimensional tangent wrapping around the actual tool section; bone rest axes remain explicit.
const HANDLE_CONTACT_PROFILES={"axe":{"fingers":[[[-0.0081689,-0.0224438],[-0.011574,-0.0186765],[-0.0171594,-0.012608],[-0.0169449,-0.006583],[-0.0166645,0.0030577],[-0.012956,0.007811],[-0.0069739,0.0153764],[-0.0019439,0.0160736],[0.0062356,0.0171321],[0.0096407,0.0133647],[0.0152261,0.0072962],[0.0150116,0.0012712],[0.0147312,-0.0083694],[0.0110227,-0.0131227],[0.0050406,-0.0206881],[0.0000106,-0.0213853]],[[-0.0079313,-0.021791],[-0.0124545,-0.0167866],[-0.0170409,-0.0118035],[-0.016756,-0.0038002],[-0.0165257,0.0041161],[-0.0115995,0.0104302],[-0.0066874,0.0166425],[-0.0000057,0.0175686],[0.0067108,0.0184378],[0.011234,0.0134334],[0.0158204,0.0084503],[0.0155355,0.000447],[0.0153052,-0.0074694],[0.010379,-0.0137834],[0.0054669,-0.0199957],[-0.0012148,-0.0209218]],[[-0.0076937,-0.0211381],[-0.013335,-0.0148967],[-0.0169224,-0.0109991],[-0.016567,-0.0010174],[-0.0163869,0.0051746],[-0.010243,0.0130495],[-0.0064008,0.0179086],[0.0019326,0.0190636],[0.007186,0.0197434],[0.0128273,0.013502],[0.0164147,0.0096044],[0.0160594,-0.0003773],[0.0158792,-0.0065693],[0.0097353,-0.0144442],[0.0058932,-0.0193033],[-0.0024402,-0.0204583]],[[-0.007456,-0.0204853],[-0.0142154,-0.0130069],[-0.0168038,-0.0101946],[-0.016378,0.0017654],[-0.016248,0.0062331],[-0.0088865,0.0156687],[-0.0061143,0.0191746],[0.0038708,0.0205586],[0.0076613,0.0210491],[0.0144207,0.0135707],[0.017009,0.0107584],[0.0165832,-0.0012016],[0.0164533,-0.0056692],[0.0090917,-0.0151049],[0.0063195,-0.0186108],[-0.0036656,-0.0199948]]],"thumb":[[-0.0079745,-0.0219097],[-0.0122944,-0.0171302],[-0.0170624,-0.0119498],[-0.0167903,-0.0043061],[-0.0165509,0.0039237],[-0.0118461,0.009954],[-0.0067395,0.0164123],[-0.0003581,0.0172968],[0.0066244,0.0182004],[0.0109443,0.0134209],[0.0157124,0.0082405],[0.0154402,0.0005968],[0.0152008,-0.007633],[0.010496,-0.0136633],[0.0053894,-0.0201216],[-0.000992,-0.0210061],[-0.0080825,-0.0222064],[-0.0118942,-0.0179893],[-0.0171163,-0.0123155],[-0.0168762,-0.0055711],[-0.016614,0.0034426],[-0.0124627,0.0087634],[-0.0068697,0.0158368],[-0.0012391,0.0166172],[0.0064084,0.0176069],[0.0102201,0.0133897],[0.0154422,0.0077159],[0.0152021,0.0009715],[0.0149399,-0.0080421],[0.0107886,-0.013363],[0.0051956,-0.0204363],[-0.000435,-0.0212168],[-0.0081905,-0.0225032],[-0.011494,-0.0188483],[-0.0171702,-0.0126811],[-0.0169621,-0.006836],[-0.0166771,0.0029614],[-0.0130793,0.0075728],[-0.007,0.0152613],[-0.0021201,0.0159377],[0.0061924,0.0170134],[0.0094958,0.0133585],[0.0151721,0.0071913],[0.014964,0.0013462],[0.014679,-0.0084512],[0.0110812,-0.0130626],[0.0050019,-0.0207511],[0.000122,-0.0214275],[-0.0082769,-0.0227406],[-0.0111738,-0.0195355],[-0.0172133,-0.0129736],[-0.0170308,-0.0078479],[-0.0167276,0.0025765],[-0.0135726,0.0066204],[-0.0071042,0.0148009],[-0.0028249,0.015394],[0.0060196,0.0165386],[0.0089164,0.0133335],[0.014956,0.0067717],[0.0147735,0.0016459],[0.0144702,-0.0087785],[0.0113153,-0.0128224],[0.0048469,-0.0210029],[0.0005676,-0.021596]]},"shotgun":{"fingers":[[[-0.0057456,0.0206232],[0,0.0237464],[-0.0199795,0.0130609],[-0.0219409,0.0076303],[-0.0304346,-0.0153882],[-0.0301858,-0.016575],[-0.028842,-0.0227686],[0.0304346,-0.0153882],[0.028842,-0.0227686],[0.0297998,-0.0136386],[0.0199795,0.0130609],[0.0147011,0.015924],[-0.0052098,-0.0227686],[0,-0.0227686],[0.0052098,-0.0227686],[-0.0201504,-0.0129782],[-0.0027575,-0.0334083],[0,-0.0363547],[0.0201504,-0.0129782],[0,-0.0129782]],[[-0.0134509,0.0249441],[0,0.0322558],[-0.0165056,0.0233212],[-0.0219778,0.0081702],[-0.0251647,-0.0004663],[-0.0225971,-0.0127161],[-0.0192846,-0.0279829],[-0.0135577,-0.0318195],[0,-0.0406865],[0.0052227,-0.037197],[0.0192846,-0.0279829],[0.0219619,-0.0153088],[0.0251647,-0.0004663],[0.0186131,0.0175912],[0.0165056,0.0233212],[0.0017793,0.0313091],[-0.011043,0.0235938],[0,0.0295966],[-0.0175912,0.0201148],[-0.0219663,0.0080015],[-0.0268115,-0.0051294],[-0.0249686,-0.013922],[-0.0205404,-0.0343311],[-0.0175421,-0.0363397],[0,-0.0478127],[0.0017421,-0.0466487],[0.0205404,-0.0343311],[0.0219421,-0.0276956],[0.0268115,-0.0051294],[0.022109,0.0078319],[0.0175912,0.0201148],[0.0058173,0.0265012],[-0.008635,0.0222435],[0,0.0269374],[-0.0186768,0.0169085],[-0.0219548,0.0078328],[-0.0284584,-0.0097925],[-0.0273401,-0.0151279],[-0.0217962,-0.0406793],[-0.0215265,-0.0408599],[-0.0182996,-0.0429704],[0.0217962,-0.0406793],[0.0182996,-0.0429704],[0.0219223,-0.0400825],[0.0284584,-0.0097925],[0.0256048,-0.0019274],[0.0186768,0.0169085],[0.0098554,0.0216934],[0,-0.0429704]],[[-0.0017834,0.0344715],[0,0.035537],[-0.0156537,0.026935],[-0.0159227,0.0259605],[-0.0175597,0.0206435],[0.0156537,0.026935],[0.0175597,0.0206435],[0.0147836,0.0274519],[-0.0219917,0.0083727],[-0.0231885,0.0051294],[-0.0197513,-0.0112689],[-0.0177777,-0.0203651],[-0.0087764,-0.0263952],[0,-0.0321352],[0.0093994,-0.025855],[0.0177777,-0.0203651],[0.0219857,-0.0004445],[0.0231885,0.0051294]],[[-0.0069502,0.0374961],[0,0.0416484],[-0.0163116,0.0324095],[-0.018398,0.0248505],[-0.0226037,0.0111902],[-0.021261,0.0070428],[-0.0156767,-0.0086172],[-0.0147322,-0.0091318],[-0.0000965,-0.0163931],[0.0156767,-0.0086172],[0.0000965,-0.0163931],[0.0162027,-0.0070124],[0.0226037,0.0111902],[0.0209431,0.0171212],[0.0163116,0.0324095],[0.0095625,0.0364187],[-0.0000107,-0.0164506],[0,-0.0164576]]],"thumb":[[-0.0100798,0.0230537],[0,0.0285329],[-0.0180254,0.0188323],[-0.0219617,0.007934],[-0.0274703,-0.0069946],[-0.0259172,-0.0144044],[-0.0210427,-0.0368704],[-0.0191359,-0.0381478],[0,-0.0506631],[0.0003498,-0.0504294],[0.0210427,-0.0368704],[0.0219342,-0.0326504],[0.0274703,-0.0069946],[0.0235073,0.0039282],[0.0180254,0.0188323],[0.0074326,0.0245781],[-0.0076719,0.0217034],[0,0.0258738],[-0.019111,0.0156259],[-0.0219502,0.0077653],[-0.0291171,-0.0116577],[-0.0282886,-0.0156103],[-0.0238134,-0.0362365],[0.0291171,-0.0116577],[0.0238134,-0.0362365],[0.0270032,-0.0058311],[0.019111,0.0156259],[0.0114706,0.0197703],[-0.01735,-0.0362365],[0,-0.0362365],[0.01735,-0.0362365],[-0.004898,-0.0264461],[-0.0006703,-0.031412],[0,-0.0321282],[0.004898,-0.0264461],[0,-0.0264461],[-0.005264,0.0203532],[0,0.0232146],[-0.0201966,0.0124196],[-0.0219386,0.0075965],[-0.030764,-0.0163208],[-0.0306601,-0.0168162],[-0.0300992,-0.0194017],[0.030764,-0.0163208],[0.0300992,-0.0194017],[0.030499,-0.0155904],[0.0201966,0.0124196],[0.0155087,0.0149624],[-0.0021748,-0.0194017],[0,-0.0194017],[0.0021748,-0.0194017],[-0.0239636,-0.0096112],[-0.0032793,-0.0339074],[0,-0.0374113],[0.0239636,-0.0096112],[0,-0.0096112],[-0.0033376,0.0192729],[0,0.0210872],[-0.0210651,0.0098545],[-0.0219294,0.0074615],[-0.0268722,-0.0059338],[0.0210651,0.0098545],[0.0268722,-0.0059338],[0.0187391,0.0111162],[0,-0.0059338],[-0.0099654,-0.0059338],[0.0099654,-0.0059338],[-0.0347839,0.0038566],[-0.0366934,0.0015853],[-0.037,0.0012536],[-0.0053665,-0.0359037],[0,-0.0416379],[0.0365886,0.0008085],[0.037,0.0012536],[0.0347839,0.0038566],[0,0.0038566]]},"flashlight":{"fingers":[[[0.019,0],[0.013753,0.0126673],[0.013435,0.013435],[0.013435,-0.013435],[0.018682,-0.0007677],[0,-0.019],[0.0126673,-0.013753],[-0.013435,-0.013435],[-0.0007677,-0.018682],[-0.019,0],[-0.013753,-0.0126673],[-0.013435,0.013435],[-0.018682,0.0007677],[0,0.019],[-0.0126673,0.013753],[0.0007677,0.018682],[0.009051,0.0175362],[0.0098224,0.0167649],[0.0175362,0.009051],[0.0205061,0.0120208],[0.0127922,0.0197347],[0.0120208,0.0205061],[0.009321,0.0178062],[0.0178062,0.009321]],[[0.02,0],[0.0188136,0.0028642],[0.0141421,0.0141421],[0.0141421,-0.0141421],[0.0153285,-0.0112779],[0,-0.02],[0.0028642,-0.0188136],[-0.0141421,-0.0141421],[-0.0112779,-0.0153285],[-0.02,0],[-0.0188136,-0.0028642],[-0.0141421,0.0141421],[-0.0153285,0.0112779],[0,0.02],[-0.0028642,0.0188136],[0.0112779,0.0153285]],[[0.02,0],[0.0171823,0.0068025],[0.0141421,0.0141421],[0.0141421,-0.0141421],[0.0169598,-0.0073396],[0,-0.02],[0.0068025,-0.0171823],[-0.0141421,-0.0141421],[-0.0073396,-0.0169598],[-0.02,0],[-0.0171823,-0.0068025],[-0.0141421,0.0141421],[-0.0169598,0.0073396],[0,0.02],[-0.0068025,0.0171823],[0.0073396,0.0169598]],[[0.02,0],[0.015551,0.0107409],[0.0141421,0.0141421],[0.0141421,-0.0141421],[0.0185911,-0.0034013],[0,-0.02],[0.0107409,-0.015551],[-0.0141421,-0.0141421],[-0.0034013,-0.0185911],[-0.02,0],[-0.015551,-0.0107409],[-0.0141421,0.0141421],[-0.0185911,0.0034013],[0,0.02],[-0.0107409,0.015551],[0.0034013,0.0185911]]],"thumb":[[0.02,0],[0.0191102,0.0021482],[0.0141421,0.0141421],[0.0141421,-0.0141421],[0.0150319,-0.011994],[0,-0.02],[0.0021482,-0.0191102],[-0.0141421,-0.0141421],[-0.011994,-0.0150319],[-0.02,0],[-0.0191102,-0.0021482],[-0.0141421,0.0141421],[-0.0150319,0.011994],[0,0.02],[-0.0021482,0.0191102],[0.011994,0.0150319],[0.0198517,0.000358],[0.0142904,-0.0137841],[0.000358,-0.0198517],[-0.0137841,-0.0142904],[-0.0198517,-0.000358],[-0.0142904,0.0137841],[-0.000358,0.0198517],[0.0137841,0.0142904],[0.019,0],[0.014071,0.0118996],[0.013435,0.013435],[0.013435,-0.013435],[0.018364,-0.0015354],[0,-0.019],[0.0118996,-0.014071],[-0.013435,-0.013435],[-0.0015354,-0.018364],[-0.019,0],[-0.014071,-0.0118996],[-0.013435,0.013435],[-0.018364,0.0015354],[0,0.019],[-0.0118996,0.014071],[0.0015354,0.018364],[0.009051,0.0175362],[0.0105937,0.0159935],[0.0175362,0.009051],[0.0205061,0.0120208],[0.0135636,0.0189633],[0.0120208,0.0205061],[0.0095909,0.0180762],[0.0180762,0.0095909],[0.015343,0.0088287],[0.017092,-0.0046063],[0.0088287,-0.015343],[-0.0046063,-0.017092],[-0.015343,-0.0088287],[-0.017092,0.0046063],[-0.0088287,0.015343],[0.0046063,0.017092],[0.0136793,0.0129079],[0.0166492,0.0158778],[0.0106709,0.0191562],[0.0191562,0.0106709],[0.0130815,0.0194454],[0.0169978,0.0155292],[0.0194454,0.0130815],[0.0210718,0.0147078],[0.0186241,0.0171555],[0.0147078,0.0210718],[0.0140823,0.0204463],[0.0204463,0.0140823]]},"reload":{"fingers":[[[0.0260008,0.0143645],[0.0216889,0.0216889],[0.0364,-0.0057273],[0.0351736,-0.0117736],[0.0297885,-0.0297885],[0.0237421,-0.0310149],[0.0057273,-0.0364],[-0.0015971,-0.032088],[-0.0216889,-0.0216889],[-0.0260008,-0.0143645],[-0.0364,0.0057273],[-0.0351736,0.0117736],[-0.0297885,0.0297885],[-0.0237421,0.0310149],[-0.0057273,0.0364],[0.0015971,0.032088]],[[0.0278339,0.0081976],[0.0205575,0.0205575],[0.0353,-0.0062273],[0.0332305,-0.0164305],[0.0293642,-0.0293642],[0.019161,-0.0314338],[0.0062273,-0.0353],[-0.0061327,-0.0280236],[-0.0205575,-0.0205575],[-0.0278339,-0.0081976],[-0.0353,0.0062273],[-0.0332305,0.0164305],[-0.0293642,0.0293642],[-0.019161,0.0314338],[-0.0062273,0.0353],[0.0061327,0.0280236]],[[0.029667,0.0020307],[0.0194262,0.0194262],[0.0342,-0.0067273],[0.0312873,-0.0210873],[0.02894,-0.02894],[0.0145799,-0.0318526],[0.0067273,-0.0342],[-0.0106682,-0.0239591],[-0.0194262,-0.0194262],[-0.029667,-0.0020307],[-0.0342,0.0067273],[-0.0312873,0.0210873],[-0.02894,0.02894],[-0.0145799,0.0318526],[-0.0067273,0.0342],[0.0106682,0.0239591]],[[0.0315001,-0.0041362],[0.0182948,0.0182948],[0.0331,-0.0072273],[0.0293442,-0.0257442],[0.0285157,-0.0285157],[0.0099988,-0.0322715],[0.0072273,-0.0331],[-0.0152037,-0.0198947],[-0.0182948,-0.0182948],[-0.0315001,0.0041362],[-0.0331,0.0072273],[-0.0293442,0.0257442],[-0.0285157,0.0285157],[-0.0099988,0.0322715],[-0.0072273,0.0331],[0.0152037,0.0198947]]],"thumb":[[0.0275006,0.0093188],[0.0207632,0.0207632],[0.0355,-0.0061364],[0.0335838,-0.0155838],[0.0294414,-0.0294414],[0.019994,-0.0313576],[0.0061364,-0.0355],[-0.005308,-0.0287626],[-0.0207632,-0.0207632],[-0.0275006,-0.0093188],[-0.0355,0.0061364],[-0.0335838,0.0155838],[-0.0294414,0.0294414],[-0.019994,0.0313576],[-0.0061364,0.0355],[0.005308,0.0287626],[0.0266674,0.012122],[0.0212775,0.0212775],[0.036,-0.0059091],[0.034467,-0.013467],[0.0296342,-0.0296342],[0.0220763,-0.0311672],[0.0059091,-0.036],[-0.0032464,-0.0306101],[-0.0212775,-0.0212775],[-0.0266674,-0.012122],[-0.036,0.0059091],[-0.034467,0.013467],[-0.0296342,0.0296342],[-0.0220763,0.0311672],[-0.0059091,0.036],[0.0032464,0.0306101],[0.0258342,0.0149251],[0.0217917,0.0217917],[0.0365,-0.0056818],[0.0353503,-0.0113503],[0.0298271,-0.0298271],[0.0241586,-0.0309768],[0.0056818,-0.0365],[-0.0011848,-0.0324575],[-0.0217917,-0.0217917],[-0.0258342,-0.0149251],[-0.0365,0.0056818],[-0.0353503,0.0113503],[-0.0298271,0.0298271],[-0.0241586,0.0309768],[-0.0056818,0.0365],[0.0011848,0.0324575],[0.0251676,0.0171676],[0.0222032,0.0222032],[0.0369,-0.0055],[0.0360569,-0.0096569],[0.0299813,-0.0299813],[0.0258245,-0.0308245],[0.0055,-0.0369],[0.0004645,-0.0339355],[-0.0222032,-0.0222032],[-0.0251676,-0.0171676],[-0.0369,0.0055],[-0.0360569,0.0096569],[-0.0299813,0.0299813],[-0.0258245,0.0308245],[-0.0055,0.0369],[-0.0004645,0.0339355]]},"reloadBody":{"fingers":[[[0.02465,0.0165759],[0.019716,0.0234967],[0.0367607,-0.002533],[0.0360659,-0.0086632],[0.0322714,-0.0270789],[0.0263549,-0.0288276],[0.0088779,-0.0357623],[0.0012056,-0.0321051],[-0.019716,-0.0234967],[-0.02465,-0.0165759],[-0.0367607,0.002533],[-0.0360659,0.0086632],[-0.0322714,0.0270789],[-0.0263549,0.0288276],[-0.0088779,0.0357623],[-0.0012056,0.0321051],[0.0246543,0.0436427],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0201274,0.0419136],[0.0207442,0.0409265],[0.0250945,0.0349687],[0.0249706,0.0331965],[0.0204159,0.0362306],[0.0203347,0.0350695],[0.0203522,0.0276925],[0.0192103,0.0263315],[0.0173088,0.0314634],[0.0165607,0.0305718],[0.0122388,0.0245934],[0.010515,0.0241636],[0.0119931,0.029433],[0.0108637,0.0291514],[0.0038532,0.0268551],[0.002206,0.0275206],[0.0064992,0.0309148],[0.0054199,0.0313508],[-0.0016014,0.0336138],[-0.0025429,0.0351204],[0.0029254,0.0353429],[0.0023086,0.03633],[-0.0020417,0.0422878],[-0.0019177,0.04406],[0.002637,0.0410259],[0.0027182,0.042187],[0.0027006,0.049564],[0.0038426,0.0509249],[0.005744,0.0457931],[0.0064922,0.0466847],[0.0108141,0.0526631],[0.0125379,0.0530929],[0.0110597,0.0478235],[0.0121891,0.0481051],[0.0191996,0.0504014],[0.0165537,0.0463417],[0.0491677,0.0230735],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0446409,0.0213444],[0.0452577,0.0203573],[0.0496079,0.0143995],[0.049484,0.0126272],[0.0449293,0.0156614],[0.0448481,0.0145003],[0.0448656,0.0071233],[0.0437237,0.0057623],[0.0418223,0.0108942],[0.0410741,0.0100026],[0.0367522,0.0040242],[0.0350284,0.0035944],[0.0365066,0.0088638],[0.0353772,0.0085822],[0.0283666,0.0062859],[0.0267194,0.0069514],[0.0310126,0.0103456],[0.0299334,0.0107816],[0.022912,0.0130446],[0.0219706,0.0145512],[0.0274388,0.0147737],[0.026822,0.0157608],[0.0224718,0.0217186],[0.0225957,0.0234908],[0.0271504,0.0204567],[0.0272316,0.0216178],[0.0272141,0.0289948],[0.028356,0.0303557],[0.0302574,0.0252239],[0.0310056,0.0261155],[0.0353275,0.0320939],[0.0370513,0.0325237],[0.0355731,0.0272543],[0.0367025,0.0275359],[0.0437131,0.0298322],[0.0410671,0.0257725],[0.0393312,0.0381337],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0344799,0.0389409],[0.0331036,0.0394513],[0.0300899,0.0445991],[0.0293482,0.0458659],[0.0349412,0.0437919]],[[0.0270136,0.0105923],[0.0186876,0.022271],[0.0357084,-0.003127],[0.034536,-0.0134717],[0.0318117,-0.0266932],[0.0218277,-0.0296441],[0.0092802,-0.0346229],[-0.0036669,-0.0284514],[-0.0186876,-0.022271],[-0.0270136,-0.0105923],[-0.0357084,0.003127],[-0.034536,0.0134717],[-0.0318117,0.0266932],[-0.0218277,0.0296441],[-0.0092802,0.0346229],[0.0036669,0.0284514],[0.0248376,0.0433494],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0202475,0.0417214],[0.0207442,0.0409265],[0.0250704,0.0346237],[0.0249706,0.0331965],[0.0204001,0.0360046],[0.0203347,0.0350695],[0.0201299,0.0274275],[0.0192103,0.0263315],[0.0171632,0.0312898],[0.0165607,0.0305718],[0.0119032,0.0245097],[0.010515,0.0241636],[0.0117733,0.0293782],[0.0108637,0.0291514],[0.0035325,0.0269847],[0.002206,0.0275206],[0.006289,0.0309997],[0.0054199,0.0313508],[-0.0017847,0.0339071],[-0.0025429,0.0351204],[0.0028053,0.0355351],[0.0023086,0.03633],[-0.0020175,0.0426328],[-0.0019177,0.04406],[0.0026528,0.0412519],[0.0027182,0.042187],[0.002923,0.049829],[0.0038426,0.0509249],[0.0058897,0.0459667],[0.0064922,0.0466847],[0.0111497,0.0527468],[0.0125379,0.0530929],[0.0112796,0.0478783],[0.0121891,0.0481051],[0.0195203,0.0502718],[0.0167638,0.0462568],[0.049351,0.0227802],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0447609,0.0211522],[0.0452577,0.0203573],[0.0495838,0.0140545],[0.049484,0.0126272],[0.0449135,0.0154353],[0.0448481,0.0145003],[0.0446433,0.0068583],[0.0437237,0.0057623],[0.0416766,0.0107206],[0.0410741,0.0100026],[0.0364166,0.0039405],[0.0350284,0.0035944],[0.0362867,0.0088089],[0.0353772,0.0085822],[0.0280459,0.0064154],[0.0267194,0.0069514],[0.0308025,0.0104305],[0.0299334,0.0107816],[0.0227287,0.0133379],[0.0219706,0.0145512],[0.0273188,0.0149659],[0.026822,0.0157608],[0.0224959,0.0220636],[0.0225957,0.0234908],[0.0271662,0.0206827],[0.0272316,0.0216178],[0.0274364,0.0292598],[0.028356,0.0303557],[0.0304031,0.0253974],[0.0310056,0.0261155],[0.0356631,0.0321776],[0.0370513,0.0325237],[0.035793,0.0273091],[0.0367025,0.0275359],[0.0440338,0.0297026],[0.0412772,0.0256876],[0.0394795,0.0378803],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0342046,0.039043],[0.0331036,0.0394513],[0.0299415,0.0448525],[0.0293482,0.0458659],[0.0352164,0.0436898]],[[0.0293772,0.0046086],[0.0176591,0.0210453],[0.0346562,-0.0037209],[0.0330061,-0.0182802],[0.0313521,-0.0263075],[0.0173006,-0.0304607],[0.0096824,-0.0334835],[-0.0085394,-0.0247977],[-0.0176591,-0.0210453],[-0.0293772,-0.0046086],[-0.0346562,0.0037209],[-0.0330061,0.0182802],[-0.0313521,0.0263075],[-0.0173006,0.0304607],[-0.0096824,0.0334835],[0.0085394,0.0247977],[0.0250209,0.0430561],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0203676,0.0415292],[0.0207442,0.0409265],[0.0250463,0.0342786],[0.0249706,0.0331965],[0.0203843,0.0357785],[0.0203347,0.0350695],[0.0199076,0.0271626],[0.0192103,0.0263315],[0.0170175,0.0311162],[0.0165607,0.0305718],[0.0115675,0.024426],[0.010515,0.0241636],[0.0115534,0.0293233],[0.0108637,0.0291514],[0.0032118,0.0271142],[0.002206,0.0275206],[0.0060789,0.0310846],[0.0054199,0.0313508],[-0.001968,0.0342004],[-0.0025429,0.0351204],[0.0026853,0.0357272],[0.0023086,0.03633],[-0.0019934,0.0429779],[-0.0019177,0.04406],[0.0026686,0.041478],[0.0027182,0.042187],[0.0031453,0.0500939],[0.0038426,0.0509249],[0.0060353,0.0461402],[0.0064922,0.0466847],[0.0114853,0.0528305],[0.0125379,0.0530929],[0.0114995,0.0479332],[0.0121891,0.0481051],[0.019841,0.0501423],[0.0169739,0.0461719],[0.0495343,0.0224869],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.044881,0.02096],[0.0452577,0.0203573],[0.0495597,0.0137094],[0.049484,0.0126272],[0.0448977,0.0152093],[0.0448481,0.0145003],[0.044421,0.0065934],[0.0437237,0.0057623],[0.0415309,0.010547],[0.0410741,0.0100026],[0.036081,0.0038568],[0.0350284,0.0035944],[0.0360668,0.0087541],[0.0353772,0.0085822],[0.0277253,0.006545],[0.0267194,0.0069514],[0.0305924,0.0105154],[0.0299334,0.0107816],[0.0225454,0.0136312],[0.0219706,0.0145512],[0.0271987,0.015158],[0.026822,0.0157608],[0.02252,0.0224087],[0.0225957,0.0234908],[0.027182,0.0209088],[0.0272316,0.0216178],[0.0276587,0.0295247],[0.028356,0.0303557],[0.0305488,0.025571],[0.0310056,0.0261155],[0.0359987,0.0322613],[0.0370513,0.0325237],[0.0360129,0.027364],[0.0367025,0.0275359],[0.0443545,0.0295731],[0.0414873,0.0256027],[0.0396279,0.037627],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0339294,0.0391451],[0.0331036,0.0394513],[0.0297932,0.0451058],[0.0293482,0.0458659],[0.0354917,0.0435877]],[[0.0317408,-0.0013751],[0.0166307,0.0198197],[0.0336039,-0.0043149],[0.0314763,-0.0230887],[0.0308925,-0.0259219],[0.0127734,-0.0312773],[0.0100846,-0.0323441],[-0.013412,-0.021144],[-0.0166307,-0.0198197],[-0.0317408,0.0013751],[-0.0336039,0.0043149],[-0.0314763,0.0230887],[-0.0308925,0.0259219],[-0.0127734,0.0312773],[-0.0100846,0.0323441],[0.013412,0.021144],[0.0252041,0.0427628],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0204877,0.0413371],[0.0207442,0.0409265],[0.0250221,0.0339336],[0.0249706,0.0331965],[0.0203684,0.0355524],[0.0203347,0.0350695],[0.0196852,0.0268976],[0.0192103,0.0263315],[0.0168719,0.0309427],[0.0165607,0.0305718],[0.0112319,0.0243423],[0.010515,0.0241636],[0.0113335,0.0292685],[0.0108637,0.0291514],[0.0028911,0.0272438],[0.002206,0.0275206],[0.0058688,0.0311695],[0.0054199,0.0313508],[-0.0021513,0.0344937],[-0.0025429,0.0351204],[0.0025652,0.0359194],[0.0023086,0.03633],[-0.0019693,0.0433229],[-0.0019177,0.04406],[0.0026844,0.0417041],[0.0027182,0.042187],[0.0033676,0.0503589],[0.0038426,0.0509249],[0.006181,0.0463138],[0.0064922,0.0466847],[0.0118209,0.0529142],[0.0125379,0.0530929],[0.0117194,0.047988],[0.0121891,0.0481051],[0.0201617,0.0500127],[0.017184,0.046087],[0.0497176,0.0221936],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0450011,0.0207679],[0.0452577,0.0203573],[0.0495356,0.0133644],[0.049484,0.0126272],[0.0448819,0.0149832],[0.0448481,0.0145003],[0.0441987,0.0063284],[0.0437237,0.0057623],[0.0413853,0.0103734],[0.0410741,0.0100026],[0.0357454,0.0037731],[0.0350284,0.0035944],[0.0358469,0.0086993],[0.0353772,0.0085822],[0.0274046,0.0066746],[0.0267194,0.0069514],[0.0303822,0.0106003],[0.0299334,0.0107816],[0.0223621,0.0139245],[0.0219706,0.0145512],[0.0270786,0.0153502],[0.026822,0.0157608],[0.0225441,0.0227537],[0.0225957,0.0234908],[0.0271978,0.0211349],[0.0272316,0.0216178],[0.027881,0.0297897],[0.028356,0.0303557],[0.0306944,0.0257446],[0.0310056,0.0261155],[0.0363343,0.032345],[0.0370513,0.0325237],[0.0362328,0.0274188],[0.0367025,0.0275359],[0.0446752,0.0294435],[0.0416975,0.0255178],[0.0397762,0.0373736],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0336541,0.0392471],[0.0331036,0.0394513],[0.0296449,0.0453592],[0.0293482,0.0458659],[0.035767,0.0434857]]],"thumb":[[0.0265838,0.0116802],[0.0188746,0.0224939],[0.0358997,-0.003019],[0.0348142,-0.0125974],[0.0318953,-0.0267633],[0.0226509,-0.0294957],[0.009207,-0.0348301],[-0.002781,-0.0291158],[-0.0188746,-0.0224939],[-0.0265838,-0.0116802],[-0.0358997,0.003019],[-0.0348142,0.0125974],[-0.0318953,0.0267633],[-0.0226509,0.0294957],[-0.009207,0.0348301],[0.002781,0.0291158],[0.0248042,0.0434027],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0202257,0.0417564],[0.0207442,0.0409265],[0.0250748,0.0346864],[0.0249706,0.0331965],[0.0204029,0.0360457],[0.0203347,0.0350695],[0.0201703,0.0274757],[0.0192103,0.0263315],[0.0171897,0.0313214],[0.0165607,0.0305718],[0.0119642,0.0245249],[0.010515,0.0241636],[0.0118132,0.0293881],[0.0108637,0.0291514],[0.0035908,0.0269611],[0.002206,0.0275206],[0.0063272,0.0309843],[0.0054199,0.0313508],[-0.0017514,0.0338537],[-0.0025429,0.0351204],[0.0028272,0.0355001],[0.0023086,0.03633],[-0.0020219,0.0425701],[-0.0019177,0.04406],[0.0026499,0.0412108],[0.0027182,0.042187],[0.0028825,0.0497808],[0.0038426,0.0509249],[0.0058632,0.0459351],[0.0064922,0.0466847],[0.0110887,0.0527316],[0.0125379,0.0530929],[0.0112396,0.0478684],[0.0121891,0.0481051],[0.019462,0.0502954],[0.0167256,0.0462722],[0.0493177,0.0228335],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0447391,0.0211872],[0.0452577,0.0203573],[0.0495882,0.0141172],[0.049484,0.0126272],[0.0449164,0.0154764],[0.0448481,0.0145003],[0.0446837,0.0069065],[0.0437237,0.0057623],[0.0417031,0.0107522],[0.0410741,0.0100026],[0.0364776,0.0039557],[0.0350284,0.0035944],[0.0363267,0.0088189],[0.0353772,0.0085822],[0.0281043,0.0063919],[0.0267194,0.0069514],[0.0308407,0.010415],[0.0299334,0.0107816],[0.022762,0.0132845],[0.0219706,0.0145512],[0.0273406,0.0149309],[0.026822,0.0157608],[0.0224915,0.0220009],[0.0225957,0.0234908],[0.0271633,0.0206416],[0.0272316,0.0216178],[0.027396,0.0292116],[0.028356,0.0303557],[0.0303766,0.0253659],[0.0310056,0.0261155],[0.0356021,0.0321624],[0.0370513,0.0325237],[0.0357531,0.0272992],[0.0367025,0.0275359],[0.0439754,0.0297262],[0.041239,0.025703],[0.0394526,0.0379264],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0342547,0.0390244],[0.0331036,0.0394513],[0.0299685,0.0448064],[0.0293482,0.0458659],[0.0351664,0.0437084],[0.0255094,0.0144001],[0.0193421,0.023051],[0.036378,-0.002749],[0.0355096,-0.0104118],[0.0321042,-0.0269386],[0.0247087,-0.0291245],[0.0090242,-0.035348],[-0.0005662,-0.0307765],[-0.0193421,-0.023051],[-0.0255094,-0.0144001],[-0.036378,0.002749],[-0.0355096,0.0104118],[-0.0321042,0.0269386],[-0.0247087,0.0291245],[-0.0090242,0.035348],[0.0005662,0.0307765],[0.0247209,0.0435361],[0.0201711,0.0418437],[0.0250858,0.0348432],[0.0204101,0.0361484],[0.0202714,0.0275961],[0.0172559,0.0314003],[0.0121167,0.0245629],[0.0119132,0.029413],[0.0037366,0.0269022],[0.0064228,0.0309457],[-0.0016681,0.0337204],[0.0028818,0.0354128],[-0.0020329,0.0424133],[0.0026427,0.0411081],[0.0027815,0.0496604],[0.005797,0.0458562],[0.0109361,0.0526936],[0.0111397,0.0478435],[0.0193163,0.0503543],[0.0166301,0.0463108],[0.0492343,0.0229669],[0.0446845,0.0212745],[0.0495992,0.014274],[0.0449235,0.0155792],[0.0447848,0.0070269],[0.0417693,0.0108311],[0.0366301,0.0039937],[0.0364266,0.0088438],[0.02825,0.006333],[0.0309362,0.0103765],[0.0228454,0.0131512],[0.0273952,0.0148436],[0.0224805,0.0218441],[0.0271562,0.0205389],[0.0272949,0.0290912],[0.0303104,0.025287],[0.0354496,0.0321244],[0.0356531,0.0272742],[0.0438297,0.0297851],[0.0411435,0.0257416],[0.0393852,0.0380416],[0.0343798,0.038978],[0.0300359,0.0446912],[0.0350413,0.0437548],[0.0244351,0.0171199],[0.0198095,0.0236081],[0.0368563,-0.002479],[0.036205,-0.0082261],[0.0323131,-0.027114],[0.0267665,-0.0287534],[0.0088414,-0.0358659],[0.0016486,-0.0324373],[-0.0198095,-0.0236081],[-0.0244351,-0.0171199],[-0.0368563,0.002479],[-0.036205,0.0082261],[-0.0323131,0.027114],[-0.0267665,0.0287534],[-0.0088414,0.0358659],[-0.0016486,0.0324373],[0.0246376,0.0436694],[0.0201165,0.0419311],[0.0250967,0.0350001],[0.0204173,0.0362512],[0.0203724,0.0277166],[0.0173221,0.0314792],[0.0122693,0.024601],[0.0120131,0.029438],[0.0038824,0.0268433],[0.0065183,0.0309071],[-0.0015848,0.0335871],[0.0029363,0.0353254],[-0.0020439,0.0422564],[0.0026356,0.0410053],[0.0026804,0.0495399],[0.0057308,0.0457773],[0.0107836,0.0526555],[0.0110397,0.0478185],[0.0191705,0.0504132],[0.0165346,0.0463494],[0.049151,0.0231002],[0.0446299,0.0213619],[0.0496101,0.0144309],[0.0449307,0.015682],[0.0448859,0.0071474],[0.0418355,0.01091],[0.0367827,0.0040318],[0.0365265,0.0088688],[0.0283958,0.0062741],[0.0310317,0.0103379],[0.0229287,0.0130179],[0.0274498,0.0147562],[0.0224696,0.0216872],[0.027149,0.0204361],[0.0271939,0.0289707],[0.0302442,0.0252081],[0.035297,0.0320863],[0.0355532,0.0272493],[0.0436839,0.029844],[0.041048,0.0257802],[0.0393177,0.0381567],[0.0345049,0.0389316],[0.0301033,0.0445761],[0.0349161,0.0438012],[0.0235756,0.0192958],[0.0201835,0.0240538],[0.0372389,-0.002263],[0.0367613,-0.0064775],[0.0324803,-0.0272542],[0.0284127,-0.0284564],[0.0086951,-0.0362802],[0.0034204,-0.0337659],[-0.0201835,-0.0240538],[-0.0235756,-0.0192958],[-0.0372389,0.002263],[-0.0367613,0.0064775],[-0.0324803,0.0272542],[-0.0284127,0.0284564],[-0.0086951,0.0362802],[-0.0034204,0.0337659],[0.024571,0.0437761],[0.0200728,0.042001],[0.0251055,0.0351255],[0.0204231,0.0363334],[0.0204533,0.0278129],[0.0173751,0.0315423],[0.0123913,0.0246314],[0.0120931,0.0294579],[0.003999,0.0267962],[0.0065947,0.0308762],[-0.0015181,0.0334804],[0.00298,0.0352555],[-0.0020526,0.042131],[0.0026298,0.0409231],[0.0025996,0.0494436],[0.0056778,0.0457141],[0.0106615,0.0526251],[0.0109598,0.0477986],[0.0190539,0.0504603],[0.0164582,0.0463803],[0.0490844,0.0232069],[0.0445863,0.0214318],[0.0496189,0.0145563],[0.0449365,0.0157642],[0.0449667,0.0072437],[0.0418885,0.0109731],[0.0369047,0.0040622],[0.0366065,0.0088887],[0.0285124,0.006227],[0.0311081,0.010307],[0.0229953,0.0129112],[0.0274934,0.0146863],[0.0224608,0.0215618],[0.0271432,0.0203539],[0.027113,0.0288744],[0.0301912,0.0251449],[0.035175,0.0320559],[0.0354732,0.0272294],[0.0435673,0.0298911],[0.0409716,0.0258111],[0.0392638,0.0382489],[0.034605,0.0388945],[0.0301573,0.0444839],[0.034816,0.0438383]]},"reloadFps":{"fingers":[[[0.02465,0.0165759],[0.019716,0.0234967],[0.0367607,-0.002533],[0.0360659,-0.0086632],[0.0322714,-0.0270789],[0.0263549,-0.0288276],[0.0088779,-0.0357623],[0.0012056,-0.0321051],[-0.019716,-0.0234967],[-0.02465,-0.0165759],[-0.0367607,0.002533],[-0.0360659,0.0086632],[-0.0322714,0.0270789],[-0.0263549,0.0288276],[-0.0088779,0.0357623],[-0.0012056,0.0321051],[0.0246543,0.0436427],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0201274,0.0419136],[0.0207442,0.0409265],[0.0250945,0.0349687],[0.0249706,0.0331965],[0.0204159,0.0362306],[0.0203347,0.0350695],[0.0203522,0.0276925],[0.0192103,0.0263315],[0.0173088,0.0314634],[0.0165607,0.0305718],[0.0122388,0.0245934],[0.010515,0.0241636],[0.0119931,0.029433],[0.0108637,0.0291514],[0.0038532,0.0268551],[0.002206,0.0275206],[0.0064992,0.0309148],[0.0054199,0.0313508],[-0.0016014,0.0336138],[-0.0025429,0.0351204],[0.0029254,0.0353429],[0.0023086,0.03633],[-0.0020417,0.0422878],[-0.0019177,0.04406],[0.002637,0.0410259],[0.0027182,0.042187],[0.0027006,0.049564],[0.0038426,0.0509249],[0.005744,0.0457931],[0.0064922,0.0466847],[0.0108141,0.0526631],[0.0125379,0.0530929],[0.0110597,0.0478235],[0.0121891,0.0481051],[0.0191996,0.0504014],[0.0165537,0.0463417],[0.0491677,0.0230735],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0446409,0.0213444],[0.0452577,0.0203573],[0.0496079,0.0143995],[0.049484,0.0126272],[0.0449293,0.0156614],[0.0448481,0.0145003],[0.0448656,0.0071233],[0.0437237,0.0057623],[0.0418223,0.0108942],[0.0410741,0.0100026],[0.0367522,0.0040242],[0.0350284,0.0035944],[0.0365066,0.0088638],[0.0353772,0.0085822],[0.0283666,0.0062859],[0.0267194,0.0069514],[0.0310126,0.0103456],[0.0299334,0.0107816],[0.022912,0.0130446],[0.0219706,0.0145512],[0.0274388,0.0147737],[0.026822,0.0157608],[0.0224718,0.0217186],[0.0225957,0.0234908],[0.0271504,0.0204567],[0.0272316,0.0216178],[0.0272141,0.0289948],[0.028356,0.0303557],[0.0302574,0.0252239],[0.0310056,0.0261155],[0.0353275,0.0320939],[0.0370513,0.0325237],[0.0355731,0.0272543],[0.0367025,0.0275359],[0.0437131,0.0298322],[0.0410671,0.0257725],[0.0393312,0.0381337],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0344799,0.0389409],[0.0331036,0.0394513],[0.0300899,0.0445991],[0.0293482,0.0458659],[0.0349412,0.0437919]],[[0.0270136,0.0105923],[0.0186876,0.022271],[0.0357084,-0.003127],[0.034536,-0.0134717],[0.0318117,-0.0266932],[0.0218277,-0.0296441],[0.0092802,-0.0346229],[-0.0036669,-0.0284514],[-0.0186876,-0.022271],[-0.0270136,-0.0105923],[-0.0357084,0.003127],[-0.034536,0.0134717],[-0.0318117,0.0266932],[-0.0218277,0.0296441],[-0.0092802,0.0346229],[0.0036669,0.0284514],[0.0248376,0.0433494],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0202475,0.0417214],[0.0207442,0.0409265],[0.0250704,0.0346237],[0.0249706,0.0331965],[0.0204001,0.0360046],[0.0203347,0.0350695],[0.0201299,0.0274275],[0.0192103,0.0263315],[0.0171632,0.0312898],[0.0165607,0.0305718],[0.0119032,0.0245097],[0.010515,0.0241636],[0.0117733,0.0293782],[0.0108637,0.0291514],[0.0035325,0.0269847],[0.002206,0.0275206],[0.006289,0.0309997],[0.0054199,0.0313508],[-0.0017847,0.0339071],[-0.0025429,0.0351204],[0.0028053,0.0355351],[0.0023086,0.03633],[-0.0020175,0.0426328],[-0.0019177,0.04406],[0.0026528,0.0412519],[0.0027182,0.042187],[0.002923,0.049829],[0.0038426,0.0509249],[0.0058897,0.0459667],[0.0064922,0.0466847],[0.0111497,0.0527468],[0.0125379,0.0530929],[0.0112796,0.0478783],[0.0121891,0.0481051],[0.0195203,0.0502718],[0.0167638,0.0462568],[0.049351,0.0227802],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0447609,0.0211522],[0.0452577,0.0203573],[0.0495838,0.0140545],[0.049484,0.0126272],[0.0449135,0.0154353],[0.0448481,0.0145003],[0.0446433,0.0068583],[0.0437237,0.0057623],[0.0416766,0.0107206],[0.0410741,0.0100026],[0.0364166,0.0039405],[0.0350284,0.0035944],[0.0362867,0.0088089],[0.0353772,0.0085822],[0.0280459,0.0064154],[0.0267194,0.0069514],[0.0308025,0.0104305],[0.0299334,0.0107816],[0.0227287,0.0133379],[0.0219706,0.0145512],[0.0273188,0.0149659],[0.026822,0.0157608],[0.0224959,0.0220636],[0.0225957,0.0234908],[0.0271662,0.0206827],[0.0272316,0.0216178],[0.0274364,0.0292598],[0.028356,0.0303557],[0.0304031,0.0253974],[0.0310056,0.0261155],[0.0356631,0.0321776],[0.0370513,0.0325237],[0.035793,0.0273091],[0.0367025,0.0275359],[0.0440338,0.0297026],[0.0412772,0.0256876],[0.0394795,0.0378803],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0342046,0.039043],[0.0331036,0.0394513],[0.0299415,0.0448525],[0.0293482,0.0458659],[0.0352164,0.0436898]],[[0.0293772,0.0046086],[0.0176591,0.0210453],[0.0346562,-0.0037209],[0.0330061,-0.0182802],[0.0313521,-0.0263075],[0.0173006,-0.0304607],[0.0096824,-0.0334835],[-0.0085394,-0.0247977],[-0.0176591,-0.0210453],[-0.0293772,-0.0046086],[-0.0346562,0.0037209],[-0.0330061,0.0182802],[-0.0313521,0.0263075],[-0.0173006,0.0304607],[-0.0096824,0.0334835],[0.0085394,0.0247977],[0.0250209,0.0430561],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0203676,0.0415292],[0.0207442,0.0409265],[0.0250463,0.0342786],[0.0249706,0.0331965],[0.0203843,0.0357785],[0.0203347,0.0350695],[0.0199076,0.0271626],[0.0192103,0.0263315],[0.0170175,0.0311162],[0.0165607,0.0305718],[0.0115675,0.024426],[0.010515,0.0241636],[0.0115534,0.0293233],[0.0108637,0.0291514],[0.0032118,0.0271142],[0.002206,0.0275206],[0.0060789,0.0310846],[0.0054199,0.0313508],[-0.001968,0.0342004],[-0.0025429,0.0351204],[0.0026853,0.0357272],[0.0023086,0.03633],[-0.0019934,0.0429779],[-0.0019177,0.04406],[0.0026686,0.041478],[0.0027182,0.042187],[0.0031453,0.0500939],[0.0038426,0.0509249],[0.0060353,0.0461402],[0.0064922,0.0466847],[0.0114853,0.0528305],[0.0125379,0.0530929],[0.0114995,0.0479332],[0.0121891,0.0481051],[0.019841,0.0501423],[0.0169739,0.0461719],[0.0495343,0.0224869],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.044881,0.02096],[0.0452577,0.0203573],[0.0495597,0.0137094],[0.049484,0.0126272],[0.0448977,0.0152093],[0.0448481,0.0145003],[0.044421,0.0065934],[0.0437237,0.0057623],[0.0415309,0.010547],[0.0410741,0.0100026],[0.036081,0.0038568],[0.0350284,0.0035944],[0.0360668,0.0087541],[0.0353772,0.0085822],[0.0277253,0.006545],[0.0267194,0.0069514],[0.0305924,0.0105154],[0.0299334,0.0107816],[0.0225454,0.0136312],[0.0219706,0.0145512],[0.0271987,0.015158],[0.026822,0.0157608],[0.02252,0.0224087],[0.0225957,0.0234908],[0.027182,0.0209088],[0.0272316,0.0216178],[0.0276587,0.0295247],[0.028356,0.0303557],[0.0305488,0.025571],[0.0310056,0.0261155],[0.0359987,0.0322613],[0.0370513,0.0325237],[0.0360129,0.027364],[0.0367025,0.0275359],[0.0443545,0.0295731],[0.0414873,0.0256027],[0.0396279,0.037627],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0339294,0.0391451],[0.0331036,0.0394513],[0.0297932,0.0451058],[0.0293482,0.0458659],[0.0354917,0.0435877]],[[0.0317408,-0.0013751],[0.0166307,0.0198197],[0.0336039,-0.0043149],[0.0314763,-0.0230887],[0.0308925,-0.0259219],[0.0127734,-0.0312773],[0.0100846,-0.0323441],[-0.013412,-0.021144],[-0.0166307,-0.0198197],[-0.0317408,0.0013751],[-0.0336039,0.0043149],[-0.0314763,0.0230887],[-0.0308925,0.0259219],[-0.0127734,0.0312773],[-0.0100846,0.0323441],[0.013412,0.021144],[0.0252041,0.0427628],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0204877,0.0413371],[0.0207442,0.0409265],[0.0250221,0.0339336],[0.0249706,0.0331965],[0.0203684,0.0355524],[0.0203347,0.0350695],[0.0196852,0.0268976],[0.0192103,0.0263315],[0.0168719,0.0309427],[0.0165607,0.0305718],[0.0112319,0.0243423],[0.010515,0.0241636],[0.0113335,0.0292685],[0.0108637,0.0291514],[0.0028911,0.0272438],[0.002206,0.0275206],[0.0058688,0.0311695],[0.0054199,0.0313508],[-0.0021513,0.0344937],[-0.0025429,0.0351204],[0.0025652,0.0359194],[0.0023086,0.03633],[-0.0019693,0.0433229],[-0.0019177,0.04406],[0.0026844,0.0417041],[0.0027182,0.042187],[0.0033676,0.0503589],[0.0038426,0.0509249],[0.006181,0.0463138],[0.0064922,0.0466847],[0.0118209,0.0529142],[0.0125379,0.0530929],[0.0117194,0.047988],[0.0121891,0.0481051],[0.0201617,0.0500127],[0.017184,0.046087],[0.0497176,0.0221936],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0450011,0.0207679],[0.0452577,0.0203573],[0.0495356,0.0133644],[0.049484,0.0126272],[0.0448819,0.0149832],[0.0448481,0.0145003],[0.0441987,0.0063284],[0.0437237,0.0057623],[0.0413853,0.0103734],[0.0410741,0.0100026],[0.0357454,0.0037731],[0.0350284,0.0035944],[0.0358469,0.0086993],[0.0353772,0.0085822],[0.0274046,0.0066746],[0.0267194,0.0069514],[0.0303822,0.0106003],[0.0299334,0.0107816],[0.0223621,0.0139245],[0.0219706,0.0145512],[0.0270786,0.0153502],[0.026822,0.0157608],[0.0225441,0.0227537],[0.0225957,0.0234908],[0.0271978,0.0211349],[0.0272316,0.0216178],[0.027881,0.0297897],[0.028356,0.0303557],[0.0306944,0.0257446],[0.0310056,0.0261155],[0.0363343,0.032345],[0.0370513,0.0325237],[0.0362328,0.0274188],[0.0367025,0.0275359],[0.0446752,0.0294435],[0.0416975,0.0255178],[0.0397762,0.0373736],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0336541,0.0392471],[0.0331036,0.0394513],[0.0296449,0.0453592],[0.0293482,0.0458659],[0.035767,0.0434857]]],"thumb":[[0.0265838,0.0116802],[0.0188746,0.0224939],[0.0358997,-0.003019],[0.0348142,-0.0125974],[0.0318953,-0.0267633],[0.0226509,-0.0294957],[0.009207,-0.0348301],[-0.002781,-0.0291158],[-0.0188746,-0.0224939],[-0.0265838,-0.0116802],[-0.0358997,0.003019],[-0.0348142,0.0125974],[-0.0318953,0.0267633],[-0.0226509,0.0294957],[-0.009207,0.0348301],[0.002781,0.0291158],[0.0248042,0.0434027],[0.0208469,0.0497359],[0.0255957,0.0421361],[0.0176329,0.0459057],[0.0202257,0.0417564],[0.0207442,0.0409265],[0.0250748,0.0346864],[0.0249706,0.0331965],[0.0204029,0.0360457],[0.0203347,0.0350695],[0.0201703,0.0274757],[0.0192103,0.0263315],[0.0171897,0.0313214],[0.0165607,0.0305718],[0.0119642,0.0245249],[0.010515,0.0241636],[0.0118132,0.0293881],[0.0108637,0.0291514],[0.0035908,0.0269611],[0.002206,0.0275206],[0.0063272,0.0309843],[0.0054199,0.0313508],[-0.0017514,0.0338537],[-0.0025429,0.0351204],[0.0028272,0.0355001],[0.0023086,0.03633],[-0.0020219,0.0425701],[-0.0019177,0.04406],[0.0026499,0.0412108],[0.0027182,0.042187],[0.0028825,0.0497808],[0.0038426,0.0509249],[0.0058632,0.0459351],[0.0064922,0.0466847],[0.0110887,0.0527316],[0.0125379,0.0530929],[0.0112396,0.0478684],[0.0121891,0.0481051],[0.019462,0.0502954],[0.0167256,0.0462722],[0.0493177,0.0228335],[0.0453603,0.0291667],[0.0501091,0.0215669],[0.0421463,0.0253365],[0.0447391,0.0211872],[0.0452577,0.0203573],[0.0495882,0.0141172],[0.049484,0.0126272],[0.0449164,0.0154764],[0.0448481,0.0145003],[0.0446837,0.0069065],[0.0437237,0.0057623],[0.0417031,0.0107522],[0.0410741,0.0100026],[0.0364776,0.0039557],[0.0350284,0.0035944],[0.0363267,0.0088189],[0.0353772,0.0085822],[0.0281043,0.0063919],[0.0267194,0.0069514],[0.0308407,0.010415],[0.0299334,0.0107816],[0.022762,0.0132845],[0.0219706,0.0145512],[0.0273406,0.0149309],[0.026822,0.0157608],[0.0224915,0.0220009],[0.0225957,0.0234908],[0.0271633,0.0206416],[0.0272316,0.0216178],[0.027396,0.0292116],[0.028356,0.0303557],[0.0303766,0.0253659],[0.0310056,0.0261155],[0.0356021,0.0321624],[0.0370513,0.0325237],[0.0357531,0.0272992],[0.0367025,0.0275359],[0.0439754,0.0297262],[0.041239,0.025703],[0.0394526,0.0379264],[0.0363175,0.0432815],[0.0400728,0.0368669],[0.0342547,0.0390244],[0.0331036,0.0394513],[0.0299685,0.0448064],[0.0293482,0.0458659],[0.0351664,0.0437084],[0.0255094,0.0144001],[0.0193421,0.023051],[0.036378,-0.002749],[0.0355096,-0.0104118],[0.0321042,-0.0269386],[0.0247087,-0.0291245],[0.0090242,-0.035348],[-0.0005662,-0.0307765],[-0.0193421,-0.023051],[-0.0255094,-0.0144001],[-0.036378,0.002749],[-0.0355096,0.0104118],[-0.0321042,0.0269386],[-0.0247087,0.0291245],[-0.0090242,0.035348],[0.0005662,0.0307765],[0.0247209,0.0435361],[0.0201711,0.0418437],[0.0250858,0.0348432],[0.0204101,0.0361484],[0.0202714,0.0275961],[0.0172559,0.0314003],[0.0121167,0.0245629],[0.0119132,0.029413],[0.0037366,0.0269022],[0.0064228,0.0309457],[-0.0016681,0.0337204],[0.0028818,0.0354128],[-0.0020329,0.0424133],[0.0026427,0.0411081],[0.0027815,0.0496604],[0.005797,0.0458562],[0.0109361,0.0526936],[0.0111397,0.0478435],[0.0193163,0.0503543],[0.0166301,0.0463108],[0.0492343,0.0229669],[0.0446845,0.0212745],[0.0495992,0.014274],[0.0449235,0.0155792],[0.0447848,0.0070269],[0.0417693,0.0108311],[0.0366301,0.0039937],[0.0364266,0.0088438],[0.02825,0.006333],[0.0309362,0.0103765],[0.0228454,0.0131512],[0.0273952,0.0148436],[0.0224805,0.0218441],[0.0271562,0.0205389],[0.0272949,0.0290912],[0.0303104,0.025287],[0.0354496,0.0321244],[0.0356531,0.0272742],[0.0438297,0.0297851],[0.0411435,0.0257416],[0.0393852,0.0380416],[0.0343798,0.038978],[0.0300359,0.0446912],[0.0350413,0.0437548],[0.0244351,0.0171199],[0.0198095,0.0236081],[0.0368563,-0.002479],[0.036205,-0.0082261],[0.0323131,-0.027114],[0.0267665,-0.0287534],[0.0088414,-0.0358659],[0.0016486,-0.0324373],[-0.0198095,-0.0236081],[-0.0244351,-0.0171199],[-0.0368563,0.002479],[-0.036205,0.0082261],[-0.0323131,0.027114],[-0.0267665,0.0287534],[-0.0088414,0.0358659],[-0.0016486,0.0324373],[0.0246376,0.0436694],[0.0201165,0.0419311],[0.0250967,0.0350001],[0.0204173,0.0362512],[0.0203724,0.0277166],[0.0173221,0.0314792],[0.0122693,0.024601],[0.0120131,0.029438],[0.0038824,0.0268433],[0.0065183,0.0309071],[-0.0015848,0.0335871],[0.0029363,0.0353254],[-0.0020439,0.0422564],[0.0026356,0.0410053],[0.0026804,0.0495399],[0.0057308,0.0457773],[0.0107836,0.0526555],[0.0110397,0.0478185],[0.0191705,0.0504132],[0.0165346,0.0463494],[0.049151,0.0231002],[0.0446299,0.0213619],[0.0496101,0.0144309],[0.0449307,0.015682],[0.0448859,0.0071474],[0.0418355,0.01091],[0.0367827,0.0040318],[0.0365265,0.0088688],[0.0283958,0.0062741],[0.0310317,0.0103379],[0.0229287,0.0130179],[0.0274498,0.0147562],[0.0224696,0.0216872],[0.027149,0.0204361],[0.0271939,0.0289707],[0.0302442,0.0252081],[0.035297,0.0320863],[0.0355532,0.0272493],[0.0436839,0.029844],[0.041048,0.0257802],[0.0393177,0.0381567],[0.0345049,0.0389316],[0.0301033,0.0445761],[0.0349161,0.0438012],[0.0235756,0.0192958],[0.0201835,0.0240538],[0.0372389,-0.002263],[0.0367613,-0.0064775],[0.0324803,-0.0272542],[0.0284127,-0.0284564],[0.0086951,-0.0362802],[0.0034204,-0.0337659],[-0.0201835,-0.0240538],[-0.0235756,-0.0192958],[-0.0372389,0.002263],[-0.0367613,0.0064775],[-0.0324803,0.0272542],[-0.0284127,0.0284564],[-0.0086951,0.0362802],[-0.0034204,0.0337659],[0.024571,0.0437761],[0.0200728,0.042001],[0.0251055,0.0351255],[0.0204231,0.0363334],[0.0204533,0.0278129],[0.0173751,0.0315423],[0.0123913,0.0246314],[0.0120931,0.0294579],[0.003999,0.0267962],[0.0065947,0.0308762],[-0.0015181,0.0334804],[0.00298,0.0352555],[-0.0020526,0.042131],[0.0026298,0.0409231],[0.0025996,0.0494436],[0.0056778,0.0457141],[0.0106615,0.0526251],[0.0109598,0.0477986],[0.0190539,0.0504603],[0.0164582,0.0463803],[0.0490844,0.0232069],[0.0445863,0.0214318],[0.0496189,0.0145563],[0.0449365,0.0157642],[0.0449667,0.0072437],[0.0418885,0.0109731],[0.0369047,0.0040622],[0.0366065,0.0088887],[0.0285124,0.006227],[0.0311081,0.010307],[0.0229953,0.0129112],[0.0274934,0.0146863],[0.0224608,0.0215618],[0.0271432,0.0203539],[0.027113,0.0288744],[0.0301912,0.0251449],[0.035175,0.0320559],[0.0354732,0.0272294],[0.0435673,0.0298911],[0.0409716,0.0258111],[0.0392638,0.0382489],[0.034605,0.0388945],[0.0301573,0.0444839],[0.034816,0.0438383]]},"reloadShellBody":{"outline":[[-0.001933,0.0167356],[-0.004029,0.02009],[0.0001631,0.0133812],[-0.0001128,0.0094354],[-0.0003888,0.0054896],[-0.0029313,0.0024596],[-0.0054737,-0.0005704],[-0.0093117,-0.0015273],[-0.0131496,-0.0024842],[-0.016817,-0.0010025],[-0.0204844,0.0004792],[-0.0225804,0.0038336],[-0.0246765,0.007188],[-0.0244006,0.0111338],[-0.0241247,0.0150796],[-0.0215822,0.0181096],[-0.0190397,0.0211396],[-0.0152018,0.0220965],[-0.0113638,0.0230534],[-0.0076964,0.0215717],[0.0225804,-0.0038336],[0.0204844,-0.0004792],[0.0246765,-0.007188],[0.0244006,-0.0111338],[0.0241247,-0.0150796],[0.0215822,-0.0181096],[0.0190397,-0.0211396],[0.0152018,-0.0220965],[0.0113638,-0.0230534],[0.0076964,-0.0215717],[0.004029,-0.02009],[0.001933,-0.0167356],[-0.0001631,-0.0133812],[0.0001128,-0.0094354],[0.0003888,-0.0054896],[0.0029313,-0.0024596],[0.0054737,0.0005704],[0.0093117,0.0015273],[0.0131496,0.0024842],[0.016817,0.0010025]],"marker":[0.1265,0.085,0],"frame":[-0.24184476264797528,-0.6644630243886747,0.24184476264797522,0.6644630243886748]},"reloadShellFps":{"outline":[[-0.001933,0.0167356],[-0.004029,0.02009],[0.0001631,0.0133812],[-0.0001128,0.0094354],[-0.0003888,0.0054896],[-0.0029313,0.0024596],[-0.0054737,-0.0005704],[-0.0093117,-0.0015273],[-0.0131496,-0.0024842],[-0.016817,-0.0010025],[-0.0204844,0.0004792],[-0.0225804,0.0038336],[-0.0246765,0.007188],[-0.0244006,0.0111338],[-0.0241247,0.0150796],[-0.0215822,0.0181096],[-0.0190397,0.0211396],[-0.0152018,0.0220965],[-0.0113638,0.0230534],[-0.0076964,0.0215717],[0.0225804,-0.0038336],[0.0204844,-0.0004792],[0.0246765,-0.007188],[0.0244006,-0.0111338],[0.0241247,-0.0150796],[0.0215822,-0.0181096],[0.0190397,-0.0211396],[0.0152018,-0.0220965],[0.0113638,-0.0230534],[0.0076964,-0.0215717],[0.004029,-0.02009],[0.001933,-0.0167356],[-0.0001631,-0.0133812],[0.0001128,-0.0094354],[0.0003888,-0.0054896],[0.0029313,-0.0024596],[0.0054737,0.0005704],[0.0093117,0.0015273],[0.0131496,0.0024842],[0.016817,0.0010025]],"marker":[0.1265,0.085,0],"frame":[-0.24184476264797528,-0.6644630243886747,0.24184476264797522,0.6644630243886748]}};
function triggerIndexRotations(fire=false){
const rotation=graspFrame(1,'shotgun').invert().multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1),-5.710593*Math.PI/180)),center=new THREE.Vector3(...gripDatum('shotgun')),marker=new THREE.Vector3(-.060,.046,0),toHand=p=>new THREE.Vector3(...p).sub(marker).applyQuaternion(rotation).add(center),root=new THREE.Vector3(.034,-.106,.043),lengths=FINGER_LENGTHS[0],tip=toHand(fire?[.022,.017,.0095]:[.040,.034,.046]),distal=new THREE.Vector3(...(fire?[1,-.25,-.85]:[1,-.05,-.10])).normalize().applyQuaternion(rotation),p2=tip.clone().addScaledVector(distal,-lengths[2]),towards=p2.clone().sub(root),distance=towards.length();
if(distance>lengths[0]+lengths[1])throw Error('Trigger index target exceeds digit reach');towards.normalize();const cos=(lengths[0]**2+distance**2-lengths[1]**2)/(2*lengths[0]*distance),pole=new THREE.Vector3(0,0,1).applyQuaternion(rotation);pole.addScaledVector(towards,-pole.dot(towards)).normalize();const p1=root.clone().addScaledVector(towards,lengths[0]*cos).addScaledVector(pole,lengths[0]*Math.sqrt(Math.max(0,1-cos*cos))),points=[root,p1,p2,tip],result={};let previous=new THREE.Quaternion();for(let i=0;i<3;i++){const absolute=new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0,-1,0),points[i+1].clone().sub(points[i]).normalize());result['finger_right_0_'+['a','b','c'][i]]=previous.clone().invert().multiply(absolute);previous=absolute;}return result;
}
function stockThumbRotations(){const rotation=graspFrame(1,'shotgun').invert().multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1),-5.710593*Math.PI/180)),center=new THREE.Vector3(...gripDatum('shotgun')),marker=new THREE.Vector3(-.060,.046,0),toHand=p=>new THREE.Vector3(...p).sub(marker).applyQuaternion(rotation).add(center),base=new THREE.Vector3(.027,-.076,.040),rest=[new THREE.Vector3(0,-.020,-.010),new THREE.Vector3(0,-.025,0),new THREE.Vector3(0,-.018,0)],lengths=rest.map(v=>v.length()),tip=toHand([.020,.087,.028]),axis=new THREE.Vector3(1,-.10,-.50).normalize().applyQuaternion(rotation),p2=tip.clone().addScaledVector(axis,-lengths[2]),towards=p2.clone().sub(base),distance=towards.length();if(distance>lengths[0]+lengths[1])throw Error('Thumb resting target exceeds reach');towards.normalize();const cos=(lengths[0]**2+distance**2-lengths[1]**2)/(2*lengths[0]*distance),pole=new THREE.Vector3(0,0,1).applyQuaternion(rotation);pole.addScaledVector(towards,-pole.dot(towards)).normalize();const p1=base.clone().addScaledVector(towards,lengths[0]*cos).addScaledVector(pole,lengths[0]*Math.sqrt(Math.max(0,1-cos*cos))),points=[base,p1,p2,tip],result={};let previous=new THREE.Quaternion();for(let i=0;i<3;i++){const absolute=new THREE.Quaternion().setFromUnitVectors(rest[i].clone().normalize(),points[i+1].clone().sub(points[i]).normalize());result['thumb_right_'+['a','b','c'][i]]=previous.clone().invert().multiply(absolute);previous=absolute;}return result;}
function graspRotations(side,weapon,kind='hold'){
const result={},suffix=side<0?'left':'right',center=new THREE.Vector3(...gripDatum(weapon)),shell=weapon==='reload'&&kind==='shell',profile=weapon==='reload'?HANDLE_CONTACT_PROFILES['reload'+(shell?'Shell':'')+(MODE==='fps-arms'?'Fps':'Body')]:HANDLE_CONTACT_PROFILES[weapon];
function tangent(p,profile,r,sign){const relative=p.clone().sub(center),evaluate=t=>{const n=new THREE.Vector2(Math.cos(t),Math.sin(t));let best=profile[0],h=-Infinity;for(const v of profile){const d=v[0]*n.x+v[1]*n.y;if(d>h){h=d;best=v;}}return {q:new THREE.Vector2(...best).addScaledVector(n,r+.0006),n};};let last=evaluate(0),f0=(relative.x-last.q.x)*last.n.x+(relative.y-last.q.y)*last.n.y;for(let i=1;i<=128;i++){let hi=i*Math.PI*2/128,lo=(i-1)*Math.PI*2/128,s=evaluate(hi),f=(relative.x-s.q.x)*s.n.x+(relative.y-s.q.y)*s.n.y;if(f*f0<=0){let fl=f0;for(let n=0;n<25;n++){const mid=(lo+hi)/2,m=evaluate(mid),fm=(relative.x-m.q.x)*m.n.x+(relative.y-m.q.y)*m.n.y;if(fl*fm<=0)hi=mid;else{lo=mid;fl=fm;}}s=evaluate((lo+hi)/2);const d=new THREE.Vector3(-sign*s.n.y,sign*s.n.x,0),toward=new THREE.Vector3(s.q.x-relative.x,s.q.y-relative.y,0);if(d.dot(toward)>0)return d;}f0=f;}throw Error('Digit section tangent unavailable '+weapon+' '+p.toArray());}
function digit(role,start,offsets,radii,sign,profile,axialShift=0){let p=new THREE.Vector3(...start),previous=new THREE.Quaternion();for(let n=0;n<offsets.length;n++){const rest=new THREE.Vector3(...offsets[n]),r=radii[n];const d=tangent(p,profile,r,sign);if(axialShift)d.z=axialShift;d.normalize();const phalanxQ=new THREE.Quaternion().setFromUnitVectors(rest.clone().normalize(),d),local=previous.clone().invert().multiply(phalanxQ);result[role+'_'+['a','b','c'][n]]=local;p.addScaledVector(d,rest.length());previous=phalanxQ;}}
for(let f=0;f<4;f++){const ls=FINGER_LENGTHS[f],z=(1.5-f)*side*.022;if(weapon==='shotgun'&&f===0)continue;if(shell&&f!==0){for(const [n,s]of ['a','b','c'].entries())result['finger_'+suffix+'_'+f+'_'+s]=new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1),[45,20,20][n]*Math.PI/180);continue;}digit('finger_'+suffix+'_'+f,[.025,-.095,shell?0:z],ls.map(l=>[0,-l,0]),[.0095,.0085,.0075],1,shell?profile.outline:profile.fingers[f]);}
if(weapon==='shotgun'){Object.assign(result,stockThumbRotations());return result;}digit('thumb_'+suffix,[weapon==='shotgun'?.027:.030,weapon==='shotgun'?-.076:-.065,shell?0:side*.040],[[0,-.020,-side*.010],[0,-.025,0],[0,-.018,0]],[.011,.009,.0075],-1,shell?profile.outline:profile.thumb,shell?0:-side*.12);
return result;
}
const BODY_SPEC={"schemaVersion":3,"model":"pbrMetallicRoughness","name":"Caretaker olive workwear and weathered skin","roughness":0.96,"metalness":0,"emissiveIntensity":1,"alphaMode":"opaque","alphaCutoff":0.5,"doubleSided":false,"textures":{"baseColor":{"kind":"resource","resourceId":"kiln.library.b5db650c0b2c4afff7b590debb66dbc7bccd85ae7500e3e5a38a135dab24764b.base-color","sampler":{"minFilter":"nearest","magFilter":"nearest","wrapS":"clamp-to-edge","wrapT":"clamp-to-edge"}}}};
async function build(){
const root=createRoot(MODE==='fps-arms'?'CaretakerFPS':'Caretaker');
const material=await compilePortableMaterialSpecV3(BODY_SPEC),bones=[],byRole={},names={},fragments={BodySkin:[],HeadSkin:[],ArmsSkin:[]};
function chain(name,segments,parent){const result=createBoneChain(name,segments,{parent});segments.forEach((s,i)=>{const bone=result.nodes[i];bones.push(bone);byRole[s.role]=bone;names[s.role]=bone.name;});return result;}
const body=chain('Body',[{role:'pelvis',offset:[0,.94,0]},{role:'spine',offset:[.01,.18,0]},{role:'chest',offset:[.015,.2,0]},{role:'neck',offset:[.015,.12,0]},{role:'head',offset:[.015,.12,0]}],root);
for(const side of [-1,1]){const suffix=side<0?'left':'right';chain('Arm_'+suffix,[{role:'shoulder_'+suffix,offset:MODE==='fps-arms'?[-.265,.16,side*.26]:[-.01,.08,side*.22]},{role:'elbow_'+suffix,offset:MODE==='fps-arms'?[.30,-.35,side*.14]:[.015,-.27,side*.05]},{role:'wrist_'+suffix,offset:MODE==='fps-arms'?[0,-.28,0]:[.015,-.24,side*.005]}],byRole.chest);chain('Leg_'+suffix,[{role:'hip_'+suffix,offset:[0,-.02,side*.105]},{role:'knee_'+suffix,offset:[.02,-.43,0]},{role:'ankle_'+suffix,offset:[-.015,-.37,0]}],byRole.pelvis);
for(let finger=0;finger<4;finger++){const ls=FINGER_LENGTHS[finger];chain('Finger_'+suffix+'_'+finger,[{role:'finger_'+suffix+'_'+finger+'_a',offset:[.025,-.095,(1.5-finger)*side*.022]},{role:'finger_'+suffix+'_'+finger+'_b',offset:[0,-ls[0],0]},{role:'finger_'+suffix+'_'+finger+'_c',offset:[0,-ls[1],0]}],byRole['wrist_'+suffix]);}
chain('Thumb_'+suffix,[{role:'thumb_'+suffix+'_a',offset:[.030,-.065,side*.040]},{role:'thumb_'+suffix+'_b',offset:[0,-.020,-side*.010]},{role:'thumb_'+suffix+'_c',offset:[0,-.025,0]}],byRole['wrist_'+suffix]);
}
root.updateMatrixWorld(true);const positions={};for(const role of Object.keys(byRole))positions[role]=byRole[role].getWorldPosition(new THREE.Vector3());
const eye=positions.head.clone().add(new THREE.Vector3(.135,.05,0));if(MODE==='fps-arms'){root.position.set(0,-1.61,0);root.updateMatrixWorld(true);}
function anchor(name,parent,position){const object=new THREE.Object3D();object.name=name;object.position.fromArray(position);object.userData.nightmanAnchor={version:1,role:name,forward:'+X',up:'+Y'};parent.add(object);return object;}
anchor('camera_eye',MODE==='fps-arms'?root:byRole.head,MODE==='fps-arms'?[0,1.61,0]:[.135,.05,0]);anchor('chest_mount',byRole.chest,[.125,.035,0]);anchor('grip_left_flashlight',byRole.wrist_left,gripDatum('flashlight')).quaternion.copy(graspFrame(-1,'flashlight').invert());for(const suffix of ['left','right']){const side=suffix==='left'?-1:1;anchor('grip_'+suffix,byRole['wrist_'+suffix],gripDatum(side<0?'reload':'shotgun')).quaternion.copy(graspFrame(side,side<0?'reload':'shotgun').invert());anchor('grip_'+suffix+'_axe',byRole['wrist_'+suffix],gripDatum('axe')).quaternion.copy(graspFrame(side,'axe').invert());anchor('foot_contact_'+suffix,byRole['ankle_'+suffix],[.04,-.115,0]);}
root.userData.nightman={version:1,mode:MODE,joints:names,eyeHeight:eye.y,eyePosition:eye.toArray(),bodyHeight:1.72,ownCameraHide:['Mesh_Head','Mesh_Cap','Mesh_CapBrim','Mesh_Nose','Mesh_EarLeft','Mesh_EarRight','Mesh_Beard','Mesh_Neck'],paletteMaterial:'nm-caretaker-clothing-skin',fpsOrigin:'fixed feet-relative eye; root camera_eye does not inherit head motion',derivedFromBodyProgram:'p_e468609d7cbc',cameraMountLocal:[0,1.61,0],contacts:'authored point witnesses; runtime solves grounded movement'};
const index=role=>bones.indexOf(byRole[role]);
function blend(roleA,roleB,t){return [[roleA,1-Math.max(0,Math.min(1,t))],[roleB,Math.max(0,Math.min(1,t))]];}
function geometry(positions,uvs,indices){let g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(positions,3));g.setAttribute('uv',new THREE.Float32BufferAttribute(uvs,2));g.setIndex(indices);g=g.toNonIndexed();g.computeVertexNormals();return g;}
function skin(name,g,region,weight){if(region==='hand'&&['Finger','Thumb','Hand'].some(prefix=>name.startsWith(prefix))){const uv=g.getAttribute('uv'),finger=name.startsWith('Finger'),thumb=name.startsWith('Thumb');for(let i=0;i<uv.count;i++)uv.setXY(i,uv.getX(i)*(finger?.42:thumb?.55:1)+(finger?.29:thumb?.225:0),uv.getY(i)*(finger?.42:thumb?.30:.67)+(finger?.2:thumb?.25:.15));}if(region==='beard'){const uv=g.getAttribute('uv');for(let i=0;i<uv.count;i++)uv.setY(i,1-uv.getY(i));}g=remapUVToAtlas(g,material.map,region,{inputOrigin:'top-left',mode:'texel-center'});if(g.index)g=g.toNonIndexed();const a=g.getAttribute('position'),indices=[],weights=[];for(let i=0;i<a.count;i++){const influences=weight(a.getX(i),a.getY(i),a.getZ(i));for(let lane=0;lane<4;lane++){const weight=influences[lane]?.[1]??0;indices.push(weight>0?index(influences[lane][0]):0);weights.push(weight);}}const bucket=['Head','Neck','Nose','EarLeft','EarRight','Cap','CapBrim','Beard'].includes(name)?'HeadSkin':/^(Sleeve|Hand|Finger|Thumb)/.test(name)?'ArmsSkin':'BodySkin';fragments[bucket].push({name,region,g,indices,weights});g.computeBoundingBox();const marker=new THREE.Object3D();marker.name='Mesh_'+name;marker.userData.nightmanPart={version:1,skinGroup:bucket,bounds:{min:g.boundingBox.min.toArray(),max:g.boundingBox.max.toArray()}};root.add(marker);return marker;}
// Explicit profile rings and split normals control silhouette and skin deformation.
function tube(rings,segments=8,start=-Math.PI,end=Math.PI,caps=true){const p=[],uv=[],ix=[],stride=segments+1;for(let j=0;j<rings.length;j++){const r=rings[j];for(let i=0;i<=segments;i++){const angle=start+(end-start)*i/segments;p.push(r.x+r.rx*Math.cos(angle),r.y+(r.ySlope??0)*Math.sin(angle)+(r.yWave??0)*Math.abs(Math.sin(angle)),r.z+r.rz*Math.sin(angle));uv.push(i/segments,j/(rings.length-1));}}for(let j=0;j<rings.length-1;j++)for(let i=0;i<segments;i++){const a=j*stride+i,b=a+stride;if(rings.at(-1).y>rings[0].y)ix.push(a,b,a+1,a+1,b,b+1);else ix.push(a,a+1,b,a+1,b+1,b);}if(caps&&end-start>6){for(const [j,reverse] of [[0,rings.at(-1).y<rings[0].y],[rings.length-1,rings.at(-1).y>rings[0].y]]){const r=rings[j],center=p.length/3;p.push(r.x,r.y,r.z);uv.push(.5,.5);for(let i=0;i<segments;i++){const a=j*stride+i;ix.push(center,reverse?a+1:a,reverse?a:a+1);}}}return geometry(p,uv,ix);}
function nasalUV(g){const uv=g.getAttribute('uv');for(let i=0;i<uv.count;i++)uv.setXY(i,(12+uv.getX(i)*2)/27,1-(11+uv.getY(i)*3)/27);return g;}
function box(x,y,z,w,h,d){const g=new THREE.BoxGeometry(w,h,d);g.translate(x,y,z);const uv=g.getAttribute('uv');for(let i=0;i<uv.count;i++)uv.setY(i,1-uv.getY(i));return g;}
function rigid(name,g,region,role){if(region==='face'){const uv=g.getAttribute('uv');for(let i=0;i<uv.count;i++)uv.setY(i,1-uv.getY(i));}return skin(name,g,region,()=>[[role,1]]);}
function finalizeSkin(){
for(const [bucket,parts]of Object.entries(fragments)){
if(!parts.length)continue;const p=[],n=[],uv=[],indices=[],weights=[],partRanges=[];
for(const part of parts){const g=part.g,a=g.getAttribute('position'),normal=g.getAttribute('normal'),tex=g.getAttribute('uv'),start=p.length/3;
for(let i=0;i<a.count;i++){p.push(a.getX(i),a.getY(i),a.getZ(i));n.push(normal.getX(i),normal.getY(i),normal.getZ(i));uv.push(tex.getX(i),tex.getY(i));}
indices.push(...part.indices);weights.push(...part.weights);partRanges.push({name:part.name,region:part.region,vertexStart:start,vertexCount:a.count});
}
const g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(p,3));g.setAttribute('normal',new THREE.Float32BufferAttribute(n,3));g.setAttribute('uv',new THREE.Float32BufferAttribute(uv,2));
const name=MODE==='fps-arms'?'FPSArmsSkin':bucket,mesh=createSkinnedPart(name,g,material,{parent:root,bones,indices,weights});mesh.name=name;mesh.userData.nightmanSkin={version:1,group:name,parts:partRanges,sharedRig:'47 named joints; three finger phalanges and thumb CMC/MCP/IP',partRangeSpace:'pre-export non-indexed vertex stream; not compacted GLB accessor indices',palette:'nm-caretaker-clothing-skin'};
if(bucket!=='ArmsSkin')markOpenShell(mesh,'Joined garment/face surfaces include intended open seams; pose and contact checks are separate from solid-volume QA');
}
root.userData.nightman.renderGroups={body:'BodySkin',head:'HeadSkin',arms:'ArmsSkin',fps:'FPSArmsSkin',ownViewHide:['HeadSkin','ArmsSkin']};
}
function bodyWeights(x,y){if(y<1.08)return blend('pelvis','spine',(y-.95)/.13);if(y<1.27)return blend('spine','chest',(y-1.08)/.19);return [['chest',1]];}
if(MODE!=='fps-arms'){
const torso=[{x:0,y:.91,z:0,rx:.10,rz:.16},{x:.01,y:1.02,z:0,rx:.102,rz:.165},{x:.02,y:1.15,z:0,rx:.11,rz:.18},{x:.028,y:1.29,z:0,rx:.10,rz:.183},{x:.035,y:1.385,z:0,rx:.095,rz:.205},{x:.041,y:1.41,z:0,rx:.075,rz:.185},{x:.045,y:1.425,z:0,rx:.055,rz:.073}];
const front=skin('JacketFront',tube(torso,6,-Math.PI/2,Math.PI/2,false),'jacket-front',bodyWeights),back=skin('JacketBack',tube(torso,6,Math.PI/2,3*Math.PI/2,false),'jacket-back',bodyWeights);markOpenShell(front,'Garment shell open at waist and neck; sleeve and collar terminate inside it');markOpenShell(back,'Garment shell open at waist and neck; sleeve and collar terminate inside it');
rigid('ShirtCollar',box(.101,1.36,0,.025,.17,.12),'shirt','chest');
const lp=geometry([.101,1.435,-.071,.108,1.31,-.105,.132,1.35,-.025,.137,1.395,-.044,.101,1.435,.071,.108,1.31,.105,.132,1.35,.025,.137,1.395,.044],[0,0,0,1,1,1,.5,.3,1,0,1,1,0,1,.5,.3],[0,3,1,1,3,2,2,3,0,4,5,7,5,6,7,6,4,7]);const lapels=skin('JacketLapels',lp,'jacket-front',()=>[['chest',1]]);markOpenShell(lapels,'Two folded garment lapels anchored over the chest shell');
skin('CollarStand',tube([{x:.05,y:1.412,z:0,rx:.056,rz:.067},{x:.05,y:1.444,z:0,rx:.053,rz:.061}],8),'sleeve',()=>[['chest',1]]);
rigid('WorkBelt',tube([{x:0,y:.926,z:0,rx:.102,rz:.163},{x:0,y:.955,z:0,rx:.102,rz:.163}],12),'leather','pelvis');
rigid('BeltBuckle',box(.11,.944,0,.018,.035,.04),'leather','pelvis');
for(const side of [-1,1]){const z=side*.085;const pocket=geometry([.132-Math.abs(z-.045)*.2,1.225,z-.045,.132-Math.abs(z+.045)*.2,1.225,z+.045,.137-Math.abs(z+.045)*.2,1.185,z+.045,.137-Math.abs(z-.045)*.2,1.185,z-.045],[0,0,1,0,1,1,0,1],[0,1,2,0,2,3]);const flap=skin(side<0?'PocketFlapLeft':'PocketFlapRight',pocket,'pocket',bodyWeights);markOpenShell(flap,'Stitched chest pocket flap over the fitted jacket shell');}
const head=positions.head;rigid('Neck',tube([{x:head.x-.01,y:1.425,z:0,rx:.041,rz:.047},{x:head.x,y:1.475,z:0,rx:.039,rz:.045}],8),'hand','neck');
rigid('Head',tube([{x:head.x+.014,y:1.468,z:0,rx:.060,rz:.063},{x:head.x+.015,y:1.49,z:0,rx:.078,rz:.069},{x:head.x,y:1.57,z:0,rx:.094,rz:.088},{x:head.x-.01,y:1.65,z:0,rx:.084,rz:.078},{x:head.x-.015,y:1.683,z:0,rx:.065,rz:.065}],8),'face','head');
const beard=skin('Beard',tube([{x:head.x+.028,y:1.468,z:0,rx:.052,rz:.043},{x:head.x+.019,y:1.490,z:0,rx:.081,rz:.061},{x:head.x+.012,y:1.535,z:0,rx:.092,rz:.081}],6,-Math.PI*.45,Math.PI*.45,false),'beard',()=>[['head',1]]);markOpenShell(beard,'Faceted beard surface fitted to chin and cheeks');
rigid('Nose',nasalUV(tube([{x:head.x+.088,y:1.57,z:0,rx:.01,rz:.018},{x:head.x+.097,y:1.595,z:0,rx:.016,rz:.019},{x:head.x+.085,y:1.62,z:0,rx:.004,rz:.015}],4)),'face','head');
for(const side of [-1,1])rigid(side<0?'EarLeft':'EarRight',tube([{x:head.x-.005,y:1.56,z:side*.085,rx:.016,rz:.012},{x:head.x+.006,y:1.615,z:side*.085,rx:.019,rz:.012}],6),'hand','head');
rigid('Cap',tube([{x:head.x-.015,y:1.64,z:0,rx:.09,rz:.086},{x:head.x-.028,y:1.70,z:0,rx:.080,rz:.079},{x:head.x-.028,y:1.719,z:0,rx:.063,rz:.067}],8),'cap','head');
rigid('CapBrim',box(head.x+.088,1.658,0,.17,.016,.16),'cap','head');
skin('TrouserPelvis',tube([{x:0,y:.80,yWave:.075,z:0,rx:.085,rz:.13},{x:0,y:.87,z:0,rx:.10,rz:.16},{x:0,y:.972,z:0,rx:.101,rz:.164}],12),'trouser',(x,y,z)=>y>=.87?[['pelvis',1]]:blend('pelvis','hip_'+(z<0?'left':'right'),Math.min(.6,(.87-y)/.09)));
for(const side of [-1,1]){const suffix=side<0?'left':'right',label=side<0?'Left':'Right';const hip=positions['hip_'+suffix],knee=positions['knee_'+suffix],ankle=positions['ankle_'+suffix];
skin('Trouser'+label,tube([{x:hip.x,y:.96,z:side*.096,rx:.10,rz:.093},{x:hip.x,y:.80,z:side*.103,rx:.09,rz:.082},{x:knee.x,y:.57,z:side*.105,rx:.079,rz:.073},{x:knee.x,y:.49,z:side*.105,rx:.074,rz:.071},{x:ankle.x,y:.30,z:side*.105,rx:.069,rz:.064},{x:ankle.x,y:.15,z:side*.105,rx:.064,rz:.061}],8),'trouser',(x,y)=>y>.58?blend('hip_'+suffix,'knee_'+suffix,(.66-y)/.17):y>.25?blend('knee_'+suffix,'ankle_'+suffix,(.28-y)/.13):[['ankle_'+suffix,1]]);
const boot=tube([{x:ankle.x+.032,y:.006,z:side*.105,rx:.147,rz:.079},{x:ankle.x+.045,y:.055,z:side*.105,rx:.153,rz:.082},{x:ankle.x+.019,y:.108,z:side*.105,rx:.102,rz:.076},{x:ankle.x-.01,y:.172,z:side*.105,rx:.063,rz:.061}],8);rigid('Boot'+label,boot,'boot','ankle_'+suffix);
}
}
for(const side of [-1,1]){const suffix=side<0?'left':'right',label=side<0?'Left':'Right',shoulder=positions['shoulder_'+suffix],elbow=positions['elbow_'+suffix],wrist=positions['wrist_'+suffix];
if(MODE==='fps-arms'){function sleeveLink(name,from,to,r0,r1,role,other){const delta=to.clone().sub(from),length=delta.length(),q=new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0,-1,0),delta.clone().normalize()),rings=[{x:0,y:.008,z:0,rx:r0*.9,rz:r0*.9},{x:0,y:0,z:0,rx:r0,rz:r0},{x:0,y:-length*.45,z:0,rx:(r0+r1)/2,rz:(r0+r1)/2},{x:0,y:-length,z:0,rx:r1,rz:r1},{x:0,y:-length-.008,z:0,rx:r1*.9,rz:r1*.9}],g=tube(rings,8);g.applyQuaternion(q);g.translate(from.x,from.y,from.z);skin(name,g,'sleeve',(x,y,z)=>{if(!other)return[[role,1]];const t=Math.max(0,Math.min(1,new THREE.Vector3(x,y,z).sub(from).dot(delta)/(length*length)));return blend(role,other,t);});}sleeveLink('SleeveUpper'+label,shoulder,elbow,.064,.075,'shoulder_'+suffix,'elbow_'+suffix);sleeveLink('SleeveForearm'+label,elbow,wrist,.075,.045,'elbow_'+suffix); }else{
const sleeveRings=[{x:shoulder.x,y:1.414,z:shoulder.z,rx:.012,rz:.012},{x:shoulder.x,y:1.395,z:shoulder.z,rx:.058,rz:.057},{x:shoulder.x+.008,y:1.35,z:shoulder.z+side*.022,rx:.068,rz:.067},{x:shoulder.x+.013,y:1.29,z:shoulder.z+side*.038,rx:.065,rz:.063},{x:elbow.x,y:1.19,z:elbow.z,rx:.076,rz:.077},{x:elbow.x,y:1.16,z:elbow.z,rx:.080,rz:.080},{x:elbow.x,y:1.13,z:elbow.z,rx:.080,rz:.080},{x:elbow.x+.004,y:1.10,z:elbow.z+side*.002,rx:.073,rz:.074},{x:elbow.x+.008,y:1.08,z:elbow.z+side*.004,rx:.064,rz:.065},{x:wrist.x,y:.945,z:wrist.z,rx:.049,rz:.048},{x:wrist.x,y:.90,z:wrist.z,rx:.044,rz:.045}];skin('Sleeve'+label,tube(MODE==='fps-arms'?sleeveRings.filter(r=>r.y<=1.19):sleeveRings),'sleeve',(x,y)=>y>1.23?[['shoulder_'+suffix,1]]:blend('shoulder_'+suffix,'elbow_'+suffix,(1.19-y)/.13));
}
skin('Hand'+label,tube([{x:wrist.x,y:.912,z:wrist.z,rx:.031,rz:.033},{x:wrist.x+.007,y:.86,z:wrist.z,rx:.029,rz:.040},{x:wrist.x+.012,y:.813,z:wrist.z,rx:.026,rz:.044},{x:wrist.x+.016,y:.787,z:wrist.z,rx:.024,rz:.038}].map(r=>MODE==='fps-arms'?{...r,y:r.y+wrist.y-.89}:r),8),'hand',()=>[['wrist_'+suffix,1]]);
function phalanx(name,role,from,offset,radius){const axis=new THREE.Vector3(...offset),length=axis.length(),q=new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0,-1,0),axis.normalize()),g=tube([{x:0,y:.003,z:0,rx:radius*.45,rz:radius*.45},{x:0,y:0,z:0,rx:radius,rz:radius},{x:0,y:-length+.003,z:0,rx:radius*.86,rz:radius*.86},{x:0,y:-length-.002,z:0,rx:radius*.35,rz:radius*.35}],8);g.applyQuaternion(q);g.translate(from.x,from.y,from.z);skin(name,g,'hand',()=>[[role,1]]);}
for(let f=0;f<4;f++){const ls=FINGER_LENGTHS[f];for(let n=0;n<3;n++){const role='finger_'+suffix+'_'+f+'_'+['a','b','c'][n];phalanx('Finger'+label+f+['Proximal','Middle','Distal'][n],role,positions[role],[0,-ls[n],0],[.0095,.0085,.0075][n]);}}
for(let n=0;n<3;n++){const role='thumb_'+suffix+'_'+['a','b','c'][n];phalanx('Thumb'+label+['Metacarpal','Proximal','Distal'][n],role,positions[role],n===0?[0,-.020,-side*.010]:n===1?[0,-.025,0]:[0,-.018,0],[.011,.009,.0075][n]);}
}
finalizeSkin();if(MODE==='fps-arms')root.userData.nightman.viewDerivative={version:2,rig:'Dedicated view sleeve origins behind fixed camera; authored baked elbow-position channels',shoulderOrigin:[-.24,1.48,.26],upperSleeve:'Continuous weighted origin-to-elbow reach',forearm:'Rigid articulated sleeve and exact body-derived hands',cameraMount:'fixed root camera_eye; no tracking/bob',worldAnatomy:'Full-body asset is authoritative world representation'};return root;
}
function animate(root){
const j=root.userData.nightman.joints,clips=[],rot=(role,keys)=>rotationTrack(j[role],keys.map(k=>({time:k[0],rotation:k[1]})),'LINEAR'),pos=(role,keys)=>positionTrack(j[role],keys.map(k=>({time:k[0],position:k[1]})),'LINEAR');
const qx=a=>new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0),a*Math.PI/180),qy=a=>new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),a*Math.PI/180),qz=a=>new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1),a*Math.PI/180);
const interpolate=(keys,time)=>{let n=keys.findIndex(k=>k[0]>=time);if(n<=0)return keys[n<0?keys.length-1:0][1];const a=keys[n-1],b=keys[n],t=(time-a[0])/(b[0]-a[0]);return a[1]+(b[1]-a[1])*t;};
const duration=1.2,times=[0,.15,.30,.45,.60,.75,.90,1.05,1.2],hipsL=[0,18,22,10,0,-18,-22,-10,0],kneesL=[0,-5,-12,-52,-60,-25,0,0,0],hipsR=hipsL.map((_,i)=>hipsL[(i+4)%8]),kneesR=kneesL.map((_,i)=>kneesL[(i+4)%8]);hipsR[8]=hipsR[0];kneesR[8]=kneesR[0];
const gait=(time,suffix)=>{const t=time%1.2,h=interpolate(times.map((v,i)=>[v,(suffix==='left'?hipsL:hipsR)[i]]),t),k=interpolate(times.map((v,i)=>[v,(suffix==='left'?kneesL:kneesR)[i]]),t);return {hip:h,knee:k,ankle:-h-k};};
const gaitHeight=time=>{const left=gait(time,'left'),right=gait(time,'right'),r=Math.PI/180,leg=v=>.43*Math.cos(v.hip*r)+.37*Math.cos((v.hip+v.knee)*r);return .02+.114+Math.max(leg(left),leg(right));};
root.updateMatrixWorld(true);const basePelvis=root.getObjectByName(j.pelvis).position.clone(),shoulders={};for(const suffix of ['left','right'])shoulders[suffix]=root.worldToLocal(root.getObjectByName(j['shoulder_'+suffix]).getWorldPosition(new THREE.Vector3()));
const poseReach={},events={};
const breechKeys=[[0,0],[.55,-45],[2,-45],[2.4,0]],shellKeys=[[0,.027],[.55,.027],[.65,.010],[.72,.010],[1,-.085],[1.45,-.085],[1.8,.010],[1.96,.027],[2.4,.027]];
function reloadGrip(time){const angle=interpolate(breechKeys,time),q=qz(angle),hinge=new THREE.Vector3(.200,.066,0),support=new THREE.Vector3(0,-.018,0).applyQuaternion(q).add(hinge),shell=new THREE.Vector3(interpolate(shellKeys,Math.min(time,1.8))+.0045-.105,.019,0).applyQuaternion(q).add(hinge);let blend=time<=.55?0:time<.72?(time-.55)/.17:time<=1.90?1:time<2?(2-time)/.10:0;return {point:support.lerp(shell,blend).sub(new THREE.Vector3(-.060,.046,0)).add(new THREE.Vector3(0,0,-interpolate([[0,0],[.22,.08],[.30,0],[.48,0],[.58,.08],[.67,.08],[.72,0],[1.82,0],[1.90,.08],[2.00,.08],[2.10,0],[2.18,.08],[2.40,0]],time))),rotation:q};}
function poseAt(keys,time){let n=keys.findIndex(k=>k.time>=time);if(n<=0)return keys[n<0?keys.length-1:0];const a=keys[n-1],b=keys[n],t=(time-a.time)/(b.time-a.time);return {position:a.position.map((v,i)=>v+(b.position[i]-v)*t),angle:a.angle+(b.angle-a.angle)*t,crouch:(a.crouch??0)+((b.crouch??0)-(a.crouch??0))*t,yaw:(a.yaw??0)+((b.yaw??0)-(a.yaw??0))*t};}
function held(name,length,keys,weapon,options={}){
const samples=keys.length===2&&!options.walk&&name!=='Reload'?keys.map(k=>k.time):[...new Set([...Array.from({length:Math.round(length*30)+1},(_,i)=>Math.min(length,i/30)),...keys.map(k=>k.time),...(name==='Reload'?breechKeys.map(k=>k[0]).concat(shellKeys.map(k=>k[0]),[.15,.22,.30,.48,.58,.64,.67,.72,1.8,1.815,1.82,1.90,1.96,2,2.10,2.18,2.4]):[])])].sort((a,b)=>a-b),channels={},fpsElbowPositions={},pelvisKeys=[],legKeys={left:{hip:[],knee:[],ankle:[]},right:{hip:[],knee:[],ankle:[]}};let maxResidual=0,maxWristBend=0,maxWristTwist=0;
const append=(role,q,time)=>{const c=channels[role]??(channels[role]={times:[],values:[],last:null});q.normalize();if(c.last&&c.last.dot(q)<0)q.set(-q.x,-q.y,-q.z,-q.w);c.times.push(time);c.values.push(q.x,q.y,q.z,q.w);c.last=q.clone();};
for(const time of samples){const pose=poseAt(keys,time),toolQ=qy(pose.yaw??0).multiply(qz(pose.angle)),base=new THREE.Vector3(...pose.position),c=(pose.crouch??0)*Math.PI/180,pelvis=basePelvis.clone();if(options.walk&&MODE!=='fps-arms')pelvis.set(0,gaitHeight(time),0);else if(pose.crouch&&MODE!=='fps-arms')pelvis.set(.005-(.005*Math.cos(c)+.06*Math.sin(c)),.14-.035*Math.sin(c)+.8*Math.cos(c),0);pelvisKeys.push({time,position:pelvis.toArray()});
for(const suffix of ['left','right']){
if(options.leftOnly&&suffix==='right')continue;const side=suffix==='left'?-1:1;
const shoulder=shoulders[suffix].clone().add(pelvis.clone().sub(basePelvis)),upper=root.getObjectByName(j['elbow_'+suffix]).position.clone(),fore=root.getObjectByName(j['wrist_'+suffix]).position.clone();let point=base.clone(),handQ=toolQ.clone();
const restPalmDown=options.neutralBoth||side<0&&!options.leftOnly&&name!=='Reload',relaxedRight=restPalmDown&&side>0&&weapon==='empty';
const frame=s=>graspFrame(s,options.leftOnly?'flashlight':side<0?'reload':weapon);
if(restPalmDown){point.set((MODE==='fps-arms'?.65:.42)+(options.walk?side*.035*Math.sin(time/1.2*Math.PI*2):0),MODE==='fps-arms'?1.20:1.12,side*.27).add(pelvis.clone().sub(basePelvis));handQ=qz(90).multiply(qy(180));if(relaxedRight){point.set((MODE==='fps-arms'?.12:.065)+(options.walk?.035*Math.sin(time/1.2*Math.PI*2):0),MODE==='fps-arms'?.93:.88,MODE==='fps-arms'?.275:.245).add(pelvis.clone().sub(basePelvis));handQ=qy(90);}}
else if(options.leftOnly)handQ.multiply(frame(-1));
else if(side<0){const reload=reloadGrip(time);point.add(reload.point.applyQuaternion(toolQ));handQ.multiply(reload.rotation).multiply(frame(-1));const alpha=Math.max(0,Math.min(1,time/.22,(2.4-time)/.22)),neutral=new THREE.Vector3(MODE==='fps-arms'?.65:.42,MODE==='fps-arms'?1.20:1.12,-.27).add(pelvis.clone().sub(basePelvis));point.lerpVectors(neutral,point,alpha);handQ=qz(90).multiply(qy(180)).slerp(handQ,alpha);}
else handQ.multiply(weapon==='shotgun'?qz(5.710593):new THREE.Quaternion()).multiply(frame(1));
const wrist=point.clone().sub(new THREE.Vector3(...(restPalmDown?[.045,-.09,0]:gripDatum(options.leftOnly?'flashlight':side<0?'reload':weapon))).applyQuaternion(handQ)),towards=wrist.clone().sub(shoulder),distance=towards.length(),l1=upper.length(),l2=fore.length(),admitted=Math.max(.001,Math.min(distance,l1+l2-.0001));if(MODE!=='fps-arms')maxResidual=Math.max(maxResidual,Math.abs(distance-admitted));towards.normalize();
let elbow;if(MODE==='fps-arms'){const foreAxis=new THREE.Vector3(0,-1,0);if(restPalmDown&&!relaxedRight)foreAxis.applyQuaternion(qz(-10));if(weapon==='shotgun'&&side>0)foreAxis.applyQuaternion(qx(-20));else if(options.leftOnly&&side<0)foreAxis.applyQuaternion(qx(30)).applyQuaternion(qz(12));foreAxis.applyQuaternion(handQ);if(weapon==='shotgun'&&(side>0||name==='Reload')){foreAxis.y=Math.max(.15,foreAxis.y);foreAxis.normalize();}elbow=wrist.clone().addScaledVector(foreAxis,-l2);}else{
const cos=Math.max(-1,Math.min(1,(l1*l1+admitted*admitted-l2*l2)/(2*l1*admitted))),perpendicular=wrist.clone().addScaledVector(new THREE.Vector3(0,-1,0).applyQuaternion(handQ),-l2).sub(shoulder);perpendicular.addScaledVector(towards,-perpendicular.dot(towards));if(perpendicular.lengthSq()<1e-10)perpendicular.set(0,-1,side*.7).addScaledVector(towards,-perpendicular.dot(towards));perpendicular.normalize();const center=shoulder.clone().addScaledVector(towards,l1*cos),radius=l1*Math.sqrt(Math.max(0,1-cos*cos)),ortho=towards.clone().cross(perpendicular).normalize();elbow=center.clone().addScaledVector(perpendicular,radius);const frontLimit=.23+pelvis.x-basePelvis.x,constraints=name==='Reload'&&side<0?[{axis:0,sign:1,limit:frontLimit},{axis:2,sign:side,limit:.28}]:[{axis:2,sign:side,limit:.28}],outside=p=>constraints.some(c=>c.sign*p.getComponent(c.axis)>=c.limit-1e-8);
if(!outside(elbow)){const candidates=[];for(const c of constraints){const a=c.sign*perpendicular.getComponent(c.axis),b=c.sign*ortho.getComponent(c.axis),amplitude=Math.hypot(a,b),wanted=(c.limit-c.sign*center.getComponent(c.axis))/radius;if(Math.abs(wanted)>amplitude+1e-6)continue;const offset=Math.atan2(b,a),angle=Math.acos(Math.max(-1,Math.min(1,wanted/amplitude)));for(const t of [offset+angle,offset-angle]){const p=center.clone().addScaledVector(perpendicular,radius*Math.cos(t)).addScaledVector(ortho,radius*Math.sin(t));if(outside(p))candidates.push(p);}}if(!candidates.length)throw Error(name+' elbow clearance exceeds reach');const handAxis=new THREE.Vector3(0,-1,0).applyQuaternion(handQ);elbow=candidates.sort((a,b)=>wrist.clone().sub(b).normalize().dot(handAxis)-wrist.clone().sub(a).normalize().dot(handAxis))[0];}
}
const upperQ=new THREE.Quaternion().setFromUnitVectors(upper.clone().normalize(),elbow.clone().sub(shoulder).normalize()),foreDirection=wrist.clone().sub(elbow).normalize(),localDirection=fore.clone().normalize(),localPalm=new THREE.Vector3(1,0,0).addScaledVector(localDirection,-localDirection.x).normalize(),worldPalm=new THREE.Vector3(1,0,0).applyQuaternion(handQ);worldPalm.addScaledVector(foreDirection,-worldPalm.dot(foreDirection)).normalize();const localFrame=new THREE.Matrix4().makeBasis(localPalm,localDirection,localPalm.clone().cross(localDirection).normalize()),worldFrame=new THREE.Matrix4().makeBasis(worldPalm,foreDirection,worldPalm.clone().cross(foreDirection).normalize()),foreQ=new THREE.Quaternion().setFromRotationMatrix(worldFrame.multiply(localFrame.invert()));
const wristQ=foreQ.clone().invert().multiply(handQ),restAxis=new THREE.Vector3(0,-1,0),posedAxis=restAxis.clone().applyQuaternion(wristQ),bend=restAxis.angleTo(posedAxis)*180/Math.PI,swing=new THREE.Quaternion().setFromUnitVectors(restAxis,posedAxis),twist=swing.invert().multiply(wristQ),twistAngle=2*Math.acos(Math.min(1,Math.abs(twist.w)))*180/Math.PI;maxWristBend=Math.max(maxWristBend,bend);maxWristTwist=Math.max(maxWristTwist,twistAngle);
if(MODE==='fps-arms'){const c=fpsElbowPositions[suffix]??(fpsElbowPositions[suffix]=[]);c.push({time,position:elbow.clone().sub(shoulder).applyQuaternion(upperQ.clone().invert()).toArray()});}append('shoulder_'+suffix,upperQ,time);append('elbow_'+suffix,upperQ.clone().invert().multiply(foreQ),time);append('wrist_'+suffix,foreQ.clone().invert().multiply(handQ),time);
}
for(const suffix of ['left','right'])for(const role of ['hip','knee','ankle'])legKeys[suffix][role].push({time,rotation:[0,0,options.walk?gait(time,suffix)[role]:role==='knee'?-2*(pose.crouch??0):pose.crouch??0]});
}
if(maxResidual>.003)throw Error(name+' authored hand target exceeds anatomical reach');
const tracks=Object.entries(channels).map(([role,v])=>new THREE.QuaternionKeyframeTrack(j[role]+'.quaternion',v.times,v.values));for(const [suffix,keys]of Object.entries(fpsElbowPositions))tracks.push(positionTrack(j['elbow_'+suffix],keys,'LINEAR'));
if(MODE!=='fps-arms'&&!options.leftOnly&&(options.walk||name==='AxeUse')){tracks.push(positionTrack(j.pelvis,pelvisKeys,'LINEAR'),rot('chest',[[0,[0,0,0]],[length,[0,0,0]]]));for(const suffix of ['left','right'])for(const role of ['hip','knee','ankle'])tracks.push(rotationTrack(j[role+'_'+suffix],legKeys[suffix][role],'LINEAR'));}
for(const suffix of ['left','right']){if(options.leftOnly&&suffix==='right'||!options.leftOnly&&suffix==='left'&&name!=='Reload'||weapon==='empty')continue;
const rotations=graspRotations(suffix==='left'?-1:1,options.leftOnly?'flashlight':suffix==='left'?'reload':weapon);
if(name==='Reload'&&suffix==='left'){
const pinch=graspRotations(-1,'reload','shell'),frames=[[0,'empty'],[.30,'empty'],[.36,'foreend'],[.42,'foreend'],[.48,'empty'],[.55,'empty'],[.67,'shell'],[1.80,'shell'],[1.82,'empty'],[2.10,'empty'],[2.14,'foreend'],[2.18,'foreend'],[2.24,'empty'],[2.40,'empty']];
for(const role of Object.keys(rotations)){const roleFrames=role.startsWith('thumb_left')?[[0,'empty'],[.15,'empty'],[.22,'foreend'],[.58,'foreend'],[.64,'empty'],[.67,'shell'],[1.80,'shell'],[1.815,'release'],[1.90,'release'],[1.96,'empty'],[2.00,'foreend'],[2.24,'foreend'],[2.40,'empty']]:role.startsWith('finger_left_0')?[[0,'empty'],[.30,'empty'],[.36,'foreend'],[.42,'foreend'],[.48,'empty'],[.55,'empty'],[.67,'shell'],[1.80,'shell'],[1.815,'release'],[1.90,'release'],[1.96,'empty'],[2.10,'empty'],[2.14,'foreend'],[2.18,'foreend'],[2.24,'empty'],[2.40,'empty']]:[[0,'empty'],[.30,'empty'],[.36,'foreend'],[.42,'foreend'],[.48,'empty'],[.55,'empty'],[.67,'shell'],[1.90,'shell'],[1.96,'empty'],[2.10,'empty'],[2.14,'foreend'],[2.18,'foreend'],[2.24,'empty'],[2.40,'empty']],times=roleFrames.map(k=>k[0]),values=[];let previous;for(const [,state]of roleFrames){const q=state==='empty'?new THREE.Quaternion():state==='release'?pinch[role].clone().premultiply(qz(role.endsWith('_a')?(role.startsWith('thumb')?15:-15):0)):(state==='shell'?pinch[role]:rotations[role]).clone();if(previous&&previous.dot(q)<0)q.set(-q.x,-q.y,-q.z,-q.w);values.push(...q.toArray());previous=q;}tracks.push(new THREE.QuaternionKeyframeTrack(j[role]+'.quaternion',times,values));}
for(const role of ['finger_left_0_a','thumb_left_a']){const rest=root.getObjectByName(j[role]).position.clone(),times=[0,.55,.67,1.90,1.96,2.40],values=times.flatMap(t=>[rest.x,rest.y,t>=.67&&t<=1.90?0:rest.z]);tracks.push(new THREE.VectorKeyframeTrack(j[role]+'.position',times,values));}
}else {for(const [role,q]of Object.entries(rotations)){const values=q.toArray();tracks.push(new THREE.QuaternionKeyframeTrack(j[role]+'.quaternion',[0,length],[...values,...values]));}if(suffix==='right'&&weapon==='shotgun'){tracks.push(pos('thumb_right_a',[[0,[.027,-.076,.040]],[length,[.027,-.076,.040]]]),pos('finger_right_0_a',[[0,[.034,-.106,.043]],[length,[.034,-.106,.043]]]));const ready=triggerIndexRotations(),fired=triggerIndexRotations(true),frames=name==='ShotgunFire'?[[0,ready],[.012,ready],[.020,fired],[.055,fired],[.16,ready],[.32,ready]]:[[0,ready],[length,ready]];for(const role of Object.keys(ready)){const times=frames.map(f=>f[0]),values=[];let previous;for(const [,pose]of frames){const q=pose[role].clone();if(previous&&previous.dot(q)<0)q.set(-q.x,-q.y,-q.z,-q.w);values.push(...q.toArray());previous=q;}tracks.push(new THREE.QuaternionKeyframeTrack(j[role]+'.quaternion',times,values));}}}
}
poseReach[name]={maxWristBendDegrees:maxWristBend,maxWristTwistDegrees:maxWristTwist,palmRest:'ground-facing; forward relaxed forearms',samples:samples.length,sampleRate:keys.length===2&&!options.walk&&name!=='Reload'?null:30,maxUnreachableResidualMeters:maxResidual,leftHand:options.leftOnly?'flashlight':name==='Reload'?'reload-shell/foreend':'empty-rest',rightHand:options.leftOnly?'unmodified':weapon};return createClip(name,length,tracks,{loop:!!options.walk||!!options.leftOnly||!!options.loop});
}
const neutralPose={position:[.34,1.12,.27],angle:0,crouch:0};
clips.push(held('Idle',3,[{time:0,...neutralPose},{time:3,...neutralPose}],'empty',{neutralBoth:true,loop:true}),held('Walk',1.2,[{time:0,...neutralPose},{time:1.2,...neutralPose}],'empty',{neutralBoth:true,walk:true}));
const axePose={position:[.45,1.38,.24],angle:10,crouch:0},gunPose={position:MODE==='fps-arms'?[.72,1.14,.24]:[.34,1.10,.24],angle:0,crouch:0},constant=(pose,length)=>[{time:0,...pose},{time:length,...pose}];
clips.push(held('AxeHold',1,constant(axePose,1),'axe'));
clips.push(held('AxeUse',1.4,[{time:0,...axePose},{time:.4,position:[.43,1.43,.24],angle:20,crouch:0},{time:.812,position:[.38,.91,.24],angle:-80,crouch:35},{time:1.05,position:[.40,1.10,.24],angle:-65,crouch:25},{time:1.4,...axePose}],'axe'));
clips.push(held('GripAim',1,constant(gunPose,1),'shotgun')); // GripAim is the single canonical shotgun hold
clips.push(held('ShotgunFire',.32,[{time:0,...gunPose},{time:.055,...gunPose,position:[gunPose.position[0]-.035,gunPose.position[1]+.008,.24],angle:1.5,crouch:0},{time:.32,...gunPose}],'shotgun'));
clips.push(held('Reload',2.4,[{time:0,...gunPose},{time:.3,...gunPose,yaw:35,angle:30,position:MODE==='fps-arms'?[.78,1.10,.20]:[.28,1.08,.20]},{time:2.1,...gunPose,yaw:35,angle:30,position:MODE==='fps-arms'?[.78,1.10,.20]:[.28,1.08,.20]},{time:2.4,...gunPose}],'shotgun'));
clips.push(held('WalkAxe',1.2,constant(axePose,1.2),'axe',{walk:true}),held('WalkShotgun',1.2,constant(gunPose,1.2),'shotgun',{walk:true}));
clips.push(held('FlashlightHold',1,constant({position:MODE==='fps-arms'?[.65,1.32,-.24]:[.22,1.36,-.16],angle:0,crouch:0},1),'flashlight',{leftOnly:true}));
const contract=new THREE.Object3D();contract.name='CaretakerAnimationContract';contract.userData.caretakerAnimation={version:3,handFrame:{palmNormalLocal:[1,0,0],fingerLongAxisLocal:[0,-1,0],knuckleRowLocal:[0,0,1],neutralPalmWorld:[0,-1,0],neutralBodyGrip:[.34,1.12,.27],neutralFpsGrip:[.65,1.20,.27],toolGripDatums:{axe:gripDatum('axe'),shotgun:gripDatum('shotgun'),flashlight:gripDatum('flashlight'),reload:gripDatum('reload')},grasp:'Actual exported per-row handle polygon tangent wraps; mirrored fingers, opposing CMC/MCP/IP thumb',elbowClearance:{lateralMeters:.28,reloadLeftFrontMeters:.23},reloadFrame:{shaftRollDegrees:-40,knuckleRowTool:'-X',palm:'up toward foreend and inward',fingers:'down and around foreend'}},wristGuide:{observedMaxBendDegrees:Math.max(...Object.values(poseReach).map(p=>p.maxWristBendDegrees)),observedMaxTwistDegrees:Math.max(...Object.values(poseReach).map(p=>p.maxWristTwistDegrees)),scope:'Measured authored rotations; per-clip values are in CaretakerPoseDiagnostics. Lower-elbow FPS shotgun presentation is distinct from the full-body pose.'},events:{AxeUse:[{phase:.58,event:'cut_window_begin'},{phase:.68,event:'cut_window_end'}],ShotgunFire:[{phase:.0625,event:'fire'}],Reload:[{phase:.3,event:'extract_shells'},{phase:.75,event:'insert_shells'},{phase:1,event:'breech_closed'}]},reload:{duration:2.4,breechKeys,shellKeys,leftContact:[.72,1.8],mechanism:'side-by-side break action',hand:'right holds stock; left grasps pair of shell heads then returns foreend'},walk:{duration:1.2,runTimeScale:1.6,cameraMotion:false},flashlight:{overlay:'left arm/fingers only',socket:'grip_left_flashlight',off:'empty left rest',reload:'consumer switches off/stows before Reload; does not auto-resume'}};root.add(contract);const diagnostics=new THREE.Object3D();diagnostics.name='CaretakerPoseDiagnostics';diagnostics.userData.caretakerPoseDiagnostics={version:1,poseReach,guide:'Native sample wrist/IK guide; actual attached skin/tool surface evidence is separate'};root.add(diagnostics);
return clips;
}Scroll code horizontally
Asset content follows the supplied CC0-1.0 licence record. Kiln and scene software retain their own licences.