-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathchunker.js
119 lines (104 loc) · 3.29 KB
/
chunker.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
115
116
117
118
var events = require('events')
var inherits = require('inherits')
module.exports = function(opts) {
return new Chunker(opts)
}
module.exports.Chunker = Chunker
function Chunker(opts) {
this.distance = opts.chunkDistance || 2
this.chunkSize = opts.chunkSize || 32
this.chunkPad = opts.chunkPad !== undefined ? opts.chunkPad : 0
this.cubeSize = opts.cubeSize || 25
this.generateVoxelChunk = opts.generateVoxelChunk
this.chunks = {}
this.meshes = {}
if (this.chunkSize & this.chunkSize-1 !== 0)
throw new Error('chunkSize must be a power of 2')
var bits = 0;
for (var size = this.chunkSize; size > 0; size >>= 1) bits++;
this.chunkBits = bits - 1;
this.chunkMask = (1 << this.chunkBits) - 1
this.chunkPadHalf = this.chunkPad >> 1
}
inherits(Chunker, events.EventEmitter)
Chunker.prototype.nearbyChunks = function(position, distance) {
var current = this.chunkAtPosition(position)
var x = current[0]
var y = current[1]
var z = current[2]
var dist = distance || this.distance
var nearby = []
for (var cx = (x - dist); cx !== (x + dist); ++cx) {
for (var cy = (y - dist); cy !== (y + dist); ++cy) {
for (var cz = (z - dist); cz !== (z + dist); ++cz) {
nearby.push([cx, cy, cz])
}
}
}
return nearby
}
Chunker.prototype.requestMissingChunks = function(position) {
var self = this
this.nearbyChunks(position).map(function(chunk) {
if (!self.chunks[chunk.join('|')]) {
self.emit('missingChunk', chunk)
}
})
}
Chunker.prototype.getBounds = function(x, y, z) {
var bits = this.chunkBits
var low = [x << bits, y << bits, z << bits]
var high = [(x+1) << bits, (y+1) << bits, (z+1) << bits]
return [low, high]
}
Chunker.prototype.generateChunk = function(x, y, z) {
var self = this
var bounds = this.getBounds(x, y, z)
var chunk = this.generateVoxelChunk(bounds[0], bounds[1], x, y, z)
var position = [x, y, z]
chunk.position = position
this.chunks[position.join('|')] = chunk
return chunk
}
Chunker.prototype.chunkAtCoordinates = function(x, y, z) {
var bits = this.chunkBits;
var cx = x >> bits;
var cy = y >> bits;
var cz = z >> bits;
var chunkPos = [cx, cy, cz];
return chunkPos;
}
Chunker.prototype.chunkAtPosition = function(position) {
var cubeSize = this.cubeSize;
var x = Math.floor(position[0] / cubeSize)
var y = Math.floor(position[1] / cubeSize)
var z = Math.floor(position[2] / cubeSize)
var chunkPos = this.chunkAtCoordinates(x, y, z)
return chunkPos
};
Chunker.prototype.voxelIndexFromCoordinates = function(x, y, z) {
throw new Error('Chunker.prototype.voxelIndexFromCoordinates removed, use voxelAtCoordinates')
}
Chunker.prototype.voxelAtCoordinates = function(x, y, z, val) {
var ckey = this.chunkAtCoordinates(x, y, z).join('|')
var chunk = this.chunks[ckey]
if (!chunk) return false
var mask = this.chunkMask
var h = this.chunkPadHalf
var mx = x & mask
var my = y & mask
var mz = z & mask
var v = chunk.get(mx+h, my+h, mz+h)
if (typeof val !== 'undefined') {
chunk.set(mx+h, my+h, mz+h, val)
}
return v
}
Chunker.prototype.voxelAtPosition = function(pos, val) {
var cubeSize = this.cubeSize;
var x = Math.floor(pos[0] / cubeSize)
var y = Math.floor(pos[1] / cubeSize)
var z = Math.floor(pos[2] / cubeSize)
var v = this.voxelAtCoordinates(x, y, z, val)
return v;
}