Skip to content

Commit 92cbdcb

Browse files
committed
client: move smoke visuals handling to World
1 parent af4ef6e commit 92cbdcb

2 files changed

Lines changed: 60 additions & 49 deletions

File tree

www/assets/js/Game.js

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as THREE from 'three' // fixme try remove from game, maybe only allow import Vec3...
2-
import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js' // todo remove
32
import {EventProcessor} from "./EventProcessor.js"
43
import {Player} from "./Player.js"
54
import {InventorySlot, SoundType} from "./Enums.js"
@@ -327,11 +326,7 @@ export class Game {
327326
spawnFlame(point, height, fireId, partId) {
328327
const size = this.#volumetrics[fireId]['size']
329328
height = Utils.lerp(height, Utils.randomInt(16, 26), Math.min(Math.sqrt(Object.keys(this.#volumetrics[fireId]).length) / Utils.randomInt(7, 9), 1))
330-
const flame = this.#world.spawnFlame(size, height)
331-
this.#volumetrics[fireId][partId] = flame
332-
flame.position.set(point.x, point.y + (height / 2), -1 * point.z)
333-
flame.rotation.x = Utils.randomInt(-10, 10) / 100
334-
flame.rotateOnWorldAxis(new THREE.Vector3(0, 1, 0), Math.random() * 6.28)
329+
this.#volumetrics[fireId][partId] = this.#world.spawnFlame(point, size, height)
335330
}
336331

337332
destroyFlame(fireId, flameId) {
@@ -341,50 +336,19 @@ export class Game {
341336
}
342337

343338
smokeStart(smokeId, position, size, maxTimeMs, maxPartCount) {
344-
this.#volumetrics[smokeId] = {}
345-
this.#volumetrics[smokeId]['size'] = size
346-
this.#volumetrics[smokeId]['count'] = maxPartCount
347-
this.#volumetrics[smokeId]['geometries'] = []
339+
this.#volumetrics[smokeId] = {'mesh': this.#world.initSmoke(smokeId, size, maxPartCount)}
348340
}
349341

350342
spawnSmoke(point, height, smokeId, partId) {
351-
const size = this.#volumetrics[smokeId]['size']
352-
const offset = Math.max(2, Math.ceil(size / 4));
353-
const geo = new THREE.CylinderGeometry(size - Utils.randomInt(0, offset), size, height - Utils.randomInt(0, offset), Utils.randomInt(5, 22))
354-
geo.translate(point.x, point.y + (geo.parameters.height / 2), -point.z)
355-
this.#volumetrics[smokeId]['geometries'].push(geo)
356-
357-
const len = this.#volumetrics[smokeId]['geometries'].length
358-
if (len % 10 !== 0 && len < this.#volumetrics[smokeId]['count']) {
359-
return
360-
}
361-
362-
let geometry = BufferGeometryUtils.mergeGeometries(this.#volumetrics[smokeId]['geometries'])
363-
geometry = BufferGeometryUtils.mergeVertices(geometry, offset)
364-
geometry.computeBoundingBox()
365-
let mesh = this.#volumetrics[smokeId]['mesh']
366-
if (mesh) {
367-
this.#world.destroyObject(mesh)
368-
}
369-
370-
mesh = this.#world.spawnSmoke(geometry)
371-
this.#volumetrics[smokeId]['mesh'] = mesh
372-
if (len === this.#volumetrics[smokeId]['count']) {
373-
this.#volumetrics[smokeId]['range'] = Math.ceil(mesh.geometry.getIndex().count / 50)
374-
mesh.geometry.setDrawRange(0, mesh.geometry.getIndex().count)
375-
}
343+
this.#world.spawnSmoke(point, height, smokeId)
376344
}
377345

378346
smokeFade(smokeId) {
379-
const range = this.#volumetrics[smokeId]['range']
380-
const mesh = this.#volumetrics[smokeId]['mesh']
381-
382-
const intervalId = setInterval(function() {
383-
const newRange = mesh.geometry.drawRange.count - range
384-
if (newRange <= 0) {
347+
const game = this
348+
const intervalId = setInterval(function () {
349+
if (game.#world.fadeSmoke(smokeId)) {
385350
clearInterval(intervalId)
386351
}
387-
mesh.geometry.setDrawRange(0, newRange)
388352
}, 50)
389353
this.#roundIntervalIds.push(intervalId)
390354
}

www/assets/js/World.js

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import * as THREE from 'three'
22
import * as Enum from "./Enums.js"
33
import {RGBELoader} from "three/addons/loaders/RGBELoader.js"
44
import {ModelRepository} from "./ModelRepository.js"
5-
import {Utils} from "./Utils.js";
5+
import {Utils} from "./Utils.js"
6+
import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'
67

78
export class World {
89
#scene
@@ -14,6 +15,7 @@ export class World {
1415
#raycaster
1516
#decals = []
1617
#cache = {}
18+
#smokes = {}
1719
volume = 30
1820

1921
constructor() {
@@ -80,7 +82,7 @@ export class World {
8082
this.volume = setting.getMasterVolume()
8183

8284
const anisotropy = Math.min(setting.getAnisotropicFiltering(), renderer.capabilities.getMaxAnisotropy())
83-
return this.#modelRepository.init(mapName, renderer, scene).then(() => {
85+
return this.#modelRepository.init(scene, renderer, mapName).then(() => {
8486
scene.traverse(function (object) {
8587
if (object.isMesh && object.material.map) {
8688
object.material.map.anisotropy = anisotropy
@@ -180,10 +182,10 @@ export class World {
180182
this.#cache[index] = loadCallback()
181183
}
182184

183-
return this.#cache[index];
185+
return this.#cache[index]
184186
}
185187

186-
spawnFlame(size, height) {
188+
spawnFlame(position, size, height) {
187189
const coneDetail = Utils.randomInt(5, 7)
188190
const lightnessValue = Utils.randomInt(30, 80)
189191
const geometry = this.loadCache(`flame-geo-c-${coneDetail}`, () => new THREE.ConeGeometry(1, 1, coneDetail))
@@ -196,20 +198,65 @@ export class World {
196198
mesh.castShadow = false
197199
mesh.receiveShadow = true
198200

201+
mesh.position.set(position.x, position.y + (height / 2), -1 * position.z)
202+
mesh.rotation.x = Utils.randomInt(-10, 10) / 100
203+
mesh.rotateOnWorldAxis(new THREE.Vector3(0, 1, 0), Math.random() * 6.28)
204+
199205
this.#scene.add(mesh)
200206
return mesh
201207
}
202208

203-
spawnSmoke(geometry) {
204-
const mesh = new THREE.Mesh(geometry, this.#modelRepository.getSmokeMaterial())
209+
initSmoke(smokeId, size, maxPartCount) {
210+
const mesh = new THREE.Mesh(new THREE.BufferGeometry(), this.#modelRepository.getSmokeMaterial())
205211
this.#scene.add(mesh)
212+
213+
this.#smokes[smokeId] = {}
214+
this.#smokes[smokeId]['size'] = size
215+
this.#smokes[smokeId]['count'] = maxPartCount
216+
this.#smokes[smokeId]['geometries'] = []
217+
this.#smokes[smokeId]['mesh'] = mesh
218+
206219
return mesh
207220
}
208221

222+
spawnSmoke(position, height, smokeId) {
223+
const size = this.#smokes[smokeId]['size']
224+
const offset = Math.max(2, Math.ceil(size / 4))
225+
const geo = new THREE.CylinderGeometry(size - Utils.randomInt(0, offset), size, height - Utils.randomInt(0, offset), Utils.randomInt(5, 22))
226+
geo.translate(position.x, position.y + (geo.parameters.height / 2), -position.z)
227+
this.#smokes[smokeId]['geometries'].push(geo)
228+
229+
let len = this.#smokes[smokeId]['geometries'].length
230+
if (len % 10 !== 0 && len < this.#smokes[smokeId]['count']) {
231+
return
232+
}
233+
234+
let geometry = BufferGeometryUtils.mergeGeometries(this.#smokes[smokeId]['geometries'])
235+
geometry.computeBoundingBox()
236+
237+
this.#smokes[smokeId]['range'] = Math.ceil(geometry.getIndex().count / 50)
238+
geometry.setDrawRange(0, geometry.getIndex().count)
239+
240+
const mesh = this.#smokes[smokeId]['mesh']
241+
mesh.geometry = geometry
242+
}
243+
244+
fadeSmoke(smokeId) {
245+
const mesh = this.#smokes[smokeId]['mesh']
246+
const newRange = mesh.geometry.drawRange.count - this.#smokes[smokeId]['range']
247+
mesh.geometry.setDrawRange(0, newRange)
248+
249+
if (newRange <= 0) {
250+
delete this.#smokes[smokeId]
251+
return true
252+
}
253+
return false
254+
}
255+
209256
bulletWallHit(origin, hitPosition, item) {
210257
const rayHit = new THREE.Vector3(hitPosition.x, hitPosition.y, -hitPosition.z)
211258
const rayDirection = rayHit.clone().sub(new THREE.Vector3(origin.x, origin.y, -origin.z)).normalize()
212-
rayHit.addScaledVector(rayDirection, -50); // offset a bit back to give raycaster more space to match server-client geometry
259+
rayHit.addScaledVector(rayDirection, -50) // offset a bit back to give raycaster more space to match server-client geometry
213260

214261
this.#raycaster.near = 1
215262
this.#raycaster.far = 100

0 commit comments

Comments
 (0)