-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzine-runtime-utils.js
112 lines (105 loc) · 3.07 KB
/
zine-runtime-utils.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
import * as THREE from 'three';
import {
entranceExitWidth,
entranceExitHeight,
entranceExitDepth,
} from '../zine/zine-constants.js';
//
const localMatrix = new THREE.Matrix4();
//
export const getCapsuleIntersectionIndex = (
entranceExitLocations,
matrixWorld,
position,
capsuleRadius,
capsuleHeight
) => {
for (let i = 0; i < entranceExitLocations.length; i++) {
const eel = entranceExitLocations[i];
const boxQuaternion = new THREE.Quaternion().fromArray(eel.quaternion);
const boxPosition = new THREE.Vector3().fromArray(eel.position)
.add(new THREE.Vector3(0, entranceExitHeight / 2, entranceExitDepth / 2).applyQuaternion(
boxQuaternion
));
const boxSize = new THREE.Vector3(entranceExitWidth, entranceExitHeight, entranceExitDepth);
localMatrix.compose(
boxPosition,
boxQuaternion,
boxSize
).premultiply(matrixWorld).decompose(
boxPosition,
boxQuaternion,
boxSize
);
const capsulePosition = position.clone().add(
new THREE.Vector3(0, -capsuleHeight / 2, 0)
);
if (capsuleIntersectsBox(
capsulePosition,
capsuleRadius,
capsuleHeight,
boxPosition,
boxQuaternion,
boxSize,
)) {
return i;
}
}
return -1;
};
// note: total height of the capsule is capsuleHeight + 2 * capsuleRadius
// the capsule is vertical, with capsulePosition in the center
// the distance from the center to the top and bottom is capsuleHeight / 2 + capsuleRadius
// check whether the given capsule intersects the given transformed box
export function capsuleIntersectsBox(
capsulePosition,
capsuleRadius,
capsuleHeight,
boxPosition,
boxQuaternion,
boxSize
) {
// first, transform the capsule line into the box's local space
const capsuleLine = new THREE.Line3(
capsulePosition.clone().add(
new THREE.Vector3(0, capsuleHeight / 2 + capsuleRadius, 0)
),
capsulePosition.clone().add(
new THREE.Vector3(0, -capsuleHeight / 2 - capsuleRadius, 0)
)
);
capsuleLine.start.sub(boxPosition).applyQuaternion(boxQuaternion.clone().invert());
capsuleLine.end.sub(boxPosition).applyQuaternion(boxQuaternion.clone().invert());
// then, get the intersection in the box's local space
return capsuleIntersectsAABB(
capsuleLine,
capsuleRadius,
boxSize
);
}
function capsuleIntersectsAABB(capsuleLine, capsuleRadius, boxSize) {
const closestPointToCenter = capsuleLine.closestPointToPoint(
new THREE.Vector3(0, 0, 0),
true,
new THREE.Vector3()
);
if (
Math.abs(closestPointToCenter.x) <= boxSize.x / 2 + capsuleRadius &&
Math.abs(closestPointToCenter.y) <= boxSize.y / 2 + capsuleRadius &&
Math.abs(closestPointToCenter.z) <= boxSize.z / 2 + capsuleRadius
) {
return true;
} else {
return false;
}
}
export function makePromise() {
let resolve, reject;
const p = new Promise((a, r) => {
resolve = a;
reject = r;
});
p.resolve = resolve;
p.reject = reject;
return p;
}