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
|
/* global AFRAME, THREE */
// The world: a plain, brightly lit white room with a small table in the middle,
// for trying things out. The chess board on the table is its own entity
// (chess.js); its reset buttons and resetChess() are passed through here.
(function () {
const ROOM = { half: 4, height: 3 }; // 8 × 8 m, 3 m tall
const TABLE = { half: 0.4, height: 0.75, top: 0.04, leg: 0.05 };
const MARGIN = 0.25; // how close your head gets to a wall
const LEAN = 0.08; // and to the table, so you can reach across it
AFRAME.registerComponent('testroom', {
init() {
this.group = new THREE.Group();
this.el.setObject3D('mesh', this.group);
this.seats = [];
this.spawn = { x: 0, z: 2.5, yaw: 0 };
this.screen = { x: 0, y: 1.55, z: -3.85, yaw: 0, width: 3 }; // against the far wall
// Child entities start first, so the board is there already.
const chess = this.chess();
this.touchables = chess ? chess.touchables : [];
const white = new THREE.MeshLambertMaterial({ color: '#ffffff', side: THREE.BackSide });
const room = new THREE.Mesh(new THREE.BoxGeometry(ROOM.half * 2, ROOM.height, ROOM.half * 2), white);
room.position.y = ROOM.height / 2;
this.group.add(room);
const wood = new THREE.MeshLambertMaterial({ color: '#b08a60' });
const top = new THREE.Mesh(new THREE.BoxGeometry(TABLE.half * 2, TABLE.top, TABLE.half * 2), wood);
top.position.y = TABLE.height - TABLE.top / 2;
this.group.add(top);
const legHeight = TABLE.height - TABLE.top;
const legGeometry = new THREE.BoxGeometry(TABLE.leg, legHeight, TABLE.leg);
const inset = TABLE.half - TABLE.leg;
for (const [x, z] of [[-1, -1], [1, -1], [-1, 1], [1, 1]]) {
const leg = new THREE.Mesh(legGeometry, wood);
leg.position.set(x * inset, legHeight / 2, z * inset);
this.group.add(leg);
}
},
chess() {
const el = this.el.querySelector('[chess]');
return el && el.components.chess;
},
resetChess() {
const chess = this.chess();
if (chess) chess.resetChess();
},
remove() {
this.group.traverse((o) => {
if (o.geometry) o.geometry.dispose();
if (o.material) o.material.dispose();
});
this.el.removeObject3D('mesh');
},
// Keeps a head position inside the walls and out of the table.
confine(p) {
const wall = ROOM.half - MARGIN;
p.x = Math.min(wall, Math.max(-wall, p.x));
p.z = Math.min(wall, Math.max(-wall, p.z));
const t = TABLE.half + LEAN;
if (Math.abs(p.x) < t && Math.abs(p.z) < t) {
if (Math.abs(p.x) > Math.abs(p.z)) p.x = Math.sign(p.x) * t;
else p.z = (Math.sign(p.z) || 1) * t;
}
return p;
},
});
})();
|