-
Notifications
You must be signed in to change notification settings - Fork 20
/
CulledMesher.js
59 lines (53 loc) · 2.46 KB
/
CulledMesher.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
export class CulledMesher {
constructor()
{
}
//Naive meshing (with face culling)
mesh(volume, dims)
{
//Precalculate direction vectors for convenience
var dir = new Array(3)
for (var i = 0; i < 3; ++i) {
dir[i] = [[0, 0, 0], [0, 0, 0]]
dir[i][0][(i + 1) % 3] = 1
dir[i][1][(i + 2) % 3] = 1
}
//March over the volume
var vertices = []
, faces = []
, x = [0, 0, 0]
, B = [[false, true] //Incrementally update bounds (this is a bit ugly)
, [false, true]
, [false, true]]
, n = -dims[0] * dims[1]
for (B[2] = [false, true], x[2] = -1; x[2] < dims[2]; B[2] = [true, (++x[2] < dims[2] - 1)])
for (n -= dims[0], B[1] = [false, true], x[1] = -1; x[1] < dims[1]; B[1] = [true, (++x[1] < dims[1] - 1)])
for (n -= 1, B[0] = [false, true], x[0] = -1; x[0] < dims[0]; B[0] = [true, (++x[0] < dims[0] - 1)], ++n) {
//Read current voxel and 3 neighboring voxels using bounds check results
var p = (B[0][0] && B[1][0] && B[2][0]) ? volume[n] : 0
, b = [(B[0][1] && B[1][0] && B[2][0]) ? volume[n + 1] : 0
, (B[0][0] && B[1][1] && B[2][0]) ? volume[n + dims[0]] : 0
, (B[0][0] && B[1][0] && B[2][1]) ? volume[n + dims[0] * dims[1]] : 0
]
//Generate faces
for (var d = 0; d < 3; ++d)
if ((!!p) !== (!!b[d])) {
var s = !p ? 1 : 0
var t = [x[0], x[1], x[2]]
, u = dir[d][s]
, v = dir[d][s ^ 1]
++t[d]
var vertex_count = vertices.length
vertices.push([t[0], t[1], t[2]])
vertices.push([t[0] + u[0], t[1] + u[1], t[2] + u[2]])
vertices.push([t[0] + u[0] + v[0], t[1] + u[1] + v[1], t[2] + u[2] + v[2]])
vertices.push([t[0] + v[0], t[1] + v[1], t[2] + v[2]])
faces.push([vertex_count, vertex_count + 1, vertex_count + 2, vertex_count + 3, s ? b[d] : p])
}
}
return {vertices: vertices, faces: faces}
}
}
// if(exports) {
// exports.mesher = CulledMesh;
// }