wobnimo 0.1.4 → 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 +1 -1
- package/dist/element.js +9 -9
- package/dist/index-Cm5wWKoT.d.ts +12 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -6
- package/dist/react.js +16 -16
- package/dist/wobnimo.js +12 -12
- package/package.json +14 -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/index-DRDEWSGV.d.ts +0 -8
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { CharacterSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A chubby panda. */
|
|
4
|
+
export const bao: CharacterSpec = {
|
|
5
|
+
id: 'bao',
|
|
6
|
+
name: 'Bao',
|
|
7
|
+
tagline: 'A chubby panda cub: round ears, eye patches, and a belly made for sitting',
|
|
8
|
+
accent: '#2f3b4c',
|
|
9
|
+
frame: { target: 0.46, radius: 0.62 },
|
|
10
|
+
bound: { y: 0.45, radius: 0.57 },
|
|
11
|
+
motion: { hop: 0.1, squash: 1.2, snap: 0.9, talkSquash: 0.4 },
|
|
12
|
+
materials: {
|
|
13
|
+
white: { color: '#f6f3ec', f0: 0.03, spec: 0.4, shininess: 20, rim: 1, sheen: 0.6, surface: { kind: 'fur', scale: 100, strength: 0.3, bone: 'head' } },
|
|
14
|
+
whiteBody: { color: '#f6f3ec', shadeOf: 'white', f0: 0.03, spec: 0.4, shininess: 20, rim: 1, sheen: 0.6, surface: { kind: 'fur', scale: 100, strength: 0.3 } },
|
|
15
|
+
black: { color: '#26252b', f0: 0.03, spec: 0.4, shininess: 20, rim: 0.9, sheen: 0.6, surface: { kind: 'fur', scale: 100, strength: 0.3 } },
|
|
16
|
+
nose: { color: '#1b1a1f', f0: 0.06, spec: 1.8, shininess: 200, rim: 0.3, gloss: 0.9 },
|
|
17
|
+
},
|
|
18
|
+
bones: [
|
|
19
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.2]], rz: [['roll', 0.35]] }, wave: { rz: [0.02, 0.5, 0] } },
|
|
20
|
+
{ name: 'head', parent: 'body', pivot: [0, 0.48, 0.02], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.8]], rz: [['roll', 0.7]] } },
|
|
21
|
+
{ name: 'armL', parent: 'body', pivot: [-0.22, 0.38, 0.06], rest: { rz: -0.4 }, drive: { rz: [['flap', -1]] } },
|
|
22
|
+
{ name: 'armR', parent: 'body', pivot: [0.22, 0.38, 0.06], rest: { rz: 0.4 }, drive: { rz: [['flap', 1]] } },
|
|
23
|
+
],
|
|
24
|
+
parts: [
|
|
25
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.26, 0], radii: [0.29, 0.27, 0.26], material: 'whiteBody' },
|
|
26
|
+
/* sitting legs, black, out front */
|
|
27
|
+
{ bone: 'body', shape: 'ellipsoid', at: [-0.15, 0.08, 0.14], radii: [0.1, 0.08, 0.12], blend: 0.05, material: 'black' },
|
|
28
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0.15, 0.08, 0.14], radii: [0.1, 0.08, 0.12], blend: 0.05, material: 'black' },
|
|
29
|
+
/* a black band over the shoulders */
|
|
30
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.42, -0.01], radii: [0.27, 0.07, 0.24], blend: 0.05, material: 'black' },
|
|
31
|
+
{ bone: 'armL', shape: 'capsule', from: [0, 0, 0], to: [-0.04, -0.16, 0.06], radius: 0.07, blend: 0.04, material: 'black' },
|
|
32
|
+
{ bone: 'armR', shape: 'capsule', from: [0, 0, 0], to: [0.04, -0.16, 0.06], radius: 0.07, blend: 0.04, material: 'black' },
|
|
33
|
+
/* a big round head and round ears */
|
|
34
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.14, 0], radii: [0.28, 0.24, 0.24], blend: 0.1, material: 'white' },
|
|
35
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.06, 0.18], radii: [0.1, 0.07, 0.08], blend: 0.06, material: 'white' },
|
|
36
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.09, 0.26], radii: [0.035, 0.022, 0.02], material: 'nose' },
|
|
37
|
+
{ bone: 'head', shape: 'sphere', at: [-0.2, 0.33, -0.02], radius: 0.075, blend: 0.03, material: 'black' },
|
|
38
|
+
{ bone: 'head', shape: 'sphere', at: [0.2, 0.33, -0.02], radius: 0.075, blend: 0.03, material: 'black' },
|
|
39
|
+
],
|
|
40
|
+
paints: [
|
|
41
|
+
/* droopy eye patches */
|
|
42
|
+
{ bone: 'head', on: ['white'], kind: 'ellipse', at: [-0.1, 0.15, 0.2], radii: [0.06, 0.08], color: '#26252b', soft: 0.2 },
|
|
43
|
+
{ bone: 'head', on: ['white'], kind: 'ellipse', at: [0.1, 0.15, 0.2], radii: [0.06, 0.08], color: '#26252b', soft: 0.2 },
|
|
44
|
+
{ bone: 'head', on: ['white'], kind: 'sphere', at: [-0.17, 0.05, 0.18], radius: 0.04, color: '#ffb3c1', soft: 0.6, opacity: 0.7 },
|
|
45
|
+
{ bone: 'head', on: ['white'], kind: 'sphere', at: [0.17, 0.05, 0.18], radius: 0.04, color: '#ffb3c1', soft: 0.6, opacity: 0.7 },
|
|
46
|
+
],
|
|
47
|
+
eyes: { kind: 'ball', bone: 'head', at: [[-0.095, 0.16, 0.21], [0.095, 0.16, 0.21]], radius: 0.04, iris: '#3a2a20', irisSize: 0.7, pupilSize: 0.5, lid: 'black' },
|
|
48
|
+
face: { kind: 'mouth', bone: 'head', on: ['white'], at: [0, 0.035, 0.25], width: 0.04, color: '#26252b', tongue: '#ff8fa3' },
|
|
49
|
+
anchors: {
|
|
50
|
+
top: { bone: 'head', at: [0.15, 0.45, 0.05] },
|
|
51
|
+
mouth: { bone: 'head', at: [0, 0.035, 0.27] },
|
|
52
|
+
ear: { bone: 'head', at: [-0.22, 0.33, 0] },
|
|
53
|
+
feet: { bone: 'root', at: [0, 0.02, 0.18] },
|
|
54
|
+
},
|
|
55
|
+
acting: {
|
|
56
|
+
idle: { armL: { rz: [0, 0.05, 0.5, 0] } },
|
|
57
|
+
thinking: { armR: { rz: 1.5, rx: -1.2, ry: -0.4 }, head: { rz: 0.1 } },
|
|
58
|
+
listening: { armL: { rz: -0.6, rx: -0.4 } },
|
|
59
|
+
speaking: { armL: { rz: [-0.2, 0.2, 1.2, 0] }, armR: { rz: [0.2, 0.2, 1.2, 1.4] } },
|
|
60
|
+
sleeping: { head: { rx: 0.25, rz: 0.15 } },
|
|
61
|
+
working: { armL: { rx: [-0.8, 0.2, 5, 0] }, armR: { rx: [-0.8, 0.2, 5, Math.PI] } },
|
|
62
|
+
error: { armL: { rz: -1.6, rx: -0.6 }, armR: { rz: 1.6, rx: -0.6 } },
|
|
63
|
+
surprised: { armL: { rz: -1.1 }, armR: { rz: 1.1 } },
|
|
64
|
+
celebrating: { armL: { rz: [-2.2, 0.3, 4, 0] }, armR: { rz: [2.2, 0.3, 4, Math.PI] } },
|
|
65
|
+
sad: { head: { rx: 0.3 }, armL: { rz: 0.1 }, armR: { rz: -0.1 } },
|
|
66
|
+
happy: { armL: { rz: [-1.5, 0.3, 3, 0] }, armR: { rz: [1.5, 0.3, 3, 1] } },
|
|
67
|
+
},
|
|
68
|
+
fx: {
|
|
69
|
+
happy: [{ glyph: 'heart', anchor: 'top', rate: 1.2, velocity: [0, 0.22, 0.04], jitter: 0.1, life: [1, 1.3], size: [0.04, 0.06], color: '#ff86b0' }],
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default bao;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { CharacterSpec, PaintSpec, PartSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A strawberry with a leafy hat. */
|
|
4
|
+
export const berry: CharacterSpec = {
|
|
5
|
+
id: 'berry',
|
|
6
|
+
name: 'Berry',
|
|
7
|
+
tagline: 'A plump strawberry with golden seeds and a leafy hat with a stalk on top',
|
|
8
|
+
accent: '#e8324f',
|
|
9
|
+
frame: { target: 0.43, radius: 0.57 },
|
|
10
|
+
bound: { y: 0.41, radius: 0.5 },
|
|
11
|
+
motion: { hop: 0.15, squash: 1.3, snap: 1.1, talkSquash: 0.5 },
|
|
12
|
+
materials: {
|
|
13
|
+
berry: { color: '#e8324f', f0: 0.07, spec: 1.6, shininess: 130, rim: 0.6, sss: 0.35, sssColor: '#ff7d8f', gloss: 0.8 },
|
|
14
|
+
leaf: { color: '#3fa34d', f0: 0.04, spec: 0.7, shininess: 50, rim: 0.6, sss: 0.25, sssColor: '#b8f0a0' },
|
|
15
|
+
bead: { color: '#1a1012', f0: 0.06, spec: 2.2, shininess: 400, rim: 0.2, gloss: 1 },
|
|
16
|
+
},
|
|
17
|
+
bones: [
|
|
18
|
+
{ name: 'body', pivot: [0, -0.042, 0], drive: { rx: [['pitch', -0.4]], ry: [['yaw', 0.6]], rz: [['roll', 0.5]] } },
|
|
19
|
+
{ name: 'hat', parent: 'body', pivot: [0, 0.73, 0], jiggle: { axis: [0, 1, 0], length: 0.12, freq: 3.2, damping: 0.16, maxAngle: 0.5 } },
|
|
20
|
+
],
|
|
21
|
+
parts: [
|
|
22
|
+
/* a rounded heart-shaped berry: wide at the shoulders, a soft point at the bottom */
|
|
23
|
+
{ bone: 'body', shape: 'roundCone', from: [0, 0.2, 0], to: [0, 0.48, 0], r1: 0.17, r2: 0.3, material: 'berry' },
|
|
24
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.5, 0], radii: [0.3, 0.2, 0.28], blend: 0.08, material: 'berry' },
|
|
25
|
+
/* five leaves splayed over the shoulders, and a stalk */
|
|
26
|
+
...[0, 1, 2, 3, 4].map((i): PartSpec => {
|
|
27
|
+
const a = (i / 5) * Math.PI * 2 + 0.3;
|
|
28
|
+
return { bone: 'hat', shape: 'ellipsoid', at: [Math.sin(a) * 0.15, -0.005, Math.cos(a) * 0.15], rot: [0.5, a, 0], radii: [0.075, 0.024, 0.15], blend: 0.02, material: 'leaf' };
|
|
29
|
+
}),
|
|
30
|
+
{ bone: 'hat', shape: 'capsule', from: [0, 0, 0], to: [0.02, 0.1, 0], radius: 0.022, blend: 0.03, material: 'leaf' },
|
|
31
|
+
],
|
|
32
|
+
paints: [
|
|
33
|
+
/* golden seeds spiralled evenly over the skin, skipping the face; each sits exactly on the surface */
|
|
34
|
+
...([
|
|
35
|
+
[0, 0.2, 0.192],
|
|
36
|
+
[0.133, 0.21, -0.145],
|
|
37
|
+
[-0.202, 0.22, 0.018],
|
|
38
|
+
[0.165, 0.229, 0.126],
|
|
39
|
+
[-0.037, 0.239, -0.209],
|
|
40
|
+
[-0.117, 0.249, 0.184],
|
|
41
|
+
[0.215, 0.259, -0.058],
|
|
42
|
+
[-0.202, 0.268, -0.105],
|
|
43
|
+
[0.08, 0.278, 0.219],
|
|
44
|
+
[0.091, 0.288, -0.22],
|
|
45
|
+
[-0.221, 0.298, 0.103],
|
|
46
|
+
[0.238, 0.308, 0.075],
|
|
47
|
+
[-0.128, 0.317, -0.22],
|
|
48
|
+
[-0.056, 0.327, 0.254],
|
|
49
|
+
[0.218, 0.337, -0.154],
|
|
50
|
+
[-0.272, 0.347, -0.035],
|
|
51
|
+
[0.012, 0.366, -0.281],
|
|
52
|
+
[-0.203, 0.376, 0.204],
|
|
53
|
+
[0.294, 0.386, -0.014],
|
|
54
|
+
[-0.227, 0.396, -0.19],
|
|
55
|
+
[0.172, 0.415, -0.248],
|
|
56
|
+
[-0.301, 0.425, 0.068],
|
|
57
|
+
[0.269, 0.435, 0.154],
|
|
58
|
+
[-0.093, 0.444, -0.293],
|
|
59
|
+
[0.292, 0.464, -0.122],
|
|
60
|
+
[-0.299, 0.474, -0.108],
|
|
61
|
+
[0.079, 0.493, -0.301],
|
|
62
|
+
[-0.266, 0.503, 0.171],
|
|
63
|
+
[0.314, 0.513, 0.054],
|
|
64
|
+
[-0.191, 0.523, -0.247],
|
|
65
|
+
[0.227, 0.542, -0.21],
|
|
66
|
+
[-0.312, 0.552, 0.001],
|
|
67
|
+
[0.225, 0.562, 0.205],
|
|
68
|
+
[-0.027, 0.572, -0.296],
|
|
69
|
+
[0.291, 0.591, -0.053],
|
|
70
|
+
[-0.245, 0.601, -0.154],
|
|
71
|
+
[0.074, 0.611, 0.27],
|
|
72
|
+
[0.126, 0.62, -0.245],
|
|
73
|
+
[-0.256, 0.63, 0.095],
|
|
74
|
+
[0.246, 0.64, 0.1]
|
|
75
|
+
] as const).map(([x, y, z]): PaintSpec => ({ bone: 'body', on: ['berry'], kind: 'sphere', at: [x, y, z], radius: 0.022, color: '#ffd166', soft: 0.2 })),
|
|
76
|
+
{ bone: 'body', on: ['berry'], kind: 'sphere', at: [-0.16, 0.42, 0.25], radius: 0.05, color: '#ff9ab0', soft: 0.6, opacity: 0.6 },
|
|
77
|
+
{ bone: 'body', on: ['berry'], kind: 'sphere', at: [0.16, 0.42, 0.25], radius: 0.05, color: '#ff9ab0', soft: 0.6, opacity: 0.6 },
|
|
78
|
+
],
|
|
79
|
+
eyes: { kind: 'bead', bone: 'body', at: [[-0.09, 0.5, 0.3], [0.09, 0.5, 0.3]], radii: [0.03, 0.045, 0.02], material: 'bead' },
|
|
80
|
+
face: { kind: 'mouth', bone: 'body', on: ['berry'], at: [0, 0.41, 0.3], width: 0.045, color: '#5a1020', tongue: '#ff8fa3' },
|
|
81
|
+
anchors: {
|
|
82
|
+
top: { bone: 'hat', at: [0.06, 0.16, 0] },
|
|
83
|
+
mouth: { bone: 'body', at: [0, 0.41, 0.31] },
|
|
84
|
+
ear: { bone: 'body', at: [-0.3, 0.5, 0] },
|
|
85
|
+
feet: { bone: 'root', at: [0, 0.02, 0.12] },
|
|
86
|
+
},
|
|
87
|
+
acting: {
|
|
88
|
+
thinking: { hat: { rz: 0.3 } },
|
|
89
|
+
sleeping: { hat: { rz: 0.4, rx: 0.2 } },
|
|
90
|
+
error: { hat: { rz: [0, 0.3, 9, 0] } },
|
|
91
|
+
celebrating: { hat: { ry: [0, 0, 0, 0, 10] } },
|
|
92
|
+
sad: { hat: { rx: 0.4, rz: 0.3 } },
|
|
93
|
+
happy: { hat: { ry: [0, 0, 0, 0, 14] } },
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export default berry;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { CharacterSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A floating ghost with a rippling hem and little arms. */
|
|
4
|
+
export const boo: CharacterSpec = {
|
|
5
|
+
id: 'boo',
|
|
6
|
+
name: 'Boo',
|
|
7
|
+
tagline: 'Floats, glows from inside, trails motes, a hem that ripples',
|
|
8
|
+
accent: '#8a6cf0',
|
|
9
|
+
frame: { target: 0.78, radius: 0.92 },
|
|
10
|
+
bound: { y: 0.72, radius: 0.72 },
|
|
11
|
+
motion: { float: 0.22, hop: 0.12, squash: 0.8, snap: 0.8, talkSquash: 0.6 },
|
|
12
|
+
glowPool: 0.55,
|
|
13
|
+
materials: {
|
|
14
|
+
ghost: { color: '#eceaff', f0: 0.04, spec: 0.5, shininess: 30, rim: 1.4, sss: 0.4, sssColor: '#b9a4ff', emit: '#6f52d9', emitStrength: 0.06 },
|
|
15
|
+
bead: { color: '#1b1430', f0: 0.06, spec: 2.2, shininess: 400, rim: 0.2, gloss: 1 },
|
|
16
|
+
},
|
|
17
|
+
bones: [
|
|
18
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { rx: [['pitch', -0.5]], ry: [['yaw', 0.7]], rz: [['roll', 0.6]] }, wave: { rz: [0.03, 0.45, 0] } },
|
|
19
|
+
{
|
|
20
|
+
name: 'armL', parent: 'body', pivot: [-0.36, 0.74, 0.04],
|
|
21
|
+
drive: { rz: [['flap', -1.2]] }, wave: { rz: [0.08, 0.7, 0] },
|
|
22
|
+
jiggle: { axis: [-0.8, -0.6, 0], length: 0.15, freq: 2, damping: 0.2, maxAngle: 0.7 },
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'armR', parent: 'body', pivot: [0.36, 0.74, 0.04],
|
|
26
|
+
drive: { rz: [['flap', 1.2]] }, wave: { rz: [-0.08, 0.7, 1.6] },
|
|
27
|
+
jiggle: { axis: [0.8, -0.6, 0], length: 0.15, freq: 2, damping: 0.2, maxAngle: 0.7 },
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
parts: [
|
|
31
|
+
{ bone: 'body', shape: 'sphere', at: [0, 0.88, 0], radius: 0.4, material: 'ghost' },
|
|
32
|
+
{ bone: 'body', shape: 'roundCone', from: [0, 0.88, 0], to: [0, 0.4, 0], r1: 0.4, r2: 0.47, material: 'ghost' },
|
|
33
|
+
{ bone: 'body', shape: 'hem', y: 0.34, amplitude: 0.045, waves: 6, speed: 2.4, blend: 0.05, material: 'ghost' },
|
|
34
|
+
{ bone: 'armL', shape: 'capsule', from: [0, 0, 0], to: [-0.12, -0.09, 0.02], radius: 0.07, blend: 0.08, material: 'ghost' },
|
|
35
|
+
{ bone: 'armR', shape: 'capsule', from: [0, 0, 0], to: [0.12, -0.09, 0.02], radius: 0.07, blend: 0.08, material: 'ghost' },
|
|
36
|
+
],
|
|
37
|
+
paints: [
|
|
38
|
+
{ bone: 'body', on: ['ghost'], kind: 'sphere', at: [-0.24, 0.78, 0.31], radius: 0.07, color: '#ffa3c4', soft: 0.6, opacity: 0.7 },
|
|
39
|
+
{ bone: 'body', on: ['ghost'], kind: 'sphere', at: [0.24, 0.78, 0.31], radius: 0.07, color: '#ffa3c4', soft: 0.6, opacity: 0.7 },
|
|
40
|
+
],
|
|
41
|
+
eyes: {
|
|
42
|
+
kind: 'bead',
|
|
43
|
+
bone: 'body',
|
|
44
|
+
at: [[-0.135, 0.9, 0.375], [0.135, 0.9, 0.375]],
|
|
45
|
+
radii: [0.048, 0.072, 0.03],
|
|
46
|
+
material: 'bead',
|
|
47
|
+
},
|
|
48
|
+
face: {
|
|
49
|
+
kind: 'mouth',
|
|
50
|
+
bone: 'body',
|
|
51
|
+
on: ['ghost'],
|
|
52
|
+
at: [0, 0.77, 0.38],
|
|
53
|
+
width: 0.075,
|
|
54
|
+
color: '#2a1a4a',
|
|
55
|
+
tongue: '#ff7fa6',
|
|
56
|
+
},
|
|
57
|
+
anchors: {
|
|
58
|
+
top: { bone: 'body', at: [0.16, 1.2, 0.1] },
|
|
59
|
+
mouth: { bone: 'body', at: [0, 0.77, 0.4] },
|
|
60
|
+
ear: { bone: 'body', at: [-0.42, 0.92, 0] },
|
|
61
|
+
center: { bone: 'body', at: [0, 0.8, 0] },
|
|
62
|
+
},
|
|
63
|
+
acting: {
|
|
64
|
+
idle: { armL: { rz: [0, 0.1, 0.7, 0] }, armR: { rz: [0, 0.1, 0.7, 1.3] } },
|
|
65
|
+
thinking: { armR: { ry: -1.1, rz: 0.9 }, armL: { rz: 0.25 } },
|
|
66
|
+
listening: { armL: { rz: -1, rx: -0.35 } },
|
|
67
|
+
speaking: {
|
|
68
|
+
armL: { rz: [-0.3, 0.3, 1.2, 0], rx: [-0.3, 0.2, 0.9, 0] },
|
|
69
|
+
armR: { rz: [0.3, 0.3, 1.2, 1.7], rx: [-0.3, 0.2, 0.9, 2.2] },
|
|
70
|
+
},
|
|
71
|
+
sleeping: { armL: { rz: 0.4 }, armR: { rz: -0.4 }, body: { rz: 0.08 } },
|
|
72
|
+
working: { armL: { rx: [-0.6, 0.15, 6, 0], rz: -0.3 }, armR: { rx: [-0.6, 0.15, 6, Math.PI], rz: 0.3 } },
|
|
73
|
+
error: { armL: { rz: [-1.0, 0.25, 10, 0] }, armR: { rz: [1.0, 0.25, 10, 1] } },
|
|
74
|
+
/* hands to its cheeks */
|
|
75
|
+
surprised: { armL: { rz: -1.4, rx: -0.4 }, armR: { rz: 1.4, rx: -0.4 } },
|
|
76
|
+
celebrating: { armL: { rz: [-1.6, 0.3, 4, 0] }, armR: { rz: [1.6, 0.3, 4, Math.PI] } },
|
|
77
|
+
sad: { armL: { rz: 0.5 }, armR: { rz: -0.5 }, body: { rz: 0.05 } },
|
|
78
|
+
happy: { armL: { rz: [-1.3, 0.35, 3, 0] }, armR: { rz: [1.3, 0.35, 3, 1.2] } },
|
|
79
|
+
},
|
|
80
|
+
fx: {
|
|
81
|
+
/* glowing motes drift around it all the time */
|
|
82
|
+
ambient: [{ glyph: 'mote', anchor: 'center', rate: 1.3, spread: 0.5, velocity: [0, 0.07, 0], jitter: 0.06, wobble: 0.09, life: [2.2, 3.2], size: [0.04, 0.02], color: '#b49cff', glow: true }],
|
|
83
|
+
happy: [{ glyph: 'heart', anchor: 'top', rate: 1.2, spread: 0.2, velocity: [0, 0.22, 0.05], jitter: 0.12, wobble: 0.06, life: [1, 1.3], size: [0.04, 0.07], color: '#ff86b0' }],
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default boo;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { CharacterSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A round bumblebee with tiny wings. */
|
|
4
|
+
export const bumble: CharacterSpec = {
|
|
5
|
+
id: 'bumble',
|
|
6
|
+
name: 'Bumble',
|
|
7
|
+
tagline: 'A fuzzy round bumblebee that hovers on wings far too small for it',
|
|
8
|
+
accent: '#f5b700',
|
|
9
|
+
frame: { target: 0.61, radius: 0.81 },
|
|
10
|
+
bound: { y: 0.5, radius: 0.62 },
|
|
11
|
+
motion: { float: 0.2, hop: 0.08, squash: 1, snap: 1.2, talkSquash: 0.5 },
|
|
12
|
+
materials: {
|
|
13
|
+
fuzz: {
|
|
14
|
+
color: '#ffc21a', f0: 0.03, spec: 0.4, shininess: 20, rim: 1.1, sheen: 0.8,
|
|
15
|
+
surface: { kind: 'fur', scale: 110, strength: 0.4, bone: 'body' },
|
|
16
|
+
},
|
|
17
|
+
stripe: { color: '#2b2118', f0: 0.03, spec: 0.4, shininess: 20, rim: 0.8, sheen: 0.6 },
|
|
18
|
+
wing: { color: '#e8f6ff', f0: 0.1, spec: 1.8, shininess: 200, rim: 1.4, sss: 0.6, sssColor: '#ffffff', gloss: 0.9 },
|
|
19
|
+
feeler: { color: '#2b2118', f0: 0.04, spec: 0.8, shininess: 60, rim: 0.5 },
|
|
20
|
+
},
|
|
21
|
+
bones: [
|
|
22
|
+
{ name: 'body', pivot: [0, 0.4, 0], drive: { rx: [['pitch', -0.4]], ry: [['yaw', 0.7]], rz: [['roll', 0.6]] }, wave: { rx: [0.03, 0.8, 0] } },
|
|
23
|
+
/* wings buzz all the time */
|
|
24
|
+
{ name: 'wingL', parent: 'body', pivot: [-0.12, 0.3, -0.18], rest: { rz: 0.5, rx: -0.3 }, wave: { rz: [0.35, 14, 0] } },
|
|
25
|
+
{ name: 'wingR', parent: 'body', pivot: [0.12, 0.3, -0.18], rest: { rz: -0.5, rx: -0.3 }, wave: { rz: [-0.35, 14, 0] } },
|
|
26
|
+
{ name: 'feelerL', parent: 'body', pivot: [-0.08, 0.36, 0.1], rest: { rz: 0.35 }, jiggle: { axis: [0, 1, 0], length: 0.14, freq: 3, damping: 0.12 } },
|
|
27
|
+
{ name: 'feelerR', parent: 'body', pivot: [0.08, 0.36, 0.1], rest: { rz: -0.35 }, jiggle: { axis: [0, 1, 0], length: 0.14, freq: 3, damping: 0.12 } },
|
|
28
|
+
],
|
|
29
|
+
parts: [
|
|
30
|
+
{ bone: 'body', shape: 'sphere', at: [0, 0, 0], radius: 0.36, material: 'fuzz' },
|
|
31
|
+
/* a little stinger at the back */
|
|
32
|
+
{ bone: 'body', shape: 'roundCone', from: [0, -0.05, -0.33], to: [0, -0.08, -0.45], r1: 0.05, r2: 0.01, blend: 0.03, material: 'stripe' },
|
|
33
|
+
{ bone: 'wingL', shape: 'ellipsoid', at: [-0.1, 0.1, 0], rot: [0, 0, 0.5], radii: [0.12, 0.17, 0.012], material: 'wing' },
|
|
34
|
+
{ bone: 'wingR', shape: 'ellipsoid', at: [0.1, 0.1, 0], rot: [0, 0, -0.5], radii: [0.12, 0.17, 0.012], material: 'wing' },
|
|
35
|
+
{ bone: 'feelerL', shape: 'capsule', from: [0, 0, 0], to: [0, 0.14, 0.02], radius: 0.012, material: 'feeler' },
|
|
36
|
+
{ bone: 'feelerL', shape: 'sphere', at: [0, 0.15, 0.02], radius: 0.03, material: 'feeler' },
|
|
37
|
+
{ bone: 'feelerR', shape: 'capsule', from: [0, 0, 0], to: [0, 0.14, 0.02], radius: 0.012, material: 'feeler' },
|
|
38
|
+
{ bone: 'feelerR', shape: 'sphere', at: [0, 0.15, 0.02], radius: 0.03, material: 'feeler' },
|
|
39
|
+
],
|
|
40
|
+
paints: [
|
|
41
|
+
/* two dark bands around the lower body, made from big soft-edged spheres below it */
|
|
42
|
+
{ bone: 'body', on: ['fuzz'], kind: 'sphere', at: [0, -1.04, 0], radius: 0.9, color: '#2b2118', soft: 0.03 },
|
|
43
|
+
{ bone: 'body', on: ['fuzz'], kind: 'sphere', at: [0, -1.15, 0], radius: 0.9, color: '#ffc21a', soft: 0.03 },
|
|
44
|
+
{ bone: 'body', on: ['fuzz'], kind: 'sphere', at: [0, -1.25, 0], radius: 0.9, color: '#2b2118', soft: 0.03 },
|
|
45
|
+
{ bone: 'body', on: ['fuzz'], kind: 'sphere', at: [0, 0.98, 0], radius: 0.7, color: '#2b2118', soft: 0.04 },
|
|
46
|
+
{ bone: 'body', on: ['fuzz'], kind: 'sphere', at: [-0.2, -0.05, 0.27], radius: 0.06, color: '#ff8a6a', soft: 0.6, opacity: 0.7 },
|
|
47
|
+
{ bone: 'body', on: ['fuzz'], kind: 'sphere', at: [0.2, -0.05, 0.27], radius: 0.06, color: '#ff8a6a', soft: 0.6, opacity: 0.7 },
|
|
48
|
+
],
|
|
49
|
+
eyes: { kind: 'ball', bone: 'body', at: [[-0.12, 0.06, 0.3], [0.12, 0.06, 0.3]], radius: 0.065, iris: '#20160e', irisSize: 0.85, pupilSize: 0.55, lid: 'fuzz' },
|
|
50
|
+
face: { kind: 'mouth', bone: 'body', on: ['fuzz'], at: [0, -0.08, 0.35], width: 0.05, color: '#3a2412', tongue: '#ff7d6e' },
|
|
51
|
+
anchors: {
|
|
52
|
+
top: { bone: 'body', at: [0.12, 0.5, 0.05] },
|
|
53
|
+
mouth: { bone: 'body', at: [0, -0.08, 0.37] },
|
|
54
|
+
ear: { bone: 'body', at: [-0.36, 0.05, 0] },
|
|
55
|
+
center: { bone: 'body', at: [0, 0, 0] },
|
|
56
|
+
},
|
|
57
|
+
acting: {
|
|
58
|
+
thinking: { feelerL: { rz: 0.6 }, feelerR: { rz: -0.1 } },
|
|
59
|
+
listening: { feelerL: { rx: -0.4 }, feelerR: { rx: -0.4 } },
|
|
60
|
+
sleeping: { wingL: { rz: 0.9 }, wingR: { rz: -0.9 }, feelerL: { rx: 0.6 }, feelerR: { rx: 0.6 } },
|
|
61
|
+
error: { feelerL: { rz: [0.4, 0.3, 9, 0] }, feelerR: { rz: [-0.4, 0.3, 9, 1] } },
|
|
62
|
+
surprised: { feelerL: { rz: 0.1, rx: -0.3 }, feelerR: { rz: -0.1, rx: -0.3 } },
|
|
63
|
+
sad: { feelerL: { rx: 0.9 }, feelerR: { rx: 0.9 } },
|
|
64
|
+
},
|
|
65
|
+
fx: {
|
|
66
|
+
happy: [{ glyph: 'sparkle', anchor: 'top', rate: 2, velocity: [0, 0.2, 0.05], jitter: 0.15, life: [0.8, 1.1], size: [0.04, 0.02], color: '#ffd84d', glow: true }],
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default bumble;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CharacterSpec, PartSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A tiny potted cactus with a pink flower on its head. */
|
|
4
|
+
export const cacti: CharacterSpec = {
|
|
5
|
+
id: 'cacti',
|
|
6
|
+
name: 'Cacti',
|
|
7
|
+
tagline: 'A tiny potted cactus with a pink flower that bounces on its head',
|
|
8
|
+
accent: '#3fae6a',
|
|
9
|
+
frame: { target: 0.52, radius: 0.69 },
|
|
10
|
+
bound: { y: 0.52, radius: 0.61 },
|
|
11
|
+
motion: { hop: 0.08, squash: 0.9, snap: 1, talkSquash: 0.5 },
|
|
12
|
+
materials: {
|
|
13
|
+
cactus: {
|
|
14
|
+
color: '#4cb873', f0: 0.04, spec: 0.8, shininess: 60, rim: 0.8, sss: 0.2, sssColor: '#a8f0b0', gloss: 0.4,
|
|
15
|
+
surface: { kind: 'speckle', scale: 30, strength: 0.4, color: '#2f8a52', bone: 'body' },
|
|
16
|
+
},
|
|
17
|
+
pot: { color: '#d9774a', f0: 0.03, spec: 0.4, shininess: 25, rim: 0.4 },
|
|
18
|
+
rim: { color: '#e88a5c', shadeOf: 'pot', f0: 0.03, spec: 0.4, shininess: 25, rim: 0.4 },
|
|
19
|
+
soil: { color: '#5b3a28', f0: 0.02, spec: 0.1, shininess: 8, rim: 0.2 },
|
|
20
|
+
petal: { color: '#ff7eb6', f0: 0.04, spec: 0.6, shininess: 40, rim: 0.7, sss: 0.4, sssColor: '#ffc1dc', sheen: 0.4 },
|
|
21
|
+
pollen: { color: '#ffd84d', f0: 0.04, spec: 0.5, shininess: 30, rim: 0.4 },
|
|
22
|
+
bead: { color: '#141a14', f0: 0.06, spec: 2.2, shininess: 400, rim: 0.2, gloss: 1 },
|
|
23
|
+
},
|
|
24
|
+
bones: [
|
|
25
|
+
{ name: 'body', pivot: [0, 0.32, 0], drive: { rx: [['pitch', -0.3]], ry: [['yaw', 0.5]], rz: [['roll', 0.5]] }, wave: { rz: [0.025, 0.5, 0] } },
|
|
26
|
+
{ name: 'armL', parent: 'body', pivot: [-0.2, 0.25, 0], rest: { rz: 0.3 }, drive: { rz: [['flap', -0.8]] } },
|
|
27
|
+
{ name: 'armR', parent: 'body', pivot: [0.2, 0.18, 0], rest: { rz: -0.2 }, drive: { rz: [['flap', 0.8]] } },
|
|
28
|
+
{ name: 'flower', parent: 'body', pivot: [0.04, 0.56, 0], jiggle: { axis: [0, 1, 0], length: 0.1, freq: 3, damping: 0.14 } },
|
|
29
|
+
],
|
|
30
|
+
parts: [
|
|
31
|
+
/* a terracotta pot with a fat rim */
|
|
32
|
+
{ bone: 'root', shape: 'roundCone', from: [0, 0.03, 0], to: [0, 0.27, 0], r1: 0.2, r2: 0.25, clip: { normal: [0, -1, 0] }, material: 'pot' },
|
|
33
|
+
{ bone: 'root', shape: 'cylinder', at: [0, 0.3, 0], radius: 0.28, half: 0.05, round: 0.03, material: 'rim' },
|
|
34
|
+
{ bone: 'root', shape: 'cylinder', at: [0, 0.33, 0], radius: 0.24, half: 0.025, round: 0.01, material: 'soil' },
|
|
35
|
+
/* the cactus: a tall rounded body */
|
|
36
|
+
{ bone: 'body', shape: 'capsule', from: [0, 0.05, 0], to: [0, 0.38, 0], radius: 0.2, material: 'cactus' },
|
|
37
|
+
/* little arms */
|
|
38
|
+
{ bone: 'armL', shape: 'capsule', from: [0, 0, 0], to: [-0.1, 0, 0], radius: 0.065, blend: 0.04, material: 'cactus' },
|
|
39
|
+
{ bone: 'armL', shape: 'capsule', from: [-0.1, 0, 0], to: [-0.11, 0.12, 0], radius: 0.06, blend: 0.03, material: 'cactus' },
|
|
40
|
+
{ bone: 'armR', shape: 'capsule', from: [0, 0, 0], to: [0.1, 0, 0], radius: 0.06, blend: 0.04, material: 'cactus' },
|
|
41
|
+
{ bone: 'armR', shape: 'capsule', from: [0.1, 0, 0], to: [0.11, 0.1, 0], radius: 0.055, blend: 0.03, material: 'cactus' },
|
|
42
|
+
/* a five-petal flower */
|
|
43
|
+
...[0, 1, 2, 3, 4].map((i): PartSpec => {
|
|
44
|
+
const a = (i / 5) * Math.PI * 2;
|
|
45
|
+
return { bone: 'flower', shape: 'ellipsoid', at: [Math.cos(a) * 0.055, 0.03, Math.sin(a) * 0.055], rot: [0, -a, 0.4], radii: [0.055, 0.02, 0.035], blend: 0.01, material: 'petal' };
|
|
46
|
+
}),
|
|
47
|
+
{ bone: 'flower', shape: 'sphere', at: [0, 0.045, 0], radius: 0.03, material: 'pollen' },
|
|
48
|
+
],
|
|
49
|
+
paints: [
|
|
50
|
+
{ bone: 'body', on: ['cactus'], kind: 'sphere', at: [-0.13, 0.2, 0.16], radius: 0.045, color: '#ff8fb4', soft: 0.6, opacity: 0.7 },
|
|
51
|
+
{ bone: 'body', on: ['cactus'], kind: 'sphere', at: [0.13, 0.2, 0.16], radius: 0.045, color: '#ff8fb4', soft: 0.6, opacity: 0.7 },
|
|
52
|
+
],
|
|
53
|
+
eyes: { kind: 'bead', bone: 'body', at: [[-0.08, 0.27, 0.185], [0.08, 0.27, 0.185]], radii: [0.03, 0.045, 0.02], material: 'bead' },
|
|
54
|
+
face: { kind: 'mouth', bone: 'body', on: ['cactus'], at: [0, 0.19, 0.2], width: 0.045, color: '#173a24', tongue: '#ff7d97' },
|
|
55
|
+
anchors: {
|
|
56
|
+
top: { bone: 'flower', at: [0, 0.1, 0] },
|
|
57
|
+
mouth: { bone: 'body', at: [0, 0.19, 0.22] },
|
|
58
|
+
ear: { bone: 'body', at: [-0.22, 0.3, 0] },
|
|
59
|
+
feet: { bone: 'root', at: [0, 0.02, 0.15] },
|
|
60
|
+
},
|
|
61
|
+
acting: {
|
|
62
|
+
idle: { armL: { rz: [0, 0.08, 0.6, 0] } },
|
|
63
|
+
thinking: { armR: { rz: 0.9, rx: -0.5 }, flower: { rz: 0.2 } },
|
|
64
|
+
listening: { armL: { rz: -0.4 }, flower: { rz: -0.15 } },
|
|
65
|
+
speaking: { armL: { rz: [-0.2, 0.25, 1.4, 0] }, armR: { rz: [0.2, 0.25, 1.4, 1.5] } },
|
|
66
|
+
sleeping: { flower: { rz: 0.6, rx: 0.4 }, body: { rz: 0.08 } },
|
|
67
|
+
working: { armL: { rz: [-0.4, 0.2, 5, 0] }, armR: { rz: [0.4, 0.2, 5, Math.PI] } },
|
|
68
|
+
error: { armL: { rz: -1 }, armR: { rz: 1 }, flower: { rz: [0, 0.3, 10, 0] } },
|
|
69
|
+
surprised: { armL: { rz: -0.9 }, armR: { rz: 0.9 } },
|
|
70
|
+
celebrating: { armL: { rz: [-0.9, 0.3, 4, 0] }, armR: { rz: [0.9, 0.3, 4, Math.PI] }, flower: { ry: [0, 0, 0, 0, 10] } },
|
|
71
|
+
sad: { flower: { rx: 0.9, rz: 0.4 }, armL: { rz: 0.4 }, armR: { rz: -0.3 } },
|
|
72
|
+
happy: { flower: { ry: [0, 0, 0, 0, 12] } },
|
|
73
|
+
},
|
|
74
|
+
fx: {
|
|
75
|
+
happy: [{ glyph: 'heart', anchor: 'top', rate: 1.2, velocity: [0, 0.22, 0.04], jitter: 0.1, life: [1, 1.3], size: [0.04, 0.06], color: '#ff7eb6' }],
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export default cacti;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { CharacterSpec, PaintSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A red mushroom with white spots. */
|
|
4
|
+
export const cap: CharacterSpec = {
|
|
5
|
+
id: 'cap',
|
|
6
|
+
name: 'Cap',
|
|
7
|
+
tagline: 'A little toadstool with a glossy red cap that wobbles when it walks',
|
|
8
|
+
accent: '#e0393e',
|
|
9
|
+
frame: { target: 0.4, radius: 0.59 },
|
|
10
|
+
bound: { y: 0.39, radius: 0.5 },
|
|
11
|
+
motion: { hop: 0.12, squash: 1.2, snap: 1, talkSquash: 0.5 },
|
|
12
|
+
materials: {
|
|
13
|
+
cap: { color: '#e53935', f0: 0.06, spec: 1.5, shininess: 120, rim: 0.6, gloss: 0.75, sss: 0.15, sssColor: '#ff8a80' },
|
|
14
|
+
gills: { color: '#efe2cf', f0: 0.02, spec: 0.2, shininess: 10, rim: 0.3 },
|
|
15
|
+
stem: { color: '#fbf3e4', f0: 0.03, spec: 0.5, shininess: 30, rim: 0.6, sss: 0.3, sssColor: '#fff8ec' },
|
|
16
|
+
bead: { color: '#1a1414', f0: 0.06, spec: 2.2, shininess: 400, rim: 0.2, gloss: 1 },
|
|
17
|
+
},
|
|
18
|
+
bones: [
|
|
19
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { rx: [['pitch', -0.3]], ry: [['yaw', 0.5]], rz: [['roll', 0.4]] } },
|
|
20
|
+
{ name: 'cap', parent: 'body', pivot: [0, 0.42, 0], drive: { rx: [['pitch', -0.4]], rz: [['roll', 0.5]] }, jiggle: { axis: [0, 1, 0], length: 0.2, freq: 2.6, damping: 0.18, maxAngle: 0.3 } },
|
|
21
|
+
],
|
|
22
|
+
parts: [
|
|
23
|
+
/* a chubby stem the face lives on */
|
|
24
|
+
{ bone: 'body', shape: 'roundCone', from: [0, 0.12, 0], to: [0, 0.4, 0], r1: 0.2, r2: 0.16, clip: { normal: [0, -1, 0] }, material: 'stem' },
|
|
25
|
+
/* a dome cap with a soft underside */
|
|
26
|
+
{ bone: 'cap', shape: 'ellipsoid', at: [0, 0.06, 0], radii: [0.42, 0.28, 0.42], clip: { normal: [0, -1, 0], offset: 0.02 }, material: 'cap' },
|
|
27
|
+
{ bone: 'cap', shape: 'ellipsoid', at: [0, 0.05, 0], radii: [0.4, 0.04, 0.4], blend: 0.03, material: 'gills' },
|
|
28
|
+
],
|
|
29
|
+
paints: [
|
|
30
|
+
/* white spots, scattered over the cap */
|
|
31
|
+
...([[0, 0.33, 0.05, 0.08], [-0.22, 0.24, 0.2, 0.07], [0.24, 0.22, 0.2, 0.065], [-0.08, 0.2, 0.33, 0.055], [0.12, 0.3, -0.18, 0.07], [-0.341, 0.196, -0.136, 0.06], [0.38, 0.173, -0.058, 0.05]] as const).map(
|
|
32
|
+
([x, y, z, r]): PaintSpec => ({ bone: 'cap', on: ['cap'], kind: 'sphere', at: [x, y, z], radius: r, color: '#fff8ee', soft: 0.12 }),
|
|
33
|
+
),
|
|
34
|
+
{ bone: 'body', on: ['stem'], kind: 'sphere', at: [-0.13, 0.22, 0.14], radius: 0.045, color: '#ff9eb0', soft: 0.6, opacity: 0.8 },
|
|
35
|
+
{ bone: 'body', on: ['stem'], kind: 'sphere', at: [0.13, 0.22, 0.14], radius: 0.045, color: '#ff9eb0', soft: 0.6, opacity: 0.8 },
|
|
36
|
+
],
|
|
37
|
+
eyes: { kind: 'bead', bone: 'body', at: [[-0.07, 0.29, 0.165], [0.07, 0.29, 0.165]], radii: [0.028, 0.042, 0.018], material: 'bead' },
|
|
38
|
+
face: { kind: 'mouth', bone: 'body', on: ['stem'], at: [0, 0.21, 0.19], width: 0.04, color: '#4a2a22', tongue: '#ff7d97' },
|
|
39
|
+
anchors: {
|
|
40
|
+
top: { bone: 'cap', at: [0.1, 0.38, 0] },
|
|
41
|
+
mouth: { bone: 'body', at: [0, 0.21, 0.21] },
|
|
42
|
+
ear: { bone: 'body', at: [-0.2, 0.3, 0] },
|
|
43
|
+
feet: { bone: 'root', at: [0, 0.02, 0.15] },
|
|
44
|
+
},
|
|
45
|
+
acting: {
|
|
46
|
+
thinking: { cap: { rz: 0.15 } },
|
|
47
|
+
sleeping: { cap: { rx: 0.2, rz: 0.15 } },
|
|
48
|
+
error: { cap: { rz: [0, 0.12, 9, 0] } },
|
|
49
|
+
surprised: { cap: { rx: -0.15 } },
|
|
50
|
+
sad: { cap: { rx: 0.3 } },
|
|
51
|
+
celebrating: { cap: { rz: [0, 0.15, 4, 0] } },
|
|
52
|
+
},
|
|
53
|
+
fx: {
|
|
54
|
+
/* puffs of spores when it lands */
|
|
55
|
+
land: [{ glyph: 'mote', anchor: 'top', rate: 6, spread: 0.2, velocity: [0, 0.2, 0], jitter: 0.2, wobble: 0.08, life: [1, 1.5], size: [0.025, 0.01], color: '#ffe8a3', glow: true }],
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default cap;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { CharacterSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A sleepy cloud in brand blue, wearing big headphones. */
|
|
4
|
+
export const drift: CharacterSpec = {
|
|
5
|
+
id: 'drift',
|
|
6
|
+
name: 'Drift',
|
|
7
|
+
tagline: 'A sleepy blue cloud that floats along to the music in its headphones',
|
|
8
|
+
accent: '#4f7cff',
|
|
9
|
+
frame: { target: 0.63, radius: 0.84 },
|
|
10
|
+
bound: { y: 0.6, radius: 0.69 },
|
|
11
|
+
motion: { float: 0.18, hop: 0.1, squash: 1.3, snap: 0.75, talkSquash: 0.8 },
|
|
12
|
+
materials: {
|
|
13
|
+
cloud: { color: '#9db8ff', f0: 0.03, spec: 0.35, shininess: 20, rim: 1.1, sss: 0.55, sssColor: '#dbe6ff', sheen: 0.3 },
|
|
14
|
+
band: { color: '#20253a', f0: 0.06, spec: 1.4, shininess: 120, rim: 0.4, gloss: 0.7 },
|
|
15
|
+
cup: { color: '#4f7cff', f0: 0.08, spec: 1.6, shininess: 160, rim: 0.5, gloss: 0.8 },
|
|
16
|
+
cushion: { color: '#2a2f45', f0: 0.03, spec: 0.3, shininess: 20, rim: 0.3, sheen: 0.6 },
|
|
17
|
+
},
|
|
18
|
+
bones: [
|
|
19
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { rx: [['pitch', -0.4]], ry: [['yaw', 0.6]], rz: [['roll', 0.7]] }, wave: { rz: [0.04, 0.35, 0] } },
|
|
20
|
+
/* the head bobs to the beat on its own */
|
|
21
|
+
{ name: 'phones', parent: 'body', pivot: [0, 0.55, 0], wave: { rz: [0.03, 1.1, 0] } },
|
|
22
|
+
],
|
|
23
|
+
parts: [
|
|
24
|
+
/* a cluster of puffs melted together, flatter underneath */
|
|
25
|
+
{ bone: 'body', shape: 'sphere', at: [0, 0.52, 0], radius: 0.32, material: 'cloud' },
|
|
26
|
+
{ bone: 'body', shape: 'sphere', at: [-0.3, 0.42, 0], radius: 0.22, blend: 0.12, material: 'cloud' },
|
|
27
|
+
{ bone: 'body', shape: 'sphere', at: [0.31, 0.43, 0], radius: 0.23, blend: 0.12, material: 'cloud' },
|
|
28
|
+
{ bone: 'body', shape: 'sphere', at: [-0.14, 0.72, -0.03], radius: 0.2, blend: 0.12, material: 'cloud' },
|
|
29
|
+
{ bone: 'body', shape: 'sphere', at: [0.16, 0.74, -0.04], radius: 0.22, blend: 0.12, material: 'cloud' },
|
|
30
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.34, 0], radii: [0.5, 0.12, 0.3], blend: 0.1, material: 'cloud' },
|
|
31
|
+
/* headphones: a band over the top, a cup and cushion on each side */
|
|
32
|
+
{ bone: 'phones', shape: 'capsule', from: [-0.47, 0.0, 0], to: [-0.4, 0.26, 0], radius: 0.028, material: 'band' },
|
|
33
|
+
{ bone: 'phones', shape: 'capsule', from: [-0.4, 0.26, 0], to: [-0.18, 0.42, 0], radius: 0.028, blend: 0.02, material: 'band' },
|
|
34
|
+
{ bone: 'phones', shape: 'capsule', from: [-0.18, 0.42, 0], to: [0.18, 0.42, 0], radius: 0.028, blend: 0.02, material: 'band' },
|
|
35
|
+
{ bone: 'phones', shape: 'capsule', from: [0.18, 0.42, 0], to: [0.4, 0.26, 0], radius: 0.028, blend: 0.02, material: 'band' },
|
|
36
|
+
{ bone: 'phones', shape: 'capsule', from: [0.4, 0.26, 0], to: [0.47, 0.0, 0], radius: 0.028, material: 'band' },
|
|
37
|
+
{ bone: 'phones', shape: 'cylinder', at: [-0.5, -0.04, 0], rot: [0, 0, Math.PI / 2], radius: 0.12, half: 0.05, round: 0.025, material: 'cup' },
|
|
38
|
+
{ bone: 'phones', shape: 'cylinder', at: [0.5, -0.04, 0], rot: [0, 0, Math.PI / 2], radius: 0.12, half: 0.05, round: 0.025, material: 'cup' },
|
|
39
|
+
{ bone: 'phones', shape: 'cylinder', at: [-0.44, -0.04, 0], rot: [0, 0, Math.PI / 2], radius: 0.1, half: 0.025, round: 0.02, material: 'cushion' },
|
|
40
|
+
{ bone: 'phones', shape: 'cylinder', at: [0.44, -0.04, 0], rot: [0, 0, Math.PI / 2], radius: 0.1, half: 0.025, round: 0.02, material: 'cushion' },
|
|
41
|
+
],
|
|
42
|
+
paints: [
|
|
43
|
+
{ bone: 'body', on: ['cloud'], kind: 'sphere', at: [-0.2, 0.46, 0.27], radius: 0.06, color: '#ff9ec4', soft: 0.6, opacity: 0.75 },
|
|
44
|
+
{ bone: 'body', on: ['cloud'], kind: 'sphere', at: [0.2, 0.46, 0.27], radius: 0.06, color: '#ff9ec4', soft: 0.6, opacity: 0.75 },
|
|
45
|
+
],
|
|
46
|
+
eyes: {
|
|
47
|
+
kind: 'ball', bone: 'body', at: [[-0.11, 0.56, 0.27], [0.11, 0.56, 0.27]],
|
|
48
|
+
radius: 0.05, iris: '#1d2550', irisSize: 0.8, pupilSize: 0.5, lid: 'cloud',
|
|
49
|
+
},
|
|
50
|
+
face: { kind: 'mouth', bone: 'body', on: ['cloud'], at: [0, 0.45, 0.31], width: 0.06, color: '#24305e', tongue: '#ff8fae' },
|
|
51
|
+
anchors: {
|
|
52
|
+
top: { bone: 'body', at: [0.18, 0.98, 0.05] },
|
|
53
|
+
mouth: { bone: 'body', at: [0, 0.45, 0.33] },
|
|
54
|
+
ear: { bone: 'phones', at: [-0.56, -0.04, 0] },
|
|
55
|
+
center: { bone: 'body', at: [0, 0.5, 0] },
|
|
56
|
+
},
|
|
57
|
+
acting: {
|
|
58
|
+
idle: { phones: { rz: [0, 0.04, 1.6, 0] } },
|
|
59
|
+
thinking: { phones: { rz: 0.12 }, body: { rz: 0.06 } },
|
|
60
|
+
listening: { phones: { rz: -0.12 } },
|
|
61
|
+
speaking: { phones: { rz: [0, 0.05, 2.2, 0] } },
|
|
62
|
+
sleeping: { phones: { rz: 0.18 }, body: { rz: 0.1 } },
|
|
63
|
+
working: { phones: { rz: [0, 0.06, 3.2, 0] } },
|
|
64
|
+
celebrating: { phones: { rz: [0, 0.12, 3, 0] } },
|
|
65
|
+
sad: { phones: { rz: -0.1 }, body: { rx: 0.1 } },
|
|
66
|
+
},
|
|
67
|
+
fx: {
|
|
68
|
+
/* music notes float out of the cups while it's idle */
|
|
69
|
+
idle: [{ glyph: 'note', anchor: 'ear', rate: 0.6, velocity: [-0.12, 0.25, 0.04], jitter: 0.08, wobble: 0.05, life: [1.4, 1.8], size: [0.05, 0.03], color: '#4f7cff' }],
|
|
70
|
+
sleeping: [{ glyph: 'cloud', anchor: 'top', rate: 0.5, velocity: [0.05, 0.12, 0], jitter: 0.04, life: [2, 2.5], size: [0.04, 0.08], color: '#dbe6ff' }],
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default drift;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { CharacterSpec } from 'wobnimo';
|
|
2
|
+
|
|
3
|
+
/** A fox cub with a big fluffy tail. */
|
|
4
|
+
export const ember: CharacterSpec = {
|
|
5
|
+
id: 'ember',
|
|
6
|
+
name: 'Ember',
|
|
7
|
+
tagline: 'A fox cub with pointed ears and a big fluffy tail that never stops swishing',
|
|
8
|
+
accent: '#f07a2a',
|
|
9
|
+
frame: { target: 0.48, radius: 0.72 },
|
|
10
|
+
bound: { y: 0.38, radius: 0.85 },
|
|
11
|
+
motion: { hop: 0.14, squash: 1, snap: 1.1, talkSquash: 0.4 },
|
|
12
|
+
materials: {
|
|
13
|
+
fur: { color: '#f07a2a', f0: 0.03, spec: 0.4, shininess: 20, rim: 1, sheen: 0.7, surface: { kind: 'fur', scale: 90, strength: 0.4, bone: 'head' } },
|
|
14
|
+
bodyFur: { color: '#f07a2a', shadeOf: 'fur', f0: 0.03, spec: 0.4, shininess: 20, rim: 1, sheen: 0.7, surface: { kind: 'fur', scale: 90, strength: 0.4 } },
|
|
15
|
+
tailFur: { color: '#f07a2a', shadeOf: 'fur', f0: 0.03, spec: 0.4, shininess: 20, rim: 1, sheen: 0.8, surface: { kind: 'fur', scale: 70, strength: 0.5, bone: 'tail' } },
|
|
16
|
+
dark: { color: '#3a2318', f0: 0.03, spec: 0.4, shininess: 20, rim: 0.6, sheen: 0.5 },
|
|
17
|
+
nose: { color: '#1d1410', f0: 0.06, spec: 1.8, shininess: 200, rim: 0.3, gloss: 0.9 },
|
|
18
|
+
},
|
|
19
|
+
bones: [
|
|
20
|
+
{ name: 'body', pivot: [0, 0, 0], drive: { ry: [['yaw', 0.2]], rz: [['roll', 0.3]] } },
|
|
21
|
+
{ name: 'head', parent: 'body', pivot: [0, 0.48, 0.02], drive: { rx: [['pitch', -1]], ry: [['yaw', 0.8]], rz: [['roll', 0.7]] } },
|
|
22
|
+
{ name: 'earL', parent: 'head', pivot: [-0.14, 0.28, 0], rest: { rz: 0.3 }, jiggle: { axis: [0, 1, 0], length: 0.16, freq: 3.5, damping: 0.2, maxAngle: 0.4 } },
|
|
23
|
+
{ name: 'earR', parent: 'head', pivot: [0.14, 0.28, 0], rest: { rz: -0.3 }, jiggle: { axis: [0, 1, 0], length: 0.16, freq: 3.5, damping: 0.2, maxAngle: 0.4 } },
|
|
24
|
+
{ name: 'tail', parent: 'body', pivot: [0.15, 0.12, -0.15], rest: { rz: -0.9, rx: -0.4 }, wave: { ry: [0.35, 0.8, 0] }, jiggle: { axis: [0, 1, 0], length: 0.35, freq: 1.8, damping: 0.18, maxAngle: 0.6 } },
|
|
25
|
+
],
|
|
26
|
+
parts: [
|
|
27
|
+
{ bone: 'body', shape: 'ellipsoid', at: [0, 0.25, 0], radii: [0.22, 0.25, 0.2], material: 'bodyFur' },
|
|
28
|
+
/* little legs */
|
|
29
|
+
{ bone: 'body', shape: 'capsule', from: [-0.1, 0.12, 0.08], to: [-0.1, 0.04, 0.12], radius: 0.06, blend: 0.05, material: 'dark' },
|
|
30
|
+
{ bone: 'body', shape: 'capsule', from: [0.1, 0.12, 0.08], to: [0.1, 0.04, 0.12], radius: 0.06, blend: 0.05, material: 'dark' },
|
|
31
|
+
/* a wide head with a pointed muzzle and cheek fluff */
|
|
32
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0, 0.12, 0], radii: [0.27, 0.22, 0.23], blend: 0.1, material: 'fur' },
|
|
33
|
+
{ bone: 'head', shape: 'roundCone', from: [0, 0.07, 0.1], to: [0, 0.05, 0.3], r1: 0.12, r2: 0.04, blend: 0.08, material: 'fur' },
|
|
34
|
+
{ bone: 'head', shape: 'sphere', at: [0, 0.06, 0.33], radius: 0.035, material: 'nose' },
|
|
35
|
+
{ bone: 'head', shape: 'ellipsoid', at: [-0.22, 0.02, 0.06], radii: [0.09, 0.07, 0.08], blend: 0.06, material: 'fur' },
|
|
36
|
+
{ bone: 'head', shape: 'ellipsoid', at: [0.22, 0.02, 0.06], radii: [0.09, 0.07, 0.08], blend: 0.06, material: 'fur' },
|
|
37
|
+
/* tall pointed ears with dark tips */
|
|
38
|
+
{ bone: 'earL', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.18, 0], r1: 0.08, r2: 0.015, material: 'fur' },
|
|
39
|
+
{ bone: 'earR', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.18, 0], r1: 0.08, r2: 0.015, material: 'fur' },
|
|
40
|
+
/* the tail: a big plume */
|
|
41
|
+
{ bone: 'tail', shape: 'roundCone', from: [0, 0, 0], to: [0, 0.3, 0], r1: 0.06, r2: 0.13, material: 'tailFur' },
|
|
42
|
+
{ bone: 'tail', shape: 'sphere', at: [0, 0.36, 0], radius: 0.11, blend: 0.08, material: 'tailFur' },
|
|
43
|
+
],
|
|
44
|
+
paints: [
|
|
45
|
+
{ bone: 'body', on: ['bodyFur'], kind: 'ellipse', at: [0, 0.26, 0.1], radii: [0.13, 0.17], color: '#fff3e6', soft: 0.25 },
|
|
46
|
+
{ bone: 'head', on: ['fur'], kind: 'sphere', at: [0, 0.0, 0.25], radius: 0.13, color: '#fff3e6', soft: 0.25 },
|
|
47
|
+
{ bone: 'head', on: ['fur'], kind: 'sphere', at: [-0.2, -0.02, 0.12], radius: 0.1, color: '#fff3e6', soft: 0.3 },
|
|
48
|
+
{ bone: 'head', on: ['fur'], kind: 'sphere', at: [0.2, -0.02, 0.12], radius: 0.1, color: '#fff3e6', soft: 0.3 },
|
|
49
|
+
{ bone: 'earL', on: ['fur'], kind: 'sphere', at: [0, 0.2, 0], radius: 0.07, color: '#3a2318', soft: 0.3 },
|
|
50
|
+
{ bone: 'earR', on: ['fur'], kind: 'sphere', at: [0, 0.2, 0], radius: 0.07, color: '#3a2318', soft: 0.3 },
|
|
51
|
+
{ bone: 'earL', on: ['fur'], kind: 'ellipse', at: [0, 0.07, 0.05], radii: [0.035, 0.07], color: '#ffd9c2', soft: 0.4 },
|
|
52
|
+
{ bone: 'earR', on: ['fur'], kind: 'ellipse', at: [0, 0.07, 0.05], radii: [0.035, 0.07], color: '#ffd9c2', soft: 0.4 },
|
|
53
|
+
{ bone: 'tail', on: ['tailFur'], kind: 'sphere', at: [0, 0.46, 0], radius: 0.13, color: '#fff3e6', soft: 0.2 },
|
|
54
|
+
],
|
|
55
|
+
eyes: { kind: 'ball', bone: 'head', at: [[-0.1, 0.15, 0.19], [0.1, 0.15, 0.19]], radius: 0.055, iris: '#2b1a10', irisSize: 0.82, pupilSize: 0.52, lid: 'fur' },
|
|
56
|
+
face: { kind: 'mouth', bone: 'head', on: ['fur'], at: [0, 0, 0.277], width: 0.045, color: '#3a2318', tongue: '#ff7d8a' },
|
|
57
|
+
anchors: {
|
|
58
|
+
top: { bone: 'head', at: [0.12, 0.45, 0.05] },
|
|
59
|
+
mouth: { bone: 'head', at: [0, 0.0, 0.33] },
|
|
60
|
+
ear: { bone: 'earL', at: [0, 0.1, 0] },
|
|
61
|
+
feet: { bone: 'root', at: [0, 0.02, 0.12] },
|
|
62
|
+
},
|
|
63
|
+
acting: {
|
|
64
|
+
idle: { tail: { ry: [0, 0.2, 0.7, 0] } },
|
|
65
|
+
thinking: { earL: { rz: 0.6 }, head: { rz: 0.12 } },
|
|
66
|
+
listening: { earL: { rx: -0.3 }, earR: { rx: -0.3 } },
|
|
67
|
+
speaking: { tail: { ry: [0, 0.3, 1.5, 0] } },
|
|
68
|
+
sleeping: { earL: { rz: 0.8 }, earR: { rz: -0.8 }, tail: { rz: -1.4 } },
|
|
69
|
+
working: { tail: { ry: [0, 0.4, 3, 0] } },
|
|
70
|
+
error: { earL: { rz: 1.1 }, earR: { rz: -1.1 } },
|
|
71
|
+
surprised: { earL: { rz: 0.05 }, earR: { rz: -0.05 }, tail: { rx: -0.8 } },
|
|
72
|
+
celebrating: { tail: { ry: [0, 0.6, 5, 0] } },
|
|
73
|
+
sad: { earL: { rz: 1, rx: 0.4 }, earR: { rz: -1, rx: 0.4 }, tail: { rz: -1.1 } },
|
|
74
|
+
happy: { tail: { ry: [0, 0.6, 6, 0] } },
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default ember;
|