forked from michaljaz/webmc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
136 lines (126 loc) · 4.06 KB
/
index.js
File metadata and controls
136 lines (126 loc) · 4.06 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { Vector3 } from 'three'
import { ChunkTerrain } from './ChunkTerrain.js'
import { AnimatedTextureAtlas } from './AnimatedTextureAtlas.js'
import { SectionComputer } from './SectionComputer.js'
import { ChunkManager } from './ChunkManager.js'
import ChunkWorker from './chunk.worker.js'
class World {
constructor (game) {
this.game = game
this.blocksDef = this.game.al.get('blocksDef')
this.chunkTerrain = new ChunkTerrain({
blocksDef: this.blocksDef
})
this.ATA = new AnimatedTextureAtlas(this.game)
this.material = this.ATA.material
this.cellUpdateTime = null
this.lastPlayerChunk = null
this.blocksUpdate = false
this.chunkManager = new ChunkManager(this.game)
this.chunkWorker = new ChunkWorker()
this.chunkWorker.onmessage = (message) => {
if (message.data.type === 'cellGeo') {
const cellId = this.chunkTerrain.vecToStr(...message.data.data.info)
const vert = message.data.data.cell
this.chunkManager.addChunk(cellId, vert)
} else if (message.data.type === 'removeCell') {
this.chunkManager.removeChunk(message.data.data)
}
}
this.chunkWorker.postMessage({
type: 'init',
data: {
blocksMapping: this.game.al.get('blocksMapping'),
toxelSize: this.game.toxelSize,
blocksTex: this.game.al.get('blocksTex'),
blocksDef: this.blocksDef
}
})
}
setChunk (chunkX, chunkY, chunkZ, buffer) {
this.cellUpdateTime = window.performance.now()
this.chunkWorker.postMessage({
type: 'setChunk',
data: [chunkX, chunkY, chunkZ, buffer]
})
this.chunkTerrain.setChunk(chunkX, chunkY, chunkZ, buffer)
}
setBlock (voxelX, voxelY, voxelZ, value) {
voxelX = parseInt(voxelX)
voxelY = parseInt(voxelY)
voxelZ = parseInt(voxelZ)
this.blocksUpdate = true
if (this.chunkTerrain.getVoxel(voxelX, voxelY, voxelZ) !== value) {
this.chunkWorker.postMessage({
type: 'setVoxel',
data: [voxelX, voxelY, voxelZ, value]
})
this.chunkTerrain.setVoxel(voxelX, voxelY, voxelZ, value)
}
}
resetWorld () {
this.chunkManager.reset()
this.chunkTerrain.reset()
this.chunkWorker.postMessage({
type: 'resetWorld',
data: null
})
}
getRayBlock () {
const start = new Vector3().setFromMatrixPosition(this.game.camera.matrixWorld)
const end = new Vector3().set(0, 0, 1).unproject(this.game.camera)
const intersection = this.chunkTerrain.intersectsRay(start, end)
if (intersection) {
const posPlace = intersection.position.map(function (v, ndx) {
return Math.floor(v + intersection.normal[ndx] * 0.5)
})
const posBreak = intersection.position.map(function (v, ndx) {
return Math.floor(v + intersection.normal[ndx] * -0.5)
})
return { posPlace, posBreak }
} else {
return false
}
}
updateChunksAroundPlayer (radius) {
this.chunkManager.update()
const pos = this.game.camera.position
const cell = this.chunkTerrain.computeChunkForVoxel(
Math.floor(pos.x + 0.5),
Math.floor(pos.y + 0.5),
Math.floor(pos.z + 0.5)
)
if (this.blocksUpdate) {
this.blocksUpdate = false
this.chunkWorker.postMessage({
type: 'updateChunksAroundPlayer',
data: [cell, radius]
})
} else if (this.lastPlayerChunk !== JSON.stringify(cell)) {
if (
this.cellUpdateTime !== null && window.performance.now() - this.cellUpdateTime > 100
) {
this.chunkManager.updateRenderOrder(cell)
this.lastPlayerChunk = JSON.stringify(cell)
this.chunkWorker.postMessage({
type: 'updateChunksAroundPlayer',
data: [cell, radius]
})
}
}
}
computeSections (sections, biomes, x, z) {
const result = SectionComputer({ sections, x, z })
const results = []
for (const i in result) {
const j = result[i]
if (j !== null) {
results.push(this.setChunk(j.x, j.y, j.z, j.cell))
} else {
results.push(undefined)
}
}
return results
}
}
export { World }