forked from michaljaz/webmc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChunkTerrain.js
More file actions
121 lines (107 loc) · 2.93 KB
/
ChunkTerrain.js
File metadata and controls
121 lines (107 loc) · 2.93 KB
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
115
116
117
118
119
120
121
const modulo = function (a, b) {
return ((+a % (b = +b)) + b) % b
}
class ChunkTerrain {
constructor (options) {
this.chunkSize = 16
this.chunks = {}
this.blocksDef = options.blocksDef
this.neighbours = {
px: [-1, 0, 0],
nx: [1, 0, 0],
ny: [0, -1, 0],
py: [0, 1, 0],
pz: [0, 0, 1],
nz: [0, 0, -1]
}
}
vecToStr (x, y, z) {
return `${parseInt(x)}:${parseInt(y)}:${parseInt(z)}`
}
strToVec (str) {
str = str.split(':')
return [parseInt(str[0]), parseInt(str[1]), parseInt(str[2])]
}
computeVoxelOffset (voxelX, voxelY, voxelZ) {
const x = modulo(voxelX, this.chunkSize) | 0
const y = modulo(voxelY, this.chunkSize) | 0
const z = modulo(voxelZ, this.chunkSize) | 0
return y * this.chunkSize * this.chunkSize + z * this.chunkSize + x
}
computeChunkForVoxel (voxelX, voxelY, voxelZ) {
return [
Math.floor(voxelX / this.chunkSize),
Math.floor(voxelY / this.chunkSize),
Math.floor(voxelZ / this.chunkSize)
]
}
addChunkForVoxel (voxelX, voxelY, voxelZ) {
const cellId = this.vecToStr(
...this.computeChunkForVoxel(voxelX, voxelY, voxelZ)
)
let cell = this.chunks[cellId]
if (!cell) {
cell = new Uint32Array(
this.chunkSize * this.chunkSize * this.chunkSize
)
this.chunks[cellId] = cell
}
return cell
}
getChunkForVoxel (voxelX, voxelY, voxelZ) {
const cellId = this.vecToStr(
...this.computeChunkForVoxel(voxelX, voxelY, voxelZ)
)
return this.chunks[cellId]
}
setVoxel (voxelX, voxelY, voxelZ, value) {
let cell = this.getChunkForVoxel(voxelX, voxelY, voxelZ)
if (!cell) {
cell = this.addChunkForVoxel(voxelX, voxelY, voxelZ)
}
const voff = this.computeVoxelOffset(voxelX, voxelY, voxelZ)
cell[voff] = value
}
getVoxel (voxelX, voxelY, voxelZ) {
const cell = this.getChunkForVoxel(voxelX, voxelY, voxelZ)
if (!cell) {
return 0
}
const voff = this.computeVoxelOffset(voxelX, voxelY, voxelZ)
return cell[voff]
}
setChunk (chunkX, chunkY, chunkZ, buffer) {
this.chunks[this.vecToStr(chunkX, chunkY, chunkZ)] = buffer
}
getBlock (blockX, blockY, blockZ) {
const stateId = this.getVoxel(blockX, blockY, blockZ)
const def = this.blocksDef[stateId]
if (def !== undefined) {
return {
name: def[0],
stateId,
boundingBox: def[1] === 1 ? 'block' : 'empty',
transparent: def[2]
}
} else {
return false
}
}
getBlockNeighbours (blockX, blockY, blockZ) {
const neighbours = {}
const main = this.getBlock(blockX, blockY, blockZ)
for (const side in this.neighbours) {
const offset = this.neighbours[side]
neighbours[side] = this.getBlock(
blockX + offset[0],
blockY + offset[1],
blockZ + offset[2]
)
}
return [main, neighbours]
}
reset () {
this.chunks = {}
}
}
export { ChunkTerrain }