wobnimo 0.0.0-stage → 0.1.0
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/AGENTS.md +84 -0
- package/LICENSE +21 -0
- package/dist/characters/boo.d.ts +6 -0
- package/dist/characters/boo.js +1 -0
- package/dist/characters/index.d.ts +12 -0
- package/dist/characters/index.js +692 -0
- package/dist/characters/inky.d.ts +6 -0
- package/dist/characters/inky.js +1 -0
- package/dist/characters/microduck.d.ts +10 -0
- package/dist/characters/microduck.js +1 -0
- package/dist/characters/miso.d.ts +6 -0
- package/dist/characters/miso.js +1 -0
- package/dist/characters/mochi.d.ts +6 -0
- package/dist/characters/mochi.js +1 -0
- package/dist/characters/pebble.d.ts +6 -0
- package/dist/characters/pebble.js +1 -0
- package/dist/characters/pip.d.ts +6 -0
- package/dist/characters/pip.js +1 -0
- package/dist/characters/rex.d.ts +6 -0
- package/dist/characters/rex.js +1 -0
- package/dist/characters/tad.d.ts +6 -0
- package/dist/characters/tad.js +1 -0
- package/dist/characters/volt.d.ts +6 -0
- package/dist/characters/volt.js +1 -0
- package/dist/element-DRDEWSGV.d.ts +8 -0
- package/dist/element.d.ts +2 -0
- package/dist/element.js +692 -0
- package/dist/index.d.ts +155 -0
- package/dist/index.js +692 -0
- package/dist/react.d.ts +23 -0
- package/dist/react.js +692 -0
- package/dist/status-DVudJbtp.d.ts +197 -0
- package/dist/types-PAZ6PnKv.d.ts +308 -0
- package/dist/wobnimo.js +692 -0
- package/package.json +74 -4
- package/README.md +0 -3
package/dist/wobnimo.js
ADDED
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
var C=()=>Z(new Float32Array(16));function Z(t){return t.fill(0),t[0]=t[5]=t[10]=t[15]=1,t}function _(t,e,r){let a=new Float32Array(16);for(let o=0;o<4;o++)for(let i=0;i<4;i++)a[o*4+i]=e[i]*r[o*4]+e[4+i]*r[o*4+1]+e[8+i]*r[o*4+2]+e[12+i]*r[o*4+3];return t.set(a),t}function ne(t,e,r,a){return Z(t),t[12]=e,t[13]=r,t[14]=a,t}function Ne(t,e,r,a){return Z(t),t[0]=e,t[5]=r,t[10]=a,t}function Q(t,e,r,a){let o=Math.cos(e),i=Math.sin(e),s=Math.cos(r),n=Math.sin(r),l=Math.cos(a),h=Math.sin(a);return Z(t),t[0]=l*s,t[1]=h*s,t[2]=-n,t[4]=l*n*i-h*o,t[5]=h*n*i+l*o,t[6]=s*i,t[8]=l*n*o+h*i,t[9]=h*n*o-l*i,t[10]=s*o,t}function le(t,e,r){let[a,o,i]=e,s=Math.cos(r),n=Math.sin(r),l=1-s;return Z(t),t[0]=l*a*a+s,t[1]=l*a*o+n*i,t[2]=l*a*i-n*o,t[4]=l*a*o-n*i,t[5]=l*o*o+s,t[6]=l*o*i+n*a,t[8]=l*a*i+n*o,t[9]=l*o*i-n*a,t[10]=l*i*i+s,t}function ye(t,e){let[r,a,o,i,s,n,l,h,f,c,d,m,u,y,w,x]=e,M=r*n-a*s,E=r*l-o*s,z=r*h-i*s,V=a*l-o*n,P=a*h-i*n,F=o*h-i*l,b=f*y-c*u,N=f*w-d*u,D=f*x-m*u,I=c*w-d*y,B=c*x-m*y,j=d*x-m*w,H=M*j-E*B+z*I+V*D-P*N+F*b;if(!H)return Z(t);let v=1/H;return t[0]=(n*j-l*B+h*I)*v,t[1]=(o*B-a*j-i*I)*v,t[2]=(y*F-w*P+x*V)*v,t[3]=(d*P-c*F-m*V)*v,t[4]=(l*D-s*j-h*N)*v,t[5]=(r*j-o*D+i*N)*v,t[6]=(w*z-u*F-x*E)*v,t[7]=(f*F-d*z+m*E)*v,t[8]=(s*B-n*D+h*b)*v,t[9]=(a*D-r*B-i*b)*v,t[10]=(u*P-y*z+x*M)*v,t[11]=(c*z-f*P-m*M)*v,t[12]=(n*N-s*I-l*b)*v,t[13]=(r*I-a*N+o*b)*v,t[14]=(y*E-u*V-w*M)*v,t[15]=(f*V-c*E+d*M)*v,t}function we(t,e){let[r,a,o]=e;return [t[0]*r+t[4]*a+t[8]*o+t[12],t[1]*r+t[5]*a+t[9]*o+t[13],t[2]*r+t[6]*a+t[10]*o+t[14]]}function ke(t,e){let[r,a,o]=e;return [t[0]*r+t[4]*a+t[8]*o,t[1]*r+t[5]*a+t[9]*o,t[2]*r+t[6]*a+t[10]*o]}var R=(t,e,r)=>Math.min(r,Math.max(e,t)),oe=(t,e,r)=>t+(e-t)*r,ze=(t,e,r)=>{let a=R((r-t)/(e-t),0,1);return a*a*(3-2*a)},De=t=>t<.5?4*t*t*t:1-Math.pow(-2*t+2,3)/2;function J(t){let e=Math.floor(t*4294967295)>>>0||1;return ()=>{e=e+1831565813>>>0;let r=e;return r=Math.imul(r^r>>>15,r|1),r^=r+Math.imul(r^r>>>7,r|61),((r^r>>>14)>>>0)/4294967296}}var k=class{constructor(e=0){this.x=e;}v=0;step(e,r,a,o){let i=a*Math.PI*2;return this.v+=(i*i*(e-this.x)-2*o*i*this.v)*r,this.x+=this.v*r,this.x}};var F0=[{round:0,open:1,weight:.34},{round:.08,open:.55,weight:.26},{round:.7,open:.85,weight:.24},{round:1,open:.5,weight:.16}],ce=class{constructor(e){this.random=e;this.silence=.15+e()*.3;}open=0;round=0;age=0;length=0;stress=0;silence=0;syllablesLeft=0;wordsLeft=0;reset(){this.age=this.length=this.open=0,this.syllablesLeft=this.wordsLeft=0,this.silence=.12;}update(e){if(this.silence>0){this.silence-=e,this.open=0;return}this.age+=e,this.age>=this.length&&this.next();let r=R(this.age/this.length,0,1);this.open=this.stress*Math.pow(Math.sin(Math.PI*r),.55);}next(){let e=this.random;this.age=0;let r=this.syllablesLeft===0;r&&(this.wordsLeft===0?(this.wordsLeft=3+Math.floor(e()*5),this.silence=this.length>0?.45+e()*.7:0):this.silence=.04+e()*.09,this.wordsLeft--,this.syllablesLeft=1+Math.floor(Math.pow(e(),1.6)*3)),this.syllablesLeft--;let a=r&&e()<.6,o=I0(F0,e());this.length=.12+e()*.13,this.stress=o.open*(a?.85+e()*.15:.5+e()*.35),this.round=o.round;}};function I0(t,e){for(let r of t){if(e<r.weight)return r;e-=r.weight;}return t[0]}var T=["idle","thinking","listening","speaking","sleeping","working","error","surprised","celebrating","sad"],$=[...T,"happy"],ie=Object.fromEntries($.map((t,e)=>[t,e])),Se={idle:{lid:.06,squint:0,smile:.35,tilt:0,energy:1,flap:.05,glow:[.45,.7,1],exposure:1,wide:0,asym:0},thinking:{lid:.4,squint:0,smile:-0.15,tilt:.22,energy:.6,flap:0,glow:[1,.55,.12],exposure:1,wide:0,asym:0},listening:{lid:0,squint:0,smile:.2,tilt:-0.08,energy:.8,flap:.05,glow:[.25,1,.5],exposure:1,wide:.15,asym:0},speaking:{lid:.04,squint:.1,smile:.45,tilt:0,energy:1.2,flap:.1,glow:[.35,.82,1],exposure:1,wide:0,asym:0},sleeping:{lid:1,squint:0,smile:0,tilt:0,energy:.35,flap:0,glow:[.08,.09,.18],exposure:.84,wide:0,asym:0},working:{lid:.3,squint:.2,smile:.05,tilt:0,energy:1.3,flap:.18,glow:[.6,.45,1],exposure:1,wide:0,asym:0},error:{lid:.12,squint:.15,smile:-0.45,tilt:.1,energy:.9,flap:.25,glow:[1,.16,.12],exposure:.97,wide:.2,asym:1},surprised:{lid:0,squint:0,smile:0,tilt:0,energy:1,flap:.55,glow:[.95,.95,1],exposure:1.04,wide:1,asym:0},celebrating:{lid:0,squint:1,smile:1,tilt:0,energy:1.8,flap:.9,glow:[1,.72,.2],exposure:1.08,wide:0,asym:0},sad:{lid:.42,squint:0,smile:-0.85,tilt:-0.32,energy:.35,flap:-0.12,glow:[.22,.32,.7],exposure:.9,wide:0,asym:0},happy:{lid:0,squint:1,smile:1,tilt:0,energy:1.6,flap:.3,glow:[1,.42,.72],exposure:1.05,wide:0,asym:0}};var B0={float:0,hop:.16,squash:1,snap:1,look:1,snapLook:0,talkSquash:0},pe=.11,j0=1.8,G=class{temperament;state="idle";pointer=null;shown="idle";previous="idle";switched=10;time=0;since=0;random;yaw=new k;pitch=new k;roll=new k;squash=new k;hover;face={lid:new k,squint:new k,smile:new k(.3),tilt:new k,talk:new k,round:new k,gazeX:new k,gazeY:new k,flap:new k,energy:new k(1),exposure:new k(1),wide:new k,asym:new k};weights;glow=[...Se.idle.glow];jump=null;look={yaw:0,pitch:0,x:0,y:0};saccade={x:0,y:0,next:0};nextLook=.6;nextBlink;blinkAge=-1;nextHop;nextSide=4;side=1;nextNod=2.5;shake={start:-10,amount:0,next:0};sigh={start:-10,next:0};reactUntil=-1;speech;lastTalk=0;syllableArmed=true;matrices={a:C(),b:C()};pose;constructor(e={},r=.5){this.temperament={...B0,...e},this.random=J(r),this.speech=new ce(this.random),this.nextBlink=1+this.random()*3,this.nextHop=6+this.random()*6,this.hover=new k(this.temperament.float),this.weights=Object.fromEntries($.map(a=>[a,new k(a==="idle"?1:0)])),this.pose={root:C(),minScale:1,lift:0,channels:{yaw:0,pitch:0,roll:0,flap:0,talk:0,energy:1},weights:Object.fromEntries($.map(a=>[a,a==="idle"?1:0])),expression:"idle",faceA:[0,0,0,0],faceB:[0,0,0,0],faceC:[0,0,1,0],faceD:[0,0,0,0],glow:this.glow,exposure:1,events:[]};}setState(e){e!==this.state&&(this.state=e,this.since=0,e==="speaking"&&this.speech.reset(),this.nextLook=0);}poke(){this.hop(this.temperament.hop*1.5,this.random()<.5?1:-1),this.reactUntil=this.time+j0;}update(e){if(!(e>0))return;let r=Math.max(1,Math.ceil(e/(1/120)));for(let a=0;a<r;a++)this.step(e/r);}enter(e,r){let a=this.temperament;e==="surprised"?(this.hop(a.hop*.6,0),this.pitch.v+=1.2,this.startShake(r,.35,1/0)):e==="error"?(this.side=this.random()<.5?1:-1,this.squash.v-=2.5,this.startShake(r,1,r+2+this.random())):e==="celebrating"?this.nextHop=r:e==="sad"&&(this.sigh.next=r+1.2);}startShake(e,r,a){this.shake.start=e,this.shake.amount=r,this.shake.next=a;}hop(e,r){if(this.jump)return;let a=this.temperament.float>0;this.jump={age:a?pe:0,height:e,spin:r,lean:(this.random()-.5)*.3,air:.42+e*.45+(a?.25:0),landed:false};}step(e){this.time+=e,this.since+=e,this.switched+=e;let r=this.time,a=this.random,o=this.temperament,i=this.pose.events,s=r<this.reactUntil?"happy":this.state;s!==this.shown&&(this.previous=this.shown,this.shown=s,this.switched=0,i.push(`enter:${s}`),this.enter(s,r));let n=Se[s];r>this.nextLook&&(this.look.yaw=(a()-.5)*.75,this.look.pitch=(a()-.5)*.24,this.look.x=R(this.look.yaw*2.2,-1,1),this.look.y=a()<.3?.6:a()<.2?-0.6:0,this.nextLook=r+oe(1.4+a()*2.6,.45+a()*1.1,o.snapLook)),r>this.saccade.next&&(this.saccade.x=(a()-.5)*.22,this.saccade.y=(a()-.5)*.14,this.saccade.next=r+.25+a()*.7);let l=0,h=0,f=0,c=Math.sin(r*1.9)*.008,d=0,m=0,u=0,y=0,w=n.flap,x=1.3,M=.62,E=o.float,z=this.pointer,V=z&&(s==="idle"||s==="listening"||s==="speaking"||s==="surprised");switch(s){case "idle":l=this.look.yaw,h=this.look.pitch,f=-this.look.yaw*.16,d=this.look.x,m=this.look.y,r>this.nextHop&&(this.hop(o.hop*(.9+a()*.4),a()<.35?a()<.5?1:-1:0),this.nextHop=r+7+a()*7);break;case "thinking":{r>this.nextSide&&(this.side=-this.side,this.nextSide=r+3+a()*2);let g=this.side;l=.24*g+Math.sin(r*.9)*.05,h=.17+Math.sin(r*1.3)*.03,f=-0.13*g,d=.7*g,m=.8,x=.9;break}case "listening":l=-0.14,h=.02,f=.17,d=-0.2,r>this.nextNod&&(this.pitch.v-=.9,this.nextNod=r+2+a()*2.5);break;case "speaking":{l=Math.sin(r*.7)*.12,f=Math.sin(r*.9)*.05,this.speech.update(e),u=this.speech.open,y=this.speech.round,h=.04+u*.07,c+=u*.014,w+=Math.sin(r*2.6)*.1,x=1.8;break}case "sleeping":h=-0.3,f=.13,l=.06,c=Math.sin(r*1.15)*.016,u=.12+.1*Math.sin(r*1.15),y=.7,E*=.65,x=.55,M=.9,r>this.nextNod&&(this.pitch.v-=.5,this.nextNod=r+5+a()*4);break;case "working":l=Math.sin(r*.8)*.07,h=-0.13+Math.abs(Math.sin(r*5.2))*.03,f=Math.sin(r*.6)*.04,d=Math.sin(r*1.6)*.45,m=-0.55,w+=Math.sin(r*11)*.06,x=1.6;break;case "error":{r>this.shake.next&&this.startShake(r,.55,2.4+a()*1.4);let g=this.side;f=.16*g,l=-0.1*g,h=.05,d=.45*g,m=.3,u=.16,x=1.5;break}case "surprised":h=.1,u=.42,y=1,x=2.2,M=.5;break;case "celebrating":l=Math.sin(r*3.1)*.22,f=Math.sin(r*6.2)*.1,h=.14,u=.6+.12*Math.sin(r*7),y=.05,w+=Math.sin(r*9)*.25,x=2,r>this.nextHop&&(this.hop(o.hop*1.25,a()<.3?a()<.5?1:-1:0),this.nextHop=r+.85+a()*.4);break;case "sad":{r>this.sigh.next&&(this.sigh.start=r,this.sigh.next=r+4+a()*2.5);let g=Math.sin(R((r-this.sigh.start)/1.7,0,1)*Math.PI);h=-0.24+g*.1,l=Math.sin(r*.3)*.1,f=.08,d=-0.15,m=-0.65+g*.3,c+=g*.018,E*=.7,x=.7,M=.85;break}case "happy":l=Math.sin(r*2.2)*.18,f=Math.sin(r*4.4)*.12,h=.12,u=.5+.15*Math.sin(r*8),y=.2,r>this.nextHop&&(this.hop(o.hop*1.05,0),this.nextHop=r+1.05+a()*.4);break}V&&z&&(l=R(z.x,-1,1)*.55,h=R(-z.y,-1,1)*.32+(s==="speaking"?u*.07:0),f=-l*.12+(s==="listening"?.12:0),d=R(z.x*2,-1,1),m=R(-z.y*1.5,-1,1)),s!=="sleeping"&&(d+=this.saccade.x,m+=this.saccade.y),o.float>0&&(c+=Math.sin(r*1.5)*.035);let P=oe(x,x*3.2,o.snapLook)*o.snap,F=oe(M,.95,o.snapLook);this.yaw.step(l*o.look,e,P,F),this.pitch.step(h*o.look,e,P,F),this.roll.step(f,e,x*o.snap,M),this.hover.step(E,e,.6,.8);let b=this.face;b.lid.step(n.lid,e,2.2,.9),b.squint.step(n.squint,e,3,.8),b.smile.step(n.smile,e,2.4,.75),b.tilt.step(n.tilt*this.side,e,1.6,.8),b.talk.step(u,e,14,.8),b.round.step(y,e,6,.8),b.gazeX.step(d,e,7,.85),b.gazeY.step(m,e,7,.85),b.flap.step(w,e,2.4*o.snap,.5),b.energy.step(n.energy,e,.8,1),b.exposure.step(n.exposure,e,.4,1),b.wide.step(n.wide,e,5,.6),b.asym.step(n.asym*this.side,e,3,.8);for(let g of $)this.weights[g].step(g===s?1:0,e,1.6*o.snap,.95);let N=1-Math.exp(-e*4),D=s==="thinking"?.55+.45*Math.sin(r*4.2):s==="speaking"?.6+.6*b.talk.x:s==="working"?.75+.25*Math.sin(r*7):s==="error"?Math.sin(r*7)>0?1.1:.45:1;for(let g=0;g<3;g++)this.glow[g]=oe(this.glow[g],n.glow[g]*D,N);this.syllableArmed&&b.talk.x>.55&&this.lastTalk<=.55&&s==="speaking"&&(i.push("syllable"),this.syllableArmed=false),b.talk.x<.35&&(this.syllableArmed=true),this.lastTalk=b.talk.x;let I=0,B=0,j=0,H=0,v=this.jump;if(v)if(v.age+=e,v.age<pe)H=.14;else {let g=(v.age-pe)/v.air;g<1?(g<.06&&this.squash.x>.05&&(this.squash.v=-2.6),I=4*v.height*g*(1-g),B=v.spin*Math.PI*2*De(R(g*1.08,0,1)),j=v.lean*Math.sin(g*Math.PI),H=g<.5?-0.05:0):v.landed?v.age-pe-v.air>.35&&(this.jump=null):(v.landed=true,o.float===0&&(this.squash.v+=3.2,i.push("land")));}o.float>0&&(H*=.3),this.squash.step(H,e,3.2,.32),r>this.nextBlink&&(this.blinkAge=0,this.nextBlink=r+2.2+a()*3.5,a()<.2&&(this.nextBlink=r+.35));let Fe=0;this.blinkAge>=0&&(this.blinkAge+=e,Fe=Math.sin(R(this.blinkAge/.17,0,1)*Math.PI),this.blinkAge>.17&&(this.blinkAge=-1));let xe=s==="sleeping",Ie=Math.sin(r*(xe?1.15:2.1))*(xe?.024:.01),Be=this.squash.x*o.squash+b.talk.x*.05*o.talkSquash,ve=1+Be*.55-Ie*.5,je=1-Be+Ie,Te=I+c+this.hover.x,{a:q0,b:P0}=this.matrices,ae=this.pose.root;ne(ae,0,Te,0),_(ae,ae,Q(q0,0,B,j)),_(ae,ae,Ne(P0,ve,je,ve));let L=this.pose;L.minScale=Math.min(ve,je),L.lift=Te,L.expression=s;let Y=L.channels,Oe=this.shake.amount*Math.max(0,1-(r-this.shake.start)/.6);Y.yaw=this.yaw.x+Math.sin(r*31)*.06*Oe,Y.pitch=this.pitch.x,Y.roll=this.roll.x+Math.sin(r*38)*.07*Oe,Y.flap=b.flap.x,Y.talk=b.talk.x,Y.energy=b.energy.x;let Ve=0;for(let g of $)Ve+=Math.max(0,this.weights[g].x);for(let g of $)L.weights[g]=Math.max(0,this.weights[g].x)/(Ve||1);L.faceA=[xe?0:Fe,b.lid.x,b.squint.x,b.smile.x],L.faceB=[b.talk.x,b.gazeX.x,b.gazeY.x,b.tilt.x],L.faceC=[ie[this.shown],ie[this.previous],R(this.switched/.35,0,1),this.switched<.3?1-this.switched/.3:0],L.faceD=[this.since,b.round.x,b.wide.x,b.asym.x],L.exposure=b.exposure.x;}};var ee=32,T0={z:0,bubble:1,sparkle:2,heart:3,note:4,arc:5,puff:6,ring:7,drop:8,spark:9,mote:10,feather:11,dot:12,exclaim:13,warning:14,confetti:15,cloud:16,star:17,gear:18},Me={sleeping:[{glyph:"z",anchor:"top",rate:.55,offset:[.12,.04,.05],spread:.02,velocity:[.07,.13,0],jitter:.015,wobble:.05,life:[3,3.6],size:[.045,.12],rotation:-0.2,spin:.12,color:"#7f88ad"}],thinking:[{glyph:"dot",anchor:"top",rate:1.1,offset:[.16,.02,.06],spread:.01,velocity:[.05,.11,0],jitter:.01,wobble:.02,life:[1.5,1.8],size:[.012,.04],color:"#a3abc9"}],listening:[{glyph:"arc",anchor:"ear",rate:1.5,offset:[-0.4,0,.04],velocity:[.3,0,0],life:[1.05,1.2],size:[.1,.05],rotation:0,color:"#5cc489"}],syllable:[{glyph:"arc",anchor:"mouth",rate:2,offset:[.1,0,.06],mirror:true,velocity:[.24,.02,.04],jitter:.02,life:[.55,.7],size:[.03,.085],rotation:0,color:"#6aaee6"}],"enter:happy":[{glyph:"sparkle",anchor:"top",rate:7,spread:.22,velocity:[0,.3,.05],jitter:.4,gravity:.5,drag:1.5,life:[.7,1.1],size:[.06,0],spin:2.4,color:"#ffc94d"},{glyph:"heart",anchor:"top",rate:2,spread:.12,velocity:[0,.32,.05],jitter:.15,wobble:.06,life:[1,1.3],size:[.045,.08],color:"#ff6b8f"}],happy:[{glyph:"sparkle",anchor:"top",rate:2.5,spread:.35,velocity:[0,.14,0],jitter:.1,life:[.6,.9],size:[.045,0],spin:1.6,color:"#ffd166"}],working:[{glyph:"gear",anchor:"top",rate:.7,offset:[.12,.02,.05],spread:.03,velocity:[.05,.1,0],jitter:.02,wobble:.02,life:[2,2.4],size:[.035,.065],spin:2.2,color:"#a99cf0"},{glyph:"dot",anchor:"top",rate:2.2,offset:[-0.16,.06,.05],spread:.02,velocity:[-0.06,.14,0],jitter:.03,life:[.8,1.1],size:[.015,.006],color:"#c7bfff",glow:true}],"enter:error":[{glyph:"warning",anchor:"top",rate:1,offset:[.02,.12,.08],velocity:[0,.16,0],drag:2.2,life:[1.5,1.5],size:[.12,.1],color:"#ff4d3d"},{glyph:"spark",anchor:"top",rate:6,offset:[0,0,.05],velocity:[0,.4,0],jitter:1.3,gravity:1.6,life:[.25,.4],size:[.035,.015],color:"#ffd166",glow:true,align:true}],error:[{glyph:"puff",anchor:"top",rate:2.2,offset:[.02,.02,0],spread:.04,velocity:[0,.16,0],jitter:.05,wobble:.04,drag:.4,life:[1.3,1.7],size:[.04,.13],color:"#8b8fa3"}],"enter:surprised":[{glyph:"exclaim",anchor:"top",rate:1,offset:[.04,.14,.06],velocity:[0,.3,0],drag:3.5,life:[1.1,1.1],size:[.11,.08],rotation:-0.15,color:"#ffcc33"},{glyph:"spark",anchor:"top",rate:8,offset:[0,.02,.04],spread:.04,velocity:[0,.5,0],jitter:1.1,drag:4,life:[.3,.42],size:[.05,.02],color:"#ffe08a",align:true}],celebrating:[{glyph:"confetti",anchor:"top",rate:2.6,spread:.25,velocity:[0,.7,.05],jitter:.7,gravity:.9,drag:1.4,wobble:.06,life:[1.6,2.2],size:[.03,.026],spin:7,color:"#ff5d8f"},{glyph:"confetti",anchor:"top",rate:2.6,spread:.25,velocity:[0,.7,.05],jitter:.7,gravity:.9,drag:1.4,wobble:.06,life:[1.6,2.2],size:[.03,.026],spin:-6,color:"#ffc933"},{glyph:"confetti",anchor:"top",rate:2.6,spread:.25,velocity:[0,.7,.05],jitter:.7,gravity:.9,drag:1.4,wobble:.06,life:[1.6,2.2],size:[.03,.026],spin:8,color:"#4dc3ff"},{glyph:"confetti",anchor:"top",rate:2.6,spread:.25,velocity:[0,.7,.05],jitter:.7,gravity:.9,drag:1.4,wobble:.06,life:[1.6,2.2],size:[.03,.026],spin:-7,color:"#5ee08f"}],"enter:celebrating":[{glyph:"star",anchor:"top",rate:6,spread:.1,velocity:[0,.55,.05],jitter:.9,gravity:.6,drag:1.6,life:[.8,1.2],size:[.06,.02],spin:2,color:"#ffd23f"}],sad:[{glyph:"cloud",anchor:"top",rate:.42,offset:[-0.12,.22,.02],velocity:[0,0,0],wobble:.015,life:[2.6,2.6],size:[.15,.15],color:"#9aa3bd"},{glyph:"drop",anchor:"top",rate:4,offset:[-0.12,.16,.03],spread:.08,velocity:[0,-0.25,0],gravity:1.2,life:[.45,.6],size:[.018,.014],color:"#6aa8ff",align:true}],land:[{glyph:"puff",anchor:"feet",rate:7,spread:.1,velocity:[0,.05,0],jitter:.32,drag:3.5,life:[.45,.7],size:[.05,.12],color:"#c4cad9"}]};function O0(t){let e=parseInt(t.replace("#",""),16);return [(e>>16&255)/255,(e>>8&255)/255,(e&255)/255]}function He(t,e){return t==="drop"?Math.atan2(e[0],-e[1]):Math.atan2(e[1],e[0])}var U=class{constructor(e,r){this.character=e;this.random=r;let a=e.spec.fx??{},o=new Set([...Object.keys(Me),...Object.keys(a)].filter(i=>i!=="replace"));for(let i of o){let s=a[i]??[],n=a.replace?.includes(i)?s:[...Me[i]??[],...s];this.emitters[i]=n.filter(l=>e.anchors[l.anchor]);}}a=new Float32Array(ee*4);b=new Float32Array(ee*4);c=new Float32Array(ee*4);count=0;emitters={};carry=new Map;particles=[];update(e,r,a){for(let i of this.emitters[r.expression]??[])this.emitContinuous(i,e*r.weights[r.expression],a);for(let i of this.emitters.ambient??[])this.emitContinuous(i,e,a);for(let i of r.events)for(let s of this.emitters[i]??[])this.burst(s,s.rate,a);let o=[];for(let i of this.particles){if(i.age+=e,i.age>=i.life)continue;let s=i.spec;i.vel[1]-=(s.gravity??0)*e;let n=Math.max(0,1-(s.drag??0)*e);for(let l=0;l<3;l++)i.vel[l]*=n,i.pos[l]+=i.vel[l]*e;s.wobble&&(i.pos[0]+=Math.cos(i.age*3.1+i.seed*6.28)*s.wobble*e*3),i.rot=s.align?He(s.glyph,i.vel):i.rot+(s.spin??0)*e,o.push(i);}this.particles=o.slice(-ee),this.pack();}emitContinuous(e,r,a){let o=(this.carry.get(e)??this.random())+e.rate*r,i=Math.floor(o);this.carry.set(e,o-i),i>0&&this.burst(e,i,a);}burst(e,r,a){let o=this.character.anchors[e.anchor],i=this.random;for(let s=0;s<r;s++){let n=e.mirror&&s%2===1?-1:1,l=e.offset??[0,0,0],h=e.spread??0,f=[o.at[0]+l[0]*n+(i()-.5)*2*h,o.at[1]+l[1]+(i()-.5)*2*h,o.at[2]+l[2]+(i()-.5)*2*h],c=e.jitter??0,d=[e.velocity[0]*n+(i()-.5)*2*c,e.velocity[1]+(i()-.5)*c,e.velocity[2]+(i()-.5)*2*c];this.particles.push({pos:a.point(o.bone,f),vel:d,age:0,life:e.life[0]+(e.life[1]-e.life[0])*i(),size:e.size,rot:e.align?He(e.glyph,d):n<0?Math.PI-(e.rotation??0):(e.rotation??0)+(e.spin?i():0),spec:e,color:O0(e.color),seed:i()});}}pack(){this.count=this.particles.length,this.particles.forEach((e,r)=>{let a=e.age/e.life,o=1-(1-a)*(1-a),i=ze(0,.12,a)*(1-ze(.62,1,a)),s=r*4;this.a.set([e.pos[0],e.pos[1],e.pos[2],e.size[0]+(e.size[1]-e.size[0])*o],s),this.b.set([T0[e.spec.glyph],i,e.rot,e.spec.glow?1:0],s),this.c.set([e.color[0],e.color[1],e.color[2],e.seed],s);});}};function O(t){let e=parseInt(t.replace("#",""),16),r=a=>Math.pow(a/255,2.2);return [r(e>>16&255),r(e>>8&255),r(e&255)]}function _e(t){return `#${t.map(e=>Math.round(Math.pow(Math.min(Math.max(e,0),1),1/2.2)*255).toString(16).padStart(2,"0")).join("")}`}var p=t=>{let e=Number(t.toFixed(5)).toString();return e.includes(".")||e.includes("e")?e:`${e}.0`},X=t=>`vec2(${p(t[0])}, ${p(t[1])})`,S=t=>`vec3(${p(t[0])}, ${p(t[1])}, ${p(t[2])})`;function Ge(t){let e=Q(C(),t[0],t[1],t[2]);return `mat3(${[0,1,2].map(a=>[e[a],e[4+a],e[8+a]]).flat().map(p).join(", ")})`}function Xe(t){let e=["vec2 map(vec3 p) {"," vec2 r = vec2(1e9, 0.0);"," vec3 l;"],r=new Set,a=o=>(r.has(o)||(r.add(o),e.push(` vec3 b${o} = (uBones[${o}] * vec4(p, 1.0)).xyz;`)),`b${o}`);return t.spec.parts.forEach((o,i)=>{let s=a(t.boneIndex(o.bone,`parts[${i}]`)),n=o.at??[0,0,0],l=o.rot?`${Ge(o.rot)} * (${s} - ${S(n)})`:`${s} - ${S(n)}`;e.push(` l = ${l};`);let h=p(t.materialId(o.material,`parts[${i}]`));if(o.shape==="hem"){e.push(` r.x = smax(r.x, ${p(o.y)} + ${p(o.amplitude)} * sin(atan(l.z, l.x) * ${p(o.waves)} + uTime * ${p(o.speed)}) - l.y, ${p(o.blend)});`);return}let f=o.clip?`max(${Ue(o)}, dot(l, ${S(V0(o.clip.normal))}) - ${p(o.clip.offset??0)})`:Ue(o),c=p(o.blend??0);e.push(o.op==="sub"?` opSub(r, ${f}, ${c});`:` opAdd(r, ${f}, ${h}, ${c});`);}),e.push(...N0(t,a)),e.push(" r.x *= uScaleFix;"," return r;","}"),e.join(`
|
|
2
|
+
`)}function V0(t){let e=Math.hypot(...t)||1;return [t[0]/e,t[1]/e,t[2]/e]}function Ue(t){switch(t.shape){case "sphere":return `sdSphere(l, ${p(t.radius)})`;case "ellipsoid":return `sdEllipsoid(l, ${S(t.radii)})`;case "roundBox":return `sdRoundBox(l, ${S(t.half)}, ${p(t.round)})`;case "capsule":return `sdCapsule(l, ${S(t.from)}, ${S(t.to)}, ${p(t.radius)})`;case "roundCone":return `sdRoundCone(l, ${S(t.from)}, ${S(t.to)}, ${p(t.r1)}, ${p(t.r2)})`;case "cylinder":return `sdCylinder(l, ${p(t.radius)}, ${p(t.half)}, ${p(t.round)})`;case "frame":return `sdFrame(l, ${X(t.half)}, ${p(t.corner)}, ${p(t.width)}, ${p(t.depth)})`;case "plate":return `sdPlate(l, ${X(t.half)}, ${p(t.corner)}, ${p(t.depth)})`;case "hem":throw new Error("unreachable")}}function N0(t,e){let r=t.spec.eyes;if(!r)return [];let a=e(t.boneIndex(r.bone,"eyes")),o=[];if(r.kind==="ball"){let i=p(t.materialId(r.lid,"eyes.lid")),s=r.radius;r.at.forEach((n,l)=>{let h=l===0?"-1.0":"1.0";o.push(` l = ${a} - ${S(n)};`,` opAdd(r, length(l) - ${p(s)}, ${p(t.eyeIds[l])}, 0.0);`," {",` float tilt = uFaceB.w * ${h};`," vec3 q = vec3(mat2(cos(tilt), sin(tilt), -sin(tilt), cos(tilt)) * l.xy, l.z);",` float shell = length(q) - ${p(s*1.1)};`,` float lid = clamp(uFaceA.y + uFaceD.w * ${h} * 0.38 - uFaceD.z * 0.1, 0.0, 1.0);`,` float top = mix(${p(s*1.18)}, ${p(-s*.14)}, max(uFaceA.x, lid));`,` float bottom = mix(${p(-s*1.18)}, ${p(-s*.02)}, uFaceA.z * 0.85);`,` opAdd(r, min(max(shell, top - q.y), max(shell, q.y - bottom)), ${i}, 0.0);`," }");});}else {let i=p(t.materialId(r.material,"eyes.material")),[s,n,l]=r.radii;o.push(" float grow = 1.0 + 0.2 * uFaceD.z;"),r.at.forEach((h,f)=>{let c=f===0?"-1.0":"1.0";o.push(` float open${f} = max(0.12, (1.0 - max(uFaceA.x, clamp(uFaceA.y + uFaceD.w * ${c} * 0.45, 0.0, 1.0))) * (1.0 - 0.6 * uFaceA.z));`,` l = ${a} - ${S(h)} - vec3(uFaceB.y * ${p(s*.45)}, uFaceB.z * ${p(n*.3)}, 0.0);`,` opAdd(r, sdEllipsoid(l, vec3(${p(s)} * grow, ${p(n)} * grow * open${f}, ${p(l)})), ${i}, 0.0);`);});}return o}var A=t=>S(O(t));function D0(t,e){let r=t.glows?`uGlow * ${p(t.emitStrength??1)}`:t.emit?`${A(t.emit)} * ${p(t.emitStrength??1)}`:"vec3(0.0)";return `Material(uAlbedo[${e}], ${p(t.f0??.04)}, ${p(t.spec??.5)}, ${p(t.shininess??40)}, ${p(t.metal??0)}, ${p(t.rim??.5)}, ${p(t.sheen??0)}, ${p(t.sss??0)}, ${t.sssColor?A(t.sssColor):"vec3(0.0)"}, ${r}, ${p(t.gloss??.3)})`}var Ke=t=>t.map(e=>`k == ${e}`).join(" || ");function We(t){let e=["Material getMaterial(float id, vec3 p, vec3 n) {"," int k = int(id + 0.5);"," Material m = material(vec3(0.5));"];return t.materials.forEach(({id:r,spec:a},o)=>e.push(` ${o?"else ":""}if (k == ${r}) m = ${D0(a,o)};`)),t.spec.paints?.forEach((r,a)=>{let o=t.boneIndex(r.bone,`paints[${a}]`),i=r.on.map(l=>t.materialId(l,`paints[${a}]`)),s=p(r.soft??.15),n=r.kind==="sphere"?`(length(q) - ${p(r.radius??.1)}) / ${p(r.radius??.1)}`:`q.z > 0.0 ? length(q.xy / ${X(r.radii??[.1,.1])}) - 1.0 : 1.0`;e.push(` if (${Ke(i)}) {`,` vec3 q = (uBones[${o}] * vec4(p, 1.0)).xyz - ${S(r.at)};`,` float e = ${n};`,` m.albedo = mix(m.albedo, ${A(r.color)}, (1.0 - smoothstep(-${s}, ${s}, e)) * ${p(r.opacity??1)});`," }");}),e.push(..._0(t),...G0(t)," return m;","}"),e.join(`
|
|
3
|
+
`)}function Ye(t){let e=["void surface(float id, vec3 p, inout vec3 n, inout Material m) {"," int k = int(id + 0.5);"];for(let{id:r,spec:a,name:o}of t.materials){let i=a.surface;if(!i)continue;let s=t.boneIndex(i.bone??"root",`materials.${o}.surface`),n=p(i.strength??.5);e.push(` if (k == ${r}) {`,` vec3 q = (uBones[${s}] * vec4(p, 1.0)).xyz * ${p(i.scale)};`,` float detail = ${n} * (1.0 - smoothstep(0.25, 0.9, gPixel * ${p(i.scale)}));`,...H0(i.kind,i.color)," }");}return e.push("}"),e.join(`
|
|
4
|
+
`)}function H0(t,e){let r=a=>[` vec3 g = vec3(noise3(${a}), noise3(${a} + 17.3), noise3(${a} + 41.7)) - 0.5;`," g -= n * dot(g, n);"];switch(t){case "fur":return [...r("q")," n = normalize(n + g * 0.5 * detail);"," float clump = noise3(q * 0.23);"," m.albedo *= mix(1.0, 0.9 + 0.2 * clump, detail);"];case "scales":return [" float c = noise3(q);"," float e = 0.12;"," vec3 grad = vec3(noise3(q + vec3(e, 0, 0)), noise3(q + vec3(0, e, 0)), noise3(q + vec3(0, 0, e))) - c;"," grad -= n * dot(grad, n);"," n = normalize(n - grad * 2.2 * detail);"," float seam = 1.0 - smoothstep(0.03, 0.13, abs(c - 0.5));",` m.albedo = mix(m.albedo, ${e?A(e):"m.albedo * 0.55"}, seam * 0.7 * detail);`," m.albedo *= 0.9 + 0.2 * noise3(q * 0.31) * detail;"];case "speckle":return [" float spot = smoothstep(0.66, 0.7, noise3(q)) * (0.6 + 0.4 * noise3(q * 0.37));",` m.albedo = mix(m.albedo, ${e?A(e):"m.albedo * 0.6"}, spot * detail);`];case "ripple":return [...r("q")," n = normalize(n + g * 0.35 * detail);"]}}function _0(t){let e=t.spec.eyes;if(e?.kind!=="ball")return [];let r=t.boneIndex(e.bone,"eyes"),a=[];return e.at.forEach((o,i)=>{a.push(` if (k == ${t.eyeIds[i]}) {`,` vec3 q = normalize((uBones[${r}] * vec4(p, 1.0)).xyz - ${S(o)});`," vec3 g = normalize(vec3(uFaceB.y * 0.5, uFaceB.z * 0.38, 1.0));"," vec3 right = normalize(cross(vec3(0.0, 1.0, 0.0), g));"," vec3 up = cross(g, right);"," vec2 s = vec2(dot(q, right), dot(q, up));"," float front = step(0.0, dot(q, g));",` float aa = gPixel / ${p(e.radius)} + 0.02;`," float rr = length(s);",` float iris = front - front * smoothstep(${p(e.irisSize)} - aa, ${p(e.irisSize)} + aa, rr);`,` float ps = ${p(e.pupilSize)} * (1.0 - 0.4 * uFaceD.z);`,` float pupil = front - front * smoothstep(ps - aa, ps + aa, length(s / vec2(${p(e.pupilAspect??1)}, 1.0)));`,` vec3 irisCol = ${A(e.iris)} * (0.55 + 0.9 * smoothstep(${p(e.irisSize)}, 0.0, rr)) * (0.7 + 0.3 * hash12(floor(vec2(atan(s.y, s.x) * 9.0, rr * 30.0))));`," vec3 albedo = mix(vec3(0.82, 0.8, 0.78), irisCol, iris);"," albedo = mix(albedo, vec3(0.004), pupil);"," m = Material(albedo, 0.06, 2.4, 600.0, 0.0, 0.15, 0.0, 0.0, vec3(0.0), vec3(0.0), 1.0);"," }");}),a}function G0(t){let e=t.spec.face;if(!e)return [];if(e.kind==="screen"){let i=t.boneIndex(e.bone,"face");return [` if (k == ${t.materialId(e.material,"face.material")}) {`,` vec2 q = (uBones[${i}] * vec4(p, 1.0)).xy - ${X(e.center)};`,` m.emit += screenLight(q, ${A(e.color)}, ${p(e.cell)}, ${X(e.half)}, ${p(e.corner)});`," }"]}let r=t.boneIndex(e.bone,"face"),a=e.on.map(i=>t.materialId(i,"face.on")),o=e.width;return [` if (${Ke(a)}) {`,` vec3 q = (uBones[${r}] * vec4(p, 1.0)).xyz - ${S(e.at)};`," if (q.z > -0.02) {",` vec3 mo = mouth(q.xy, ${p(o)}, uFaceB.x * ${p(o*1.1)}, uFaceD.y, uFaceA.w, uFaceD.w, ${p(o*.12)}, gPixel * 0.8);`," float a = mo.x;",` vec3 inner = ${A(e.color)} * (1.25 - 0.5 * mo.z);`,` m.albedo = mix(m.albedo, mix(inner, ${A(e.tongue)}, mo.y), a);`," m.spec *= 1.0 - 0.6 * a; m.sss *= 1.0 - a; m.sheen *= 1.0 - a; m.emit *= 1.0 - a;"," }"," }"]}var Ze=`
|
|
5
|
+
const vec3 KEY = vec3(-0.4485, 0.6997, 0.5562);
|
|
6
|
+
const vec3 FILL = vec3(0.8521, -0.1504, 0.5013);
|
|
7
|
+
const vec3 BACK = vec3(0.5529, 0.5529, -0.6233);
|
|
8
|
+
|
|
9
|
+
struct Material {
|
|
10
|
+
vec3 albedo;
|
|
11
|
+
float f0;
|
|
12
|
+
float spec;
|
|
13
|
+
float shininess;
|
|
14
|
+
float metal;
|
|
15
|
+
float rim;
|
|
16
|
+
float sheen;
|
|
17
|
+
float sss;
|
|
18
|
+
vec3 sssColor;
|
|
19
|
+
vec3 emit;
|
|
20
|
+
float gloss;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
Material material(vec3 albedo) {
|
|
24
|
+
return Material(albedo, 0.04, 0.5, 40.0, 0.0, 0.5, 0.0, 0.0, vec3(0.0), vec3(0.0), 0.3);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* the studio as seen in a reflection along r; gloss tightens the edges of the lights */
|
|
28
|
+
vec3 environment(vec3 r, float gloss) {
|
|
29
|
+
float up = r.y;
|
|
30
|
+
float horizon = 0.05 + 0.12 * smoothstep(-0.25, 0.3, up);
|
|
31
|
+
float softbox = 1.1 * smoothstep(mix(0.42, 0.66, gloss), mix(0.78, 0.7, gloss), up) * smoothstep(-0.9, mix(-0.2, -0.75, gloss), r.z - 0.6 * abs(r.x));
|
|
32
|
+
float window = 2.6 * smoothstep(mix(0.86, 0.95, gloss), mix(0.97, 0.965, gloss), dot(r, KEY));
|
|
33
|
+
float strip = 0.5 * smoothstep(0.6, 0.85, -r.x) * smoothstep(-0.35, 0.05, up) * (1.0 - smoothstep(0.2, 0.5, up));
|
|
34
|
+
float floorBounce = 0.06 * smoothstep(0.0, -0.6, up);
|
|
35
|
+
return vec3(0.97, 0.99, 1.04) * (horizon + softbox + window + strip) + vec3(1.0, 0.92, 0.85) * floorBounce;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float softShadow(vec3 ro, vec3 rd, float tmin, float tmax, float k) {
|
|
39
|
+
float res = 1.0;
|
|
40
|
+
float t = tmin;
|
|
41
|
+
for (int i = ZERO; i < 32; i++) {
|
|
42
|
+
float h = map(ro + rd * t).x;
|
|
43
|
+
res = min(res, k * h / t);
|
|
44
|
+
t += clamp(h, 0.012, 0.2);
|
|
45
|
+
if (res < 0.002 || t > tmax) break;
|
|
46
|
+
}
|
|
47
|
+
res = clamp(res, 0.0, 1.0);
|
|
48
|
+
return res * res * (3.0 - 2.0 * res);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
float ambientOcclusion(vec3 p, vec3 n) {
|
|
52
|
+
float occ = 0.0, sca = 1.0;
|
|
53
|
+
for (int i = ZERO; i < 5; i++) {
|
|
54
|
+
float h = 0.012 + 0.12 * float(i) / 4.0;
|
|
55
|
+
occ += (h - map(p + h * n).x) * sca;
|
|
56
|
+
sca *= 0.85;
|
|
57
|
+
}
|
|
58
|
+
return clamp(1.0 - 2.2 * occ, 0.0, 1.0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* 0 where the body is thick behind the surface, 1 where light gets through */
|
|
62
|
+
float thinness(vec3 p, vec3 n) {
|
|
63
|
+
float s = 0.0;
|
|
64
|
+
for (int i = ZERO; i < 3; i++) {
|
|
65
|
+
float h = 0.05 + 0.09 * float(i);
|
|
66
|
+
s += clamp((map(p - n * h).x + h) / h, 0.0, 1.0);
|
|
67
|
+
}
|
|
68
|
+
return s / 3.0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
vec3 shade(Material m, vec3 p, vec3 n, vec3 v) {
|
|
72
|
+
vec3 key = KEY;
|
|
73
|
+
float sh = softShadow(p + n * 0.004, key, 0.01, 2.5, 9.0);
|
|
74
|
+
float ao = ambientOcclusion(p, n);
|
|
75
|
+
|
|
76
|
+
float ndl = dot(n, key);
|
|
77
|
+
/* a little wrap so the terminator is soft, like a moulded part */
|
|
78
|
+
float keyLight = max(0.0, (ndl + 0.12) / 1.12) * sh;
|
|
79
|
+
float fill = max(0.0, dot(n, FILL));
|
|
80
|
+
float sky = 0.5 + 0.5 * n.y;
|
|
81
|
+
float ndv = max(0.0, dot(n, v));
|
|
82
|
+
float fres = m.f0 + (1.0 - m.f0) * pow(1.0 - ndv, 5.0);
|
|
83
|
+
vec3 r = reflect(-v, n);
|
|
84
|
+
float specOcc = mix(ao, 1.0, 0.35) * mix(sh, 1.0, 0.6);
|
|
85
|
+
vec3 env = environment(r, m.gloss) * fres * specOcc;
|
|
86
|
+
float hi = m.spec * pow(max(0.0, dot(n, normalize(key + v))), m.shininess) * sh;
|
|
87
|
+
float back = max(0.0, dot(n, BACK));
|
|
88
|
+
float rim = m.rim * back * back * pow(1.0 - ndv, 1.6);
|
|
89
|
+
float bounce = 0.1 * max(0.0, -n.y);
|
|
90
|
+
|
|
91
|
+
float diffuse = (0.06 + 0.12 * sky) * ao + 1.2 * keyLight + 0.16 * fill * ao + bounce * ao;
|
|
92
|
+
vec3 tint = vec3(1.0 - m.metal) + m.metal * m.albedo * 2.2;
|
|
93
|
+
vec3 col = m.albedo * diffuse * (1.0 - fres * 0.6);
|
|
94
|
+
col += (env + hi) * tint;
|
|
95
|
+
col += rim * vec3(0.62, 0.78, 1.0) * (0.35 + m.albedo);
|
|
96
|
+
/* velvet: fibres catch light at grazing angles */
|
|
97
|
+
col += m.sheen * pow(1.0 - ndv, 2.5) * (0.4 + 0.6 * keyLight) * (m.albedo * 0.7 + 0.3);
|
|
98
|
+
|
|
99
|
+
if (m.sss > 0.0) {
|
|
100
|
+
float th = thinness(p, n);
|
|
101
|
+
float through = pow(clamp(dot(v, -key) * 0.5 + 0.5, 0.0, 1.0), 2.0);
|
|
102
|
+
col += m.sssColor * m.sss * (0.18 + 0.55 * th + 0.4 * through * th) * (0.55 + 0.45 * ao);
|
|
103
|
+
}
|
|
104
|
+
return col + m.emit;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
vec3 aces(vec3 x) {
|
|
108
|
+
return clamp((x * (2.51 * x + 0.03)) / (x * (2.43 * x + 0.59) + 0.14), 0.0, 1.0);
|
|
109
|
+
}
|
|
110
|
+
`;var Qe=`
|
|
111
|
+
vec3 calcNormal(vec3 p) {
|
|
112
|
+
vec3 n = vec3(0.0);
|
|
113
|
+
for (int i = ZERO; i < 4; i++) {
|
|
114
|
+
vec3 e = 0.5773 * (2.0 * vec3(float(((i + 3) >> 1) & 1), float((i >> 1) & 1), float(i & 1)) - 1.0);
|
|
115
|
+
n += e * map(p + 0.0006 * e).x;
|
|
116
|
+
}
|
|
117
|
+
return normalize(n);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
vec4 over(vec4 top, vec4 under) { return top + under * (1.0 - top.a); }
|
|
121
|
+
|
|
122
|
+
void main() {
|
|
123
|
+
vec2 uv = (2.0 * gl_FragCoord.xy - uResolution) / uResolution.y;
|
|
124
|
+
float pitch = uCamera.w;
|
|
125
|
+
vec3 target = vec3(0.0, uCamera.x, 0.0);
|
|
126
|
+
vec3 ro = target + uCamera.y * vec3(0.0, sin(pitch), cos(pitch));
|
|
127
|
+
vec3 fw = normalize(target - ro);
|
|
128
|
+
vec3 rt = normalize(cross(fw, vec3(0.0, 1.0, 0.0)));
|
|
129
|
+
vec3 up = cross(rt, fw);
|
|
130
|
+
vec3 rd = normalize(fw + (uv.x * rt + uv.y * up) * uCamera.z);
|
|
131
|
+
float pixelAngle = 2.0 * uCamera.z / uResolution.y;
|
|
132
|
+
|
|
133
|
+
vec4 body = vec4(0.0);
|
|
134
|
+
float hitT = -1.0;
|
|
135
|
+
vec3 oc = ro - uBound.xyz;
|
|
136
|
+
float b = dot(oc, rd);
|
|
137
|
+
float disc = b * b - dot(oc, oc) + uBound.w * uBound.w;
|
|
138
|
+
if (disc > 0.0) {
|
|
139
|
+
float s = sqrt(disc);
|
|
140
|
+
float t = max(-b - s, 0.0);
|
|
141
|
+
float tEnd = -b + s;
|
|
142
|
+
float nearest = 1e9;
|
|
143
|
+
float nearestT = 0.0;
|
|
144
|
+
for (int i = ZERO; i < 140; i++) {
|
|
145
|
+
float d = map(ro + rd * t).x;
|
|
146
|
+
float px = t * pixelAngle;
|
|
147
|
+
if (d < 0.2 * px) { hitT = t; break; }
|
|
148
|
+
float ratio = d / px;
|
|
149
|
+
if (ratio < nearest) { nearest = ratio; nearestT = t; }
|
|
150
|
+
t += d * 0.85;
|
|
151
|
+
if (t > tEnd) break;
|
|
152
|
+
}
|
|
153
|
+
float coverage = hitT > 0.0 ? 1.0 : 1.0 - smoothstep(0.2, 1.0, nearest);
|
|
154
|
+
if (coverage > 0.0) {
|
|
155
|
+
float tt = hitT > 0.0 ? hitT : nearestT;
|
|
156
|
+
vec3 p = ro + rd * tt;
|
|
157
|
+
gPixel = tt * pixelAngle;
|
|
158
|
+
vec3 n = calcNormal(p);
|
|
159
|
+
float id = map(p).y;
|
|
160
|
+
Material m = getMaterial(id, p, n);
|
|
161
|
+
surface(id, p, n, m);
|
|
162
|
+
vec3 col = pow(aces(shade(m, p, n, -rd) * uExposure), vec3(1.0 / 2.2));
|
|
163
|
+
body = vec4(col * coverage, coverage);
|
|
164
|
+
if (hitT < 0.0) hitT = tt;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
vec4 floorLayer = vec4(0.0);
|
|
169
|
+
if (uFloor > 0.0 && body.a < 1.0 && rd.y < 0.0) {
|
|
170
|
+
vec3 fp = ro + rd * (-ro.y / rd.y);
|
|
171
|
+
float r = length(fp.xz - uBound.xz);
|
|
172
|
+
float reach = uBound.w * 1.15;
|
|
173
|
+
if (r < reach) {
|
|
174
|
+
float sky = softShadow(fp + vec3(0.0, 0.002, 0.0), vec3(0.1191, 0.9800, 0.1588), 0.02, 3.0, 3.2);
|
|
175
|
+
float contact = 1.0 - smoothstep(0.0, 0.28, map(fp).x);
|
|
176
|
+
float dark = (1.0 - sky) * 0.4 + contact * contact * 0.32;
|
|
177
|
+
dark *= 1.0 - smoothstep(reach * 0.45, reach, r);
|
|
178
|
+
/* a shadow fades as what casts it rises */
|
|
179
|
+
dark *= mix(1.0, 0.5, smoothstep(0.0, 0.45, uLift));
|
|
180
|
+
/* the state's light pooling on the floor */
|
|
181
|
+
vec3 pool = uGlow * uGlowPool * exp(-r * r * 5.0) * (1.0 - dark);
|
|
182
|
+
floorLayer = vec4(uShadow * dark + pool, dark) * uFloor;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
vec4 front = vec4(0.0);
|
|
187
|
+
vec4 back = vec4(0.0);
|
|
188
|
+
float pixel = 2.0 / uResolution.y;
|
|
189
|
+
for (int i = 0; i < uFxCount; i++) {
|
|
190
|
+
vec4 A = uFxA[i];
|
|
191
|
+
vec4 B = uFxB[i];
|
|
192
|
+
vec3 d = A.xyz - ro;
|
|
193
|
+
float z = dot(d, fw);
|
|
194
|
+
if (z < 0.1) continue;
|
|
195
|
+
float scale = 1.0 / (z * uCamera.z);
|
|
196
|
+
vec2 q = (uv - vec2(dot(d, rt), dot(d, up)) * scale) / (A.w * scale);
|
|
197
|
+
if (dot(q, q) > 2.0) continue;
|
|
198
|
+
float cr = cos(B.z), sr = sin(B.z);
|
|
199
|
+
q = mat2(cr, -sr, sr, cr) * q;
|
|
200
|
+
vec2 g = glyph(int(B.x + 0.5), q, pixel / (A.w * scale));
|
|
201
|
+
float a = g.x * B.y;
|
|
202
|
+
if (a < 0.002) continue;
|
|
203
|
+
vec3 col = mix(uFxC[i].rgb, vec3(1.0), clamp(g.y, 0.0, 1.0)) * (1.0 + min(g.y, 0.0));
|
|
204
|
+
vec4 layer = B.w > 0.5 ? vec4(col * a, 0.0) : vec4(col * a, a);
|
|
205
|
+
if (hitT > 0.0 && hitT < length(d)) back = over(layer, back);
|
|
206
|
+
else front = over(layer, front);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
fragColor = over(front, over(body, over(back, floorLayer)));
|
|
210
|
+
}
|
|
211
|
+
`;var Je=`
|
|
212
|
+
/* q: point in mouth space (x right, y up); w: half width; open: lip
|
|
213
|
+
separation in the same units; round: 0 for "ah"/"ee", 1 for "oo";
|
|
214
|
+
smile: -1..1; crooked: -1..1 tilts and wobbles the line, as when something
|
|
215
|
+
is wrong; t: half the stroke; px: a pixel in mouth units.
|
|
216
|
+
Returns coverage, tongue coverage, and depth inside the mouth (0 at the lips, 1 deep). */
|
|
217
|
+
vec3 mouth(vec2 q, float w, float open, float round, float smile, float crooked, float t, float px) {
|
|
218
|
+
float opened = smoothstep(0.0, 0.25 * w, open);
|
|
219
|
+
w *= 1.0 - 0.3 * round * opened;
|
|
220
|
+
open *= 1.0 + 0.1 * round;
|
|
221
|
+
/* an "oo" pushes the lips forward and flattens the smile out of them */
|
|
222
|
+
float bend = smile * 0.55 * (1.0 - 0.7 * round * opened);
|
|
223
|
+
|
|
224
|
+
float u = clamp(q.x / w, -1.0, 1.0);
|
|
225
|
+
float bulge = sqrt(max(1.0 - u * u, 0.0));
|
|
226
|
+
float line = bend * w * u * u + crooked * w * (0.22 * u + 0.12 * sin(u * 6.0));
|
|
227
|
+
float upper = line + open * (0.22 + 0.45 * round) * bulge;
|
|
228
|
+
float lower = line - open * bulge;
|
|
229
|
+
|
|
230
|
+
/* vertical distances are cheap and exact along y; the slope converts the
|
|
231
|
+
antialiasing width so the steep sides near the corners stay crisp */
|
|
232
|
+
float steep = abs(u) / max(bulge, 0.08);
|
|
233
|
+
float slope = abs(2.0 * bend * u) + abs(crooked) * 0.9 + open / w * steep;
|
|
234
|
+
float aa = px * sqrt(1.0 + min(slope * slope, 36.0));
|
|
235
|
+
|
|
236
|
+
/* the lips taper toward the corners once the mouth is open */
|
|
237
|
+
float lip = t * mix(1.0, sqrt(bulge), opened);
|
|
238
|
+
float inside = max(q.y - upper, lower - q.y);
|
|
239
|
+
float body = abs(q.x) <= w ? inside - lip : 1e3;
|
|
240
|
+
/* round caps finish the closed stroke; an open mouth's lips already meet in a point */
|
|
241
|
+
float cap = length(vec2(abs(q.x) - w, q.y - bend * w - crooked * w * (0.22 * sign(q.x) + 0.12 * sin(6.0 * sign(q.x))))) - t;
|
|
242
|
+
float a = max(1.0 - smoothstep(-aa, aa, body), (1.0 - smoothstep(-px, px, cap)) * (1.0 - opened));
|
|
243
|
+
|
|
244
|
+
/* a tongue resting on the lower lip, only inside the opening */
|
|
245
|
+
float hole = 1.0 - smoothstep(-aa, aa, inside);
|
|
246
|
+
vec2 tq = vec2(q.x / (w * (0.5 - 0.1 * round)), (q.y + open * 0.78) / max(0.42 * open, 1e-4));
|
|
247
|
+
float tongue = (1.0 - smoothstep(-0.08, 0.08, length(tq) - 1.0)) * hole * smoothstep(0.08, 0.35, open / w);
|
|
248
|
+
|
|
249
|
+
float depth = clamp(-inside / max(0.5 * open, 1e-4), 0.0, 1.0) * hole;
|
|
250
|
+
return vec3(a, tongue, depth);
|
|
251
|
+
}
|
|
252
|
+
`;var e0=`
|
|
253
|
+
float fxSegment(vec2 p, vec2 a, vec2 b) {
|
|
254
|
+
vec2 pa = p - a, ba = b - a;
|
|
255
|
+
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
|
256
|
+
return length(pa - ba * h);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
float fxDot2(vec2 v) { return dot(v, v); }
|
|
260
|
+
|
|
261
|
+
float fxHeart(vec2 p) {
|
|
262
|
+
p.x = abs(p.x);
|
|
263
|
+
if (p.y + p.x > 1.0) return sqrt(fxDot2(p - vec2(0.25, 0.75))) - sqrt(2.0) / 4.0;
|
|
264
|
+
return sqrt(min(fxDot2(p - vec2(0.0, 1.0)), fxDot2(p - 0.5 * max(p.x + p.y, 0.0)))) * sign(p.x - p.y);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
float fxTeardrop(vec2 p, float r1, float r2, float h) {
|
|
268
|
+
p.x = abs(p.x);
|
|
269
|
+
float b = (r1 - r2) / h;
|
|
270
|
+
float a = sqrt(1.0 - b * b);
|
|
271
|
+
float k = dot(p, vec2(-b, a));
|
|
272
|
+
if (k < 0.0) return length(p) - r1;
|
|
273
|
+
if (k > a * h) return length(p - vec2(0.0, h)) - r2;
|
|
274
|
+
return dot(p, vec2(a, b)) - r1;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
float fxStar(vec2 p, float r, float rf) {
|
|
278
|
+
const vec2 k1 = vec2(0.809016994375, -0.587785252292);
|
|
279
|
+
const vec2 k2 = vec2(-k1.x, k1.y);
|
|
280
|
+
p.x = abs(p.x);
|
|
281
|
+
p -= 2.0 * max(dot(k1, p), 0.0) * k1;
|
|
282
|
+
p -= 2.0 * max(dot(k2, p), 0.0) * k2;
|
|
283
|
+
p.x = abs(p.x);
|
|
284
|
+
p.y -= r;
|
|
285
|
+
vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0);
|
|
286
|
+
float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r);
|
|
287
|
+
return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
float fxTriangle(vec2 p, float r) {
|
|
291
|
+
const float k = 1.7320508;
|
|
292
|
+
p.x = abs(p.x) - r;
|
|
293
|
+
p.y = p.y + r / k;
|
|
294
|
+
if (p.x + k * p.y > 0.0) p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;
|
|
295
|
+
p.x -= clamp(p.x, -2.0 * r, 0.0);
|
|
296
|
+
return -length(p) * sign(p.y);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* an exclamation mark, tapering toward its dot */
|
|
300
|
+
float fxExclaim(vec2 p) {
|
|
301
|
+
float bar = fxSegment(p, vec2(0.0, -0.2), vec2(0.0, 0.8)) - mix(0.11, 0.19, clamp((p.y + 0.2), 0.0, 1.0));
|
|
302
|
+
return min(bar, length(p - vec2(0.0, -0.66)) - 0.15);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* coverage, highlight */
|
|
306
|
+
vec2 glyph(int g, vec2 p, float px) {
|
|
307
|
+
float d = 1e9;
|
|
308
|
+
float light = 0.0;
|
|
309
|
+
float soft = 0.0;
|
|
310
|
+
if (g == 0) {
|
|
311
|
+
d = min(min(fxSegment(p, vec2(-0.6, 0.6), vec2(0.6, 0.6)), fxSegment(p, vec2(0.6, 0.6), vec2(-0.6, -0.6))), fxSegment(p, vec2(-0.6, -0.6), vec2(0.6, -0.6))) - 0.16;
|
|
312
|
+
} else if (g == 1) {
|
|
313
|
+
float ring = abs(length(p) - 0.82) - 0.07;
|
|
314
|
+
float shine = length(p - vec2(-0.32, 0.36)) - 0.17;
|
|
315
|
+
d = min(ring, shine);
|
|
316
|
+
light = 1.0 - smoothstep(-px, px, shine);
|
|
317
|
+
soft = 0.14 * (1.0 - smoothstep(0.75, 0.82, length(p)));
|
|
318
|
+
} else if (g == 2) {
|
|
319
|
+
vec2 q = abs(p);
|
|
320
|
+
d = (sqrt(q.x) + sqrt(q.y) - 0.92) * 0.45;
|
|
321
|
+
light = 1.0 - smoothstep(0.0, 0.35, length(p));
|
|
322
|
+
} else if (g == 3) {
|
|
323
|
+
d = fxHeart(p * 0.56 + vec2(0.0, 0.5)) / 0.56;
|
|
324
|
+
light = (1.0 - smoothstep(-px, px, length(p - vec2(-0.38, 0.38)) - 0.13)) * 0.8;
|
|
325
|
+
} else if (g == 4) {
|
|
326
|
+
vec2 h = p - vec2(-0.28, -0.55);
|
|
327
|
+
float head = (length(mat2(0.92, 0.39, -0.39, 0.92) * h / vec2(0.32, 0.23)) - 1.0) * 0.23;
|
|
328
|
+
float stem = fxSegment(p, vec2(0.02, -0.5), vec2(0.02, 0.78)) - 0.07;
|
|
329
|
+
float flag = fxSegment(p, vec2(0.02, 0.78), vec2(0.42, 0.36)) - 0.09;
|
|
330
|
+
d = min(head, min(stem, flag));
|
|
331
|
+
} else if (g == 5) {
|
|
332
|
+
vec2 c = p - vec2(-1.1, 0.0);
|
|
333
|
+
float a = atan(c.y, c.x);
|
|
334
|
+
d = max(abs(length(c) - 1.45) - 0.1, (abs(a) - 0.48) * 1.45);
|
|
335
|
+
} else if (g == 6) {
|
|
336
|
+
float r = length(p);
|
|
337
|
+
return vec2((1.0 - smoothstep(0.15, 1.0, r)) * 0.75, 0.25 + 0.35 * p.y);
|
|
338
|
+
} else if (g == 7) {
|
|
339
|
+
d = abs(length(p) - 0.84) - 0.06;
|
|
340
|
+
} else if (g == 8) {
|
|
341
|
+
d = fxTeardrop(p + vec2(0.0, 0.35), 0.55, 0.06, 1.05);
|
|
342
|
+
light = (1.0 - smoothstep(-px, px, length(p - vec2(-0.2, -0.2)) - 0.12)) * 0.9;
|
|
343
|
+
} else if (g == 9) {
|
|
344
|
+
d = fxSegment(p, vec2(-1.0, 0.0), vec2(1.0, 0.0)) - 0.12 * (1.0 - abs(p.x) * 0.7);
|
|
345
|
+
light = 0.6;
|
|
346
|
+
} else if (g == 10) {
|
|
347
|
+
float r = length(p);
|
|
348
|
+
return vec2(exp(-r * r * 5.0), 1.0 - smoothstep(0.0, 0.3, r));
|
|
349
|
+
} else if (g == 11) {
|
|
350
|
+
d = (length(p / vec2(0.3, 0.95)) - 1.0) * 0.3;
|
|
351
|
+
light = -0.35 * (1.0 - smoothstep(0.0, 0.05 + px, abs(p.x + 0.04 * p.y)));
|
|
352
|
+
} else if (g == 13) {
|
|
353
|
+
d = fxExclaim(p);
|
|
354
|
+
light = 0.3 * (1.0 - smoothstep(-px, px, fxSegment(p, vec2(-0.05, 0.1), vec2(-0.05, 0.7)) - 0.035));
|
|
355
|
+
} else if (g == 14) {
|
|
356
|
+
d = fxTriangle(p - vec2(0.0, -0.12), 0.82) - 0.14;
|
|
357
|
+
/* a white mark on the coloured sign */
|
|
358
|
+
light = 1.0 - smoothstep(-px, px, fxExclaim((p - vec2(0.0, -0.08)) / 0.52) * 0.52);
|
|
359
|
+
} else if (g == 15) {
|
|
360
|
+
vec2 q = abs(p) - vec2(0.32, 0.78);
|
|
361
|
+
d = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - 0.06;
|
|
362
|
+
light = 0.35 * step(0.0, p.x);
|
|
363
|
+
} else if (g == 16) {
|
|
364
|
+
float c = min(min(length(p - vec2(-0.48, -0.08)) - 0.4, length(p - vec2(0.08, 0.18)) - 0.55), length(p - vec2(0.56, -0.1)) - 0.36);
|
|
365
|
+
d = max(c, -p.y - 0.44);
|
|
366
|
+
light = 0.45 * smoothstep(-0.2, 0.7, p.y) - 0.25 * (1.0 - smoothstep(-0.45, -0.1, p.y));
|
|
367
|
+
} else if (g == 17) {
|
|
368
|
+
d = fxStar(p, 0.92, 0.46) - 0.06;
|
|
369
|
+
light = 0.5 * (1.0 - smoothstep(0.0, 0.45, length(p - vec2(-0.12, 0.18))));
|
|
370
|
+
} else if (g == 18) {
|
|
371
|
+
float r = length(p);
|
|
372
|
+
float teeth = 0.66 + 0.2 * smoothstep(-0.25, 0.25, cos(atan(p.y, p.x) * 8.0));
|
|
373
|
+
d = max(r - teeth, 0.26 - r);
|
|
374
|
+
light = 0.3 * (1.0 - smoothstep(0.3, 0.7, length(p - vec2(-0.2, 0.25))));
|
|
375
|
+
} else {
|
|
376
|
+
d = length(p) - 0.9;
|
|
377
|
+
light = 0.35 * (1.0 - smoothstep(0.0, 0.6, length(p - vec2(-0.3, 0.35))));
|
|
378
|
+
}
|
|
379
|
+
return vec2(max(1.0 - smoothstep(-px, px, d), soft), light);
|
|
380
|
+
}
|
|
381
|
+
`;var t0=`
|
|
382
|
+
float sdSphere(vec3 p, float r) { return length(p) - r; }
|
|
383
|
+
|
|
384
|
+
float sdEllipsoid(vec3 p, vec3 r) {
|
|
385
|
+
float k0 = length(p / r);
|
|
386
|
+
float k1 = length(p / (r * r));
|
|
387
|
+
return k0 * (k0 - 1.0) / max(k1, 1e-6);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
float sdRoundBox(vec3 p, vec3 b, float r) {
|
|
391
|
+
vec3 q = abs(p) - b + r;
|
|
392
|
+
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0) - r;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
float sdCapsule(vec3 p, vec3 a, vec3 b, float r) {
|
|
396
|
+
vec3 pa = p - a, ba = b - a;
|
|
397
|
+
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
|
398
|
+
return length(pa - ba * h) - r;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
float sdRoundCone(vec3 p, vec3 a, vec3 b, float r1, float r2) {
|
|
402
|
+
vec3 ba = b - a;
|
|
403
|
+
float l2 = dot(ba, ba);
|
|
404
|
+
float rr = r1 - r2;
|
|
405
|
+
float a2 = l2 - rr * rr;
|
|
406
|
+
float il2 = 1.0 / l2;
|
|
407
|
+
vec3 pa = p - a;
|
|
408
|
+
float y = dot(pa, ba);
|
|
409
|
+
float z = y - l2;
|
|
410
|
+
vec3 xv = pa * l2 - ba * y;
|
|
411
|
+
float x2 = dot(xv, xv);
|
|
412
|
+
float y2 = y * y * l2;
|
|
413
|
+
float z2 = z * z * l2;
|
|
414
|
+
float k = sign(rr) * rr * rr * x2;
|
|
415
|
+
if (sign(z) * a2 * z2 > k) return sqrt(x2 + z2) * il2 - r2;
|
|
416
|
+
if (sign(y) * a2 * y2 < k) return sqrt(x2 + y2) * il2 - r1;
|
|
417
|
+
return (sqrt(x2 * a2 * il2) + y * rr) * il2 - r1;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* along y, with rounded rims */
|
|
421
|
+
float sdCylinder(vec3 p, float r, float h, float rr) {
|
|
422
|
+
vec2 d = vec2(length(p.xz) - r + rr, abs(p.y) - h + rr);
|
|
423
|
+
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - rr;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
float sdRoundRect(vec2 p, vec2 b, float r) {
|
|
427
|
+
vec2 q = abs(p) - b + r;
|
|
428
|
+
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* a rounded-rectangle ring in the xy plane, extruded along z: gaskets, bezels */
|
|
432
|
+
float sdFrame(vec3 p, vec2 b, float corner, float w, float depth) {
|
|
433
|
+
float ring = abs(sdRoundRect(p.xy, b, corner)) - w;
|
|
434
|
+
vec2 e = vec2(ring, abs(p.z) - depth);
|
|
435
|
+
return min(max(e.x, e.y), 0.0) + length(max(e, 0.0));
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
float sdPlate(vec3 p, vec2 b, float corner, float depth) {
|
|
439
|
+
vec2 e = vec2(sdRoundRect(p.xy, b, corner), abs(p.z) - depth);
|
|
440
|
+
return min(max(e.x, e.y), 0.0) + length(max(e, 0.0));
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
float smin(float a, float b, float k) {
|
|
444
|
+
float h = max(k - abs(a - b), 0.0) / k;
|
|
445
|
+
return min(a, b) - h * h * k * 0.25;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
float smax(float a, float b, float k) { return -smin(-a, -b, k); }
|
|
449
|
+
|
|
450
|
+
/* union that keeps the material of whichever surface is nearer */
|
|
451
|
+
void opAdd(inout vec2 r, float d, float id, float k) {
|
|
452
|
+
float m = d < r.x ? id : r.y;
|
|
453
|
+
r.x = k > 0.0 ? smin(r.x, d, k) : min(r.x, d);
|
|
454
|
+
r.y = m;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
void opSub(inout vec2 r, float d, float k) {
|
|
458
|
+
r.x = k > 0.0 ? smax(r.x, -d, k) : max(r.x, -d);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
float hash13(vec3 p3) {
|
|
462
|
+
p3 = fract(p3 * 0.1031);
|
|
463
|
+
p3 += dot(p3, p3.zyx + 31.32);
|
|
464
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/* smooth value noise, 0\u20131 */
|
|
468
|
+
float noise3(vec3 p) {
|
|
469
|
+
vec3 i = floor(p);
|
|
470
|
+
vec3 f = fract(p);
|
|
471
|
+
f = f * f * (3.0 - 2.0 * f);
|
|
472
|
+
return mix(
|
|
473
|
+
mix(mix(hash13(i), hash13(i + vec3(1, 0, 0)), f.x), mix(hash13(i + vec3(0, 1, 0)), hash13(i + vec3(1, 1, 0)), f.x), f.y),
|
|
474
|
+
mix(mix(hash13(i + vec3(0, 0, 1)), hash13(i + vec3(1, 0, 1)), f.x), mix(hash13(i + vec3(0, 1, 1)), hash13(i + vec3(1, 1, 1)), f.x), f.y),
|
|
475
|
+
f.z);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
float hash12(vec2 p) {
|
|
479
|
+
vec3 p3 = fract(vec3(p.xyx) * 0.1031);
|
|
480
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
481
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
482
|
+
}
|
|
483
|
+
`;var r0=`
|
|
484
|
+
float sdBox2(vec2 p, vec2 b) {
|
|
485
|
+
vec2 d = abs(p) - b;
|
|
486
|
+
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
float fxStarLed(vec2 p, float r, float rf) {
|
|
490
|
+
const vec2 k1 = vec2(0.809016994375, -0.587785252292);
|
|
491
|
+
const vec2 k2 = vec2(-k1.x, k1.y);
|
|
492
|
+
p.x = abs(p.x);
|
|
493
|
+
p -= 2.0 * max(dot(k1, p), 0.0) * k1;
|
|
494
|
+
p -= 2.0 * max(dot(k2, p), 0.0) * k2;
|
|
495
|
+
p.x = abs(p.x);
|
|
496
|
+
p.y -= r;
|
|
497
|
+
vec2 ba = rf * vec2(-k1.y, k1.x) - vec2(0.0, 1.0);
|
|
498
|
+
float h = clamp(dot(p, ba) / dot(ba, ba), 0.0, r);
|
|
499
|
+
return length(p - ba * h) * sign(p.y * ba.x - p.x * ba.y);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
float sdSegment(vec2 p, vec2 a, vec2 b) {
|
|
503
|
+
vec2 pa = p - a, ba = b - a;
|
|
504
|
+
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
|
|
505
|
+
return length(pa - ba * h);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/* how lit a shape is at distance d: 1 inside, falling off over soft */
|
|
509
|
+
float lit(float d, float soft) { return 1.0 - smoothstep(-0.35, soft, d); }
|
|
510
|
+
|
|
511
|
+
float faceEyes(vec2 c, float soft) {
|
|
512
|
+
vec2 g = vec2(uFaceB.y * 2.2, uFaceB.z * 1.4);
|
|
513
|
+
float blink = uFaceA.x;
|
|
514
|
+
float v = 0.0;
|
|
515
|
+
for (int i = 0; i < 2; i++) {
|
|
516
|
+
float side = i == 0 ? -1.0 : 1.0;
|
|
517
|
+
float lid = clamp(uFaceA.y + uFaceD.w * side * 0.4, 0.0, 1.0);
|
|
518
|
+
float closeTop = max(blink * 0.48, lid * 0.42);
|
|
519
|
+
float closeBottom = max(blink * 0.48, uFaceA.z * 0.4);
|
|
520
|
+
float cx = side * 4.5 + g.x;
|
|
521
|
+
float top = 3.5 + 0.8 * uFaceD.z + g.y - 4.0 * closeTop;
|
|
522
|
+
float bottom = -0.5 - 0.5 * uFaceD.z + g.y + 4.0 * closeBottom;
|
|
523
|
+
float h = max((top - bottom) * 0.5, 0.32);
|
|
524
|
+
float d = sdBox2(c - vec2(cx, (top + bottom) * 0.5), vec2(1.5 + 0.3 * uFaceD.z, h)) - 0.15;
|
|
525
|
+
v = max(v, lit(d, soft));
|
|
526
|
+
}
|
|
527
|
+
return v;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/* a mouth of two lips, like the painted ones: open is in LED rows */
|
|
531
|
+
float faceMouth(vec2 c, float open, float round, float smile, float soft) {
|
|
532
|
+
float opened = smoothstep(0.0, 0.8, open);
|
|
533
|
+
float w = 3.4 - 1.4 * round * opened;
|
|
534
|
+
vec2 m = c - vec2(0.0, -3.7 + 0.25 * open);
|
|
535
|
+
float u = clamp(m.x / w, -1.0, 1.0);
|
|
536
|
+
float bulge = sqrt(max(1.0 - u * u, 0.0));
|
|
537
|
+
float line = smile * 0.9 * u * u;
|
|
538
|
+
float inside = max(m.y - line - open * (0.2 + 0.45 * round) * bulge, line - open * bulge - m.y);
|
|
539
|
+
float body = abs(m.x) <= w ? inside : 1e3;
|
|
540
|
+
float rim = min(abs(body), length(vec2(abs(m.x) - w, m.y - smile * 0.9))) - 0.42;
|
|
541
|
+
return max(lit(rim, soft), lit(body, soft) * 0.12 * opened);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
float faceZ(vec2 c, vec2 at, float s, float soft) {
|
|
545
|
+
vec2 p = (c - at) / s;
|
|
546
|
+
float d = min(min(sdSegment(p, vec2(-1, 1), vec2(1, 1)), sdSegment(p, vec2(1, 1), vec2(-1, -1))), sdSegment(p, vec2(-1, -1), vec2(1, -1)));
|
|
547
|
+
return lit(d * s - 0.32, soft);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
bool is(float state, float id) { return abs(state - id) < 0.5; }
|
|
551
|
+
|
|
552
|
+
float faceFor(float state, vec2 c, float t, float soft) {
|
|
553
|
+
float v = 0.0;
|
|
554
|
+
if (is(state, E_THINKING)) {
|
|
555
|
+
/* heavy-lidded eyes looking up, three dots pulsing in turn */
|
|
556
|
+
v = faceEyes(c, soft);
|
|
557
|
+
for (int i = 0; i < 3; i++) {
|
|
558
|
+
float fi = float(i);
|
|
559
|
+
float pulse = 0.5 + 0.5 * sin(t * 4.2 - fi * 1.1);
|
|
560
|
+
float d = length(c - vec2(-2.4 + fi * 2.4, -4.4)) - 0.62;
|
|
561
|
+
v = max(v, lit(d, soft) * (0.25 + 0.75 * pulse * pulse));
|
|
562
|
+
}
|
|
563
|
+
} else if (is(state, E_LISTENING)) {
|
|
564
|
+
/* alert eyes over a live equaliser */
|
|
565
|
+
v = faceEyes(c, soft);
|
|
566
|
+
for (int i = 0; i < 7; i++) {
|
|
567
|
+
float fi = float(i);
|
|
568
|
+
float level = abs(sin(t * (5.0 + fi * 1.3) + fi * 1.7)) * (0.55 + 0.45 * sin(t * 2.3 + fi));
|
|
569
|
+
float d = sdBox2(c - vec2(-4.5 + fi * 1.5, -4.6), vec2(0.42, 0.45 + 1.6 * level));
|
|
570
|
+
v = max(v, lit(d, soft) * 0.9);
|
|
571
|
+
}
|
|
572
|
+
} else if (is(state, E_SPEAKING)) {
|
|
573
|
+
/* the same two-lip mouth as the painted faces; closed, the lips meet in one bar */
|
|
574
|
+
v = max(faceEyes(c, soft), faceMouth(c, uFaceB.x * 3.4, uFaceD.y, 0.0, soft));
|
|
575
|
+
} else if (is(state, E_SLEEPING)) {
|
|
576
|
+
/* closed eyes and rising z's */
|
|
577
|
+
for (int i = 0; i < 2; i++) {
|
|
578
|
+
float cx = i == 0 ? -4.5 : 4.5;
|
|
579
|
+
float d = min(sdSegment(c, vec2(cx - 1.6, 1.4), vec2(cx, 0.6)), sdSegment(c, vec2(cx, 0.6), vec2(cx + 1.6, 1.4))) - 0.38;
|
|
580
|
+
v = max(v, lit(d, soft));
|
|
581
|
+
}
|
|
582
|
+
for (int i = 0; i < 3; i++) {
|
|
583
|
+
float k = fract(t * 0.22 + float(i) / 3.0);
|
|
584
|
+
float fade = smoothstep(0.0, 0.15, k) * (1.0 - smoothstep(0.7, 1.0, k));
|
|
585
|
+
v = max(v, faceZ(c, vec2(7.6 + k * 3.2, 1.2 + k * 5.0), 0.5 + k * 0.55, soft) * fade);
|
|
586
|
+
}
|
|
587
|
+
} else if (is(state, E_WORKING)) {
|
|
588
|
+
/* narrowed eyes over a progress bar that fills, empties and fills again */
|
|
589
|
+
v = faceEyes(c, soft);
|
|
590
|
+
float rim = abs(sdBox2(c - vec2(0.0, -4.6), vec2(4.6, 0.95))) - 0.3;
|
|
591
|
+
float fill = fract(t * 0.3) * 8.4;
|
|
592
|
+
float bar = sdBox2(c - vec2(-4.2 + fill * 0.5, -4.6), vec2(fill * 0.5, 0.35));
|
|
593
|
+
v = max(v, max(lit(rim, soft) * 0.55, lit(bar, soft)));
|
|
594
|
+
} else if (is(state, E_ERROR)) {
|
|
595
|
+
/* X eyes and a zigzag mouth */
|
|
596
|
+
for (int i = 0; i < 2; i++) {
|
|
597
|
+
vec2 e = c - vec2(i == 0 ? -4.5 : 4.5, 1.5);
|
|
598
|
+
float d = min(sdSegment(e, vec2(-1.5, -1.5), vec2(1.5, 1.5)), sdSegment(e, vec2(-1.5, 1.5), vec2(1.5, -1.5))) - 0.42;
|
|
599
|
+
v = max(v, lit(d, soft));
|
|
600
|
+
}
|
|
601
|
+
float zig = 1e3;
|
|
602
|
+
for (int i = 0; i < 4; i++) {
|
|
603
|
+
float x0 = -3.6 + float(i) * 1.8;
|
|
604
|
+
zig = min(zig, sdSegment(c, vec2(x0, -4.6 + (i % 2 == 0 ? 0.6 : -0.6)), vec2(x0 + 1.8, -4.6 + (i % 2 == 0 ? -0.6 : 0.6))));
|
|
605
|
+
}
|
|
606
|
+
v = max(v, lit(zig - 0.4, soft));
|
|
607
|
+
} else if (is(state, E_SURPRISED)) {
|
|
608
|
+
/* round eyes with pinned pupils, and a little "o" */
|
|
609
|
+
for (int i = 0; i < 2; i++) {
|
|
610
|
+
vec2 e = c - vec2(i == 0 ? -4.5 : 4.5, 1.4);
|
|
611
|
+
float ring = abs(length(e) - 2.0) - 0.42;
|
|
612
|
+
v = max(v, max(lit(ring, soft), lit(length(e) - 0.62, soft)));
|
|
613
|
+
}
|
|
614
|
+
v = max(v, lit(abs(length(c - vec2(0.0, -4.7)) - 1.05) - 0.4, soft));
|
|
615
|
+
} else if (is(state, E_CELEBRATING)) {
|
|
616
|
+
/* star eyes that throb, and a wide open grin */
|
|
617
|
+
float throb = 1.0 + 0.12 * sin(t * 9.0);
|
|
618
|
+
for (int i = 0; i < 2; i++) {
|
|
619
|
+
vec2 e = (c - vec2(i == 0 ? -4.5 : 4.5, 1.6)) / throb;
|
|
620
|
+
v = max(v, lit(fxStarLed(e, 2.2, 0.48) * throb - 0.1, soft));
|
|
621
|
+
}
|
|
622
|
+
v = max(v, faceMouth(c - vec2(0.0, 0.6), 2.6, 0.0, 0.7, soft));
|
|
623
|
+
} else if (is(state, E_SAD)) {
|
|
624
|
+
/* eyes cut away at the outer top, a frown, and a tear now and then */
|
|
625
|
+
for (int i = 0; i < 2; i++) {
|
|
626
|
+
float side = i == 0 ? -1.0 : 1.0;
|
|
627
|
+
float cx = side * 4.5;
|
|
628
|
+
float box = sdBox2(c - vec2(cx, 1.0), vec2(1.5, 1.6)) - 0.15;
|
|
629
|
+
float slope = (c.y - 1.9) + 0.55 * (c.x - cx) * side;
|
|
630
|
+
v = max(v, lit(max(box, slope), soft));
|
|
631
|
+
}
|
|
632
|
+
float frown = max(abs(length(c - vec2(0.0, -7.2)) - 2.6) - 0.4, -(c.y + 5.4));
|
|
633
|
+
v = max(v, lit(frown, soft));
|
|
634
|
+
float k = fract(t * 0.35);
|
|
635
|
+
float tear = length((c - vec2(-5.4, -0.6 - k * 5.0)) / vec2(0.8, 1.0)) - 0.6;
|
|
636
|
+
v = max(v, lit(tear, soft) * smoothstep(0.0, 0.1, k) * (1.0 - smoothstep(0.6, 0.9, k)));
|
|
637
|
+
} else if (is(state, E_HAPPY)) {
|
|
638
|
+
/* ^ ^ and a smile */
|
|
639
|
+
for (int i = 0; i < 2; i++) {
|
|
640
|
+
float cx = i == 0 ? -4.5 : 4.5;
|
|
641
|
+
float d = min(sdSegment(c, vec2(cx - 1.7, 0.4), vec2(cx, 2.2)), sdSegment(c, vec2(cx, 2.2), vec2(cx + 1.7, 0.4))) - 0.5;
|
|
642
|
+
v = max(v, lit(d, soft));
|
|
643
|
+
}
|
|
644
|
+
float d = min(min(sdSegment(c, vec2(-3.0, -3.0), vec2(-1.3, -4.6)), sdSegment(c, vec2(-1.3, -4.6), vec2(1.3, -4.6))), sdSegment(c, vec2(1.3, -4.6), vec2(3.0, -3.0))) - 0.45;
|
|
645
|
+
v = max(v, lit(d, soft));
|
|
646
|
+
} else {
|
|
647
|
+
v = faceEyes(c, soft);
|
|
648
|
+
}
|
|
649
|
+
return v;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/* the face at c, cross-faded from the previous state and glitched on a switch */
|
|
653
|
+
float face(vec2 c, float soft) {
|
|
654
|
+
float row = floor(c.y);
|
|
655
|
+
float tick = floor(uTime * 24.0);
|
|
656
|
+
/* an error keeps glitching now and then */
|
|
657
|
+
float glitch = max(uFaceC.w, is(uFaceC.x, E_ERROR) ? 0.6 * step(0.86, hash12(vec2(floor(uTime * 8.0), 7.7))) : 0.0);
|
|
658
|
+
c.x += (hash12(vec2(row, tick)) - 0.5) * 7.0 * glitch * step(0.6, hash12(vec2(row * 1.7, tick)));
|
|
659
|
+
float now = faceFor(uFaceC.x, c, uFaceD.x, soft);
|
|
660
|
+
float before = faceFor(uFaceC.y, c, uFaceD.x, soft);
|
|
661
|
+
float v = mix(before, now, uFaceC.z);
|
|
662
|
+
return v * (1.0 - glitch * 0.45 * hash12(vec2(tick, 3.1)));
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/* the emitted light of the matrix at a point on the screen (screen-local, in units) */
|
|
666
|
+
vec3 screenLight(vec2 q, vec3 color, float cell, vec2 extent, float corner) {
|
|
667
|
+
vec2 c = q / cell;
|
|
668
|
+
vec2 cellCentre = floor(c) + 0.5;
|
|
669
|
+
vec2 f = fract(c) - 0.5;
|
|
670
|
+
/* round LEDs, averaged out when one is smaller than a couple of pixels */
|
|
671
|
+
float dotMask = 1.0 - smoothstep(0.26, 0.4, length(f));
|
|
672
|
+
float footprint = gPixel / cell;
|
|
673
|
+
dotMask = mix(dotMask, 0.5, smoothstep(0.18, 0.45, footprint));
|
|
674
|
+
float led = face(cellCentre, 0.25);
|
|
675
|
+
float glow = face(c, 1.6);
|
|
676
|
+
float edge = smoothstep(0.0, 0.05, -sdRoundRect(q, extent, corner));
|
|
677
|
+
/* a faint glare across the glass */
|
|
678
|
+
float glare = 0.025 * smoothstep(0.1, 0.0, abs(q.x * 0.7 + q.y - extent.y * 0.35));
|
|
679
|
+
vec3 lit = color * (led * dotMask * 2.1 + glow * 0.2) + glare + vec3(0.012, 0.016, 0.03) * dotMask;
|
|
680
|
+
return lit * edge;
|
|
681
|
+
}
|
|
682
|
+
`;var he=class extends Error{constructor(e,r){super(`${e}: ${r}`),this.name="SpecError";}};function a0(t){let e=c=>{throw new he(t.id,c)},r=[{name:"root",pivot:[0,0,0],index:0,parentIndex:-1}],a=new Map([["root",0]]);t.bones.forEach((c,d)=>{a.has(c.name)&&e(`bone "${c.name}" is declared twice`);let m=c.parent??"root",u=a.get(m);u===void 0&&e(`bone "${c.name}" names parent "${m}", which is not declared before it`),a.set(c.name,d+1),r.push({...c,index:d+1,parentIndex:u});});let o=Object.entries(t.materials).map(([c,d],m)=>({name:c,id:m+1,spec:d})),i=new Map(o.map(c=>[c.name,c.id])),s=[o.length+1,o.length+2],n=(c,d)=>a.get(c)??e(`${d} names bone "${c}", which does not exist`),l=(c,d)=>i.get(c)??e(`${d} names material "${c}", which does not exist`);o.forEach(c=>{c.spec.shadeOf!==void 0&&l(c.spec.shadeOf,`materials.${c.name}.shadeOf`);}),t.parts.forEach((c,d)=>{n(c.bone,`parts[${d}]`),l(c.material,`parts[${d}]`);}),t.paints?.forEach((c,d)=>{n(c.bone,`paints[${d}]`),c.on.forEach(m=>l(m,`paints[${d}]`));});let h=r.map(()=>[]);for(let[c,d]of Object.entries(t.acting??{}))for(let[m,u]of Object.entries(d)){let y=n(m,`acting.${c}`);for(let[w,x]of Object.entries(u))h[y].push([c,w,x]);}let f={};for(let[c,d]of Object.entries(t.anchors??{}))f[c]={bone:n(d.bone,`anchors.${c}`),at:d.at};for(let[c,d]of Object.entries(t.fx??{}))c!=="replace"&&d.forEach((m,u)=>{f[m.anchor]||e(`fx.${c}[${u}] names anchor "${m.anchor}", which does not exist`);});return {spec:t,bones:r,boneIndex:n,materials:o,materialId:l,eyeIds:s,acting:h,anchors:f}}var fe={uResolution:"vec2",uTime:"float",uCamera:"vec4",uBound:"vec4",uBones:"mat4[]",uScaleFix:"float",uFaceA:"vec4",uFaceB:"vec4",uFaceC:"vec4",uFaceD:"vec4",uGlow:"vec3",uShadow:"vec3",uFloor:"float",uLift:"float",uGlowPool:"float",uExposure:"float",uAlbedo:"vec3[materials]",uFxA:"vec4[fx]",uFxB:"vec4[fx]",uFxC:"vec4[fx]",uFxCount:"int"};function o0(t,e){return Object.entries(fe).map(([r,a])=>a==="mat4[]"?`uniform mat4 ${r}[${t}];`:a==="vec3[materials]"?`uniform vec3 ${r}[${Math.max(1,e)}];`:a==="vec4[fx]"?`uniform vec4 ${r}[${ee}];`:`uniform ${a} ${r};`).join(`
|
|
683
|
+
`)}var i0=`#version 300 es
|
|
684
|
+
void main() {
|
|
685
|
+
vec2 p = vec2(float((gl_VertexID << 1) & 2), float(gl_VertexID & 2));
|
|
686
|
+
gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0);
|
|
687
|
+
}`,U0=()=>$.map(t=>`#define E_${t.toUpperCase()} ${p(ie[t])}`).join(`
|
|
688
|
+
`)+`
|
|
689
|
+
`;function Re(t){let e=a0(t),r=["#version 300 es","precision highp float;","precision highp int;",o0(e.bones.length,e.materials.length),"out vec4 fragColor;","float gPixel = 0.001;","#define ZERO (min(int(uTime), 0))",t0,Xe(e),Ze,t.face?.kind==="screen"?U0()+r0:"",t.face?.kind==="mouth"?Je:"",We(e),Ye(e),e0,Qe].join(`
|
|
690
|
+
`);return {spec:t,bones:e.bones,acting:e.acting,anchors:e.anchors,fragment:r,materials:e.materials.map(a=>a.name),albedo:new Float32Array(e.materials.flatMap(a=>O(a.spec.color))),stats:{parts:t.parts.length+(t.eyes?2:0),bones:e.bones.length,materials:e.materials.length,shaderLines:r.split(`
|
|
691
|
+
`).length}}}var Ce=(t,e)=>[t[0]+e[0],t[1]+e[1],t[2]+e[2]],Ee=(t,e)=>[t[0]-e[0],t[1]-e[1],t[2]-e[2]],de=(t,e)=>[t[0]*e,t[1]*e,t[2]*e],s0=(t,e)=>t[0]*e[0]+t[1]*e[1]+t[2]*e[2],n0=(t,e)=>[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]],Le=t=>Math.hypot(t[0],t[1],t[2]);function se(t){let e=Le(t)||1;return [t[0]/e,t[1]/e,t[2]/e]}var l0=["rx","ry","rz"];function X0(t,e){if(typeof t=="number")return t;let[r,a=0,o=0,i=0]=t;return r+a*Math.sin(e*o*Math.PI*2+i)}var K=class{constructor(e,r=e.map(()=>[])){this.bones=e;this.acting=r;this.world=e.map(()=>C()),this.inverse=new Float32Array(e.length*16),this.tips=e.map(()=>null),this.spun=e.map(()=>({rx:0,ry:0,rz:0}));}world;inverse;tips;spun;scratch={t:C(),r:C(),j:C(),inv:C()};point(e,r){return we(this.world[e],r)}update(e,r,a,o,i){let{t:s,r:n,j:l,inv:h}=this.scratch;this.world[0].set(e);for(let f=1;f<this.bones.length;f++){let c=this.bones[f],d={rx:c.rest?.rx??0,ry:c.rest?.ry??0,rz:c.rest?.rz??0};for(let u of l0){for(let[w,x]of c.drive?.[u]??[])d[u]+=r[w]*x;let y=c.wave?.[u];y&&(d[u]+=y[0]*r.energy*Math.sin(o*y[1]*Math.PI*2+y[2]));}for(let[u,y,w]of this.acting[f]){let x=a[u];x<.001&&!(Array.isArray(w)&&w[4])||(d[y]+=x*X0(w,o),Array.isArray(w)&&w[4]&&(this.spun[f][y]+=x*w[4]*i));}for(let u of l0)d[u]+=this.spun[f][u];let m=this.world[f];_(m,this.world[c.parentIndex],ne(s,...c.pivot)),_(m,m,Q(n,d.rx,d.ry,d.rz)),c.jiggle&&_(m,m,this.jiggle(f,m,i,l,h));}for(let f=0;f<this.bones.length;f++)this.inverse.set(ye(h,this.world[f]),f*16);}jiggle(e,r,a,o,i){let{axis:s,length:n,freq:l,damping:h,maxAngle:f=.9}=this.bones[e].jiggle,c=we(r,[0,0,0]),d=Ce(c,de(se(ke(r,s)),n)),m=this.tips[e];if((!m||!(a>0))&&(m=this.tips[e]=m??{x:d,v:[0,0,0]},!(a>0)))return le(o,[0,1,0],0);let u=l*Math.PI*2;for(let z=0;z<3;z++)m.v[z]+=(u*u*(d[z]-m.x[z])-2*h*u*m.v[z])*a,m.x[z]+=m.v[z]*a;m.x=Ce(c,de(se(Ee(m.x,c)),n)),ye(i,r);let y=se(ke(i,Ee(m.x,c))),w=se(s),x=n0(w,y),M=Le(x);if(M<1e-6)return le(o,[0,1,0],0);let E=R(Math.atan2(M,s0(w,y)),0,f);return le(o,de(x,1/M),E)}};var K0=48,me=128,W0=null,ue=class t{static shared(){return W0??=new t}canvas=document.createElement("canvas");gl;programs=new Map;parallel;lastSyncBuild=-1/0;constructor(){let e=this.canvas.getContext("webgl2",{alpha:true,premultipliedAlpha:true,antialias:false,depth:false,stencil:false,powerPreference:"high-performance"});if(!e)throw new Error("WebGL2 is not available");this.gl=e,this.parallel=e.getExtension("KHR_parallel_shader_compile"),e.enable(e.SCISSOR_TEST),e.clearColor(0,0,0,0),this.canvas.addEventListener("webglcontextlost",r=>r.preventDefault()),this.canvas.addEventListener("webglcontextrestored",()=>{this.programs.clear(),e.enable(e.SCISSOR_TEST),e.clearColor(0,0,0,0);});}program(e){let r=this.programs.get(e);if(r==="failed")return null;if(r&&"program"in r)return r;if(!r){if(!this.parallel){let o=performance.now();if(o-this.lastSyncBuild<K0)return null;this.lastSyncBuild=o;}let a=this.start(e);return this.programs.set(e,a),this.parallel?null:this.finish(e,a)}return this.parallel&&!this.gl.getProgramParameter(r.building,this.parallel.COMPLETION_STATUS_KHR)?null:this.finish(e,r)}reserve(e,r){let a=Math.ceil(e/me)*me,o=Math.ceil(r/me)*me;a>this.canvas.width&&(this.canvas.width=a),o>this.canvas.height&&(this.canvas.height=o);}start(e){let{gl:r}=this,a=(n,l)=>{let h=r.createShader(n);return r.shaderSource(h,l),r.compileShader(h),h},o=a(r.VERTEX_SHADER,i0),i=a(r.FRAGMENT_SHADER,e.fragment),s=r.createProgram();return r.attachShader(s,o),r.attachShader(s,i),r.linkProgram(s),{building:s,vertex:o,fragment:i}}finish(e,{building:r,vertex:a,fragment:o}){let{gl:i}=this;if(!i.getProgramParameter(r,i.LINK_STATUS)){let l=i.getShaderInfoLog(o)||i.getProgramInfoLog(r);throw this.programs.set(e,"failed"),new Error(`${e.spec.id}: shader failed to build
|
|
692
|
+
${l}`)}i.deleteShader(a),i.deleteShader(o);let s=Object.fromEntries(Object.keys(fe).map(l=>[l,i.getUniformLocation(r,fe[l].includes("[")?`${l}[0]`:l)])),n={program:r,uniforms:s,character:e};return this.programs.set(e,n),n}};var c0=.2,Y0=.1,W=class{constructor(e){this.canvas=e;let r=e.getContext("2d");if(!r)throw new Error("Canvas 2D is not available");this.target=r;}gpu=ue.shared();target;character=null;load(e){this.character=e,this.gpu.program(e);}render(e){let r=this.character&&this.gpu.program(this.character);if(!r)return false;let{gpu:a}=this,{gl:o}=a,{width:i,height:s}=e;(this.canvas.width!==i||this.canvas.height!==s)&&(this.canvas.width=i,this.canvas.height=s),a.reserve(i,s),o.viewport(0,0,i,s),o.scissor(0,0,i,s),o.clear(o.COLOR_BUFFER_BIT),o.useProgram(r.program);let n=r.uniforms,{spec:l}=r.character,h=e.pose,f=h.lift;return o.uniform2f(n.uResolution,e.width,e.height),o.uniform1f(n.uTime,e.time),o.uniform4f(n.uCamera,l.frame.target,l.frame.radius*e.framing/c0,c0,Y0),o.uniform4f(n.uBound,0,l.bound.y+f,0,l.bound.radius),o.uniformMatrix4fv(n.uBones,false,e.bones),o.uniform1f(n.uScaleFix,h.minScale),o.uniform4fv(n.uFaceA,h.faceA),o.uniform4fv(n.uFaceB,h.faceB),o.uniform4fv(n.uFaceC,h.faceC),o.uniform4fv(n.uFaceD,h.faceD),o.uniform3fv(n.uGlow,h.glow),o.uniform3fv(n.uShadow,e.shadow),o.uniform1f(n.uFloor,e.floor),o.uniform1f(n.uLift,f),o.uniform1f(n.uExposure,e.exposure*h.exposure),o.uniform3fv(n.uAlbedo,e.albedo),o.uniform1f(n.uGlowPool,l.glowPool??0),o.uniform4fv(n.uFxA,e.fx.a),o.uniform4fv(n.uFxB,e.fx.b),o.uniform4fv(n.uFxC,e.fx.c),o.uniform1i(n.uFxCount,e.fx.count),o.drawArrays(o.TRIANGLES,0,3),this.target.globalCompositeOperation="copy",this.target.drawImage(a.canvas,0,a.canvas.height-s,i,s,0,0,i,s),true}dispose(){this.character=null;}};var Z0=/^#[0-9a-f]{6}$/i;function Q0(t,e,r,a){if(!e.includes(r))throw new Error(`${t}: palette names material "${r}". Materials are: ${e.join(", ")}.`);if(!Z0.test(a))throw new Error(`${t}: palette colour for "${r}" must look like #rrggbb, got "${a}".`)}function p0(t,e){let r=Object.keys(t.materials),a=new Map;for(let[o,i]of Object.entries(e))Q0(t.id,r,o,i),a.set(o,O(i));for(let[o,i]of Object.entries(t.materials)){let s=i.shadeOf;if(!s||a.has(o)||!(s in e))continue;let n=O(t.materials[s].color),l=O(i.color),h=a.get(s);a.set(o,[0,1,2].map(f=>Math.min(1,n[f]>.001?h[f]*l[f]/n[f]:l[f])));}return a}function h0(t,e){let r={...t.materials};for(let[a,o]of p0(t,e))r[a]={...r[a],color:a in e?e[a]:_e(o)};return {...t,materials:r}}function te(t,e){let r=t.albedo.slice();if(!e)return r;for(let[a,o]of p0(t.spec,e))r.set(o,t.materials.indexOf(a)*3);return r}function J0(t,e){let{palette:r,...a}=e,o={...t,...a,motion:{...t.motion,...a.motion}};return r?h0(o,r):o}var et=t=>t;var $e=class{members=new Set;frame=0;last=0;time=0;quality=1;slow=0;fast=0;add(e){this.members.add(e),this.start();}delete(e){this.members.delete(e),this.members.size||this.stop();}start(){this.frame||typeof requestAnimationFrame>"u"||(this.last=performance.now(),this.frame=requestAnimationFrame(this.loop));}stop(){cancelAnimationFrame(this.frame),this.frame=0;}loop=e=>{this.frame=requestAnimationFrame(this.loop);let r=Math.max(0,e-this.last),a=Math.min(r/1e3,1/20);this.adapt(r),this.last=e,this.time+=a;for(let o of this.members)o.active&&o.tick(a,this.time,this.quality);};adapt(e){e>22&&e<200?this.slow++:this.slow=Math.max(0,this.slow-1),e<17.5?this.fast++:this.fast=0,this.slow>20?(this.quality=Math.max(.55,this.quality*.85),this.slow=0):this.fast>120&&this.quality<1&&(this.quality=Math.min(1,this.quality*1.08),this.fast=0);}},Ae=new $e;var f0=new WeakMap;function be(t){let e=f0.get(t);return e||f0.set(t,e=Re(t)),e}var re=class{constructor(e,r,a={}){this.canvas=e;if(this.seed=a.seed??Math.random(),this.palette=a.palette,this.options={interactive:a.interactive??true,effects:a.effects??true,speed:a.speed??1,maxPixelRatio:a.maxPixelRatio??2,shadow:a.shadow??[.05,.06,.12],floor:a.floor??1,exposure:a.exposure??1,framing:a.framing??1,respectReducedMotion:a.respectReducedMotion??true},this.renderer=new W(e),this.load(r,a.state??"idle"),e.setAttribute("role","img"),this.reducedMotion=typeof matchMedia=="function"?matchMedia("(prefers-reduced-motion: reduce)"):null,typeof IntersectionObserver<"u"){let o=new IntersectionObserver(([i])=>this.visible=i.isIntersecting);o.observe(e),this.cleanup.push(()=>o.disconnect());}this.options.interactive&&this.listen(),Ae.add(this);}character;brain;rig;fx;renderer;options;seed;palette;albedo;visible=true;paused=false;time=0;reducedMotion;stillFrames=0;drawn=false;listeners={poke:new Set,state:new Set,ready:new Set};cleanup=[];source;get state(){return this.brain.state}get spec(){return this.source}get stats(){return this.character.stats}setState(e){if(!T.includes(e))throw new Error(`Unknown state "${e}". Expected one of ${T.join(", ")}.`);e!==this.brain.state&&(this.brain.setState(e),this.stillFrames=0,this.label(),this.emit("state",e));}setSpec(e,r){this.palette=r,this.load(e,this.brain.state);}setPalette(e){this.albedo=te(this.character,e),this.palette=e,this.stillFrames=0;}setSpeed(e){this.options.speed=Math.max(0,e);}setEffects(e){this.options.effects=e;}poke(){this.brain.poke(),this.stillFrames=0,this.emit("poke",void 0);}pause(){this.paused=true;}play(){this.paused=false;}on(e,r){return this.listeners[e].add(r),()=>this.listeners[e].delete(r)}get active(){return !this.visible||this.paused?false:!this.still||this.stillFrames<2}tick(e,r,a){let o=this.still,i=e*this.options.speed;if(o)for(let f=0;f<90;f++)this.brain.update(1/60);else this.brain.update(i),this.time+=i;let s=o?0:this.time,n=this.brain.pose;this.rig.update(n.root,n.channels,n.weights,s,o?0:i),!o&&this.options.effects?this.fx.update(i,n,this.rig):this.fx.count=0,n.events.length=0;let l=Math.min(devicePixelRatio||1,this.options.maxPixelRatio)*a,h=this.renderer.render({pose:n,bones:this.rig.inverse,fx:this.fx,albedo:this.albedo,time:s,width:Math.max(1,Math.round(this.canvas.clientWidth*l)),height:Math.max(1,Math.round(this.canvas.clientHeight*l)),shadow:this.options.shadow,floor:this.options.floor,exposure:this.options.exposure,framing:this.options.framing});h&&o&&this.stillFrames++,h&&!this.drawn&&(this.drawn=true,this.emit("ready",void 0));}get ready(){return this.drawn}dispose(){Ae.delete(this),this.cleanup.forEach(e=>e()),this.listeners.poke.clear(),this.listeners.state.clear(),this.listeners.ready.clear(),this.renderer.dispose();}load(e,r){this.source=e,this.character=be(e),this.albedo=te(this.character,this.palette),this.renderer.load(this.character),this.brain=new G(e.motion,this.seed),this.brain.setState(r),this.rig=new K(this.character.bones,this.character.acting),this.fx=new U(this.character,J(this.seed+.37)),this.stillFrames=0,this.label();}get still(){return this.options.respectReducedMotion&&(this.reducedMotion?.matches??false)}emit(e,r){for(let a of this.listeners[e])a(r);}label(){this.canvas.hasAttribute("data-own-label")||this.canvas.setAttribute("aria-label",`${this.source.name}, ${this.brain.state}`);}listen(){let e=o=>{let i=this.canvas.getBoundingClientRect(),s=Math.max(i.width,1),n=(o.clientX-(i.left+i.width/2))/(s*1.1),l=(o.clientY-(i.top+i.height*.45))/(s*1.1);this.brain.pointer=Math.hypot(n,l)<3?{x:n,y:l}:null;},r=()=>this.brain.pointer=null,a=()=>this.poke();window.addEventListener("pointermove",e,{passive:true}),document.addEventListener("pointerleave",r),this.canvas.addEventListener("click",a),this.cleanup.push(()=>{window.removeEventListener("pointermove",e),document.removeEventListener("pointerleave",r),this.canvas.removeEventListener("click",a);});}};function tt(t,e,r={}){let a=document.createElement("canvas");a.style.cssText="display:block;width:100%;height:100%;touch-action:manipulation",t.append(a);let o=new re(a,e,r),i=o.dispose.bind(o);return o.dispose=()=>{i(),a.remove();},o}var rt=()=>new Promise(t=>requestAnimationFrame(t));async function at(t,e={}){let r=e.pixelRatio??Math.min(devicePixelRatio||1,2),a=Math.max(1,Math.round((e.size??256)*r)),o=document.createElement("canvas"),i=be(t),s=new W(o);s.load(i);let n=new G(t.motion,e.seed??.5);n.setState(e.state??"idle");for(let d=0;d<90;d++)n.update(1/60);let l=n.pose,h=new K(i.bones,i.acting);h.update(l.root,l.channels,l.weights,0,0);let f=new U(i,J(0));f.count=0;let c={pose:l,bones:h.inverse,fx:f,albedo:te(i,e.palette),time:0,width:a,height:a,shadow:[.05,.06,.12],floor:e.floor??1,exposure:1,framing:e.framing??1};for(;!s.render(c);)await rt();return s.dispose(),o}var ot={submitted:"thinking",streaming:"speaking",error:"error",idle:"idle"};function ge(t,e,r=1400){if(e==="ready"){t.state==="speaking"||t.state==="thinking"?(t.setState("celebrating"),setTimeout(()=>t.state==="celebrating"&&t.setState("idle"),r)):t.setState("idle");return}t.setState(ot[e]??"idle");}var it=["character","state","status","seed","speed","palette","interactive","effects","framing","floor"];function qe(t){if(!t)return;let e=t.split(";").map(r=>r.split(":").map(a=>a.trim())).filter(([r,a])=>r&&a);return e.length?Object.fromEntries(e):void 0}function Pe(t,e="wobnimo-mascot"){if(typeof customElements>"u"||customElements.get(e))return;let r=new Map(t.map(o=>[o.id,o]));class a extends HTMLElement{static observedAttributes=it;instance=null;custom=null;canvas;constructor(){super();let i=this.attachShadow({mode:"open"});i.innerHTML="<style>:host{display:inline-block;width:160px;height:160px;position:relative}canvas{display:block;width:100%;height:100%;touch-action:manipulation}</style>",this.canvas=document.createElement("canvas"),i.append(this.canvas);}get mascot(){return this.instance}get state(){return this.getAttribute("state")??"idle"}set state(i){this.setAttribute("state",i);}get spec(){return this.custom??r.get(this.getAttribute("character")??"")??null}set spec(i){this.custom=i,this.rebuild();}connectedCallback(){this.rebuild();}disconnectedCallback(){this.instance?.dispose(),this.instance=null;}attributeChangedCallback(i,s,n){if(s===n||!this.isConnected)return;let l=this.instance;i==="status"&&l&&n?ge(l,n):i==="state"&&l&&T.includes(n)?l.setState(n):i==="speed"&&l?l.setSpeed(Number(n??1)):i==="effects"&&l?l.setEffects(n!=="false"):i==="palette"&&l?l.setPalette(qe(n)):i==="character"&&l&&this.spec?l.setSpec(this.spec,qe(this.getAttribute("palette"))):this.rebuild();}rebuild(){if(!this.isConnected)return;this.instance?.dispose(),this.instance=null;let i=this.spec;if(!i){console.warn(`<${e}>: unknown character "${this.getAttribute("character")}". Registered: ${[...r.keys()].join(", ")}.`);return}let s=this.getAttribute("seed"),n=new re(this.canvas,i,{state:T.includes(this.state)?this.state:"idle",seed:s===null?void 0:Number(s),speed:Number(this.getAttribute("speed")??1),palette:qe(this.getAttribute("palette")),interactive:this.getAttribute("interactive")!=="false",effects:this.getAttribute("effects")!=="false",framing:Number(this.getAttribute("framing")??1),floor:Number(this.getAttribute("floor")??1)});n.on("poke",()=>this.dispatchEvent(new CustomEvent("poke",{bubbles:true,composed:true}))),n.on("state",h=>this.dispatchEvent(new CustomEvent("statechange",{detail:h,bubbles:true,composed:true}))),n.on("ready",()=>this.dispatchEvent(new CustomEvent("ready",{bubbles:true,composed:true}))),this.instance=n;let l=this.getAttribute("status");l&&ge(n,l);}}customElements.define(e,a);}var d0={id:"boo",name:"Boo",tagline:"Floats, glows from inside, trails motes, a hem that ripples",accent:"#8a6cf0",frame:{target:.78,radius:.92},bound:{y:.72,radius:.72},motion:{float:.22,hop:.12,squash:.8,snap:.8,talkSquash:.6},glowPool:.55,materials:{ghost:{color:"#eceaff",f0:.04,spec:.5,shininess:30,rim:1.4,sss:.4,sssColor:"#b9a4ff",emit:"#6f52d9",emitStrength:.06},bead:{color:"#1b1430",f0:.06,spec:2.2,shininess:400,rim:.2,gloss:1}},bones:[{name:"body",pivot:[0,0,0],drive:{rx:[["pitch",-0.5]],ry:[["yaw",.7]],rz:[["roll",.6]]},wave:{rz:[.03,.45,0]}},{name:"armL",parent:"body",pivot:[-0.36,.74,.04],drive:{rz:[["flap",-1.2]]},wave:{rz:[.08,.7,0]},jiggle:{axis:[-0.8,-0.6,0],length:.15,freq:2,damping:.2,maxAngle:.7}},{name:"armR",parent:"body",pivot:[.36,.74,.04],drive:{rz:[["flap",1.2]]},wave:{rz:[-0.08,.7,1.6]},jiggle:{axis:[.8,-0.6,0],length:.15,freq:2,damping:.2,maxAngle:.7}}],parts:[{bone:"body",shape:"sphere",at:[0,.88,0],radius:.4,material:"ghost"},{bone:"body",shape:"roundCone",from:[0,.88,0],to:[0,.4,0],r1:.4,r2:.47,material:"ghost"},{bone:"body",shape:"hem",y:.34,amplitude:.045,waves:6,speed:2.4,blend:.05,material:"ghost"},{bone:"armL",shape:"capsule",from:[0,0,0],to:[-0.12,-0.09,.02],radius:.07,blend:.08,material:"ghost"},{bone:"armR",shape:"capsule",from:[0,0,0],to:[.12,-0.09,.02],radius:.07,blend:.08,material:"ghost"}],paints:[{bone:"body",on:["ghost"],kind:"sphere",at:[-0.24,.78,.31],radius:.07,color:"#ffa3c4",soft:.6,opacity:.7},{bone:"body",on:["ghost"],kind:"sphere",at:[.24,.78,.31],radius:.07,color:"#ffa3c4",soft:.6,opacity:.7}],eyes:{kind:"bead",bone:"body",at:[[-0.135,.9,.375],[.135,.9,.375]],radii:[.048,.072,.03],material:"bead"},face:{kind:"mouth",bone:"body",on:["ghost"],at:[0,.77,.38],width:.075,color:"#2a1a4a",tongue:"#ff7fa6"},anchors:{top:{bone:"body",at:[.16,1.2,.1]},mouth:{bone:"body",at:[0,.77,.4]},ear:{bone:"body",at:[-0.42,.92,0]},center:{bone:"body",at:[0,.8,0]}},acting:{idle:{armL:{rz:[0,.1,.7,0]},armR:{rz:[0,.1,.7,1.3]}},thinking:{armR:{ry:-1.1,rz:.9},armL:{rz:.25}},listening:{armL:{rz:-1,rx:-0.35}},speaking:{armL:{rz:[-0.3,.3,1.2,0],rx:[-0.3,.2,.9,0]},armR:{rz:[.3,.3,1.2,1.7],rx:[-0.3,.2,.9,2.2]}},sleeping:{armL:{rz:.4},armR:{rz:-0.4},body:{rz:.08}},working:{armL:{rx:[-0.6,.15,6,0],rz:-0.3},armR:{rx:[-0.6,.15,6,Math.PI],rz:.3}},error:{armL:{rz:[-1,.25,10,0]},armR:{rz:[1,.25,10,1]}},surprised:{armL:{rz:-1.4,rx:-0.4},armR:{rz:1.4,rx:-0.4}},celebrating:{armL:{rz:[-1.6,.3,4,0]},armR:{rz:[1.6,.3,4,Math.PI]}},sad:{armL:{rz:.5},armR:{rz:-0.5},body:{rz:.05}},happy:{armL:{rz:[-1.3,.35,3,0]},armR:{rz:[1.3,.35,3,1.2]}}},fx:{ambient:[{glyph:"mote",anchor:"center",rate:1.3,spread:.5,velocity:[0,.07,0],jitter:.06,wobble:.09,life:[2.2,3.2],size:[.04,.02],color:"#b49cff",glow:true}],happy:[{glyph:"heart",anchor:"top",rate:1.2,spread:.2,velocity:[0,.22,.05],jitter:.12,wobble:.06,life:[1,1.3],size:[.04,.07],color:"#ff86b0"}]}};var m0=[.085,.064,.044,.016],u0=[-0.6,-0.42,-0.62];function st(){let t={idle:{},thinking:{},listening:{},speaking:{},sleeping:{},working:{},error:{},surprised:{},celebrating:{},sad:{},happy:{}};for(let e=0;e<6;e++){let r=e*1.05;t.speaking[`t${e}s0`]={rx:[0,.2,1.1,r]},t.speaking[`t${e}s2`]={rx:[0,.35,1.6,r+1]},t.sleeping[`t${e}s0`]={rx:.3},t.sleeping[`t${e}s1`]={rx:.35},t.sleeping[`t${e}s2`]={rx:.55},t.happy[`t${e}s0`]={rx:[-0.45,.35,2.4,r]},t.happy[`t${e}s1`]={rx:[0,.3,2.4,r+1]},t.error[`t${e}s0`]={rx:-0.35},t.error[`t${e}s1`]={rx:[.35,.18,9,r]},t.error[`t${e}s2`]={rx:[.2,.22,11,r+2]},t.surprised[`t${e}s0`]={rx:-0.85},t.surprised[`t${e}s1`]={rx:-0.25},t.surprised[`t${e}s2`]={rx:-0.3},t.celebrating[`t${e}s0`]={rx:[-0.5,.3,3,r]},t.celebrating[`t${e}s1`]={rx:[.15,.3,3,r+1]},t.celebrating[`t${e}s2`]={rx:[.2,.3,3,r+2]},t.sad[`t${e}s0`]={rx:.45},t.sad[`t${e}s1`]={rx:.42},t.sad[`t${e}s2`]={rx:[.55,.06,.4,r]},t.working[`t${e}s0`]={rx:[-0.15,.08,1.2,r]};}return t.working.t0s0={rx:[-1.25,.22,5.5,0]},t.working.t0s1={rx:[.7,.2,5.5,.6]},t.working.t5s0={rx:[-1.25,.22,5.5,Math.PI]},t.working.t5s1={rx:[.7,.2,5.5,Math.PI+.6]},t.celebrating.t0s0={rx:-0.3,rz:[1.05,.25,3.2,0]},t.celebrating.t0s1={rx:[.5,.15,3.2,1]},t.celebrating.t0s2={rx:[.6,.2,3.2,2]},t.celebrating.t5s0={rx:-0.3,rz:[-1.05,.25,3.2,Math.PI]},t.celebrating.t5s1={rx:[.5,.15,3.2,Math.PI+1]},t.celebrating.t5s2={rx:[.6,.2,3.2,Math.PI+2]},t.thinking.t0s0={rx:-1.75},t.thinking.t0s1={rx:.95},t.thinking.t0s2={rx:[1,.12,1.6,0]},t.listening.t5s0={rx:-1.6},t.listening.t5s1={rx:-0.2},t.listening.t5s2={rx:.7},t}var b0=[{name:"mantle",pivot:[0,.42,0],drive:{rx:[["pitch",-0.6]],ry:[["yaw",.6]],rz:[["roll",.6]]}}],g0=[];for(let t=0;t<6;t++){let e=(t+.5)/6*Math.PI*2;for(let r=0;r<3;r++){let a=`t${t}s${r}`;b0.push({name:a,parent:r===0?"mantle":`t${t}s${r-1}`,pivot:r===0?[.26*Math.sin(e),.02,.26*Math.cos(e)]:[0,-0.17,0],rest:r===0?{rx:u0[0],ry:e}:{rx:u0[r]},wave:{rx:[.12+r*.1,.32,t*1.3+r*.8],rz:[.06+r*.05,.21,t*2.1+r]},jiggle:{axis:[0,-1,0],length:.17,freq:2.4-r*.4,damping:.25,maxAngle:.8}}),g0.push({bone:a,shape:"roundCone",from:[0,0,0],to:[0,-0.17,0],r1:m0[r],r2:m0[r+1],blend:r===0?.1:.04,material:"skin"});}}var x0={id:"inky",name:"Inky",tagline:"Floats, with six tentacles that trail on spring chains",accent:"#e04f7d",frame:{target:.86,radius:.98},bound:{y:.64,radius:1},motion:{float:.32,hop:.12,squash:1.1,snap:.85,look:.8,talkSquash:.5},materials:{skin:{color:"#f2647f",f0:.05,spec:1.1,shininess:90,rim:.8,sss:.35,sssColor:"#ffb0c4",gloss:.7}},bones:b0,parts:[{bone:"mantle",shape:"ellipsoid",at:[0,.38,-0.04],radii:[.43,.45,.41],material:"skin"},{bone:"mantle",shape:"ellipsoid",at:[0,.04,0],radii:[.35,.15,.35],blend:.16,material:"skin"},...g0],paints:[...[[.14,.78,.12,.07],[-0.2,.72,.16,.055],[.33,.6,.12,.05],[-0.04,.83,-0.05,.06],[-0.36,.52,.1,.05],[.06,.62,.33,.045],[.3,.42,-0.26,.045]].map(([t,e,r,a])=>({bone:"mantle",on:["skin"],kind:"sphere",at:[t,e,r],radius:a,color:"#d23f6c",soft:.2})),{bone:"mantle",on:["skin"],kind:"sphere",at:[-0.27,.18,.31],radius:.065,color:"#ff9db0",soft:.6,opacity:.7},{bone:"mantle",on:["skin"],kind:"sphere",at:[.27,.18,.31],radius:.065,color:"#ff9db0",soft:.6,opacity:.7}],eyes:{kind:"ball",bone:"mantle",at:[[-0.16,.27,.3],[.16,.27,.3]],radius:.098,iris:"#f2b33d",irisSize:.66,pupilSize:.3,pupilAspect:1.9,lid:"skin"},face:{kind:"mouth",bone:"mantle",on:["skin"],at:[0,.13,.3],width:.062,color:"#5a1430",tongue:"#ff8fa8"},anchors:{top:{bone:"mantle",at:[.16,.86,.1]},mouth:{bone:"mantle",at:[0,.13,.33]},ear:{bone:"mantle",at:[-0.46,.4,0]},skirt:{bone:"mantle",at:[0,0,0]}},acting:st(),fx:{replace:["syllable"],ambient:[{glyph:"bubble",anchor:"skirt",rate:.7,spread:.35,velocity:[0,.18,0],jitter:.05,wobble:.06,life:[2.4,3.2],size:[.02,.045],color:"#8fcfff"}],syllable:[{glyph:"bubble",anchor:"mouth",rate:2,offset:[0,0,.04],velocity:[.05,.2,.1],jitter:.1,wobble:.05,life:[1,1.4],size:[.014,.034],color:"#9ad7ff"}]}};var q=Math.PI/2,v0={id:"microduck",name:"Microduck",tagline:"A bipedal robot duck: servo neck, lens eyes, a bill that clacks when it talks, and boots it marches in",accent:"#ff6a1f",frame:{target:.57,radius:.8},bound:{y:.58,radius:.88},motion:{hop:.12,squash:.45,snap:1.4,look:.9,snapLook:1,talkSquash:.12},materials:{shell:{color:"#f3f1ec",f0:.04,spec:1.1,shininess:70,rim:.55,gloss:.5,sss:.12,sssColor:"#ffffff",surface:{kind:"ripple",scale:70,strength:.12,bone:"head"}},bodyShell:{color:"#f3f1ec",shadeOf:"shell",f0:.04,spec:1.1,shininess:70,rim:.55,gloss:.5,sss:.12,sssColor:"#ffffff",surface:{kind:"ripple",scale:70,strength:.12,bone:"body"}},bill:{color:"#ff5f1f",f0:.05,spec:1.3,shininess:90,rim:.45,gloss:.65,sss:.2,sssColor:"#ffb27a"},ring:{color:"#ff8410",f0:.05,spec:1.3,shininess:90,rim:.4,gloss:.65,sss:.15,sssColor:"#ffd08a"},boot:{color:"#ff5a24",f0:.04,spec:.9,shininess:50,rim:.4,gloss:.4,sss:.15,sssColor:"#ffb08a"},sole:{color:"#ffb12e",f0:.04,spec:.7,shininess:40,rim:.3,gloss:.3},servo:{color:"#2a2d33",f0:.06,spec:1.2,shininess:80,rim:.5,gloss:.55,metal:.25},horn:{color:"#a3a9b1",f0:.3,spec:1.6,shininess:120,rim:.4,gloss:.7,metal:.8},lens:{color:"#101318",f0:.12,spec:2.6,shininess:420,rim:.3,gloss:1},mouth:{color:"#3b1510",f0:.04,spec:.5,shininess:30,rim:0},led:{color:"#ffffff",f0:.05,spec:1,shininess:120,rim:0,glows:true}},bones:[{name:"hips",pivot:[0,0,0],rest:{ry:.55}},{name:"legL",parent:"hips",pivot:[-0.12,.36,0]},{name:"shinL",parent:"legL",pivot:[0,-0.15,0]},{name:"legR",parent:"hips",pivot:[.12,.36,0]},{name:"shinR",parent:"legR",pivot:[0,-0.15,0]},{name:"body",parent:"hips",pivot:[0,.39,0],drive:{ry:[["yaw",.2]],rz:[["roll",.4]]}},{name:"neck0",parent:"body",pivot:[0,.19,.04],drive:{rx:[["pitch",-0.15]],ry:[["yaw",.25]]}},{name:"neck1",parent:"neck0",pivot:[0,.09,0],drive:{rx:[["pitch",-0.1]],ry:[["yaw",.2]]},jiggle:{axis:[0,1,0],length:.2,freq:3.4,damping:.35,maxAngle:.16}},{name:"head",parent:"neck1",pivot:[0,.09,0],drive:{rx:[["pitch",-0.35]],ry:[["yaw",.55]],rz:[["roll",.6]]}},{name:"jaw",parent:"head",pivot:[0,.063,-0.18],drive:{rx:[["talk",.24]]}}],parts:[{bone:"head",shape:"roundBox",at:[0,.245,.05],half:[.2,.17,.3],round:.16,clip:{normal:[0,-1,0],offset:.145},material:"shell"},{bone:"head",shape:"roundBox",at:[0,.085,.1],half:[.208,.022,.32],round:.016,material:"bill"},{bone:"head",shape:"roundBox",at:[0,.045,-0.06],half:[.17,.035,.12],round:.02,material:"mouth"},{bone:"jaw",shape:"roundBox",at:[0,-0.017,.27],half:[.192,.018,.285],round:.014,material:"bill"},{bone:"head",shape:"cylinder",at:[-0.205,.225,.15],rot:[q,-1.05,0],radius:.08,half:.026,round:.016,material:"ring"},{bone:"head",shape:"cylinder",at:[.205,.225,.15],rot:[q,1.05,0],radius:.08,half:.026,round:.016,material:"ring"},{bone:"head",shape:"sphere",at:[-0.2,.31,.25],radius:.016,material:"servo"},{bone:"head",shape:"sphere",at:[.2,.31,.25],radius:.016,material:"servo"},{bone:"head",shape:"roundBox",at:[0,.01,0],half:[.07,.035,.07],round:.016,material:"servo"},{bone:"neck0",shape:"roundBox",at:[0,.045,0],half:[.048,.047,.042],round:.016,material:"servo"},{bone:"neck0",shape:"cylinder",at:[0,.02,0],rot:[0,0,q],radius:.026,half:.057,round:.01,material:"horn"},{bone:"neck1",shape:"roundBox",at:[0,.045,0],half:[.045,.047,.04],round:.016,material:"servo"},{bone:"neck1",shape:"cylinder",at:[0,.02,0],rot:[0,0,q],radius:.024,half:.053,round:.01,material:"horn"},{bone:"body",shape:"roundBox",at:[0,.1,-0.01],half:[.19,.1,.15],round:.085,material:"bodyShell"},{bone:"body",shape:"capsule",from:[-0.03,.12,.14],to:[.03,.12,.14],radius:.014,material:"led"},{bone:"hips",shape:"roundBox",at:[0,.37,0],half:[.15,.04,.09],round:.02,material:"servo"},{bone:"hips",shape:"cylinder",at:[-0.16,.36,0],rot:[0,0,q],radius:.045,half:.026,round:.012,material:"horn"},{bone:"hips",shape:"cylinder",at:[.16,.36,0],rot:[0,0,q],radius:.045,half:.026,round:.012,material:"horn"},...[["legL","shinL",-1],["legR","shinR",1]].flatMap(([t,e,r])=>[{bone:t,shape:"roundBox",at:[0,-0.075,0],half:[.038,.07,.042],round:.015,material:"servo"},{bone:t,shape:"cylinder",at:[0,-0.15,0],rot:[0,0,q],radius:.036,half:.05,round:.012,material:"horn"},{bone:t,shape:"plate",at:[r*.056,-0.1,-5e-3],rot:[r*q,r*Math.PI/4,q],half:[.058,.058],corner:.034,depth:.012,material:"bodyShell"},{bone:e,shape:"roundBox",at:[0,-0.06,0],half:[.034,.055,.038],round:.014,material:"servo"},{bone:e,shape:"roundBox",at:[0,-0.135,.005],half:[.048,.036,.052],round:.016,material:"servo"},{bone:e,shape:"roundBox",at:[0,-0.17,.045],half:[.074,.04,.108],round:.038,material:"boot"},{bone:e,shape:"roundBox",at:[0,-0.196,.045],half:[.079,.014,.113],round:.012,material:"sole"}])],paints:[...[-1,1].flatMap(t=>[{bone:"head",on:["bill"],kind:"sphere",at:[t*.208,.085,-0.13],radius:.013,color:"#c8261a",soft:.2},{bone:"head",on:["bill"],kind:"sphere",at:[t*.208,.085,-0.18],radius:.013,color:"#c8261a",soft:.2}]),...["shinL","shinR"].flatMap(t=>[[-0.03,.1],[.03,.1],[0,.13],[-0.03,.06],[.03,.06]].map(([e,r])=>({bone:t,on:["boot"],kind:"sphere",at:[e,-0.13,r],radius:.011,color:"#c23a14",soft:.25}))),...[-1,1].map(t=>({bone:"body",on:["bodyShell"],kind:"sphere",at:[t*.15,.03,.13],radius:.009,color:"#8d9198",soft:.2}))],eyes:{kind:"bead",bone:"head",at:[[-0.228,.225,.165],[.228,.225,.165]],radii:[.048,.048,.048],material:"lens"},anchors:{top:{bone:"head",at:[.1,.42,.08]},mouth:{bone:"head",at:[0,.06,.45]},ear:{bone:"head",at:[-0.24,.2,.05]},feet:{bone:"root",at:[0,.02,.08]},chest:{bone:"body",at:[0,.12,.16]},neck:{bone:"neck0",at:[.05,.08,.05]}},acting:{idle:{body:{rz:[0,.03,.45,0]},neck0:{rx:[0,.04,.9,0]}},thinking:{head:{rz:.22,rx:-0.1},jaw:{rx:.06},legR:{rx:[-0.05,.05,2.4,0]},shinR:{rx:[.05,.05,2.4,Math.PI]}},listening:{head:{rz:-0.24,ry:.2},neck0:{rx:.1}},speaking:{neck0:{rx:[0,.05,1.6,0]},body:{rz:[0,.03,.8,0]}},sleeping:{neck0:{rx:.08},neck1:{rx:.05},head:{rz:.12},legL:{rx:-0.12},shinL:{rx:.24},legR:{rx:-0.12},shinR:{rx:.24}},working:{neck0:{rx:[.1,.06,4.2,0]},neck1:{rx:[.04,.04,4.2,.6]},jaw:{rx:[.03,.03,8.4,0]}},error:{head:{rz:[.2,.06,9,0]},jaw:{rx:.06},legL:{rz:.1},legR:{rz:-0.1},neck0:{rx:.12}},surprised:{neck0:{rx:-0.15},head:{rx:.05}},celebrating:{legL:{rx:[-0.25,.25,2.4,0]},shinL:{rx:[.25,.25,2.4,Math.PI]},legR:{rx:[-0.25,.25,2.4,Math.PI]},shinR:{rx:[.25,.25,2.4,0]},head:{rz:[0,.2,1.2,0]}},sad:{head:{rz:-0.1},legL:{rx:-0.08},shinL:{rx:.16},legR:{rx:-0.08},shinR:{rx:.16}},happy:{legL:{rx:[-0.2,.2,4,0]},shinL:{rx:[.2,.2,4,Math.PI]},legR:{rx:[-0.2,.2,4,Math.PI]},shinR:{rx:[.2,.2,4,0]},jaw:{rx:[.08,.08,8,0]}}},fx:{error:[{glyph:"spark",anchor:"neck",rate:5,spread:.03,velocity:[.25,.3,.1],jitter:.8,gravity:2,life:[.2,.35],size:[.03,.012],color:"#ffd166",glow:true,align:true}],working:[{glyph:"dot",anchor:"chest",rate:1.6,offset:[0,.02,.02],spread:.03,velocity:[0,.1,.06],jitter:.02,life:[.7,.9],size:[.012,.004],color:"#ffb27a",glow:true}]}};var y0={id:"miso",name:"Miso",tagline:"A plush tabby with velvet fur, swivelling ears and a tail that never sits still",accent:"#e38b3c",frame:{target:.56,radius:.72},bound:{y:.56,radius:.78},motion:{hop:.14,squash:1.2,snap:1.1,talkSquash:.3},materials:{fur:{color:"#eaa15c",f0:.015,spec:.06,shininess:6,rim:1.1,sheen:.95,gloss:0,sss:.18,sssColor:"#ffcf9e"},cream:{color:"#fbe8d0",f0:.015,spec:.06,shininess:6,rim:1,sheen:.9,gloss:0,sss:.18,sssColor:"#ffe6cc"},pink:{color:"#ff9fb2",f0:.04,spec:.5,shininess:40,rim:.4,sss:.4,sssColor:"#ffc4cf"},nose:{color:"#f27a93",f0:.06,spec:1.6,shininess:160,rim:.3,gloss:.8},whisker:{color:"#fff8ee",f0:.04,spec:.6,shininess:60,rim:.5}},bones:[{name:"body",pivot:[0,0,0],drive:{ry:[["yaw",.2]],rz:[["roll",.25]]}},{name:"head",parent:"body",pivot:[0,.5,.02],drive:{rx:[["pitch",-1]],ry:[["yaw",.85]],rz:[["roll",.8]]}},{name:"earL",parent:"head",pivot:[-0.19,.38,-0.02],rest:{rz:.32},wave:{rx:[.06,.37,0]},jiggle:{axis:[0,1,0],length:.16,freq:3.2,damping:.16,maxAngle:.5}},{name:"earR",parent:"head",pivot:[.19,.38,-0.02],rest:{rz:-0.32},wave:{rx:[.06,.29,2]},jiggle:{axis:[0,1,0],length:.16,freq:3.2,damping:.16,maxAngle:.5}},{name:"pawL",parent:"body",pivot:[-0.13,.22,.17],drive:{rx:[["flap",-1.2]],rz:[["flap",-0.4]]}},{name:"pawR",parent:"body",pivot:[.13,.22,.17],drive:{rx:[["flap",-1.2]],rz:[["flap",.4]]}},{name:"tail0",parent:"body",pivot:[.12,.1,-0.24],rest:{rx:-0.5,rz:-0.5},wave:{rz:[.25,.45,0]},jiggle:{axis:[0,1,0],length:.16,freq:2,damping:.25,maxAngle:.7}},{name:"tail1",parent:"tail0",pivot:[0,.16,0],rest:{rx:-0.3},wave:{rz:[.2,.45,.8]},jiggle:{axis:[0,1,0],length:.15,freq:1.8,damping:.22,maxAngle:.8}},{name:"tail2",parent:"tail1",pivot:[0,.15,0],rest:{rx:.25},wave:{rz:[.3,.45,1.6]},jiggle:{axis:[0,1,0],length:.13,freq:1.6,damping:.2,maxAngle:.9}}],parts:[{bone:"body",shape:"ellipsoid",at:[0,.25,-0.02],radii:[.29,.26,.26],material:"fur"},{bone:"body",shape:"ellipsoid",at:[-0.17,.13,-0.02],radii:[.14,.13,.19],blend:.08,material:"fur"},{bone:"body",shape:"ellipsoid",at:[.17,.13,-0.02],radii:[.14,.13,.19],blend:.08,material:"fur"},{bone:"body",shape:"ellipsoid",at:[-0.17,.04,.14],radii:[.085,.05,.11],blend:.03,material:"cream"},{bone:"body",shape:"ellipsoid",at:[.17,.04,.14],radii:[.085,.05,.11],blend:.03,material:"cream"},{bone:"head",shape:"ellipsoid",at:[0,.2,0],radii:[.34,.28,.29],blend:.1,material:"fur"},{bone:"head",shape:"sphere",at:[-0.17,.1,.12],radius:.15,blend:.1,material:"fur"},{bone:"head",shape:"sphere",at:[.17,.1,.12],radius:.15,blend:.1,material:"fur"},{bone:"head",shape:"ellipsoid",at:[0,.09,.22],radii:[.12,.075,.08],blend:.05,material:"cream"},{bone:"head",shape:"ellipsoid",at:[0,.135,.3],rot:[.3,0,0],radii:[.032,.02,.018],blend:.01,material:"nose"},{bone:"earL",shape:"roundCone",from:[0,0,0],to:[0,.15,0],r1:.1,r2:.022,blend:.05,material:"fur"},{bone:"earL",shape:"ellipsoid",at:[0,.055,.045],radii:[.05,.075,.03],material:"pink"},{bone:"earR",shape:"roundCone",from:[0,0,0],to:[0,.15,0],r1:.1,r2:.022,blend:.05,material:"fur"},{bone:"earR",shape:"ellipsoid",at:[0,.055,.045],radii:[.05,.075,.03],material:"pink"},{bone:"pawL",shape:"capsule",from:[0,0,0],to:[0,-0.15,.03],radius:.065,blend:.05,material:"fur"},{bone:"pawL",shape:"ellipsoid",at:[0,-0.17,.05],radii:[.07,.05,.075],blend:.03,material:"cream"},{bone:"pawR",shape:"capsule",from:[0,0,0],to:[0,-0.15,.03],radius:.065,blend:.05,material:"fur"},{bone:"pawR",shape:"ellipsoid",at:[0,-0.17,.05],radii:[.07,.05,.075],blend:.03,material:"cream"},{bone:"tail0",shape:"roundCone",from:[0,0,0],to:[0,.16,0],r1:.055,r2:.05,blend:.04,material:"fur"},{bone:"tail1",shape:"roundCone",from:[0,0,0],to:[0,.15,0],r1:.05,r2:.047,blend:.02,material:"fur"},{bone:"tail2",shape:"roundCone",from:[0,0,0],to:[0,.12,0],r1:.047,r2:.04,blend:.02,material:"cream"},{bone:"head",shape:"capsule",from:[-0.13,.1,.27],to:[-0.33,.13,.24],radius:.005,material:"whisker"},{bone:"head",shape:"capsule",from:[-0.13,.08,.27],to:[-0.33,.06,.23],radius:.005,material:"whisker"},{bone:"head",shape:"capsule",from:[.13,.1,.27],to:[.33,.13,.24],radius:.005,material:"whisker"},{bone:"head",shape:"capsule",from:[.13,.08,.27],to:[.33,.06,.23],radius:.005,material:"whisker"}],paints:[{bone:"head",on:["fur"],kind:"ellipse",at:[0,.4,.2],radii:[.022,.08],color:"#c4733a",soft:.5},{bone:"head",on:["fur"],kind:"ellipse",at:[-0.075,.38,.2],radii:[.018,.065],color:"#c4733a",soft:.5},{bone:"head",on:["fur"],kind:"ellipse",at:[.075,.38,.2],radii:[.018,.065],color:"#c4733a",soft:.5},{bone:"body",on:["fur"],kind:"ellipse",at:[0,.24,.2],radii:[.17,.2],color:"#fbe8d0",soft:.35},{bone:"head",on:["fur"],kind:"sphere",at:[-0.21,.1,.24],radius:.06,color:"#ff9db0",soft:.6,opacity:.75},{bone:"head",on:["fur"],kind:"sphere",at:[.21,.1,.24],radius:.06,color:"#ff9db0",soft:.6,opacity:.75}],eyes:{kind:"ball",bone:"head",at:[[-0.125,.22,.2],[.125,.22,.2]],radius:.088,iris:"#8ccf4d",irisSize:.78,pupilSize:.42,pupilAspect:.5,lid:"fur"},face:{kind:"mouth",bone:"head",on:["cream"],at:[0,.06,.29],width:.045,color:"#5b2630",tongue:"#ff8ea3"},anchors:{top:{bone:"head",at:[.2,.42,.08]},mouth:{bone:"head",at:[0,.06,.32]},ear:{bone:"head",at:[-0.34,.25,0]},feet:{bone:"root",at:[0,.03,.18]},tail:{bone:"tail2",at:[0,.12,0]}},acting:{idle:{tail0:{rz:[-0.5,.15,.4,0]}},thinking:{pawR:{rx:-1.75,rz:.35},tail2:{rx:[.25,.3,1.6,0]},earL:{ry:.5}},listening:{earL:{rx:-0.35,ry:-0.6},earR:{rx:-0.35},tail0:{rz:-0.35}},speaking:{pawL:{rx:[-0.4,.25,1.2,0]},pawR:{rx:[-0.3,.25,1.2,1.9]},tail0:{rz:[-0.5,.2,.9,0]}},sleeping:{earL:{rz:.5,rx:.4},earR:{rz:-0.5,rx:.4},tail0:{rx:.4,rz:-1.2},tail1:{rx:.5}},working:{pawL:{rx:[-0.35,.3,3.4,0]},pawR:{rx:[-0.35,.3,3.4,Math.PI]},earL:{rx:-0.25},earR:{rx:-0.25},tail2:{rx:[.25,.2,1.7,0]}},error:{earL:{rz:1.1,rx:.3},earR:{rz:-1.1,rx:.3},tail0:{rx:[-0.9,.05,12,0],rz:0},tail1:{rx:.3},tail2:{rx:.2}},surprised:{earL:{rz:-0.1,rx:-0.2},earR:{rz:.1,rx:-0.2},pawL:{rx:-1.4,rz:-0.4},pawR:{rx:-1.4,rz:.4},tail0:{rx:-0.9,rz:0}},celebrating:{pawL:{rx:[-2.2,.35,4,0],rz:-0.5},pawR:{rx:[-2.2,.35,4,Math.PI],rz:.5},tail0:{rz:[-0.4,.5,2.6,0]}},sad:{earL:{rz:.95,rx:.35},earR:{rz:-0.95,rx:.35},tail0:{rx:.7,rz:-0.8},tail1:{rx:.3},tail2:{rx:.1}},happy:{pawL:{rx:[-1.6,.3,5,0]},pawR:{rx:[-1.6,.3,5,1.4]},tail0:{rz:[-0.5,.45,3,0]}}},fx:{happy:[{glyph:"heart",anchor:"top",rate:1.2,spread:.15,velocity:[0,.22,.05],jitter:.12,wobble:.06,life:[1,1.3],size:[.04,.07],color:"#ff86a2"}]}};var w0={id:"mochi",name:"Mochi",tagline:"Translucent jelly that squashes and splashes, with a propeller sprout",accent:"#1fae8a",frame:{target:.56,radius:.8},bound:{y:.5,radius:.82},motion:{hop:.17,squash:1.9,snap:.9,talkSquash:1.3},materials:{jelly:{color:"#3fcf9f",f0:.06,spec:1.6,shininess:140,rim:.7,sss:.55,sssColor:"#9effd9",gloss:.9},bead:{color:"#120d18",f0:.06,spec:2.2,shininess:400,rim:.2,gloss:1},leaf:{color:"#5bbf3a",f0:.04,spec:.7,shininess:50,rim:.6,sss:.25,sssColor:"#c8ff7a"}},bones:[{name:"body",pivot:[0,0,0],drive:{rx:[["pitch",-0.35]],ry:[["yaw",.55]],rz:[["roll",.6]]}},{name:"sprout",parent:"body",pivot:[0,.83,-0.02],jiggle:{axis:[0,1,0],length:.16,freq:2.2,damping:.09}}],parts:[{bone:"body",shape:"sphere",at:[0,.41,0],radius:.42,material:"jelly"},{bone:"body",shape:"ellipsoid",at:[0,.17,0],radii:[.5,.17,.47],blend:.24,material:"jelly"},{bone:"body",shape:"roundCone",from:[0,.62,0],to:[0,.83,-0.02],r1:.17,r2:.035,blend:.22,material:"jelly"},{bone:"sprout",shape:"capsule",from:[0,-0.02,0],to:[0,.09,0],radius:.014,material:"leaf"},{bone:"sprout",shape:"ellipsoid",at:[-0.065,.11,0],rot:[0,.3,.5],radii:[.075,.018,.042],blend:.015,material:"leaf"},{bone:"sprout",shape:"ellipsoid",at:[.07,.12,0],rot:[0,-0.3,-0.45],radii:[.08,.018,.045],blend:.015,material:"leaf"}],paints:[{bone:"body",on:["jelly"],kind:"sphere",at:[-0.25,.32,.31],radius:.07,color:"#ff8fa8",soft:.6,opacity:.8},{bone:"body",on:["jelly"],kind:"sphere",at:[.25,.32,.31],radius:.07,color:"#ff8fa8",soft:.6,opacity:.8}],eyes:{kind:"bead",bone:"body",at:[[-0.14,.43,.385],[.14,.43,.385]],radii:[.045,.066,.03],material:"bead"},face:{kind:"mouth",bone:"body",on:["jelly"],at:[0,.32,.4],width:.065,color:"#173528",tongue:"#ff7d97"},anchors:{top:{bone:"body",at:[.16,.86,.1]},mouth:{bone:"body",at:[0,.32,.42]},ear:{bone:"body",at:[-0.42,.45,0]},feet:{bone:"root",at:[0,.05,.25]}},acting:{idle:{sprout:{rz:[0,.1,.6,0]}},thinking:{sprout:{rx:-0.15,ry:[0,0,0,0,7]}},listening:{sprout:{rx:-0.4,rz:.15}},speaking:{sprout:{rz:[0,.2,2.4,0]}},sleeping:{sprout:{rx:.85,rz:.35}},working:{sprout:{ry:[0,0,0,0,3]}},error:{sprout:{rx:.45,rz:[.3,.15,12,0]}},surprised:{sprout:{rx:-0.3}},celebrating:{sprout:{ry:[0,0,0,0,18]}},sad:{sprout:{rx:1.1,rz:.5}},happy:{sprout:{ry:[0,0,0,0,16]}}},fx:{replace:["land"],land:[{glyph:"drop",anchor:"feet",rate:7,spread:.18,velocity:[0,.65,.05],jitter:.7,gravity:3.2,life:[.45,.6],size:[.035,.022],color:"#55d6ad",align:true}],"enter:happy":[{glyph:"drop",anchor:"top",rate:5,velocity:[0,.7,.05],jitter:.9,gravity:3,life:[.5,.7],size:[.035,.02],color:"#6fe3bd",align:true}]}};var k0={id:"pebble",name:"Pebble",tagline:"A penguin chick in a knitted scarf: satin coat, waddling walk, flippers that flap when it is happy",accent:"#3d5a9e",frame:{target:.56,radius:.76},bound:{y:.52,radius:.74},motion:{hop:.12,squash:1.2,snap:1.05,talkSquash:.45},materials:{coat:{color:"#27324f",f0:.04,spec:.7,shininess:46,rim:1,sheen:.55,gloss:.35,surface:{kind:"fur",scale:130,strength:.28,bone:"head"}},bodyCoat:{color:"#27324f",shadeOf:"coat",f0:.04,spec:.7,shininess:46,rim:1,sheen:.55,gloss:.35,surface:{kind:"fur",scale:130,strength:.28}},flipper:{color:"#222b45",shadeOf:"coat",f0:.04,spec:.8,shininess:50,rim:.9,sheen:.5,gloss:.4},beak:{color:"#ffa53d",f0:.05,spec:1,shininess:80,rim:.4,gloss:.6},mouth:{color:"#5d1a22",f0:.04,spec:.5,shininess:30,rim:0},feet:{color:"#ff9b3d",f0:.04,spec:.7,shininess:50,rim:.35,gloss:.4,sss:.25,sssColor:"#ffc68a"},knit:{color:"#e8433f",f0:.02,spec:.15,shininess:10,rim:.7,sheen:.7,surface:{kind:"scales",scale:42,strength:.75,color:"#a8242a"}},knitStripe:{color:"#fff2e6",f0:.02,spec:.15,shininess:10,rim:.6,sheen:.7}},bones:[{name:"body",pivot:[0,0,0],drive:{ry:[["yaw",.2]],rz:[["roll",.35]]},wave:{rz:[.035,.9,0]}},{name:"head",parent:"body",pivot:[0,.6,.01],drive:{rx:[["pitch",-1]],ry:[["yaw",.8]],rz:[["roll",.7]]}},{name:"beak",parent:"head",pivot:[0,.12,.27],drive:{rx:[["talk",-0.22]]}},{name:"jaw",parent:"head",pivot:[0,.12,.27],drive:{rx:[["talk",.75]]}},{name:"tuft",parent:"head",pivot:[0,.42,.02],rest:{rx:-0.2},jiggle:{axis:[0,1,0],length:.1,freq:3.4,damping:.15}},{name:"flipperL",parent:"body",pivot:[-0.3,.5,0],rest:{rz:-0.2},drive:{rz:[["flap",-1.4]]},jiggle:{axis:[0,-1,0],length:.26,freq:3.4,damping:.3,maxAngle:.45}},{name:"flipperR",parent:"body",pivot:[.3,.5,0],rest:{rz:.2},drive:{rz:[["flap",1.4]]},jiggle:{axis:[0,-1,0],length:.26,freq:3.4,damping:.3,maxAngle:.45}},{name:"scarf",parent:"body",pivot:[.13,.56,.25],rest:{rz:.12,rx:-0.15},jiggle:{axis:[0,-1,0],length:.2,freq:2.4,damping:.16,maxAngle:.7}},{name:"tail",parent:"body",pivot:[0,.1,-0.27],rest:{rx:-1.2},jiggle:{axis:[0,1,0],length:.08,freq:3,damping:.2}}],parts:[{bone:"body",shape:"ellipsoid",at:[0,.34,-0.01],radii:[.32,.34,.29],material:"bodyCoat"},{bone:"head",shape:"sphere",at:[0,.16,0],radius:.28,blend:.14,material:"coat"},{bone:"body",shape:"ellipsoid",at:[0,.575,.005],radii:[.3,.078,.28],material:"knit"},{bone:"scarf",shape:"roundBox",at:[0,-0.1,.01],half:[.05,.1,.018],round:.016,material:"knit"},{bone:"scarf",shape:"roundBox",at:[0,-0.195,.01],half:[.052,.018,.02],round:.012,material:"knitStripe"},{bone:"head",shape:"ellipsoid",at:[0,.12,.29],radii:[.035,.02,.025],material:"mouth"},{bone:"beak",shape:"ellipsoid",at:[0,0,.035],rot:[.15,0,0],radii:[.05,.034,.05],clip:{normal:[0,-1,0]},material:"beak"},{bone:"beak",shape:"ellipsoid",at:[0,0,.035],rot:[.15,0,0],radii:[.041,.028,.042],clip:{normal:[0,-1,0],offset:.003},material:"mouth"},{bone:"jaw",shape:"ellipsoid",at:[0,0,.026],radii:[.043,.025,.044],clip:{normal:[0,1,0]},material:"beak"},{bone:"jaw",shape:"ellipsoid",at:[0,0,.026],radii:[.035,.019,.036],clip:{normal:[0,1,0],offset:.003},material:"mouth"},{bone:"tuft",shape:"roundCone",from:[0,-0.03,0],to:[.01,.07,.02],r1:.035,r2:.008,blend:.03,material:"coat"},{bone:"tuft",shape:"roundCone",from:[0,-0.03,0],to:[-0.04,.05,-0.02],r1:.028,r2:.007,blend:.03,material:"coat"},{bone:"flipperL",shape:"ellipsoid",at:[-0.02,-0.16,.02],rot:[0,0,-0.12],radii:[.045,.2,.11],blend:.02,material:"flipper"},{bone:"flipperR",shape:"ellipsoid",at:[.02,-0.16,.02],rot:[0,0,.12],radii:[.045,.2,.11],blend:.02,material:"flipper"},{bone:"tail",shape:"ellipsoid",at:[0,.05,0],radii:[.08,.07,.025],blend:.03,material:"bodyCoat"},...[-1,1].flatMap(t=>[{bone:"root",shape:"ellipsoid",at:[t*.13,.03,.17],rot:[0,t*.25,0],radii:[.1,.03,.11],material:"feet"},...[-1,0,1].map(e=>({bone:"root",shape:"sphere",at:[t*.16+e*.055,.03,.26-Math.abs(e)*.02],radius:.034,blend:.03,material:"feet"}))])],paints:[{bone:"body",on:["bodyCoat"],kind:"ellipse",at:[0,.3,.08],radii:[.24,.27],color:"#f8f6f0",soft:.12},{bone:"head",on:["coat"],kind:"sphere",at:[-0.1,.13,.22],radius:.14,color:"#f8f6f0",soft:.12},{bone:"head",on:["coat"],kind:"sphere",at:[.1,.13,.22],radius:.14,color:"#f8f6f0",soft:.12},{bone:"head",on:["coat"],kind:"ellipse",at:[0,.02,.1],radii:[.17,.08],color:"#f8f6f0",soft:.2},{bone:"head",on:["coat"],kind:"sphere",at:[-0.17,.06,.2],radius:.05,color:"#ff9eb0",soft:.6,opacity:.8},{bone:"head",on:["coat"],kind:"sphere",at:[.17,.06,.2],radius:.05,color:"#ff9eb0",soft:.6,opacity:.8},{bone:"scarf",on:["knit"],kind:"ellipse",at:[0,-0.12,0],radii:[.08,.018],color:"#fff2e6",soft:.15}],eyes:{kind:"ball",bone:"head",at:[[-0.1,.18,.23],[.1,.18,.23]],radius:.066,iris:"#1d2233",irisSize:.8,pupilSize:.5,lid:"coat"},anchors:{top:{bone:"head",at:[.12,.44,.06]},mouth:{bone:"head",at:[0,.11,.36]},ear:{bone:"head",at:[-0.3,.18,0]},feet:{bone:"root",at:[0,.02,.17]},chest:{bone:"body",at:[0,.4,.3]}},acting:{idle:{tail:{rz:[0,.2,.9,0]}},thinking:{flipperR:{rz:1.2,rx:-1.1,ry:-0.3},head:{rz:.1}},listening:{flipperL:{rz:-0.9,rx:-0.3},tuft:{rx:-0.35}},speaking:{flipperL:{rz:[-0.15,.15,1.8,0]},flipperR:{rz:[.15,.15,1.8,1.5]}},sleeping:{flipperL:{ry:.6,rz:.2},flipperR:{ry:-0.6,rz:-0.2},tuft:{rx:.5}},working:{flipperL:{rx:[-0.7,.15,6,0],rz:.2},flipperR:{rx:[-0.7,.15,6,Math.PI],rz:-0.2},head:{rx:.12}},error:{flipperL:{rz:[-1.25,.08,13,0]},flipperR:{rz:[1.25,.08,13,1]},tuft:{rx:-0.6}},surprised:{flipperL:{rz:-1.6,rx:-0.3},flipperR:{rz:1.6,rx:-0.3},tuft:{rx:-0.7}},celebrating:{flipperL:{rz:[-1.1,.55,8,0]},flipperR:{rz:[1.1,.55,8,0]},tail:{rz:[0,.4,4,0]}},sad:{flipperL:{rz:.18},flipperR:{rz:-0.18},tuft:{rx:.8},scarf:{rx:.1}},happy:{flipperL:{rz:[-0.8,.6,9,0]},flipperR:{rz:[.8,.6,9,0]},tail:{rz:[0,.35,5,0]}}},fx:{replace:["land"],land:[{glyph:"puff",anchor:"feet",rate:8,spread:.12,velocity:[0,.06,0],jitter:.34,drag:3.5,life:[.5,.75],size:[.05,.12],color:"#eef4ff"}],celebrating:[{glyph:"sparkle",anchor:"top",rate:3,spread:.4,velocity:[0,-0.05,0],jitter:.08,wobble:.08,life:[1.4,1.8],size:[.04,.01],spin:1.2,color:"#dff0ff"}]}};var z0={id:"pip",name:"Pip",tagline:"Sings with a real beak, snaps its head like a bird, flaps",accent:"#e8892a",frame:{target:.66,radius:.86},bound:{y:.62,radius:.92},motion:{hop:.13,squash:1.1,snap:1.25,snapLook:1,talkSquash:.5},materials:{feather:{color:"#f4a63c",f0:.03,spec:.22,shininess:14,rim:.9,sheen:.55},wing:{color:"#d8692a",shadeOf:"feather",f0:.03,spec:.25,shininess:16,rim:.8,sheen:.5},beak:{color:"#ff7a45",f0:.05,spec:.9,shininess:70,rim:.4,gloss:.6},feet:{color:"#e9683b",f0:.04,spec:.6,shininess:40,rim:.3},mouth:{color:"#6b1a26",f0:.04,spec:.6,shininess:40,rim:0},tongue:{color:"#ff7f91",f0:.05,spec:1,shininess:60,rim:.2,gloss:.6}},bones:[{name:"body",pivot:[0,0,0],drive:{rz:[["roll",.3]],rx:[["pitch",-0.12]]}},{name:"head",parent:"body",pivot:[0,.62,0],drive:{rx:[["pitch",-1]],ry:[["yaw",.9]],rz:[["roll",.8]]}},{name:"beak",parent:"head",pivot:[0,.14,.33],drive:{rx:[["talk",-0.24]]}},{name:"jaw",parent:"head",pivot:[0,.14,.33],drive:{rx:[["talk",.8]]}},{name:"tuft",parent:"head",pivot:[0,.5,.04],rest:{rx:.25},jiggle:{axis:[0,1,0],length:.14,freq:3,damping:.14}},{name:"wingL",parent:"body",pivot:[-0.38,.6,-0.02],drive:{rz:[["flap",-1.5]]},wave:{rz:[.04,.8,0]},jiggle:{axis:[0,-1,0],length:.3,freq:3.2,damping:.3,maxAngle:.5}},{name:"wingR",parent:"body",pivot:[.38,.6,-0.02],drive:{rz:[["flap",1.5]]},wave:{rz:[-0.04,.8,1.1]},jiggle:{axis:[0,-1,0],length:.3,freq:3.2,damping:.3,maxAngle:.5}},{name:"tail",parent:"body",pivot:[0,.3,-0.36],rest:{rx:-0.95},jiggle:{axis:[0,1,0],length:.18,freq:2.6,damping:.18}}],parts:[{bone:"body",shape:"ellipsoid",at:[0,.42,0],radii:[.45,.41,.42],material:"feather"},{bone:"head",shape:"sphere",at:[0,.18,.03],radius:.35,blend:.18,material:"feather"},{bone:"head",shape:"ellipsoid",at:[0,.14,.37],radii:[.05,.03,.035],material:"mouth"},{bone:"beak",shape:"ellipsoid",at:[0,0,.06],rot:[.12,0,0],radii:[.076,.056,.1],clip:{normal:[0,-1,0]},material:"beak"},{bone:"beak",shape:"ellipsoid",at:[0,0,.06],rot:[.12,0,0],radii:[.064,.048,.088],clip:{normal:[0,-1,0],offset:.003},material:"mouth"},{bone:"jaw",shape:"ellipsoid",at:[0,0,.045],radii:[.064,.04,.08],clip:{normal:[0,1,0]},material:"beak"},{bone:"jaw",shape:"ellipsoid",at:[0,0,.045],radii:[.053,.032,.068],clip:{normal:[0,1,0],offset:.003},material:"mouth"},{bone:"jaw",shape:"ellipsoid",at:[0,.002,.04],radii:[.034,.01,.042],material:"tongue"},{bone:"tuft",shape:"roundCone",from:[0,-0.04,0],to:[.015,.12,.03],r1:.045,r2:.01,blend:.03,material:"feather"},{bone:"tuft",shape:"roundCone",from:[0,-0.04,-0.02],to:[-0.05,.08,-0.05],r1:.035,r2:.008,blend:.03,material:"feather"},{bone:"tuft",shape:"roundCone",from:[0,-0.04,-0.02],to:[.06,.07,-0.04],r1:.03,r2:.008,blend:.03,material:"feather"},{bone:"wingL",shape:"ellipsoid",at:[-0.02,-0.17,0],rot:[0,0,-0.18],radii:[.08,.23,.2],blend:.02,material:"wing"},{bone:"wingR",shape:"ellipsoid",at:[.02,-0.17,0],rot:[0,0,.18],radii:[.08,.23,.2],blend:.02,material:"wing"},{bone:"tail",shape:"ellipsoid",at:[0,.1,0],radii:[.14,.12,.035],blend:.04,material:"wing"},{bone:"root",shape:"capsule",from:[-0.15,.03,.12],to:[-0.2,.025,.25],radius:.026,material:"feet"},{bone:"root",shape:"capsule",from:[-0.15,.03,.12],to:[-0.12,.025,.26],radius:.026,material:"feet"},{bone:"root",shape:"capsule",from:[-0.15,.03,.12],to:[-0.15,.06,.02],radius:.03,blend:.02,material:"feet"},{bone:"root",shape:"capsule",from:[.15,.03,.12],to:[.2,.025,.25],radius:.026,material:"feet"},{bone:"root",shape:"capsule",from:[.15,.03,.12],to:[.12,.025,.26],radius:.026,material:"feet"},{bone:"root",shape:"capsule",from:[.15,.03,.12],to:[.15,.06,.02],radius:.03,blend:.02,material:"feet"}],paints:[{bone:"body",on:["feather"],kind:"ellipse",at:[0,.3,0],radii:[.29,.28],color:"#fde7c0",soft:.07},{bone:"head",on:["feather"],kind:"sphere",at:[-0.22,.08,.27],radius:.075,color:"#ff8c8c",soft:.6,opacity:.75},{bone:"head",on:["feather"],kind:"sphere",at:[.22,.08,.27],radius:.075,color:"#ff8c8c",soft:.6,opacity:.75}],eyes:{kind:"ball",bone:"head",at:[[-0.14,.24,.3],[.14,.24,.3]],radius:.078,iris:"#4a2a12",irisSize:.72,pupilSize:.42,lid:"feather"},anchors:{top:{bone:"head",at:[.14,.5,.1]},mouth:{bone:"head",at:[0,.13,.47]},ear:{bone:"head",at:[-0.32,.22,0]},feet:{bone:"root",at:[0,.02,.12]},chest:{bone:"body",at:[0,.45,.32]}},acting:{idle:{tail:{rx:[0,.14,1.3,0]}},thinking:{wingR:{rz:1.05,rx:-0.95,ry:-0.35},tuft:{rx:.25},tail:{rx:[0,.08,.5,0]}},listening:{wingL:{rz:-1.1,rx:-0.55},tuft:{rx:-0.4},head:{rz:.12}},speaking:{head:{rx:[-0.14,.05,1.1,0]},wingL:{rz:[-0.18,.14,2.3,0]},wingR:{rz:[.18,.14,2.3,1.2]},tail:{rx:[0,.22,2.3,.5]}},sleeping:{wingL:{ry:.5,rz:.12},wingR:{ry:-0.5,rz:-0.12},tuft:{rx:.75}},working:{wingL:{rz:[-0.4,.18,6,0],rx:-0.6},wingR:{rz:[.4,.18,6,Math.PI],rx:-0.6},head:{rx:[.1,.07,5.2,0]}},error:{wingL:{rz:[-1,.1,12,0]},wingR:{rz:[1,.1,12,1]},tuft:{rx:-0.5},tail:{rx:-0.45}},surprised:{wingL:{rz:-1.7},wingR:{rz:1.7},tuft:{rx:-0.6},tail:{rx:-0.5}},celebrating:{wingL:{rz:[-1.4,.5,9,0]},wingR:{rz:[1.4,.5,9,0]},tail:{rx:[0,.3,6,0]},tuft:{rx:[0,.25,6,0]}},sad:{wingL:{rz:.25},wingR:{rz:-0.25},tuft:{rx:.9},tail:{rx:.5}},happy:{wingL:{rz:[-0.9,.75,7,0]},wingR:{rz:[.9,.75,7,0]},tail:{rx:[0,.3,5,0]},tuft:{rx:[0,.2,5,0]}}},fx:{replace:["syllable"],syllable:[{glyph:"note",anchor:"mouth",rate:1,offset:[.12,-0.03,.02],velocity:[.2,.13,.05],jitter:.06,wobble:.07,life:[1.1,1.5],size:[.045,.075],rotation:-0.15,color:"#f08a3c"}],happy:[{glyph:"note",anchor:"mouth",rate:1.6,velocity:[0,.24,.05],jitter:.25,wobble:.07,life:[1,1.3],size:[.04,.07],rotation:.15,color:"#e8664a"}],"enter:happy":[{glyph:"feather",anchor:"chest",rate:4,spread:.12,velocity:[0,.18,.12],jitter:.45,gravity:.12,drag:1.4,wobble:.14,life:[1.8,2.4],size:[.05,.05],spin:1.6,color:"#f6b04a"}]}};var S0=[{parent:"head",at:[0,.43,.05],tilt:-0.1,size:.075},{parent:"head",at:[0,.41,-0.1],tilt:-0.5,size:.09},{parent:"head",at:[0,.3,-0.24],tilt:-1,size:.085},{parent:"body",at:[0,.5,-0.24],tilt:-1.2,size:.08},{parent:"body",at:[0,.34,-0.3],tilt:-1.45,size:.07},{parent:"tail0",at:[0,.12,.07],tilt:0,size:.06},{parent:"tail1",at:[0,.1,.05],tilt:0,size:.045}],M0={id:"rex",name:"Rex",tagline:"A baby T. rex with pebbly scales, wobbly back spikes, tiny arms and a wagging tail",accent:"#4fb86a",frame:{target:.52,radius:.76},bound:{y:.5,radius:.8},motion:{hop:.15,squash:1.15,snap:1.05,talkSquash:.35},materials:{hide:{color:"#78cf7f",f0:.04,spec:.7,shininess:40,rim:.7,gloss:.35,sss:.2,sssColor:"#c8ffb0",surface:{kind:"scales",scale:24,strength:.5,color:"#4b9f5d",bone:"head"}},bodyHide:{color:"#78cf7f",shadeOf:"hide",f0:.04,spec:.7,shininess:40,rim:.7,gloss:.35,sss:.2,sssColor:"#c8ffb0",surface:{kind:"scales",scale:24,strength:.5,color:"#4b9f5d"}},belly:{color:"#fff0c4",f0:.04,spec:.5,shininess:30,rim:.5,gloss:.3,sss:.25,sssColor:"#fff6d8"},spike:{color:"#ff9b4a",f0:.05,spec:.9,shininess:60,rim:.5,gloss:.5,sss:.35,sssColor:"#ffc58f"},claw:{color:"#fff6e2",f0:.05,spec:1,shininess:80,rim:.3,gloss:.6}},bones:[{name:"body",pivot:[0,0,0],drive:{ry:[["yaw",.25]],rz:[["roll",.3]]}},{name:"head",parent:"body",pivot:[0,.56,.06],drive:{rx:[["pitch",-1]],ry:[["yaw",.8]],rz:[["roll",.7]]}},{name:"armL",parent:"body",pivot:[-0.15,.42,.25],rest:{rx:-0.6},drive:{rx:[["flap",-0.9]],rz:[["flap",-0.5]]}},{name:"armR",parent:"body",pivot:[.15,.42,.25],rest:{rx:-0.6},drive:{rx:[["flap",-0.9]],rz:[["flap",.5]]}},{name:"tail0",parent:"body",pivot:[.08,.17,-0.24],rest:{rx:-1.25,rz:-0.6},wave:{rz:[.2,.5,0]},jiggle:{axis:[0,1,0],length:.18,freq:2.2,damping:.25,maxAngle:.6}},{name:"tail1",parent:"tail0",pivot:[0,.18,0],rest:{rx:.2},wave:{rz:[.2,.5,.8]},jiggle:{axis:[0,1,0],length:.15,freq:2,damping:.22,maxAngle:.7}},{name:"tail2",parent:"tail1",pivot:[0,.15,0],rest:{rx:.15},wave:{rz:[.25,.5,1.6]},jiggle:{axis:[0,1,0],length:.12,freq:1.8,damping:.2,maxAngle:.8}},...S0.map(({parent:t,at:e,tilt:r},a)=>({name:`spike${a}`,parent:t,pivot:e,rest:{rx:r},jiggle:{axis:[0,1,0],length:.08,freq:4+a*.3,damping:.12,maxAngle:.45}}))],parts:[{bone:"body",shape:"ellipsoid",at:[0,.3,-0.02],radii:[.3,.3,.28],material:"bodyHide"},{bone:"body",shape:"ellipsoid",at:[-0.19,.15,-0.02],radii:[.13,.15,.17],blend:.08,material:"bodyHide"},{bone:"body",shape:"ellipsoid",at:[.19,.15,-0.02],radii:[.13,.15,.17],blend:.08,material:"bodyHide"},...[-1,1].flatMap(t=>[{bone:"body",shape:"ellipsoid",at:[t*.2,.045,.1],radii:[.1,.05,.13],blend:.05,material:"bodyHide"},...[-1,0,1].map(e=>({bone:"body",shape:"ellipsoid",at:[t*.2+e*.05,.03,.225-Math.abs(e)*.015],radii:[.022,.022,.026],blend:.012,material:"claw"}))]),{bone:"head",shape:"ellipsoid",at:[0,.2,-0.02],radii:[.29,.25,.27],blend:.12,material:"hide"},{bone:"head",shape:"ellipsoid",at:[0,.1,.17],radii:[.23,.14,.18],blend:.1,material:"hide"},{bone:"head",shape:"sphere",at:[-0.05,.17,.34],radius:.014,op:"sub",blend:.01,material:"hide"},{bone:"head",shape:"sphere",at:[.05,.17,.34],radius:.014,op:"sub",blend:.01,material:"hide"},...[["armL",-1],["armR",1]].flatMap(([t,e])=>[{bone:t,shape:"capsule",from:[0,0,0],to:[e*.01,-0.1,.03],radius:.042,blend:.04,material:"bodyHide"},{bone:t,shape:"sphere",at:[e*-0.014,-0.135,.05],radius:.015,blend:.01,material:"claw"},{bone:t,shape:"sphere",at:[e*.02,-0.135,.045],radius:.015,blend:.01,material:"claw"}]),{bone:"tail0",shape:"roundCone",from:[0,0,0],to:[0,.18,0],r1:.12,r2:.09,blend:.06,material:"bodyHide"},{bone:"tail1",shape:"roundCone",from:[0,0,0],to:[0,.15,0],r1:.09,r2:.06,blend:.03,material:"bodyHide"},{bone:"tail2",shape:"roundCone",from:[0,0,0],to:[0,.12,0],r1:.06,r2:.03,blend:.03,material:"bodyHide"},...S0.map(({size:t},e)=>({bone:`spike${e}`,shape:"roundCone",from:[0,-0.02,0],to:[0,t*1.1,0],r1:t*.65,r2:t*.15,blend:.025,material:"spike"}))],paints:[{bone:"body",on:["bodyHide"],kind:"ellipse",at:[0,.24,.08],radii:[.16,.2],color:"#fff0c4",soft:.2},{bone:"head",on:["hide"],kind:"ellipse",at:[0,-0.01,.15],radii:[.17,.06],color:"#fff0c4",soft:.35},{bone:"head",on:["hide"],kind:"sphere",at:[-0.2,.12,.24],radius:.055,color:"#ff9a9a",soft:.6,opacity:.7},{bone:"head",on:["hide"],kind:"sphere",at:[.2,.12,.24],radius:.055,color:"#ff9a9a",soft:.6,opacity:.7},...[[-0.09,.22],[-0.115,.19],[.09,.22],[.115,.19]].map(([t,e])=>({bone:"head",on:["hide"],kind:"sphere",at:[t,e,.31],radius:.009,color:"#3f8a4f",soft:.3}))],eyes:{kind:"ball",bone:"head",at:[[-0.13,.26,.19],[.13,.26,.19]],radius:.085,iris:"#e0942f",irisSize:.78,pupilSize:.46,pupilAspect:.75,lid:"hide"},face:{kind:"mouth",bone:"head",on:["hide"],at:[0,.06,.34],width:.1,color:"#5b1f2b",tongue:"#ff7f93"},anchors:{top:{bone:"head",at:[.16,.44,.06]},mouth:{bone:"head",at:[0,.06,.37]},ear:{bone:"head",at:[-0.3,.22,0]},feet:{bone:"root",at:[0,.02,.15]},tail:{bone:"tail2",at:[0,.12,0]}},acting:{idle:{tail0:{rz:[-0.6,.12,.45,0]}},thinking:{armR:{rx:[-1.3,.08,2.5,0],rz:.3},tail2:{rx:[.15,.3,1.4,0]}},listening:{armL:{rx:-1.1,rz:-0.6},tail0:{rz:-0.4}},speaking:{armL:{rx:[-0.6,.25,1.6,0]},armR:{rx:[-0.6,.25,1.6,2]},tail0:{rz:[-0.6,.18,.9,0]}},sleeping:{armL:{rx:.1,rz:.2},armR:{rx:.1,rz:-0.2},tail0:{rz:-1.3,rx:-1},tail1:{rx:.4}},working:{armL:{rx:[-0.9,.15,7,0]},armR:{rx:[-0.9,.15,7,Math.PI]},head:{rx:.12},tail2:{rx:[.15,.2,2,0]}},error:{armL:{rx:[-1.6,.35,9,0],rz:-0.4},armR:{rx:[-1.6,.35,9,1.4],rz:.4},tail0:{rz:[-0.5,.06,12,0],rx:-1.45},spike1:{rx:-0.2},spike2:{rx:-0.6},spike3:{rx:-0.8}},surprised:{armL:{rx:-1.9,rz:-0.6},armR:{rx:-1.9,rz:.6},tail0:{rx:-1.5}},celebrating:{armL:{rx:[-2.2,.3,4,0],rz:-0.5},armR:{rx:[-2.2,.3,4,Math.PI],rz:.5},tail0:{rz:[-0.6,.55,3,0]}},sad:{armL:{rx:.2},armR:{rx:.2},tail0:{rx:-0.95,rz:-0.4},tail1:{rx:.35}},happy:{armL:{rx:[-1.4,.4,6,0]},armR:{rx:[-1.4,.4,6,1.4]},tail0:{rz:[-0.6,.5,4,0]}}},fx:{"enter:surprised":[{glyph:"arc",anchor:"mouth",rate:3,offset:[.08,0,.05],mirror:true,velocity:[.3,.05,.1],jitter:.04,life:[.5,.6],size:[.04,.11],color:"#7fd18a"}]}};var R0={id:"tad",name:"Tad",tagline:"A glossy tree frog with a wet sheen, eyes on top and a throat that puffs as it talks",accent:"#3fae4a",frame:{target:.42,radius:.66},bound:{y:.4,radius:.72},motion:{hop:.26,squash:1.6,snap:1.2,look:.8,talkSquash:.45},materials:{skin:{color:"#5fc24e",f0:.07,spec:2,shininess:260,rim:.7,gloss:.95,sss:.3,sssColor:"#c6ff8f",surface:{kind:"speckle",scale:9,strength:.85,color:"#2f8a3a",bone:"head"}},bodySkin:{color:"#5fc24e",shadeOf:"skin",f0:.07,spec:2,shininess:260,rim:.7,gloss:.95,sss:.3,sssColor:"#c6ff8f",surface:{kind:"speckle",scale:9,strength:.85,color:"#2f8a3a"}},belly:{color:"#f3f0b6",f0:.06,spec:1.6,shininess:200,rim:.5,gloss:.9,sss:.45,sssColor:"#fffbd0"},toe:{color:"#ffb54a",f0:.06,spec:1.4,shininess:160,rim:.4,gloss:.8,sss:.3,sssColor:"#ffd99a"}},bones:[{name:"body",pivot:[0,0,0],drive:{ry:[["yaw",.25]],rz:[["roll",.3]]}},{name:"head",parent:"body",pivot:[0,.3,.02],drive:{rx:[["pitch",-0.8]],ry:[["yaw",.7]],rz:[["roll",.6]]}},{name:"throat",parent:"head",pivot:[0,.02,.12],drive:{rx:[["talk",.9]]}},{name:"armL",parent:"body",pivot:[-0.22,.2,.18],drive:{rz:[["flap",-1.3]],rx:[["flap",-0.4]]}},{name:"armR",parent:"body",pivot:[.22,.2,.18],drive:{rz:[["flap",1.3]],rx:[["flap",-0.4]]}}],parts:[{bone:"body",shape:"ellipsoid",at:[0,.22,-0.03],radii:[.36,.22,.32],material:"bodySkin"},{bone:"body",shape:"ellipsoid",at:[-0.3,.12,-0.04],rot:[0,.25,0],radii:[.13,.11,.22],blend:.09,material:"bodySkin"},{bone:"body",shape:"ellipsoid",at:[.3,.12,-0.04],rot:[0,-0.25,0],radii:[.13,.11,.22],blend:.09,material:"bodySkin"},{bone:"body",shape:"ellipsoid",at:[-0.33,.025,.16],rot:[0,.5,0],radii:[.08,.025,.13],blend:.03,material:"bodySkin"},{bone:"body",shape:"ellipsoid",at:[.33,.025,.16],rot:[0,-0.5,0],radii:[.08,.025,.13],blend:.03,material:"bodySkin"},{bone:"head",shape:"ellipsoid",at:[0,.1,.05],radii:[.38,.19,.31],blend:.14,material:"skin"},{bone:"head",shape:"sphere",at:[-0.19,.24,.1],radius:.13,blend:.07,material:"skin"},{bone:"head",shape:"sphere",at:[.19,.24,.1],radius:.13,blend:.07,material:"skin"},{bone:"throat",shape:"ellipsoid",at:[0,-0.04,.1],radii:[.14,.1,.12],blend:.05,material:"belly"},{bone:"armL",shape:"capsule",from:[0,0,0],to:[-0.03,-0.17,.08],radius:.045,blend:.05,material:"bodySkin"},{bone:"armL",shape:"sphere",at:[-0.07,-0.19,.12],radius:.026,blend:.02,material:"toe"},{bone:"armL",shape:"sphere",at:[-0.02,-0.19,.15],radius:.026,blend:.02,material:"toe"},{bone:"armL",shape:"sphere",at:[.03,-0.19,.13],radius:.026,blend:.02,material:"toe"},{bone:"armR",shape:"capsule",from:[0,0,0],to:[.03,-0.17,.08],radius:.045,blend:.05,material:"bodySkin"},{bone:"armR",shape:"sphere",at:[.07,-0.19,.12],radius:.026,blend:.02,material:"toe"},{bone:"armR",shape:"sphere",at:[.02,-0.19,.15],radius:.026,blend:.02,material:"toe"},{bone:"armR",shape:"sphere",at:[-0.03,-0.19,.13],radius:.026,blend:.02,material:"toe"}],paints:[{bone:"body",on:["bodySkin"],kind:"ellipse",at:[0,.16,.28],radii:[.22,.13],color:"#f3f0b6",soft:.3},{bone:"head",on:["skin"],kind:"ellipse",at:[0,-0.01,.34],radii:[.2,.06],color:"#f3f0b6",soft:.4},{bone:"head",on:["skin"],kind:"sphere",at:[-0.24,.07,.27],radius:.055,color:"#ff8f9c",soft:.6,opacity:.7},{bone:"head",on:["skin"],kind:"sphere",at:[.24,.07,.27],radius:.055,color:"#ff8f9c",soft:.6,opacity:.7}],eyes:{kind:"ball",bone:"head",at:[[-0.19,.27,.15],[.19,.27,.15]],radius:.1,iris:"#e7b93a",irisSize:.74,pupilSize:.36,pupilAspect:1.8,lid:"skin"},face:{kind:"mouth",bone:"head",on:["skin"],at:[0,.06,.34],width:.12,color:"#5a1f2e",tongue:"#ff7b93"},anchors:{top:{bone:"head",at:[.2,.36,.05]},mouth:{bone:"head",at:[0,.05,.37]},ear:{bone:"head",at:[-0.38,.12,0]},feet:{bone:"root",at:[0,.03,.22]}},acting:{idle:{throat:{rx:[0,.12,1.1,0]}},thinking:{armR:{rz:.6,rx:-1.5}},listening:{armL:{rz:-1.6,rx:-0.4}},speaking:{armL:{rx:[-0.25,.2,1.3,0]},armR:{rx:[-0.25,.2,1.3,2]}},sleeping:{armL:{rx:.2},armR:{rx:.2},throat:{rx:[.2,.25,.18,0]}},working:{armL:{rx:[-0.5,.2,7,0]},armR:{rx:[-0.5,.2,7,Math.PI]},throat:{rx:[0,.15,3.5,0]}},error:{armL:{rz:[-1.2,.15,12,0]},armR:{rz:[1.2,.15,12,1]},throat:{rx:.6}},surprised:{armL:{rz:-1.8},armR:{rz:1.8},throat:{rx:.9}},celebrating:{armL:{rz:[-2,.4,4,0]},armR:{rz:[2,.4,4,Math.PI]},throat:{rx:[.4,.4,4,0]}},sad:{armL:{rz:.2,rx:.3},armR:{rz:-0.2,rx:.3}},happy:{armL:{rz:[-1.5,.4,5,0]},armR:{rz:[1.5,.4,5,1]},throat:{rx:[.4,.4,5,0]}}},fx:{replace:["land"],land:[{glyph:"drop",anchor:"feet",rate:8,spread:.2,velocity:[0,.7,.05],jitter:.7,gravity:3.2,life:[.45,.6],size:[.035,.022],color:"#7fd0ff",align:true}],syllable:[{glyph:"bubble",anchor:"mouth",rate:1,offset:[.1,0,.02],velocity:[.08,.18,.05],jitter:.08,wobble:.05,life:[.9,1.2],size:[.016,.036],color:"#a6e8ff"}]}};function C0(t){let e=t<0?"L":"R";return [{name:`shoulder${e}`,parent:"body",pivot:[.385*t,.47,.02],drive:{rz:[["flap",.5*t]]}},{name:`fore${e}`,parent:`shoulder${e}`,pivot:[0,-0.17,0],jiggle:{axis:[0,-1,0],length:.16,freq:3.2,damping:.35,maxAngle:.3}}]}function E0(t){let e=t<0?"L":"R";return [{bone:`shoulder${e}`,shape:"sphere",radius:.074,material:"trim"},{bone:`shoulder${e}`,shape:"capsule",from:[0,-0.02,0],to:[0,-0.15,0],radius:.058,material:"shell"},{bone:`fore${e}`,shape:"sphere",radius:.052,material:"trim"},{bone:`fore${e}`,shape:"capsule",from:[0,-0.02,0],to:[0,-0.12,0],radius:.052,material:"shell"},{bone:`fore${e}`,shape:"sphere",at:[0,-0.175,0],radius:.066,material:"trim"},{bone:`fore${e}`,shape:"sphere",op:"sub",blend:.012,at:[0,-0.235,.012],radius:.036,material:"trim"}]}function L0(t){let e=t<0?"L":"R";return [{bone:`ear${e}`,shape:"cylinder",rot:[0,0,1.5708],radius:.112,half:.03,round:.018,material:"trim"},{bone:`ear${e}`,shape:"cylinder",at:[.045*t,0,0],rot:[0,0,1.5708],radius:.058,half:.035,round:.018,material:"trim"},{bone:`ear${e}`,shape:"sphere",at:[.035*t,.078,0],radius:.02,material:"metal"},{bone:`ear${e}`,shape:"sphere",at:[.035*t,-0.078,0],radius:.02,material:"metal"}]}var $0={id:"volt",name:"Volt",tagline:"LED face, claw hands, gear ears, a sprung antenna",accent:"#3b63d9",frame:{target:.86,radius:1.02},bound:{y:.86,radius:1.12},motion:{hop:.16,squash:1,snap:1},glowPool:.35,materials:{shell:{color:"#2f56c4",f0:.05,spec:.7,shininess:70,rim:.55,gloss:.55},trim:{color:"#c3cce3",f0:.07,spec:.8,shininess:90,metal:.25,rim:.4,gloss:.5},metal:{color:"#8f98ae",f0:.45,spec:1,shininess:120,metal:.85,rim:.3,gloss:.7},rubber:{color:"#151a28",f0:.03,spec:.15,shininess:12,rim:.2},screen:{color:"#03060c",f0:.045,spec:1.6,shininess:260,rim:.1,gloss:1},bulb:{color:"#f2f5ff",f0:.04,spec:.6,shininess:40,rim:.3,glows:true,emitStrength:1.4,sss:.4,sssColor:"#ffffff"},lamp:{color:"#e9eeff",f0:.05,spec:1,shininess:80,glows:true,emitStrength:1.1,gloss:.9},ring:{color:"#d8e4ff",f0:.04,spec:.4,shininess:30,glows:true,emitStrength:1.6}},bones:[{name:"body",pivot:[0,0,0],drive:{ry:[["yaw",.2]],rz:[["roll",.25]]}},{name:"head",parent:"body",pivot:[0,.64,0],drive:{rx:[["pitch",-1]],ry:[["yaw",.8]],rz:[["roll",.75]]}},{name:"antenna",parent:"head",pivot:[0,.755,0],jiggle:{axis:[0,1,0],length:.26,freq:2.3,damping:.11}},{name:"earL",parent:"head",pivot:[-0.585,.37,0]},{name:"earR",parent:"head",pivot:[.585,.37,0]},...C0(-1),...C0(1)],parts:[{bone:"body",shape:"roundBox",at:[0,.32,0],half:[.35,.27,.28],round:.22,material:"shell"},{bone:"body",shape:"roundBox",at:[0,.38,.27],half:[.15,.08,.03],round:.06,material:"rubber"},{bone:"body",shape:"sphere",at:[0,.38,.285],radius:.04,material:"lamp"},{bone:"body",shape:"plate",op:"sub",blend:.006,at:[0,.225,.3],half:[.075,.009],corner:.009,depth:.03,material:"shell"},{bone:"body",shape:"plate",op:"sub",blend:.006,at:[0,.19,.295],half:[.075,.009],corner:.009,depth:.03,material:"shell"},{bone:"body",shape:"plate",op:"sub",blend:.006,at:[0,.155,.285],half:[.06,.009],corner:.009,depth:.03,material:"shell"},{bone:"body",shape:"roundBox",at:[-0.17,.035,.05],half:[.11,.035,.14],round:.035,material:"trim"},{bone:"body",shape:"roundBox",at:[.17,.035,.05],half:[.11,.035,.14],round:.035,material:"trim"},{bone:"body",shape:"cylinder",at:[0,.62,0],radius:.075,half:.06,round:.02,material:"metal"},{bone:"head",shape:"roundBox",at:[0,.37,0],half:[.56,.37,.35],round:.17,material:"shell"},{bone:"head",shape:"roundBox",op:"sub",blend:.035,at:[0,.37,.41],half:[.45,.28,.1],round:.12,material:"shell"},{bone:"head",shape:"plate",at:[0,.37,.31],half:[.45,.28],corner:.12,depth:.012,material:"screen"},{bone:"head",shape:"frame",at:[0,.37,.3],half:[.448,.278],corner:.118,width:.014,depth:.018,material:"rubber"},{bone:"head",shape:"cylinder",at:[-0.555,.37,0],rot:[0,0,1.5708],radius:.122,half:.012,round:.006,material:"ring"},{bone:"head",shape:"cylinder",at:[.555,.37,0],rot:[0,0,1.5708],radius:.122,half:.012,round:.006,material:"ring"},...L0(-1),...L0(1),{bone:"head",shape:"cylinder",at:[0,.745,0],radius:.065,half:.025,round:.012,material:"trim"},{bone:"antenna",shape:"capsule",from:[0,0,0],to:[0,.2,0],radius:.016,material:"metal"},{bone:"antenna",shape:"sphere",at:[0,.25,0],radius:.055,material:"bulb"},...E0(-1),...E0(1)],face:{kind:"screen",bone:"head",material:"screen",center:[0,.37],half:[.44,.27],corner:.11,cell:.034,color:"#c4ecff"},anchors:{top:{bone:"head",at:[.3,.78,.1]},mouth:{bone:"head",at:[0,.22,.34]},ear:{bone:"head",at:[-0.66,.37,0]},feet:{bone:"root",at:[0,.02,.06]},antenna:{bone:"antenna",at:[0,.25,0]}},acting:{idle:{shoulderL:{rz:[-0.08,.04,.45,0],rx:[0,.06,.35,1]},shoulderR:{rz:[.08,.04,.45,1.6],rx:[0,.06,.35,2.4]},foreL:{rx:-0.25},foreR:{rx:-0.25}},thinking:{shoulderR:{rx:-1.5,ry:-0.8,rz:-0.1},foreR:{rx:[-0.95,.1,1.8,0]},shoulderL:{rx:-1,ry:.8,rz:-0.3},foreL:{rx:-0.8},earL:{rx:[0,0,0,0,5]},earR:{rx:[0,0,0,0,-5]}},listening:{shoulderL:{rx:.1,ry:.3,rz:-2.8},foreL:{rx:-0.6},shoulderR:{rz:.14,rx:.05},foreR:{rx:-0.3},earL:{rx:[.3,.15,.8,0]}},speaking:{shoulderL:{rx:[-0.55,.32,.72,0],rz:[-0.28,.12,.5,0]},foreL:{rx:[-0.85,.38,1.44,.6]},shoulderR:{rx:[-0.45,.32,.72,2.2],rz:[.28,.12,.5,1]},foreR:{rx:[-0.95,.38,1.44,2.8]},earL:{rx:[0,0,0,0,1.4]},earR:{rx:[0,0,0,0,-1.4]}},sleeping:{shoulderL:{rz:-0.03,rx:-0.3},shoulderR:{rz:.03,rx:-0.3},foreL:{rx:-0.4},foreR:{rx:-0.4}},working:{shoulderL:{rx:-0.85,rz:-0.12},shoulderR:{rx:-0.85,rz:.12},foreL:{rx:[-0.95,.2,6,0]},foreR:{rx:[-0.95,.2,6,Math.PI]},earL:{rx:[0,0,0,0,3]},earR:{rx:[0,0,0,0,-3]}},error:{shoulderL:{rz:[-0.95,.1,11,0],rx:-0.2},shoulderR:{rz:[.95,.1,11,1],rx:-0.2},foreL:{rx:-1.1},foreR:{rx:-1.1}},surprised:{shoulderL:{rz:-1.55,rx:-0.3},shoulderR:{rz:1.55,rx:-0.3},foreL:{rx:-0.35},foreR:{rx:-0.35}},celebrating:{shoulderL:{rz:[-2.55,.28,4,0]},shoulderR:{rz:[2.55,.28,4,Math.PI]},foreL:{rz:[.2,.4,8,0]},foreR:{rz:[-0.2,.4,8,Math.PI]},earL:{rx:[0,0,0,0,12]},earR:{rx:[0,0,0,0,-12]}},sad:{shoulderL:{rz:.04,rx:.22},shoulderR:{rz:-0.04,rx:.22},foreL:{rx:-0.05},foreR:{rx:-0.05}},happy:{shoulderL:{rz:[-2.5,.22,2.2,0]},foreL:{rz:[.1,.5,4.2,0]},shoulderR:{rz:[2.5,.22,2.2,1.5]},foreR:{rz:[-0.1,.5,4.2,2]},earL:{rx:[0,0,0,0,10]},earR:{rx:[0,0,0,0,-10]}}},fx:{replace:["syllable"],syllable:[{glyph:"arc",anchor:"mouth",rate:2,offset:[.5,.1,-0.1],mirror:true,velocity:[.26,.02,.02],jitter:.02,life:[.55,.7],size:[.04,.1],rotation:0,color:"#6aaee6"}],thinking:[{glyph:"ring",anchor:"antenna",rate:1.3,velocity:[0,.02,0],life:[.9,1.1],size:[.03,.17],color:"#ffb347",glow:true}],listening:[{glyph:"ring",anchor:"antenna",rate:1.1,velocity:[0,0,0],life:[1,1.2],size:[.2,.03],color:"#62e39a",glow:true}],land:[{glyph:"spark",anchor:"feet",rate:6,spread:.12,velocity:[0,.6,0],jitter:1.1,gravity:3,life:[.25,.42],size:[.035,.02],color:"#ffd27a",glow:true,align:true}],"enter:happy":[{glyph:"spark",anchor:"antenna",rate:8,velocity:[0,.5,0],jitter:1.4,gravity:2,life:[.3,.5],size:[.04,.02],color:"#ffe08a",glow:true,align:true}]}};var A0=[$0,z0,w0,d0,x0,y0,R0,k0,M0,v0];function nt(t="wobnimo-mascot"){Pe(A0,t);}export{G as Brain,Me as DEFAULT_FX,$ as EXPRESSIONS,U as Fx,re as Mascot,K as Rig,T as STATES,he as SpecError,W as WebGL2Renderer,te as albedo,A0 as characters,Re as compile,be as compileCached,et as defineCharacter,Pe as defineMascotElement,nt as defineWobnimoElement,ge as driveFromStatus,tt as mount,h0 as recolor,at as snapshot,J0 as variant};
|