minecraft-renderer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +297 -0
- package/dist/index.html +83 -0
- package/dist/static/image/arrow.6f27b59f.png +0 -0
- package/dist/static/image/blocksAtlasLatest.7850afa3.png +0 -0
- package/dist/static/image/blocksAtlasLegacy.5c76823d.png +0 -0
- package/dist/static/image/itemsAtlasLatest.36036f95.png +0 -0
- package/dist/static/image/itemsAtlasLegacy.dcb1b58d.png +0 -0
- package/dist/static/image/tipped_arrow.6f27b59f.png +0 -0
- package/dist/static/js/365.f05233ab.js +8462 -0
- package/dist/static/js/365.f05233ab.js.LICENSE.txt +52 -0
- package/dist/static/js/async/738.efa27644.js +1 -0
- package/dist/static/js/index.092ec5be.js +56 -0
- package/dist/static/js/lib-polyfill.98986ac5.js +1 -0
- package/dist/static/js/lib-react.5c9129e0.js +2 -0
- package/dist/static/js/lib-react.5c9129e0.js.LICENSE.txt +39 -0
- package/package.json +104 -0
- package/src/assets/destroy_stage_0.png +0 -0
- package/src/assets/destroy_stage_1.png +0 -0
- package/src/assets/destroy_stage_2.png +0 -0
- package/src/assets/destroy_stage_3.png +0 -0
- package/src/assets/destroy_stage_4.png +0 -0
- package/src/assets/destroy_stage_5.png +0 -0
- package/src/assets/destroy_stage_6.png +0 -0
- package/src/assets/destroy_stage_7.png +0 -0
- package/src/assets/destroy_stage_8.png +0 -0
- package/src/assets/destroy_stage_9.png +0 -0
- package/src/examples/README.md +146 -0
- package/src/examples/appViewerExample.ts +205 -0
- package/src/examples/initialMenuStart.ts +161 -0
- package/src/graphicsBackend/appViewer.ts +297 -0
- package/src/graphicsBackend/config.ts +119 -0
- package/src/graphicsBackend/index.ts +10 -0
- package/src/graphicsBackend/playerState.ts +61 -0
- package/src/graphicsBackend/types.ts +143 -0
- package/src/index.ts +97 -0
- package/src/lib/DebugGui.ts +190 -0
- package/src/lib/animationController.ts +85 -0
- package/src/lib/buildSharedConfig.mjs +1 -0
- package/src/lib/cameraBobbing.ts +94 -0
- package/src/lib/canvas2DOverlay.example.ts +361 -0
- package/src/lib/canvas2DOverlay.quickstart.ts +242 -0
- package/src/lib/canvas2DOverlay.ts +381 -0
- package/src/lib/cleanupDecorator.ts +29 -0
- package/src/lib/createPlayerObject.ts +55 -0
- package/src/lib/frameTimingCollector.ts +164 -0
- package/src/lib/guiRenderer.ts +283 -0
- package/src/lib/items.ts +140 -0
- package/src/lib/mesherlogReader.ts +131 -0
- package/src/lib/moreBlockDataGenerated.json +714 -0
- package/src/lib/preflatMap.json +1741 -0
- package/src/lib/simpleUtils.ts +40 -0
- package/src/lib/smoothSwitcher.ts +168 -0
- package/src/lib/spiral.ts +29 -0
- package/src/lib/ui/newStats.ts +120 -0
- package/src/lib/utils/proxy.ts +23 -0
- package/src/lib/utils/skins.ts +63 -0
- package/src/lib/utils.ts +76 -0
- package/src/lib/workerProxy.ts +342 -0
- package/src/lib/worldrendererCommon.ts +1088 -0
- package/src/mesher/mesher.ts +253 -0
- package/src/mesher/models.ts +769 -0
- package/src/mesher/modelsGeometryCommon.ts +142 -0
- package/src/mesher/shared.ts +80 -0
- package/src/mesher/standaloneRenderer.ts +270 -0
- package/src/mesher/test/a.ts +3 -0
- package/src/mesher/test/mesherTester.ts +76 -0
- package/src/mesher/test/playground.ts +19 -0
- package/src/mesher/test/test-perf.ts +74 -0
- package/src/mesher/test/tests.test.ts +56 -0
- package/src/mesher/world.ts +294 -0
- package/src/mesher/worldConstants.ts +1 -0
- package/src/modules/index.ts +11 -0
- package/src/modules/starfield.ts +313 -0
- package/src/modules/types.ts +110 -0
- package/src/playerState/playerState.ts +78 -0
- package/src/playerState/types.ts +36 -0
- package/src/playground/allEntitiesDebug.ts +170 -0
- package/src/playground/baseScene.ts +587 -0
- package/src/playground/mobileControls.tsx +268 -0
- package/src/playground/playground.html +83 -0
- package/src/playground/playground.ts +11 -0
- package/src/playground/playgroundUi.tsx +140 -0
- package/src/playground/reactUtils.ts +71 -0
- package/src/playground/scenes/allEntities.ts +13 -0
- package/src/playground/scenes/entities.ts +37 -0
- package/src/playground/scenes/floorRandom.ts +33 -0
- package/src/playground/scenes/frequentUpdates.ts +148 -0
- package/src/playground/scenes/geometryExport.ts +142 -0
- package/src/playground/scenes/index.ts +12 -0
- package/src/playground/scenes/lightingStarfield.ts +40 -0
- package/src/playground/scenes/main.ts +313 -0
- package/src/playground/scenes/railsCobweb.ts +14 -0
- package/src/playground/scenes/rotationIssue.ts +7 -0
- package/src/playground/scenes/slabsOptimization.ts +16 -0
- package/src/playground/scenes/transparencyIssue.ts +11 -0
- package/src/playground/shared.ts +79 -0
- package/src/resourcesManager/index.ts +5 -0
- package/src/resourcesManager/resourcesManager.ts +314 -0
- package/src/shims/minecraftData.ts +41 -0
- package/src/sign-renderer/index.html +21 -0
- package/src/sign-renderer/index.ts +216 -0
- package/src/sign-renderer/noop.js +1 -0
- package/src/sign-renderer/playground.ts +38 -0
- package/src/sign-renderer/tests.test.ts +69 -0
- package/src/sign-renderer/vite.config.ts +10 -0
- package/src/three/appShared.ts +75 -0
- package/src/three/bannerRenderer.ts +275 -0
- package/src/three/cameraShake.ts +120 -0
- package/src/three/cinimaticScript.ts +350 -0
- package/src/three/documentRenderer.ts +491 -0
- package/src/three/entities.ts +1580 -0
- package/src/three/entity/EntityMesh.ts +707 -0
- package/src/three/entity/animations.js +171 -0
- package/src/three/entity/armorModels.json +204 -0
- package/src/three/entity/armorModels.ts +36 -0
- package/src/three/entity/entities.json +6230 -0
- package/src/three/entity/exportedModels.js +38 -0
- package/src/three/entity/externalTextures.json +1 -0
- package/src/three/entity/models/allay.obj +325 -0
- package/src/three/entity/models/arrow.obj +60 -0
- package/src/three/entity/models/axolotl.obj +509 -0
- package/src/three/entity/models/blaze.obj +601 -0
- package/src/three/entity/models/boat.obj +417 -0
- package/src/three/entity/models/camel.obj +1061 -0
- package/src/three/entity/models/cat.obj +509 -0
- package/src/three/entity/models/chicken.obj +371 -0
- package/src/three/entity/models/cod.obj +371 -0
- package/src/three/entity/models/creeper.obj +279 -0
- package/src/three/entity/models/dolphin.obj +371 -0
- package/src/three/entity/models/ender_dragon.obj +2993 -0
- package/src/three/entity/models/enderman.obj +325 -0
- package/src/three/entity/models/endermite.obj +187 -0
- package/src/three/entity/models/fox.obj +463 -0
- package/src/three/entity/models/frog.obj +739 -0
- package/src/three/entity/models/ghast.obj +463 -0
- package/src/three/entity/models/goat.obj +601 -0
- package/src/three/entity/models/guardian.obj +1015 -0
- package/src/three/entity/models/horse.obj +1061 -0
- package/src/three/entity/models/llama.obj +509 -0
- package/src/three/entity/models/minecart.obj +233 -0
- package/src/three/entity/models/parrot.obj +509 -0
- package/src/three/entity/models/piglin.obj +739 -0
- package/src/three/entity/models/pillager.obj +371 -0
- package/src/three/entity/models/rabbit.obj +555 -0
- package/src/three/entity/models/sheep.obj +555 -0
- package/src/three/entity/models/shulker.obj +141 -0
- package/src/three/entity/models/sniffer.obj +693 -0
- package/src/three/entity/models/spider.obj +509 -0
- package/src/three/entity/models/tadpole.obj +95 -0
- package/src/three/entity/models/turtle.obj +371 -0
- package/src/three/entity/models/vex.obj +325 -0
- package/src/three/entity/models/villager.obj +509 -0
- package/src/three/entity/models/warden.obj +463 -0
- package/src/three/entity/models/witch.obj +647 -0
- package/src/three/entity/models/wolf.obj +509 -0
- package/src/three/entity/models/zombie_villager.obj +463 -0
- package/src/three/entity/objModels.js +1 -0
- package/src/three/fireworks.ts +661 -0
- package/src/three/fireworksRenderer.ts +434 -0
- package/src/three/globals.d.ts +7 -0
- package/src/three/graphicsBackend.ts +274 -0
- package/src/three/graphicsBackendOffThread.ts +107 -0
- package/src/three/hand.ts +89 -0
- package/src/three/holdingBlock.ts +926 -0
- package/src/three/index.ts +20 -0
- package/src/three/itemMesh.ts +427 -0
- package/src/three/modules.d.ts +14 -0
- package/src/three/panorama.ts +308 -0
- package/src/three/panoramaShared.ts +1 -0
- package/src/three/renderSlot.ts +82 -0
- package/src/three/skyboxRenderer.ts +406 -0
- package/src/three/starField.ts +13 -0
- package/src/three/threeJsMedia.ts +731 -0
- package/src/three/threeJsMethods.ts +15 -0
- package/src/three/threeJsParticles.ts +160 -0
- package/src/three/threeJsSound.ts +95 -0
- package/src/three/threeJsUtils.ts +90 -0
- package/src/three/waypointSprite.ts +435 -0
- package/src/three/waypoints.ts +163 -0
- package/src/three/world/cursorBlock.ts +172 -0
- package/src/three/world/vr.ts +257 -0
- package/src/three/worldGeometryExport.ts +259 -0
- package/src/three/worldGeometryHandler.ts +279 -0
- package/src/three/worldRendererThree.ts +1381 -0
- package/src/worldView/index.ts +6 -0
- package/src/worldView/types.ts +66 -0
- package/src/worldView/worldView.ts +424 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GraphicsBackend } from '../../../src/appViewer'
|
|
2
|
+
import type { ThreeJsBackendMethods } from './graphicsBackend'
|
|
3
|
+
|
|
4
|
+
export function getThreeJsRendererMethods (): ThreeJsBackendMethods | undefined {
|
|
5
|
+
const renderer = appViewer.backend
|
|
6
|
+
if (renderer?.id !== 'threejs' || !renderer.backendMethods) return
|
|
7
|
+
return new Proxy(renderer.backendMethods, {
|
|
8
|
+
get (target, prop) {
|
|
9
|
+
return async (...args) => {
|
|
10
|
+
const result = await (target[prop as any] as any)(...args)
|
|
11
|
+
return result
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}) as ThreeJsBackendMethods
|
|
15
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
|
|
3
|
+
interface ParticleMesh extends THREE.Mesh {
|
|
4
|
+
velocity: THREE.Vector3;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface ParticleConfig {
|
|
8
|
+
fountainHeight: number;
|
|
9
|
+
resetHeight: number;
|
|
10
|
+
xVelocityRange: number;
|
|
11
|
+
zVelocityRange: number;
|
|
12
|
+
particleCount: number;
|
|
13
|
+
particleRadiusRange: { min: number; max: number };
|
|
14
|
+
yVelocityRange: { min: number; max: number };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface FountainOptions {
|
|
18
|
+
position?: { x: number, y: number, z: number }
|
|
19
|
+
particleConfig?: Partial<ParticleConfig>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class Fountain {
|
|
23
|
+
private readonly particles: ParticleMesh[] = []
|
|
24
|
+
private readonly config: { particleConfig: ParticleConfig }
|
|
25
|
+
private readonly position: THREE.Vector3
|
|
26
|
+
container: THREE.Object3D | undefined
|
|
27
|
+
|
|
28
|
+
constructor (public sectionId: string, options: FountainOptions = {}) {
|
|
29
|
+
this.position = options.position ? new THREE.Vector3(options.position.x, options.position.y, options.position.z) : new THREE.Vector3(0, 0, 0)
|
|
30
|
+
this.config = this.createConfig(options.particleConfig)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private createConfig (
|
|
34
|
+
particleConfigOverride?: Partial<ParticleConfig>
|
|
35
|
+
): { particleConfig: ParticleConfig } {
|
|
36
|
+
const particleConfig: ParticleConfig = {
|
|
37
|
+
fountainHeight: 10,
|
|
38
|
+
resetHeight: 0,
|
|
39
|
+
xVelocityRange: 0.4,
|
|
40
|
+
zVelocityRange: 0.4,
|
|
41
|
+
particleCount: 400,
|
|
42
|
+
particleRadiusRange: { min: 0.1, max: 0.6 },
|
|
43
|
+
yVelocityRange: { min: 0.1, max: 2 },
|
|
44
|
+
...particleConfigOverride
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { particleConfig }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
createParticles (container: THREE.Object3D): void {
|
|
52
|
+
this.container = container
|
|
53
|
+
const colorStart = new THREE.Color(0xff_ff_00)
|
|
54
|
+
const colorEnd = new THREE.Color(0xff_a5_00)
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < this.config.particleConfig.particleCount; i++) {
|
|
57
|
+
const radius = Math.random() *
|
|
58
|
+
(this.config.particleConfig.particleRadiusRange.max - this.config.particleConfig.particleRadiusRange.min) +
|
|
59
|
+
this.config.particleConfig.particleRadiusRange.min
|
|
60
|
+
const geometry = new THREE.SphereGeometry(radius)
|
|
61
|
+
const material = new THREE.MeshBasicMaterial({
|
|
62
|
+
color: colorStart.clone().lerp(colorEnd, Math.random())
|
|
63
|
+
})
|
|
64
|
+
const mesh = new THREE.Mesh(geometry, material)
|
|
65
|
+
const particle = mesh as unknown as ParticleMesh
|
|
66
|
+
|
|
67
|
+
particle.position.set(
|
|
68
|
+
this.position.x + (Math.random() - 0.5) * this.config.particleConfig.xVelocityRange * 2,
|
|
69
|
+
this.position.y + this.config.particleConfig.fountainHeight,
|
|
70
|
+
this.position.z + (Math.random() - 0.5) * this.config.particleConfig.zVelocityRange * 2
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
particle.velocity = new THREE.Vector3(
|
|
74
|
+
(Math.random() - 0.5) * this.config.particleConfig.xVelocityRange,
|
|
75
|
+
-Math.random() * this.config.particleConfig.yVelocityRange.max,
|
|
76
|
+
(Math.random() - 0.5) * this.config.particleConfig.zVelocityRange
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
this.particles.push(particle)
|
|
80
|
+
this.container.add(particle)
|
|
81
|
+
|
|
82
|
+
// this.container.onBeforeRender = () => {
|
|
83
|
+
// this.render()
|
|
84
|
+
// }
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
render (): void {
|
|
89
|
+
for (const particle of this.particles) {
|
|
90
|
+
particle.velocity.y -= 0.01 + Math.random() * 0.1
|
|
91
|
+
particle.position.add(particle.velocity)
|
|
92
|
+
|
|
93
|
+
if (particle.position.y < this.position.y + this.config.particleConfig.resetHeight) {
|
|
94
|
+
particle.position.set(
|
|
95
|
+
this.position.x + (Math.random() - 0.5) * this.config.particleConfig.xVelocityRange * 2,
|
|
96
|
+
this.position.y + this.config.particleConfig.fountainHeight,
|
|
97
|
+
this.position.z + (Math.random() - 0.5) * this.config.particleConfig.zVelocityRange * 2
|
|
98
|
+
)
|
|
99
|
+
particle.velocity.set(
|
|
100
|
+
(Math.random() - 0.5) * this.config.particleConfig.xVelocityRange,
|
|
101
|
+
-Math.random() * this.config.particleConfig.yVelocityRange.max,
|
|
102
|
+
(Math.random() - 0.5) * this.config.particleConfig.zVelocityRange
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private updateParticleCount (newCount: number): void {
|
|
109
|
+
if (newCount !== this.config.particleConfig.particleCount) {
|
|
110
|
+
this.config.particleConfig.particleCount = newCount
|
|
111
|
+
const currentCount = this.particles.length
|
|
112
|
+
|
|
113
|
+
if (newCount > currentCount) {
|
|
114
|
+
this.addParticles(newCount - currentCount)
|
|
115
|
+
} else if (newCount < currentCount) {
|
|
116
|
+
this.removeParticles(currentCount - newCount)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private addParticles (count: number): void {
|
|
122
|
+
const geometry = new THREE.SphereGeometry(0.1)
|
|
123
|
+
const material = new THREE.MeshBasicMaterial({ color: 0x00_ff_00 })
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < count; i++) {
|
|
126
|
+
const mesh = new THREE.Mesh(geometry, material)
|
|
127
|
+
const particle = mesh as unknown as ParticleMesh
|
|
128
|
+
particle.position.copy(this.position)
|
|
129
|
+
particle.velocity = new THREE.Vector3(
|
|
130
|
+
Math.random() * this.config.particleConfig.xVelocityRange -
|
|
131
|
+
this.config.particleConfig.xVelocityRange / 2,
|
|
132
|
+
Math.random() * 2,
|
|
133
|
+
Math.random() * this.config.particleConfig.zVelocityRange -
|
|
134
|
+
this.config.particleConfig.zVelocityRange / 2
|
|
135
|
+
)
|
|
136
|
+
this.particles.push(particle)
|
|
137
|
+
this.container!.add(particle)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private removeParticles (count: number): void {
|
|
142
|
+
for (let i = 0; i < count; i++) {
|
|
143
|
+
const particle = this.particles.pop()
|
|
144
|
+
if (particle) {
|
|
145
|
+
this.container!.remove(particle)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public dispose (): void {
|
|
151
|
+
for (const particle of this.particles) {
|
|
152
|
+
particle.geometry.dispose()
|
|
153
|
+
if (Array.isArray(particle.material)) {
|
|
154
|
+
for (const material of particle.material) material.dispose()
|
|
155
|
+
} else {
|
|
156
|
+
particle.material.dispose()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import { WorldRendererThree } from './worldRendererThree'
|
|
3
|
+
import { SoundSystem } from '@/graphicsBackend/types'
|
|
4
|
+
|
|
5
|
+
export class ThreeJsSound implements SoundSystem {
|
|
6
|
+
audioListener: THREE.AudioListener | undefined
|
|
7
|
+
private readonly activeSounds = new Set<THREE.PositionalAudio>()
|
|
8
|
+
private readonly audioContext: AudioContext | undefined
|
|
9
|
+
private readonly soundVolumes = new Map<THREE.PositionalAudio, number>()
|
|
10
|
+
baseVolume = 1
|
|
11
|
+
|
|
12
|
+
constructor(public worldRenderer: WorldRendererThree) {
|
|
13
|
+
worldRenderer.onWorldSwitched.push(() => {
|
|
14
|
+
this.stopAll()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
worldRenderer.onReactiveConfigUpdated('volume', (volume) => {
|
|
18
|
+
this.changeVolume(volume)
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
initAudioListener() {
|
|
23
|
+
if (this.audioListener) return
|
|
24
|
+
this.audioListener = new THREE.AudioListener()
|
|
25
|
+
this.worldRenderer.camera.add(this.audioListener)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
playSound(position: { x: number, y: number, z: number }, path: string, volume = 1, pitch = 1, timeout = 500) {
|
|
29
|
+
this.initAudioListener()
|
|
30
|
+
|
|
31
|
+
const sound = new THREE.PositionalAudio(this.audioListener!)
|
|
32
|
+
this.activeSounds.add(sound)
|
|
33
|
+
this.soundVolumes.set(sound, volume)
|
|
34
|
+
|
|
35
|
+
const audioLoader = new THREE.AudioLoader()
|
|
36
|
+
const start = Date.now()
|
|
37
|
+
void audioLoader.loadAsync(path).then((buffer) => {
|
|
38
|
+
if (Date.now() - start > timeout) {
|
|
39
|
+
console.warn('Ignored playing sound', path, 'due to timeout:', timeout, 'ms <', Date.now() - start, 'ms')
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
// play
|
|
43
|
+
sound.setBuffer(buffer)
|
|
44
|
+
sound.setRefDistance(20)
|
|
45
|
+
sound.setVolume(volume * this.baseVolume)
|
|
46
|
+
sound.setPlaybackRate(pitch) // set the pitch
|
|
47
|
+
this.worldRenderer.scene.add(sound)
|
|
48
|
+
// set sound position
|
|
49
|
+
sound.position.set(position.x, position.y, position.z)
|
|
50
|
+
sound.onEnded = () => {
|
|
51
|
+
this.worldRenderer.scene.remove(sound)
|
|
52
|
+
if (sound.source) {
|
|
53
|
+
sound.disconnect()
|
|
54
|
+
}
|
|
55
|
+
this.activeSounds.delete(sound)
|
|
56
|
+
this.soundVolumes.delete(sound)
|
|
57
|
+
audioLoader.manager.itemEnd(path)
|
|
58
|
+
}
|
|
59
|
+
sound.play()
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
stopAll() {
|
|
64
|
+
for (const sound of this.activeSounds) {
|
|
65
|
+
if (!sound) continue
|
|
66
|
+
sound.stop()
|
|
67
|
+
if (sound.source) {
|
|
68
|
+
sound.disconnect()
|
|
69
|
+
}
|
|
70
|
+
this.worldRenderer.scene.remove(sound)
|
|
71
|
+
}
|
|
72
|
+
this.activeSounds.clear()
|
|
73
|
+
this.soundVolumes.clear()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
changeVolume(volume: number) {
|
|
77
|
+
this.baseVolume = volume
|
|
78
|
+
for (const [sound, individualVolume] of this.soundVolumes) {
|
|
79
|
+
sound.setVolume(individualVolume * this.baseVolume)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
destroy() {
|
|
84
|
+
this.stopAll()
|
|
85
|
+
// Remove and cleanup audio listener
|
|
86
|
+
if (this.audioListener) {
|
|
87
|
+
this.audioListener.removeFromParent()
|
|
88
|
+
this.audioListener = undefined
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
playTestSound() {
|
|
93
|
+
this.playSound(this.worldRenderer.camera.position, '/sound.mp3')
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import { getLoadedImage } from 'mc-assets/dist/utils'
|
|
3
|
+
import { createCanvas, loadImageFromUrl } from '../lib/utils'
|
|
4
|
+
|
|
5
|
+
export const disposeObject = (obj: THREE.Object3D, cleanTextures = false) => {
|
|
6
|
+
// not cleaning texture there as it might be used by other objects, but would be good to also do that
|
|
7
|
+
if (obj instanceof THREE.Mesh) {
|
|
8
|
+
obj.geometry?.dispose?.()
|
|
9
|
+
obj.material?.dispose?.()
|
|
10
|
+
}
|
|
11
|
+
if (obj.children) {
|
|
12
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
13
|
+
obj.children.forEach(child => disposeObject(child, cleanTextures))
|
|
14
|
+
}
|
|
15
|
+
if (cleanTextures) {
|
|
16
|
+
if (obj instanceof THREE.Mesh) {
|
|
17
|
+
obj.material?.map?.dispose?.()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let textureCache: Record<string, THREE.Texture> = {}
|
|
23
|
+
let imagesPromises: Record<string, Promise<THREE.Texture>> = {}
|
|
24
|
+
|
|
25
|
+
export const loadThreeJsTextureFromUrlSync = (imageUrl: string) => {
|
|
26
|
+
const texture = new THREE.Texture()
|
|
27
|
+
const promise = loadImageFromUrl(imageUrl).then(bitmap => {
|
|
28
|
+
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height)
|
|
29
|
+
const ctx = canvas.getContext('2d')!
|
|
30
|
+
ctx.drawImage(bitmap, 0, 0)
|
|
31
|
+
texture.source.data = canvas
|
|
32
|
+
texture.needsUpdate = true
|
|
33
|
+
return texture
|
|
34
|
+
})
|
|
35
|
+
return {
|
|
36
|
+
texture,
|
|
37
|
+
promise
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// MAIN
|
|
41
|
+
// const texture = new THREE.Texture()
|
|
42
|
+
// const promise = getLoadedImage(imageUrl).then(image => {
|
|
43
|
+
// texture.image = image
|
|
44
|
+
// texture.needsUpdate = true
|
|
45
|
+
// return texture
|
|
46
|
+
// })
|
|
47
|
+
// return {
|
|
48
|
+
// texture,
|
|
49
|
+
// promise
|
|
50
|
+
// }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const loadThreeJsTextureFromUrl = async (imageUrl: string) => {
|
|
54
|
+
return loadThreeJsTextureFromUrlSync(imageUrl).texture
|
|
55
|
+
|
|
56
|
+
// MAIN
|
|
57
|
+
// const loaded = new THREE.TextureLoader().loadAsync(imageUrl)
|
|
58
|
+
// return loaded
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const loadThreeJsTextureFromBitmap = (image: ImageBitmap) => {
|
|
62
|
+
const canvas = createCanvas(image.width, image.height)
|
|
63
|
+
const ctx = canvas.getContext('2d')!
|
|
64
|
+
ctx.drawImage(image, 0, 0)
|
|
65
|
+
const texture = new THREE.Texture(canvas)
|
|
66
|
+
texture.magFilter = THREE.NearestFilter
|
|
67
|
+
texture.minFilter = THREE.NearestFilter
|
|
68
|
+
return texture
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function loadTexture (texture: string, cb: (texture: THREE.Texture) => void, onLoad?: () => void): Promise<void> {
|
|
72
|
+
const cached = textureCache[texture]
|
|
73
|
+
if (!cached) {
|
|
74
|
+
const { promise, resolve } = Promise.withResolvers<THREE.Texture>()
|
|
75
|
+
const t = loadThreeJsTextureFromUrlSync(texture)
|
|
76
|
+
textureCache[texture] = t.texture
|
|
77
|
+
void t.promise.then(resolve)
|
|
78
|
+
imagesPromises[texture] = promise
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
cb(textureCache[texture])
|
|
82
|
+
void imagesPromises[texture].then(() => {
|
|
83
|
+
onLoad?.()
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const clearTextureCache = () => {
|
|
88
|
+
textureCache = {}
|
|
89
|
+
imagesPromises = {}
|
|
90
|
+
}
|