-
Notifications
You must be signed in to change notification settings - Fork 0
/
body-model.js
114 lines (98 loc) · 2.68 KB
/
body-model.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
class BodyModel extends HTMLElement {
connectedCallback() {
this.update = fill(this)
this.update()
}
disconnectedCallback() {
this.innerHTML = ''
}
get paramPath() { return [] }
}
const {random: num} = Math
const True = () => 'true'
const False = () => 'false'
const Bool = (p=0.5) => (t=True, f=False) => num() < p ? t() : f()
const bool = Bool()
const Vec = size => (element=num) => () => `[${
new Array(size).fill(0)
.map(() => element())
.join(', ')
}]`
const Enum = (...cases) => () => cases[Math.floor(cases.length * num())]
const vec4 = Vec(4)()
const vec2 = Vec(2)()
const mat4 = Vec(4)(vec4)
const mat8_2 = Vec(8)(vec2)
const params = {
l: {
upper_arm_pos: vec4,
forearm_pos: vec4,
hand_pos: vec4,
finger_pos: mat4,
arm_pos: vec4,
armpit_touch_pts: mat8_2,
upper_leg_pos: vec4,
lower_leg_pos: vec4,
knee_angle: num,
knee_skew: num,
foot_pos: vec4,
toe_pos: mat4,
},
torso_rot: vec2,
r: {
upper_arm_pos: vec4,
forearm_pos: vec4,
hand_pos: vec4,
finger_pos: mat4,
arm_pos: vec4,
armpit_touch_pts: mat8_2,
upper_leg_pos: vec4,
lower_leg_pos: vec4,
knee_angle: num,
knee_skew: num,
foot_pos: vec4,
toe_pos: mat4,
},
stomach_acid: num,
__deprecated_appendix_t: num,
is_hungry: bool,
last_thought_about_breakup_t: num,
}
const tag = name => (attrs={}, ...children) => {
const e = document.createElement(name)
Object.entries(attrs)
.forEach(([attr, value]) => e.setAttribute(attr, value))
children.forEach(child => {
if (typeof child === 'string') {
e.appendChild(document.createTextNode(child))
return
}
e.appendChild(child)
})
return e
}
const span = tag('span')
const wipe = Enum('wipe-north-south', 'wipe-east-west', 'wipe-west-east', 'wipe-south-north')
const paramElement = param => span({id: `${param}_param`, class: `param ${param} ${wipe()}`}, param, ':')
const valueElement = param => span({id: `${param}_value`, class: `value ${param} ${wipe()}`})
const fill = (parent, p=params) => {
const children = Object.entries(p)
.map(([param, gen]) => {
const child = span()
const paramPath = parent.paramPath.concat(param)
const path = paramPath.join('_')
parent.appendChild(child)
const p = paramElement(path)
const v = valueElement(path)
v.paramPath = paramPath
child.appendChild(p)
child.appendChild(v)
child.id = path
if (typeof gen === 'function') {
return child.update = () => v.textContent = gen()
}
return child.update = fill(v, gen)
})
return () => children.forEach(x => x())
}
customElements.define('body-model', BodyModel)