wobnimo 0.1.3 → 0.2.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 +18 -4
- package/README.md +38 -7
- package/dist/characters/bao.d.ts +6 -0
- package/dist/characters/bao.js +1 -0
- package/dist/characters/berry.d.ts +6 -0
- package/dist/characters/berry.js +1 -0
- package/dist/characters/boo.js +1 -1
- package/dist/characters/bumble.d.ts +6 -0
- package/dist/characters/bumble.js +1 -0
- package/dist/characters/cacti.d.ts +6 -0
- package/dist/characters/cacti.js +1 -0
- package/dist/characters/cap.d.ts +6 -0
- package/dist/characters/cap.js +1 -0
- package/dist/characters/drift.d.ts +6 -0
- package/dist/characters/drift.js +1 -0
- package/dist/characters/ember.d.ts +6 -0
- package/dist/characters/ember.js +1 -0
- package/dist/characters/hop.d.ts +6 -0
- package/dist/characters/hop.js +1 -0
- package/dist/characters/index.d.ts +11 -1
- package/dist/characters/index.js +11 -11
- package/dist/characters/inky.js +1 -1
- package/dist/characters/latte.d.ts +6 -0
- package/dist/characters/latte.js +1 -0
- package/dist/characters/microduck.js +1 -1
- package/dist/characters/miso.js +1 -1
- package/dist/characters/mochi.js +1 -1
- package/dist/characters/pebble.js +1 -1
- package/dist/characters/pip.js +1 -1
- package/dist/characters/rex.js +1 -1
- package/dist/characters/swirl.d.ts +6 -0
- package/dist/characters/swirl.js +1 -0
- package/dist/characters/tad.js +1 -1
- package/dist/characters/volt.js +1 -1
- package/dist/cli.js +1888 -0
- package/dist/element.d.ts +20 -2
- package/dist/element.js +11 -11
- package/dist/index-Cm5wWKoT.d.ts +12 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +6 -6
- package/dist/{status-DVudJbtp.d.ts → mascot-DZ91_ss-.d.ts} +1 -10
- package/dist/react.d.ts +2 -1
- package/dist/react.js +16 -16
- package/dist/status-C14-19fT.d.ts +12 -0
- package/dist/wobnimo.js +15 -15
- package/package.json +30 -4
- package/skill/SKILL.md +719 -0
- package/skill/examples/bao.ts +73 -0
- package/skill/examples/berry.ts +97 -0
- package/skill/examples/boo.ts +87 -0
- package/skill/examples/bumble.ts +70 -0
- package/skill/examples/cacti.ts +79 -0
- package/skill/examples/cap.ts +59 -0
- package/skill/examples/drift.ts +74 -0
- package/skill/examples/ember.ts +78 -0
- package/skill/examples/hop.ts +66 -0
- package/skill/examples/inky.ts +168 -0
- package/skill/examples/latte.ts +73 -0
- package/skill/examples/microduck.ts +222 -0
- package/skill/examples/miso.ts +182 -0
- package/skill/examples/mochi.ts +78 -0
- package/skill/examples/pebble.ts +174 -0
- package/skill/examples/pip.ts +170 -0
- package/skill/examples/rex.ts +193 -0
- package/skill/examples/swirl.ts +69 -0
- package/skill/examples/tad.ts +117 -0
- package/skill/examples/volt.ts +214 -0
- package/skill/reference/recipes.md +551 -0
- package/skill/reference/spec.md +258 -0
- package/skill/templates/starter.ts +73 -0
- package/dist/element-DRDEWSGV.d.ts +0 -8
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { BoneSpec, CharacterSpec, PaintSpec, PartSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/* The soft back spikes: one jiggling bone each, running from the crown down the tail. */
|
|
4
|
+
const SPIKES: Array<{ parent: string; at: [number, number, number]; tilt: number; size: number }> = [
|
|
5
|
+
{ parent: 'head', at: [0, 0.43, 0.05], tilt: -0.1, size: 0.075 },
|
|
6
|
+
{ parent: 'head', at: [0, 0.41, -0.1], tilt: -0.5, size: 0.09 },
|
|
7
|
+
{ parent: 'head', at: [0, 0.3, -0.24], tilt: -1.0, size: 0.085 },
|
|
8
|
+
{ parent: 'body', at: [0, 0.5, -0.24], tilt: -1.2, size: 0.08 },
|
|
9
|
+
{ parent: 'body', at: [0, 0.34, -0.3], tilt: -1.45, size: 0.07 },
|
|
10
|
+
{ parent: 'tail0', at: [0, 0.12, 0.07], tilt: 0, size: 0.06 },
|
|
11
|
+
{ parent: 'tail1', at: [0, 0.1, 0.05], tilt: 0, size: 0.045 },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
/** A baby T. rex: pebbly scales, a toothless grin, tiny arms and a tail that wags. */
|
|
15
|
+
export const rex: CharacterSpec = {
|
|
16
|
+
id: 'rex',
|
|
17
|
+
name: 'Rex',
|
|
18
|
+
tagline: 'A baby T. rex with pebbly scales, wobbly back spikes, tiny arms and a wagging tail',
|
|
19
|
+
accent: '#4fb86a',
|
|
20
|
+
frame: { target: 0.52, radius: 0.76 },
|
|
21
|
+
bound: { y: 0.46, radius: 0.86 },
|
|
22
|
+
motion: { hop: 0.15, squash: 1.15, snap: 1.05, talkSquash: 0.35 },
|
|
23
|
+
materials: {
|
|
24
|
+
/* a soft vinyl-toy hide: satin, with pebbled scales and darker seams */
|
|
25
|
+
hide: {
|
|
26
|
+
color: '#78cf7f', f0: 0.04, spec: 0.7, shininess: 40, rim: 0.7, gloss: 0.35, sss: 0.2, sssColor: '#c8ffb0',
|
|
27
|
+
surface: { kind: 'scales', scale: 24, strength: 0.5, color: '#4b9f5d', bone: 'head' },
|
|
28
|
+
},
|
|
29
|
+
bodyHide: {
|
|
30
|
+
color: '#78cf7f', shadeOf: 'hide', f0: 0.04, spec: 0.7, shininess: 40, rim: 0.7, gloss: 0.35, sss: 0.2, sssColor: '#c8ffb0',
|
|
31
|
+
surface: { kind: 'scales', scale: 24, strength: 0.5, color: '#4b9f5d' },
|
|
32
|
+
},
|
|
33
|
+
belly: { color: '#fff0c4', f0: 0.04, spec: 0.5, shininess: 30, rim: 0.5, gloss: 0.3, sss: 0.25, sssColor: '#fff6d8' },
|
|
34
|
+
spike: { color: '#ff9b4a', f0: 0.05, spec: 0.9, shininess: 60, rim: 0.5, gloss: 0.5, sss: 0.35, sssColor: '#ffc58f' },
|
|
35
|
+
claw: { color: '#fff6e2', f0: 0.05, spec: 1, shininess: 80, rim: 0.3, gloss: 0.6 },
|
|
36
|
+
},
|
|
37
|
+
bones: [
|
|
38
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.25]], rz: [['roll', 0.3]] } },
|
|
39
|
+
{ name: 'head', parent: 'body', pivot: [0, 0.56, 0.06], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.8]], rz: [['roll', 0.7]] } },
|
|
40
|
+
/* tiny arms, held up in front of the chest */
|
|
41
|
+
{ name: 'armL', parent: 'body', pivot: [-0.15, 0.42, 0.25], rest: { rx: -0.6 }, drive: { rx: [['flap', -0.9]], rz: [['flap', -0.5]] } },
|
|
42
|
+
{ name: 'armR', parent: 'body', pivot: [0.15, 0.42, 0.25], rest: { rx: -0.6 }, drive: { rx: [['flap', -0.9]], rz: [['flap', 0.5]] } },
|
|
43
|
+
/* the tail sweeps out behind and to the side, so it shows from the front */
|
|
44
|
+
{ name: 'tail0', parent: 'body', pivot: [0.08, 0.17, -0.24], rest: { rx: -1.25, rz: -0.6 }, wave: { rz: [0.2, 0.5, 0] }, jiggle: { axis: [0, 1, 0], length: 0.18, freq: 2.2, damping: 0.25, maxAngle: 0.6 } },
|
|
45
|
+
{ name: 'tail1', parent: 'tail0', pivot: [0, 0.18, 0], rest: { rx: 0.2 }, wave: { rz: [0.2, 0.5, 0.8] }, jiggle: { axis: [0, 1, 0], length: 0.15, freq: 2, damping: 0.22, maxAngle: 0.7 } },
|
|
46
|
+
{ name: 'tail2', parent: 'tail1', pivot: [0, 0.15, 0], rest: { rx: 0.15 }, wave: { rz: [0.25, 0.5, 1.6] }, jiggle: { axis: [0, 1, 0], length: 0.12, freq: 1.8, damping: 0.2, maxAngle: 0.8 } },
|
|
47
|
+
...SPIKES.map(({ parent, at, tilt }, i): BoneSpec => ({
|
|
48
|
+
name: `spike${i}`, parent, pivot: at, rest: { rx: tilt },
|
|
49
|
+
jiggle: { axis: [0, 1, 0], length: 0.08, freq: 4 + i * 0.3, damping: 0.12, maxAngle: 0.45 },
|
|
50
|
+
})),
|
|
51
|
+
],
|
|
52
|
+
parts: [
|
|
53
|
+
/* a pear of a body on two chunky thighs */
|
|
54
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.3, -0.02], radii: [0.3, 0.3, 0.28], material: 'bodyHide' },
|
|
55
|
+
{ bone: 'body', shape: 'ellipsoid', at: [-0.19, 0.15, -0.02], radii: [0.13, 0.15, 0.17], blend: 0.08, material: 'bodyHide' },
|
|
56
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0.19, 0.15, -0.02], radii: [0.13, 0.15, 0.17], blend: 0.08, material: 'bodyHide' },
|
|
57
|
+
/* feet with three blunt claws each */
|
|
58
|
+
...[-1, 1].flatMap((s): PartSpec[] => [
|
|
59
|
+
{ bone: 'body', shape: 'ellipsoid', at: [s * 0.2, 0.045, 0.1], radii: [0.1, 0.05, 0.13], blend: 0.05, material: 'bodyHide' },
|
|
60
|
+
...[-1, 0, 1].map((t): PartSpec => ({
|
|
61
|
+
bone: 'body', shape: 'ellipsoid', at: [s * 0.2 + t * 0.05, 0.03, 0.225 - Math.abs(t) * 0.015], radii: [0.022, 0.022, 0.026], blend: 0.012, material: 'claw',
|
|
62
|
+
})),
|
|
63
|
+
]),
|
|
64
|
+
/* a big round head with a wide, soft snout */
|
|
65
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.2, -0.02], radii: [0.29, 0.25, 0.27], blend: 0.12, material: 'hide' },
|
|
66
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.1, 0.17], radii: [0.23, 0.14, 0.18], blend: 0.1, material: 'hide' },
|
|
67
|
+
/* nostrils */
|
|
68
|
+
{ bone: 'head', shape: 'sphere', at: [-0.047, 0.162, 0.322], radius: 0.014, op: 'sub', blend: 0.01, material: 'hide' },
|
|
69
|
+
{ bone: 'head', shape: 'sphere', at: [0.047, 0.162, 0.322], radius: 0.014, op: 'sub', blend: 0.01, material: 'hide' },
|
|
70
|
+
/* tiny arms with two little claws */
|
|
71
|
+
...([['armL', -1], ['armR', 1]] as const).flatMap(([bone, s]): PartSpec[] => [
|
|
72
|
+
{ bone, shape: 'capsule', from: [0, 0, 0], to: [s * 0.01, -0.1, 0.03], radius: 0.042, blend: 0.04, material: 'bodyHide' },
|
|
73
|
+
{ bone, shape: 'sphere', at: [s * -0.014, -0.135, 0.05], radius: 0.015, blend: 0.01, material: 'claw' },
|
|
74
|
+
{ bone, shape: 'sphere', at: [s * 0.02, -0.135, 0.045], radius: 0.015, blend: 0.01, material: 'claw' },
|
|
75
|
+
]),
|
|
76
|
+
/* the tail, tapering */
|
|
77
|
+
{ bone: 'tail0', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.18, 0], r1: 0.12, r2: 0.09, blend: 0.06, material: 'bodyHide' },
|
|
78
|
+
{ bone: 'tail1', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.15, 0], r1: 0.09, r2: 0.06, blend: 0.03, material: 'bodyHide' },
|
|
79
|
+
{ bone: 'tail2', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.12, 0], r1: 0.06, r2: 0.03, blend: 0.03, material: 'bodyHide' },
|
|
80
|
+
/* soft orange spikes */
|
|
81
|
+
...SPIKES.map(({ size }, i): PartSpec => ({
|
|
82
|
+
bone: `spike${i}`, shape: 'roundCone', from: [0, -0.02, 0], to: [0, size * 1.1, 0], r1: size * 0.65, r2: size * 0.15, blend: 0.025, material: 'spike',
|
|
83
|
+
})),
|
|
84
|
+
],
|
|
85
|
+
paints: [
|
|
86
|
+
/* a cream belly and chin, freckles on the snout, blushing cheeks */
|
|
87
|
+
{ bone: 'body', on: ['bodyHide'], kind: 'ellipse', at: [0, 0.24, 0.08], radii: [0.16, 0.2], color: '#fff0c4', soft: 0.2 },
|
|
88
|
+
{ bone: 'head', on: ['hide'], kind: 'ellipse', at: [0, -0.01, 0.15], radii: [0.17, 0.06], color: '#fff0c4', soft: 0.35 },
|
|
89
|
+
{ bone: 'head', on: ['hide'], kind: 'sphere', at: [-0.2, 0.12, 0.24], radius: 0.055, color: '#ff9a9a', soft: 0.6, opacity: 0.7 },
|
|
90
|
+
{ bone: 'head', on: ['hide'], kind: 'sphere', at: [0.2, 0.12, 0.24], radius: 0.055, color: '#ff9a9a', soft: 0.6, opacity: 0.7 },
|
|
91
|
+
...[[-0.083, 0.204, 0.289], [-0.109, 0.181, 0.297], [0.083, 0.204, 0.289], [0.109, 0.181, 0.297]].map(([x, y, z]): PaintSpec => ({
|
|
92
|
+
bone: 'head', on: ['hide'], kind: 'sphere', at: [x, y, z], radius: 0.009, color: '#3f8a4f', soft: 0.3,
|
|
93
|
+
})),
|
|
94
|
+
],
|
|
95
|
+
eyes: {
|
|
96
|
+
kind: 'ball',
|
|
97
|
+
bone: 'head',
|
|
98
|
+
at: [[-0.13, 0.26, 0.19], [0.13, 0.26, 0.19]],
|
|
99
|
+
radius: 0.085,
|
|
100
|
+
iris: '#e0942f',
|
|
101
|
+
irisSize: 0.78,
|
|
102
|
+
pupilSize: 0.46,
|
|
103
|
+
pupilAspect: 0.75,
|
|
104
|
+
lid: 'hide',
|
|
105
|
+
},
|
|
106
|
+
/* a wide, toothless grin across the snout */
|
|
107
|
+
face: {
|
|
108
|
+
kind: 'mouth',
|
|
109
|
+
bone: 'head',
|
|
110
|
+
on: ['hide'],
|
|
111
|
+
at: [0, 0.06, 0.34],
|
|
112
|
+
width: 0.1,
|
|
113
|
+
color: '#5b1f2b',
|
|
114
|
+
tongue: '#ff7f93',
|
|
115
|
+
},
|
|
116
|
+
anchors: {
|
|
117
|
+
top: { bone: 'head', at: [0.16, 0.44, 0.06] },
|
|
118
|
+
mouth: { bone: 'head', at: [0, 0.06, 0.37] },
|
|
119
|
+
ear: { bone: 'head', at: [-0.3, 0.22, 0] },
|
|
120
|
+
feet: { bone: 'root', at: [0, 0.02, 0.15] },
|
|
121
|
+
tail: { bone: 'tail2', at: [0, 0.12, 0] },
|
|
122
|
+
},
|
|
123
|
+
acting: {
|
|
124
|
+
idle: { tail0: { rz: [-0.6, 0.12, 0.45, 0] } },
|
|
125
|
+
/* a tiny claw tapping the chin, which it can't quite reach */
|
|
126
|
+
thinking: {
|
|
127
|
+
armR: { rx: [-1.3, 0.08, 2.5, 0], rz: 0.3 },
|
|
128
|
+
tail2: { rx: [0.15, 0.3, 1.4, 0] },
|
|
129
|
+
},
|
|
130
|
+
listening: {
|
|
131
|
+
armL: { rx: -1.1, rz: -0.6 },
|
|
132
|
+
tail0: { rz: -0.4 },
|
|
133
|
+
},
|
|
134
|
+
speaking: {
|
|
135
|
+
armL: { rx: [-0.6, 0.25, 1.6, 0] },
|
|
136
|
+
armR: { rx: [-0.6, 0.25, 1.6, 2] },
|
|
137
|
+
tail0: { rz: [-0.6, 0.18, 0.9, 0] },
|
|
138
|
+
},
|
|
139
|
+
/* curled up: arms tucked, the tail wrapped round the front */
|
|
140
|
+
sleeping: {
|
|
141
|
+
armL: { rx: 0.1, rz: 0.2 },
|
|
142
|
+
armR: { rx: 0.1, rz: -0.2 },
|
|
143
|
+
tail0: { rz: -1.3, rx: -1.0 },
|
|
144
|
+
tail1: { rx: 0.4 },
|
|
145
|
+
},
|
|
146
|
+
/* scribbling with both little hands */
|
|
147
|
+
working: {
|
|
148
|
+
armL: { rx: [-0.9, 0.15, 7, 0] },
|
|
149
|
+
armR: { rx: [-0.9, 0.15, 7, Math.PI] },
|
|
150
|
+
head: { rx: 0.12 },
|
|
151
|
+
tail2: { rx: [0.15, 0.2, 2, 0] },
|
|
152
|
+
},
|
|
153
|
+
/* arms flailing, tail stiff, every spike on end */
|
|
154
|
+
error: {
|
|
155
|
+
armL: { rx: [-1.6, 0.35, 9, 0], rz: -0.4 },
|
|
156
|
+
armR: { rx: [-1.6, 0.35, 9, 1.4], rz: 0.4 },
|
|
157
|
+
tail0: { rz: [-0.5, 0.06, 12, 0], rx: -1.45 },
|
|
158
|
+
spike1: { rx: -0.2 },
|
|
159
|
+
spike2: { rx: -0.6 },
|
|
160
|
+
spike3: { rx: -0.8 },
|
|
161
|
+
},
|
|
162
|
+
surprised: {
|
|
163
|
+
armL: { rx: -1.9, rz: -0.6 },
|
|
164
|
+
armR: { rx: -1.9, rz: 0.6 },
|
|
165
|
+
tail0: { rx: -1.5 },
|
|
166
|
+
},
|
|
167
|
+
/* a happy stomp with tiny arms in the air and a wagging tail */
|
|
168
|
+
celebrating: {
|
|
169
|
+
armL: { rx: [-2.2, 0.3, 4, 0], rz: -0.5 },
|
|
170
|
+
armR: { rx: [-2.2, 0.3, 4, Math.PI], rz: 0.5 },
|
|
171
|
+
tail0: { rz: [-0.6, 0.55, 3, 0] },
|
|
172
|
+
},
|
|
173
|
+
sad: {
|
|
174
|
+
armL: { rx: 0.2 },
|
|
175
|
+
armR: { rx: 0.2 },
|
|
176
|
+
tail0: { rx: -0.95, rz: -0.4 },
|
|
177
|
+
tail1: { rx: 0.35 },
|
|
178
|
+
},
|
|
179
|
+
happy: {
|
|
180
|
+
armL: { rx: [-1.4, 0.4, 6, 0] },
|
|
181
|
+
armR: { rx: [-1.4, 0.4, 6, 1.4] },
|
|
182
|
+
tail0: { rz: [-0.6, 0.5, 4, 0] },
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
fx: {
|
|
186
|
+
/* a little roar on surprise */
|
|
187
|
+
'enter:surprised': [
|
|
188
|
+
{ glyph: 'arc', anchor: 'mouth', rate: 3, offset: [0.08, 0, 0.05], mirror: true, velocity: [0.3, 0.05, 0.1], jitter: 0.04, life: [0.5, 0.6], size: [0.04, 0.11], color: '#7fd18a' },
|
|
189
|
+
],
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export default rex;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { CharacterSpec, PartSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A snail whose shell looks like a cinnamon roll. */
|
|
4
|
+
export const swirl: CharacterSpec = {
|
|
5
|
+
id: 'swirl',
|
|
6
|
+
name: 'Swirl',
|
|
7
|
+
tagline: 'A slow, sweet snail carrying a glazed cinnamon roll for a shell',
|
|
8
|
+
accent: '#c27a3e',
|
|
9
|
+
frame: { target: 0.38, radius: 0.59 },
|
|
10
|
+
bound: { y: 0.35, radius: 0.6 },
|
|
11
|
+
motion: { hop: 0.03, squash: 1.4, snap: 0.7, talkSquash: 0.6 },
|
|
12
|
+
materials: {
|
|
13
|
+
skin: { color: '#b9d97a', f0: 0.06, spec: 1.4, shininess: 110, rim: 0.7, sss: 0.45, sssColor: '#e6ffb0', gloss: 0.8, surface: { kind: 'ripple', scale: 18, strength: 0.25 } },
|
|
14
|
+
dough: { color: '#d9944f', f0: 0.03, spec: 0.5, shininess: 30, rim: 0.5, sheen: 0.3 },
|
|
15
|
+
cinnamon: { color: '#8a4b22', shadeOf: 'dough', f0: 0.03, spec: 0.5, shininess: 30, rim: 0.4 },
|
|
16
|
+
glaze: { color: '#fff4e4', f0: 0.08, spec: 1.6, shininess: 160, rim: 0.6, sss: 0.4, sssColor: '#ffffff', gloss: 0.9 },
|
|
17
|
+
bead: { color: '#1a1410', f0: 0.06, spec: 2.2, shininess: 400, rim: 0.2, gloss: 1 },
|
|
18
|
+
},
|
|
19
|
+
bones: [
|
|
20
|
+
{ name: 'body', pivot: [0, 0.053, 0], drive: { ry: [['yaw', 0.3]], rz: [['roll', 0.3]] }, wave: { rz: [0.02, 0.4, 0] } },
|
|
21
|
+
/* the head rises out of the foot at the front */
|
|
22
|
+
{ name: 'head', parent: 'body', pivot: [0.24, 0.12, 0.08], drive: { rx: [['pitch', -0.7]], ry: [['yaw', 0.7]], rz: [['roll', 0.6]] } },
|
|
23
|
+
{ name: 'stalkL', parent: 'head', pivot: [-0.06, 0.3, 0.02], rest: { rz: 0.3 }, jiggle: { axis: [0, 1, 0], length: 0.16, freq: 2.4, damping: 0.12 } },
|
|
24
|
+
{ name: 'stalkR', parent: 'head', pivot: [0.06, 0.3, 0.02], rest: { rz: -0.3 }, jiggle: { axis: [0, 1, 0], length: 0.16, freq: 2.4, damping: 0.12 } },
|
|
25
|
+
{ name: 'shell', parent: 'body', pivot: [-0.08, 0.12, -0.04], wave: { rz: [0.015, 0.4, 1] } },
|
|
26
|
+
],
|
|
27
|
+
parts: [
|
|
28
|
+
/* a long soft foot */
|
|
29
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.07, 0], radii: [0.42, 0.08, 0.2], material: 'skin' },
|
|
30
|
+
/* the head and neck */
|
|
31
|
+
{ bone: 'head', shape: 'capsule', from: [0, -0.05, 0], to: [0, 0.2, 0.02], radius: 0.13, blend: 0.08, material: 'skin' },
|
|
32
|
+
{ bone: 'stalkL', shape: 'capsule', from: [0, 0, 0], to: [0, 0.14, 0], radius: 0.02, material: 'skin' },
|
|
33
|
+
{ bone: 'stalkL', shape: 'sphere', at: [0, 0.15, 0], radius: 0.035, material: 'skin' },
|
|
34
|
+
{ bone: 'stalkR', shape: 'capsule', from: [0, 0, 0], to: [0, 0.14, 0], radius: 0.02, material: 'skin' },
|
|
35
|
+
{ bone: 'stalkR', shape: 'sphere', at: [0, 0.15, 0], radius: 0.035, material: 'skin' },
|
|
36
|
+
/* the shell: a cinnamon roll on its side, a spiral of dough and a lick of glaze */
|
|
37
|
+
{ bone: 'shell', shape: 'cylinder', at: [0, 0.27, 0], rot: [Math.PI / 2, 0, 0], radius: 0.27, half: 0.13, round: 0.07, material: 'dough' },
|
|
38
|
+
/* the spiral: alternately carve a groove and fill the next ring back in, outside to centre
|
|
39
|
+
(a subtraction only cuts what comes before it, so the order is the pattern) */
|
|
40
|
+
...[0.21, 0.15, 0.09].flatMap((r, i): PartSpec[] => [
|
|
41
|
+
{ bone: 'shell', shape: 'cylinder', at: [0.01 * i, 0.27 + 0.01 * i, 0.12], rot: [Math.PI / 2, 0, 0], radius: r, half: 0.03, round: 0.02, op: 'sub', blend: 0.015, material: 'cinnamon' },
|
|
42
|
+
{ bone: 'shell', shape: 'cylinder', at: [0.01 * i, 0.27 + 0.01 * i, 0.1], rot: [Math.PI / 2, 0, 0], radius: r - 0.03, half: 0.03, round: 0.025, blend: 0.01, material: 'dough' },
|
|
43
|
+
]),
|
|
44
|
+
{ bone: 'shell', shape: 'ellipsoid', at: [-0.04, 0.47, 0.03], radii: [0.2, 0.06, 0.15], blend: 0.03, material: 'glaze' },
|
|
45
|
+
],
|
|
46
|
+
paints: [
|
|
47
|
+
{ bone: 'head', on: ['skin'], kind: 'sphere', at: [-0.09, 0.06, 0.1], radius: 0.035, color: '#ff9eb0', soft: 0.6, opacity: 0.8 },
|
|
48
|
+
{ bone: 'head', on: ['skin'], kind: 'sphere', at: [0.09, 0.06, 0.1], radius: 0.035, color: '#ff9eb0', soft: 0.6, opacity: 0.8 },
|
|
49
|
+
],
|
|
50
|
+
eyes: { kind: 'bead', bone: 'head', at: [[-0.055, 0.14, 0.128], [0.055, 0.14, 0.128]], radii: [0.026, 0.038, 0.018], material: 'bead' },
|
|
51
|
+
face: { kind: 'mouth', bone: 'head', on: ['skin'], at: [0, 0.05, 0.14], width: 0.04, color: '#3d4f1c', tongue: '#ff8a9a' },
|
|
52
|
+
anchors: {
|
|
53
|
+
top: { bone: 'shell', at: [0, 0.58, 0] },
|
|
54
|
+
mouth: { bone: 'head', at: [0, 0.05, 0.16] },
|
|
55
|
+
ear: { bone: 'head', at: [-0.14, 0.15, 0] },
|
|
56
|
+
feet: { bone: 'root', at: [0.3, 0.02, 0.12] },
|
|
57
|
+
},
|
|
58
|
+
acting: {
|
|
59
|
+
thinking: { head: { rz: 0.2 }, stalkL: { rz: 0.6 } },
|
|
60
|
+
listening: { stalkL: { rx: -0.4 }, stalkR: { rx: -0.4 } },
|
|
61
|
+
sleeping: { head: { rx: 0.5 }, stalkL: { rx: 1.1 }, stalkR: { rx: 1.1 } },
|
|
62
|
+
error: { stalkL: { rz: [0.3, 0.3, 8, 0] }, stalkR: { rz: [-0.3, 0.3, 8, 1] } },
|
|
63
|
+
surprised: { stalkL: { rz: 0.05 }, stalkR: { rz: -0.05 }, head: { rx: -0.2 } },
|
|
64
|
+
celebrating: { stalkL: { rz: [0.4, 0.3, 4, 0] }, stalkR: { rz: [-0.4, 0.3, 4, Math.PI] } },
|
|
65
|
+
sad: { head: { rx: 0.3 }, stalkL: { rx: 1.2, rz: 0.5 }, stalkR: { rx: 1.2, rz: -0.5 } },
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default swirl;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { CharacterSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A tree frog: wet, glossy and spotted, with eyes on top and a throat that puffs when it talks. */
|
|
4
|
+
export const tad: CharacterSpec = {
|
|
5
|
+
id: 'tad',
|
|
6
|
+
name: 'Tad',
|
|
7
|
+
tagline: 'A glossy tree frog with a wet sheen, eyes on top and a throat that puffs as it talks',
|
|
8
|
+
accent: '#3fae4a',
|
|
9
|
+
frame: { target: 0.42, radius: 0.66 },
|
|
10
|
+
bound: { y: 0.4, radius: 0.72 },
|
|
11
|
+
motion: { hop: 0.26, squash: 1.6, snap: 1.2, look: 0.8, talkSquash: 0.45 },
|
|
12
|
+
materials: {
|
|
13
|
+
/* wet skin: a strong, sharp clear coat over a little translucency */
|
|
14
|
+
skin: {
|
|
15
|
+
color: '#5fc24e', f0: 0.07, spec: 2, shininess: 260, rim: 0.7, gloss: 0.95, sss: 0.3, sssColor: '#c6ff8f',
|
|
16
|
+
surface: { kind: 'speckle', scale: 9, strength: 0.85, color: '#2f8a3a', bone: 'head' },
|
|
17
|
+
},
|
|
18
|
+
bodySkin: {
|
|
19
|
+
color: '#5fc24e', shadeOf: 'skin', f0: 0.07, spec: 2, shininess: 260, rim: 0.7, gloss: 0.95, sss: 0.3, sssColor: '#c6ff8f',
|
|
20
|
+
surface: { kind: 'speckle', scale: 9, strength: 0.85, color: '#2f8a3a' },
|
|
21
|
+
},
|
|
22
|
+
belly: { color: '#f3f0b6', f0: 0.06, spec: 1.6, shininess: 200, rim: 0.5, gloss: 0.9, sss: 0.45, sssColor: '#fffbd0' },
|
|
23
|
+
toe: { color: '#ffb54a', f0: 0.06, spec: 1.4, shininess: 160, rim: 0.4, gloss: 0.8, sss: 0.3, sssColor: '#ffd99a' },
|
|
24
|
+
},
|
|
25
|
+
bones: [
|
|
26
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.25]], rz: [['roll', 0.3]] } },
|
|
27
|
+
/* frogs have no neck: the whole top of the body tips and turns */
|
|
28
|
+
{ name: 'head', parent: 'body', pivot: [0, 0.3, 0.02], drive: { rx: [['pitch', -0.8]], ry: [['yaw', 0.7]], rz: [['roll', 0.6]] } },
|
|
29
|
+
/* the throat sac swings forward and out from under the chin as it talks */
|
|
30
|
+
{ name: 'throat', parent: 'head', pivot: [0, 0.02, 0.12], drive: { rx: [['talk', 0.9]] } },
|
|
31
|
+
{ name: 'armL', parent: 'body', pivot: [-0.22, 0.2, 0.18], drive: { rz: [['flap', -1.3]], rx: [['flap', -0.4]] } },
|
|
32
|
+
{ name: 'armR', parent: 'body', pivot: [0.22, 0.2, 0.18], drive: { rz: [['flap', 1.3]], rx: [['flap', -0.4]] } },
|
|
33
|
+
],
|
|
34
|
+
parts: [
|
|
35
|
+
/* a squat, pear-shaped body with folded back legs */
|
|
36
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.22, -0.03], radii: [0.36, 0.22, 0.32], material: 'bodySkin' },
|
|
37
|
+
{ bone: 'body', shape: 'ellipsoid', at: [-0.3, 0.12, -0.04], rot: [0, 0.25, 0], radii: [0.13, 0.11, 0.22], blend: 0.09, material: 'bodySkin' },
|
|
38
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0.3, 0.12, -0.04], rot: [0, -0.25, 0], radii: [0.13, 0.11, 0.22], blend: 0.09, material: 'bodySkin' },
|
|
39
|
+
/* webbed back feet, splayed */
|
|
40
|
+
{ bone: 'body', shape: 'ellipsoid', at: [-0.33, 0.025, 0.16], rot: [0, 0.5, 0], radii: [0.08, 0.025, 0.13], blend: 0.03, material: 'bodySkin' },
|
|
41
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0.33, 0.025, 0.16], rot: [0, -0.5, 0], radii: [0.08, 0.025, 0.13], blend: 0.03, material: 'bodySkin' },
|
|
42
|
+
/* the wide head, with two domes for the eyes */
|
|
43
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.1, 0.05], radii: [0.38, 0.19, 0.31], blend: 0.14, material: 'skin' },
|
|
44
|
+
{ bone: 'head', shape: 'sphere', at: [-0.19, 0.24, 0.1], radius: 0.13, blend: 0.07, material: 'skin' },
|
|
45
|
+
{ bone: 'head', shape: 'sphere', at: [0.19, 0.24, 0.1], radius: 0.13, blend: 0.07, material: 'skin' },
|
|
46
|
+
/* the throat sac: hidden under the chin at rest */
|
|
47
|
+
{ bone: 'throat', shape: 'ellipsoid', at: [0, -0.04, 0.1], radii: [0.14, 0.1, 0.12], blend: 0.05, material: 'belly' },
|
|
48
|
+
/* little arms with round toe pads */
|
|
49
|
+
{ bone: 'armL', shape: 'capsule', from: [0, 0, 0], to: [-0.03, -0.17, 0.08], radius: 0.045, blend: 0.05, material: 'bodySkin' },
|
|
50
|
+
{ bone: 'armL', shape: 'sphere', at: [-0.07, -0.19, 0.12], radius: 0.026, blend: 0.02, material: 'toe' },
|
|
51
|
+
{ bone: 'armL', shape: 'sphere', at: [-0.02, -0.19, 0.15], radius: 0.026, blend: 0.02, material: 'toe' },
|
|
52
|
+
{ bone: 'armL', shape: 'sphere', at: [0.03, -0.19, 0.13], radius: 0.026, blend: 0.02, material: 'toe' },
|
|
53
|
+
{ bone: 'armR', shape: 'capsule', from: [0, 0, 0], to: [0.03, -0.17, 0.08], radius: 0.045, blend: 0.05, material: 'bodySkin' },
|
|
54
|
+
{ bone: 'armR', shape: 'sphere', at: [0.07, -0.19, 0.12], radius: 0.026, blend: 0.02, material: 'toe' },
|
|
55
|
+
{ bone: 'armR', shape: 'sphere', at: [0.02, -0.19, 0.15], radius: 0.026, blend: 0.02, material: 'toe' },
|
|
56
|
+
{ bone: 'armR', shape: 'sphere', at: [-0.03, -0.19, 0.13], radius: 0.026, blend: 0.02, material: 'toe' },
|
|
57
|
+
],
|
|
58
|
+
paints: [
|
|
59
|
+
{ bone: 'body', on: ['bodySkin'], kind: 'ellipse', at: [0, 0.16, 0.28], radii: [0.22, 0.13], color: '#f3f0b6', soft: 0.3 },
|
|
60
|
+
{ bone: 'head', on: ['skin'], kind: 'ellipse', at: [0, -0.01, 0.34], radii: [0.2, 0.06], color: '#f3f0b6', soft: 0.4 },
|
|
61
|
+
{ bone: 'head', on: ['skin'], kind: 'sphere', at: [-0.24, 0.07, 0.27], radius: 0.055, color: '#ff8f9c', soft: 0.6, opacity: 0.7 },
|
|
62
|
+
{ bone: 'head', on: ['skin'], kind: 'sphere', at: [0.24, 0.07, 0.27], radius: 0.055, color: '#ff8f9c', soft: 0.6, opacity: 0.7 },
|
|
63
|
+
],
|
|
64
|
+
eyes: {
|
|
65
|
+
kind: 'ball',
|
|
66
|
+
bone: 'head',
|
|
67
|
+
at: [[-0.19, 0.27, 0.15], [0.19, 0.27, 0.15]],
|
|
68
|
+
radius: 0.1,
|
|
69
|
+
iris: '#e7b93a',
|
|
70
|
+
irisSize: 0.74,
|
|
71
|
+
pupilSize: 0.36,
|
|
72
|
+
pupilAspect: 1.8,
|
|
73
|
+
lid: 'skin',
|
|
74
|
+
},
|
|
75
|
+
/* a frog's mouth runs nearly ear to ear */
|
|
76
|
+
face: {
|
|
77
|
+
kind: 'mouth',
|
|
78
|
+
bone: 'head',
|
|
79
|
+
on: ['skin'],
|
|
80
|
+
at: [0, 0.06, 0.34],
|
|
81
|
+
width: 0.12,
|
|
82
|
+
color: '#5a1f2e',
|
|
83
|
+
tongue: '#ff7b93',
|
|
84
|
+
},
|
|
85
|
+
anchors: {
|
|
86
|
+
top: { bone: 'head', at: [0.2, 0.36, 0.05] },
|
|
87
|
+
mouth: { bone: 'head', at: [0, 0.05, 0.37] },
|
|
88
|
+
ear: { bone: 'head', at: [-0.38, 0.12, 0] },
|
|
89
|
+
feet: { bone: 'root', at: [0, 0.03, 0.22] },
|
|
90
|
+
},
|
|
91
|
+
acting: {
|
|
92
|
+
idle: { throat: { rx: [0, 0.12, 1.1, 0] } },
|
|
93
|
+
/* a toe to the chin */
|
|
94
|
+
thinking: { armR: { rz: 0.6, rx: -1.5 } },
|
|
95
|
+
listening: { armL: { rz: -1.6, rx: -0.4 } },
|
|
96
|
+
speaking: {
|
|
97
|
+
armL: { rx: [-0.25, 0.2, 1.3, 0] },
|
|
98
|
+
armR: { rx: [-0.25, 0.2, 1.3, 2] },
|
|
99
|
+
},
|
|
100
|
+
sleeping: { armL: { rx: 0.2 }, armR: { rx: 0.2 }, throat: { rx: [0.2, 0.25, 0.18, 0] } },
|
|
101
|
+
/* drumming its toes */
|
|
102
|
+
working: { armL: { rx: [-0.5, 0.2, 7, 0] }, armR: { rx: [-0.5, 0.2, 7, Math.PI] }, throat: { rx: [0, 0.15, 3.5, 0] } },
|
|
103
|
+
error: { armL: { rz: [-1.2, 0.15, 12, 0] }, armR: { rz: [1.2, 0.15, 12, 1] }, throat: { rx: 0.6 } },
|
|
104
|
+
surprised: { armL: { rz: -1.8 }, armR: { rz: 1.8 }, throat: { rx: 0.9 } },
|
|
105
|
+
celebrating: { armL: { rz: [-2, 0.4, 4, 0] }, armR: { rz: [2, 0.4, 4, Math.PI] }, throat: { rx: [0.4, 0.4, 4, 0] } },
|
|
106
|
+
sad: { armL: { rz: 0.2, rx: 0.3 }, armR: { rz: -0.2, rx: 0.3 } },
|
|
107
|
+
happy: { armL: { rz: [-1.5, 0.4, 5, 0] }, armR: { rz: [1.5, 0.4, 5, 1] }, throat: { rx: [0.4, 0.4, 5, 0] } },
|
|
108
|
+
},
|
|
109
|
+
fx: {
|
|
110
|
+
replace: ['land'],
|
|
111
|
+
/* a splash every time it lands, and a ribbit of bubbles */
|
|
112
|
+
land: [{ glyph: 'drop', anchor: 'feet', rate: 8, spread: 0.2, velocity: [0, 0.7, 0.05], jitter: 0.7, gravity: 3.2, life: [0.45, 0.6], size: [0.035, 0.022], color: '#7fd0ff', align: true }],
|
|
113
|
+
syllable: [{ glyph: 'bubble', anchor: 'mouth', rate: 1, offset: [0.1, 0, 0.02], velocity: [0.08, 0.18, 0.05], jitter: 0.08, wobble: 0.05, life: [0.9, 1.2], size: [0.016, 0.036], color: '#a6e8ff' }],
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export default tad;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import type { BoneSpec, CharacterSpec, PartSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/* A jointed arm: shoulder, elbow, and a claw hand. `side` is -1 for the
|
|
4
|
+
arm on screen left, 1 for screen right. */
|
|
5
|
+
function arm(side: -1 | 1): BoneSpec[] {
|
|
6
|
+
const s = side < 0 ? 'L' : 'R';
|
|
7
|
+
return [
|
|
8
|
+
{ name: `shoulder${s}`, parent: 'body', pivot: [0.385 * side, 0.47, 0.02], drive: { rz: [['flap', 0.5 * side]] } },
|
|
9
|
+
{
|
|
10
|
+
name: `fore${s}`, parent: `shoulder${s}`, pivot: [0, -0.17, 0],
|
|
11
|
+
jiggle: { axis: [0, -1, 0], length: 0.16, freq: 3.2, damping: 0.35, maxAngle: 0.3 },
|
|
12
|
+
},
|
|
13
|
+
];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function armParts(side: -1 | 1): PartSpec[] {
|
|
17
|
+
const s = side < 0 ? 'L' : 'R';
|
|
18
|
+
return [
|
|
19
|
+
{ bone: `shoulder${s}`, shape: 'sphere', radius: 0.074, material: 'trim' },
|
|
20
|
+
{ bone: `shoulder${s}`, shape: 'capsule', from: [0, -0.02, 0], to: [0, -0.15, 0], radius: 0.058, material: 'shell' },
|
|
21
|
+
{ bone: `fore${s}`, shape: 'sphere', radius: 0.052, material: 'trim' },
|
|
22
|
+
{ bone: `fore${s}`, shape: 'capsule', from: [0, -0.02, 0], to: [0, -0.12, 0], radius: 0.052, material: 'shell' },
|
|
23
|
+
/* a claw: a ball with a bite out of it */
|
|
24
|
+
{ bone: `fore${s}`, shape: 'sphere', at: [0, -0.175, 0], radius: 0.066, material: 'trim' },
|
|
25
|
+
{ bone: `fore${s}`, shape: 'sphere', op: 'sub', blend: 0.012, at: [0, -0.235, 0.012], radius: 0.036, material: 'trim' },
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* knob ears that spin like gears when it thinks; two studs make the turn readable */
|
|
30
|
+
function earParts(side: -1 | 1): PartSpec[] {
|
|
31
|
+
const s = side < 0 ? 'L' : 'R';
|
|
32
|
+
return [
|
|
33
|
+
{ bone: `ear${s}`, shape: 'cylinder', rot: [0, 0, 1.5708], radius: 0.112, half: 0.03, round: 0.018, material: 'trim' },
|
|
34
|
+
{ bone: `ear${s}`, shape: 'cylinder', at: [0.045 * side, 0, 0], rot: [0, 0, 1.5708], radius: 0.058, half: 0.035, round: 0.018, material: 'trim' },
|
|
35
|
+
{ bone: `ear${s}`, shape: 'sphere', at: [0.035 * side, 0.078, 0], radius: 0.02, material: 'metal' },
|
|
36
|
+
{ bone: `ear${s}`, shape: 'sphere', at: [0.035 * side, -0.078, 0], radius: 0.02, material: 'metal' },
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** A glossy TV-headed robot: LED face, jointed arms with claws, gear ears, sprung antenna. */
|
|
41
|
+
export const volt: CharacterSpec = {
|
|
42
|
+
id: 'volt',
|
|
43
|
+
name: 'Volt',
|
|
44
|
+
tagline: 'LED face, claw hands, gear ears, a sprung antenna',
|
|
45
|
+
accent: '#3b63d9',
|
|
46
|
+
frame: { target: 0.86, radius: 1.02 },
|
|
47
|
+
bound: { y: 0.86, radius: 1.12 },
|
|
48
|
+
motion: { hop: 0.16, squash: 1, snap: 1 },
|
|
49
|
+
glowPool: 0.35,
|
|
50
|
+
materials: {
|
|
51
|
+
shell: { color: '#2f56c4', f0: 0.05, spec: 0.7, shininess: 70, rim: 0.55, gloss: 0.55 },
|
|
52
|
+
trim: { color: '#c3cce3', f0: 0.07, spec: 0.8, shininess: 90, metal: 0.25, rim: 0.4, gloss: 0.5 },
|
|
53
|
+
metal: { color: '#8f98ae', f0: 0.45, spec: 1, shininess: 120, metal: 0.85, rim: 0.3, gloss: 0.7 },
|
|
54
|
+
rubber: { color: '#151a28', f0: 0.03, spec: 0.15, shininess: 12, rim: 0.2 },
|
|
55
|
+
screen: { color: '#03060c', f0: 0.045, spec: 1.6, shininess: 260, rim: 0.1, gloss: 1 },
|
|
56
|
+
bulb: { color: '#f2f5ff', f0: 0.04, spec: 0.6, shininess: 40, rim: 0.3, glows: true, emitStrength: 1.4, sss: 0.4, sssColor: '#ffffff' },
|
|
57
|
+
lamp: { color: '#e9eeff', f0: 0.05, spec: 1, shininess: 80, glows: true, emitStrength: 1.1, gloss: 0.9 },
|
|
58
|
+
ring: { color: '#d8e4ff', f0: 0.04, spec: 0.4, shininess: 30, glows: true, emitStrength: 1.6 },
|
|
59
|
+
},
|
|
60
|
+
bones: [
|
|
61
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.2]], rz: [['roll', 0.25]] } },
|
|
62
|
+
{ name: 'head', parent: 'body', pivot: [0, 0.64, 0], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.8]], rz: [['roll', 0.75]] } },
|
|
63
|
+
{ name: 'antenna', parent: 'head', pivot: [0, 0.755, 0], jiggle: { axis: [0, 1, 0], length: 0.26, freq: 2.3, damping: 0.11 } },
|
|
64
|
+
{ name: 'earL', parent: 'head', pivot: [-0.585, 0.37, 0] },
|
|
65
|
+
{ name: 'earR', parent: 'head', pivot: [0.585, 0.37, 0] },
|
|
66
|
+
...arm(-1),
|
|
67
|
+
...arm(1),
|
|
68
|
+
],
|
|
69
|
+
parts: [
|
|
70
|
+
/* the body: a soft puck on two feet, a lamp and a speaker grille in the chest */
|
|
71
|
+
{ bone: 'body', shape: 'roundBox', at: [0, 0.32, 0], half: [0.35, 0.27, 0.28], round: 0.22, material: 'shell' },
|
|
72
|
+
{ bone: 'body', shape: 'roundBox', at: [0, 0.38, 0.27], half: [0.15, 0.08, 0.03], round: 0.06, material: 'rubber' },
|
|
73
|
+
{ bone: 'body', shape: 'sphere', at: [0, 0.38, 0.285], radius: 0.04, material: 'lamp' },
|
|
74
|
+
{ bone: 'body', shape: 'plate', op: 'sub', blend: 0.006, at: [0, 0.225, 0.3], half: [0.075, 0.009], corner: 0.009, depth: 0.03, material: 'shell' },
|
|
75
|
+
{ bone: 'body', shape: 'plate', op: 'sub', blend: 0.006, at: [0, 0.19, 0.295], half: [0.075, 0.009], corner: 0.009, depth: 0.03, material: 'shell' },
|
|
76
|
+
{ bone: 'body', shape: 'plate', op: 'sub', blend: 0.006, at: [0, 0.155, 0.27], half: [0.06, 0.009], corner: 0.009, depth: 0.03, material: 'shell' },
|
|
77
|
+
{ bone: 'body', shape: 'roundBox', at: [-0.17, 0.035, 0.05], half: [0.11, 0.035, 0.14], round: 0.035, material: 'trim' },
|
|
78
|
+
{ bone: 'body', shape: 'roundBox', at: [0.17, 0.035, 0.05], half: [0.11, 0.035, 0.14], round: 0.035, material: 'trim' },
|
|
79
|
+
{ bone: 'body', shape: 'cylinder', at: [0, 0.62, 0], radius: 0.075, half: 0.06, round: 0.02, material: 'metal' },
|
|
80
|
+
|
|
81
|
+
/* the head: a shell with a rolled lip into the screen, and the glass */
|
|
82
|
+
{ bone: 'head', shape: 'roundBox', at: [0, 0.37, 0], half: [0.56, 0.37, 0.35], round: 0.17, material: 'shell' },
|
|
83
|
+
{ bone: 'head', shape: 'roundBox', op: 'sub', blend: 0.035, at: [0, 0.37, 0.41], half: [0.45, 0.28, 0.1], round: 0.12, material: 'shell' },
|
|
84
|
+
{ bone: 'head', shape: 'plate', at: [0, 0.37, 0.31], half: [0.45, 0.28], corner: 0.12, depth: 0.012, material: 'screen' },
|
|
85
|
+
/* glowing rings where the ears meet the head */
|
|
86
|
+
{ bone: 'head', shape: 'cylinder', at: [-0.555, 0.37, 0], rot: [0, 0, 1.5708], radius: 0.122, half: 0.012, round: 0.006, material: 'ring' },
|
|
87
|
+
{ bone: 'head', shape: 'cylinder', at: [0.555, 0.37, 0], rot: [0, 0, 1.5708], radius: 0.122, half: 0.012, round: 0.006, material: 'ring' },
|
|
88
|
+
...earParts(-1),
|
|
89
|
+
...earParts(1),
|
|
90
|
+
/* the antenna's collar, stem and bulb */
|
|
91
|
+
{ bone: 'head', shape: 'cylinder', at: [0, 0.745, 0], radius: 0.065, half: 0.025, round: 0.012, material: 'trim' },
|
|
92
|
+
{ bone: 'antenna', shape: 'capsule', from: [0, 0, 0], to: [0, 0.2, 0], radius: 0.016, material: 'metal' },
|
|
93
|
+
{ bone: 'antenna', shape: 'sphere', at: [0, 0.25, 0], radius: 0.055, material: 'bulb' },
|
|
94
|
+
|
|
95
|
+
...armParts(-1),
|
|
96
|
+
...armParts(1),
|
|
97
|
+
],
|
|
98
|
+
face: {
|
|
99
|
+
kind: 'screen',
|
|
100
|
+
bone: 'head',
|
|
101
|
+
material: 'screen',
|
|
102
|
+
center: [0, 0.37],
|
|
103
|
+
half: [0.44, 0.27],
|
|
104
|
+
corner: 0.11,
|
|
105
|
+
cell: 0.034,
|
|
106
|
+
color: '#c4ecff',
|
|
107
|
+
},
|
|
108
|
+
anchors: {
|
|
109
|
+
top: { bone: 'head', at: [0.3, 0.78, 0.1] },
|
|
110
|
+
mouth: { bone: 'head', at: [0, 0.22, 0.34] },
|
|
111
|
+
ear: { bone: 'head', at: [-0.66, 0.37, 0] },
|
|
112
|
+
feet: { bone: 'root', at: [0, 0.02, 0.06] },
|
|
113
|
+
antenna: { bone: 'antenna', at: [0, 0.25, 0] },
|
|
114
|
+
},
|
|
115
|
+
acting: {
|
|
116
|
+
idle: {
|
|
117
|
+
shoulderL: { rz: [-0.08, 0.04, 0.45, 0], rx: [0, 0.06, 0.35, 1] },
|
|
118
|
+
shoulderR: { rz: [0.08, 0.04, 0.45, 1.6], rx: [0, 0.06, 0.35, 2.4] },
|
|
119
|
+
foreL: { rx: -0.25 },
|
|
120
|
+
foreR: { rx: -0.25 },
|
|
121
|
+
},
|
|
122
|
+
/* the thinker: one claw up to the chin and tapping, the other arm across the belly */
|
|
123
|
+
thinking: {
|
|
124
|
+
shoulderR: { rx: -1.5, ry: -0.8, rz: -0.1 },
|
|
125
|
+
foreR: { rx: [-0.95, 0.1, 1.8, 0] },
|
|
126
|
+
shoulderL: { rx: -1.0, ry: 0.8, rz: -0.3 },
|
|
127
|
+
foreL: { rx: -0.8 },
|
|
128
|
+
earL: { rx: [0, 0, 0, 0, 5] },
|
|
129
|
+
earR: { rx: [0, 0, 0, 0, -5] },
|
|
130
|
+
},
|
|
131
|
+
/* a claw cupped up by the ear */
|
|
132
|
+
listening: {
|
|
133
|
+
shoulderL: { rx: 0.1, ry: 0.3, rz: -2.8 },
|
|
134
|
+
foreL: { rx: -0.6 },
|
|
135
|
+
shoulderR: { rz: 0.14, rx: 0.05 },
|
|
136
|
+
foreR: { rx: -0.3 },
|
|
137
|
+
earL: { rx: [0.3, 0.15, 0.8, 0] },
|
|
138
|
+
},
|
|
139
|
+
/* talking with its hands */
|
|
140
|
+
speaking: {
|
|
141
|
+
shoulderL: { rx: [-0.55, 0.32, 0.72, 0], rz: [-0.28, 0.12, 0.5, 0] },
|
|
142
|
+
foreL: { rx: [-0.85, 0.38, 1.44, 0.6] },
|
|
143
|
+
shoulderR: { rx: [-0.45, 0.32, 0.72, 2.2], rz: [0.28, 0.12, 0.5, 1] },
|
|
144
|
+
foreR: { rx: [-0.95, 0.38, 1.44, 2.8] },
|
|
145
|
+
earL: { rx: [0, 0, 0, 0, 1.4] },
|
|
146
|
+
earR: { rx: [0, 0, 0, 0, -1.4] },
|
|
147
|
+
},
|
|
148
|
+
sleeping: {
|
|
149
|
+
shoulderL: { rz: -0.03, rx: -0.3 },
|
|
150
|
+
shoulderR: { rz: 0.03, rx: -0.3 },
|
|
151
|
+
foreL: { rx: -0.4 },
|
|
152
|
+
foreR: { rx: -0.4 },
|
|
153
|
+
},
|
|
154
|
+
/* typing: arms forward, claws tapping in turn, ears turning like drives */
|
|
155
|
+
working: {
|
|
156
|
+
shoulderL: { rx: -0.85, rz: -0.12 },
|
|
157
|
+
shoulderR: { rx: -0.85, rz: 0.12 },
|
|
158
|
+
foreL: { rx: [-0.95, 0.2, 6, 0] },
|
|
159
|
+
foreR: { rx: [-0.95, 0.2, 6, Math.PI] },
|
|
160
|
+
earL: { rx: [0, 0, 0, 0, 3] },
|
|
161
|
+
earR: { rx: [0, 0, 0, 0, -3] },
|
|
162
|
+
},
|
|
163
|
+
/* arms thrown out, shaking; the ears seize up */
|
|
164
|
+
error: {
|
|
165
|
+
shoulderL: { rz: [-0.95, 0.1, 11, 0], rx: -0.2 },
|
|
166
|
+
shoulderR: { rz: [0.95, 0.1, 11, 1], rx: -0.2 },
|
|
167
|
+
foreL: { rx: -1.1 },
|
|
168
|
+
foreR: { rx: -1.1 },
|
|
169
|
+
},
|
|
170
|
+
surprised: {
|
|
171
|
+
shoulderL: { rz: -1.55, rx: -0.3 },
|
|
172
|
+
shoulderR: { rz: 1.55, rx: -0.3 },
|
|
173
|
+
foreL: { rx: -0.35 },
|
|
174
|
+
foreR: { rx: -0.35 },
|
|
175
|
+
},
|
|
176
|
+
/* fists pumping overhead, ears spinning */
|
|
177
|
+
celebrating: {
|
|
178
|
+
shoulderL: { rz: [-2.55, 0.28, 4, 0] },
|
|
179
|
+
shoulderR: { rz: [2.55, 0.28, 4, Math.PI] },
|
|
180
|
+
foreL: { rz: [0.2, 0.4, 8, 0] },
|
|
181
|
+
foreR: { rz: [-0.2, 0.4, 8, Math.PI] },
|
|
182
|
+
earL: { rx: [0, 0, 0, 0, 12] },
|
|
183
|
+
earR: { rx: [0, 0, 0, 0, -12] },
|
|
184
|
+
},
|
|
185
|
+
/* arms hanging, a little behind the body */
|
|
186
|
+
sad: {
|
|
187
|
+
shoulderL: { rz: 0.04, rx: 0.22 },
|
|
188
|
+
shoulderR: { rz: -0.04, rx: 0.22 },
|
|
189
|
+
foreL: { rx: -0.05 },
|
|
190
|
+
foreR: { rx: -0.05 },
|
|
191
|
+
},
|
|
192
|
+
/* both arms up, claws waving */
|
|
193
|
+
happy: {
|
|
194
|
+
shoulderL: { rz: [-2.5, 0.22, 2.2, 0] },
|
|
195
|
+
foreL: { rz: [0.1, 0.5, 4.2, 0] },
|
|
196
|
+
shoulderR: { rz: [2.5, 0.22, 2.2, 1.5] },
|
|
197
|
+
foreR: { rz: [-0.1, 0.5, 4.2, 2] },
|
|
198
|
+
earL: { rx: [0, 0, 0, 0, 10] },
|
|
199
|
+
earR: { rx: [0, 0, 0, 0, -10] },
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
fx: {
|
|
203
|
+
replace: ['syllable'],
|
|
204
|
+
/* sound comes out of the sides of the screen */
|
|
205
|
+
syllable: [{ glyph: 'arc', anchor: 'mouth', rate: 2, offset: [0.5, 0.1, -0.1], mirror: true, velocity: [0.26, 0.02, 0.02], jitter: 0.02, life: [0.55, 0.7], size: [0.04, 0.1], rotation: 0, color: '#6aaee6' }],
|
|
206
|
+
/* signal rings off the antenna while it thinks and listens */
|
|
207
|
+
thinking: [{ glyph: 'ring', anchor: 'antenna', rate: 1.3, velocity: [0, 0.02, 0], life: [0.9, 1.1], size: [0.03, 0.17], color: '#ffb347', glow: true }],
|
|
208
|
+
listening: [{ glyph: 'ring', anchor: 'antenna', rate: 1.1, velocity: [0, 0, 0], life: [1, 1.2], size: [0.2, 0.03], color: '#62e39a', glow: true }],
|
|
209
|
+
land: [{ glyph: 'spark', anchor: 'feet', rate: 6, spread: 0.12, velocity: [0, 0.6, 0], jitter: 1.1, gravity: 3, life: [0.25, 0.42], size: [0.035, 0.02], color: '#ffd27a', glow: true, align: true }],
|
|
210
|
+
'enter:happy': [{ glyph: 'spark', anchor: 'antenna', rate: 8, velocity: [0, 0.5, 0], jitter: 1.4, gravity: 2, life: [0.3, 0.5], size: [0.04, 0.02], color: '#ffe08a', glow: true, align: true }],
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export default volt;
|