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,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppViewer - Base application viewer for Minecraft renderer.
|
|
3
|
+
*
|
|
4
|
+
* This is the main entry point for integrating the renderer into an application.
|
|
5
|
+
* It manages:
|
|
6
|
+
* - Graphics backend loading and lifecycle
|
|
7
|
+
* - World view management
|
|
8
|
+
* - Player state
|
|
9
|
+
* - Renderer state
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Vec3 } from 'vec3'
|
|
13
|
+
import { proxy } from 'valtio'
|
|
14
|
+
import type {
|
|
15
|
+
GraphicsBackend,
|
|
16
|
+
GraphicsBackendConfig,
|
|
17
|
+
GraphicsBackendLoader,
|
|
18
|
+
GraphicsInitOptions,
|
|
19
|
+
DisplayWorldOptions,
|
|
20
|
+
RendererReactiveState,
|
|
21
|
+
NonReactiveState
|
|
22
|
+
} from './types'
|
|
23
|
+
import { WorldView, WorldProvider, WorldViewWorker } from '../worldView'
|
|
24
|
+
import { getInitialPlayerState } from './playerState'
|
|
25
|
+
import { defaultWorldRendererConfig, defaultGraphicsBackendConfig, getDefaultRendererState } from './config'
|
|
26
|
+
import type { WorldRendererConfig } from '../lib/worldrendererCommon'
|
|
27
|
+
import { PlayerStateReactive } from '@/playerState/playerState'
|
|
28
|
+
import { ResourcesManager, ResourcesManagerTransferred } from '@/resourcesManager'
|
|
29
|
+
|
|
30
|
+
export interface AppViewerOptions {
|
|
31
|
+
config?: Partial<GraphicsBackendConfig>
|
|
32
|
+
rendererConfig?: Partial<WorldRendererConfig>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* AppViewer - Main application viewer class.
|
|
37
|
+
*
|
|
38
|
+
* This is designed to be extended for specific use cases (game client, playground, etc.)
|
|
39
|
+
*/
|
|
40
|
+
export class AppViewer {
|
|
41
|
+
waitBackendLoadPromises: Promise<void>[] = []
|
|
42
|
+
|
|
43
|
+
// World view
|
|
44
|
+
worldView?: WorldView
|
|
45
|
+
|
|
46
|
+
// Configuration
|
|
47
|
+
readonly config: GraphicsBackendConfig
|
|
48
|
+
readonly inWorldRenderingConfig: WorldRendererConfig
|
|
49
|
+
|
|
50
|
+
// Backend
|
|
51
|
+
backend?: GraphicsBackend
|
|
52
|
+
backendLoader?: GraphicsBackendLoader
|
|
53
|
+
private currentState?: {
|
|
54
|
+
method: string
|
|
55
|
+
args: any[]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Display state
|
|
59
|
+
currentDisplay: 'menu' | 'world' | null = null
|
|
60
|
+
|
|
61
|
+
// Player state
|
|
62
|
+
playerState = {
|
|
63
|
+
reactive: getInitialPlayerState()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Renderer state
|
|
67
|
+
rendererState: RendererReactiveState
|
|
68
|
+
nonReactiveState: NonReactiveState
|
|
69
|
+
|
|
70
|
+
// World ready promise
|
|
71
|
+
worldReady!: Promise<void>
|
|
72
|
+
private resolveWorldReady!: () => void
|
|
73
|
+
|
|
74
|
+
// Timing
|
|
75
|
+
lastCamUpdate = 0
|
|
76
|
+
|
|
77
|
+
constructor(options: AppViewerOptions = {}, public resourcesManager: ResourcesManager = new ResourcesManager()) {
|
|
78
|
+
this.config = {
|
|
79
|
+
...defaultGraphicsBackendConfig,
|
|
80
|
+
...options.config
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.inWorldRenderingConfig = proxy({
|
|
84
|
+
...defaultWorldRendererConfig,
|
|
85
|
+
...options.rendererConfig
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const defaultState = getDefaultRendererState()
|
|
89
|
+
this.rendererState = defaultState.reactive
|
|
90
|
+
this.nonReactiveState = defaultState.nonReactive
|
|
91
|
+
|
|
92
|
+
this.initWorldReadyPromise()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private initWorldReadyPromise(): void {
|
|
96
|
+
const { promise, resolve } = Promise.withResolvers<void>()
|
|
97
|
+
this.worldReady = promise
|
|
98
|
+
this.resolveWorldReady = resolve
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Load a graphics backend.
|
|
103
|
+
*/
|
|
104
|
+
async loadBackend(loader: GraphicsBackendLoader): Promise<void> {
|
|
105
|
+
if (this.backend) {
|
|
106
|
+
this.disconnectBackend()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
await Promise.all(this.waitBackendLoadPromises)
|
|
110
|
+
this.waitBackendLoadPromises = []
|
|
111
|
+
|
|
112
|
+
this.backendLoader = loader
|
|
113
|
+
|
|
114
|
+
const loaderOptions: GraphicsInitOptions = { // todo!
|
|
115
|
+
resourcesManager: this.resourcesManager! as unknown as ResourcesManagerTransferred,
|
|
116
|
+
config: this.config,
|
|
117
|
+
callbacks: {
|
|
118
|
+
displayCriticalError: (error) => {
|
|
119
|
+
console.error('[AppViewer] Critical error:', error)
|
|
120
|
+
},
|
|
121
|
+
setRendererSpecificSettings: (key, value) => {
|
|
122
|
+
// Override in implementation
|
|
123
|
+
},
|
|
124
|
+
fireCustomEvent: (eventName, ...args) => {
|
|
125
|
+
// Override in implementation
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
rendererSpecificSettings: {}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const backendResult = loader(loaderOptions)
|
|
132
|
+
this.backend = await Promise.resolve(backendResult)
|
|
133
|
+
|
|
134
|
+
// Execute queued action if exists
|
|
135
|
+
if (this.currentState) {
|
|
136
|
+
if (this.currentState.method === 'startPanorama') {
|
|
137
|
+
this.startPanorama()
|
|
138
|
+
} else {
|
|
139
|
+
const { method, args } = this.currentState
|
|
140
|
+
; (this.backend as any)[method](...args)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Start the world with a given world provider and render distance.
|
|
147
|
+
*/
|
|
148
|
+
async startWorld(
|
|
149
|
+
world: WorldProvider,
|
|
150
|
+
renderDistance: number,
|
|
151
|
+
playerStateReactive: PlayerStateReactive = this.playerState.reactive,
|
|
152
|
+
startPosition?: Vec3
|
|
153
|
+
): Promise<boolean> {
|
|
154
|
+
if (this.currentDisplay === 'world') {
|
|
155
|
+
throw new Error('World already started')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.currentDisplay = 'world'
|
|
159
|
+
const finalStartPosition = startPosition ?? new Vec3(0, 64, 0)
|
|
160
|
+
|
|
161
|
+
this.worldView = new WorldView(world, renderDistance, finalStartPosition)
|
|
162
|
+
this.worldView.isPlayground = this.inWorldRenderingConfig.isPlayground
|
|
163
|
+
|
|
164
|
+
const displayWorldOptions: DisplayWorldOptions = {
|
|
165
|
+
version: this.resourcesManager?.currentConfig?.version ?? '1.20.4',
|
|
166
|
+
worldView: this.worldView as unknown as WorldViewWorker,
|
|
167
|
+
inWorldRenderingConfig: this.inWorldRenderingConfig,
|
|
168
|
+
playerStateReactive,
|
|
169
|
+
rendererState: this.rendererState,
|
|
170
|
+
nonReactiveState: this.nonReactiveState
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let promise: Promise<void> | undefined
|
|
174
|
+
if (this.backend) {
|
|
175
|
+
const result = this.backend.startWorld(displayWorldOptions)
|
|
176
|
+
if (result && typeof result.then === 'function') {
|
|
177
|
+
promise = result
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
this.currentState = { method: 'startWorld', args: [displayWorldOptions] }
|
|
182
|
+
|
|
183
|
+
await promise
|
|
184
|
+
this.resolveWorldReady()
|
|
185
|
+
return !!promise
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Start panorama display (menu background).
|
|
190
|
+
*/
|
|
191
|
+
startPanorama(): void {
|
|
192
|
+
if (this.currentDisplay === 'menu') return
|
|
193
|
+
|
|
194
|
+
if (this.backend) {
|
|
195
|
+
this.currentDisplay = 'menu'
|
|
196
|
+
this.backend.startPanorama()
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
this.currentState = { method: 'startPanorama', args: [] }
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Reset the backend.
|
|
204
|
+
*/
|
|
205
|
+
resetBackend(cleanState = false): void {
|
|
206
|
+
this.disconnectBackend(cleanState)
|
|
207
|
+
if (this.backendLoader) {
|
|
208
|
+
void this.loadBackend(this.backendLoader)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Disconnect the backend.
|
|
214
|
+
*/
|
|
215
|
+
disconnectBackend(cleanState = false): void {
|
|
216
|
+
if (cleanState) {
|
|
217
|
+
this.currentState = undefined
|
|
218
|
+
this.currentDisplay = null
|
|
219
|
+
this.worldView = undefined
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (this.backend) {
|
|
223
|
+
this.backend.disconnect()
|
|
224
|
+
this.backend = undefined
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
this.currentDisplay = null
|
|
228
|
+
this.initWorldReadyPromise()
|
|
229
|
+
this.rendererState = proxy(getDefaultRendererState().reactive)
|
|
230
|
+
this.nonReactiveState = getDefaultRendererState().nonReactive
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Update camera position and rotation.
|
|
235
|
+
*/
|
|
236
|
+
updateCamera(pos: Vec3 | null, yaw: number, pitch: number): void {
|
|
237
|
+
this.backend?.updateCamera(pos, yaw, pitch)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Set rendering active/paused.
|
|
242
|
+
*/
|
|
243
|
+
setRendering(rendering: boolean): void {
|
|
244
|
+
this.backend?.setRendering(rendering)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Start world with bot (convenience method).
|
|
249
|
+
*/
|
|
250
|
+
async startWithBot(bot: any, renderDistance: number): Promise<void> {
|
|
251
|
+
await this.startWorld(bot.world, renderDistance)
|
|
252
|
+
if (this.worldView) {
|
|
253
|
+
// Listen to bot events if worldView supports it
|
|
254
|
+
if (typeof (this.worldView as any).listenToBot === 'function') {
|
|
255
|
+
(this.worldView as any).listenToBot(bot)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Destroy all resources including resource manager.
|
|
262
|
+
*/
|
|
263
|
+
destroyAll(): void {
|
|
264
|
+
this.disconnectBackend(true)
|
|
265
|
+
if (this.resourcesManager && typeof (this.resourcesManager as any).destroy === 'function') {
|
|
266
|
+
(this.resourcesManager as any).destroy()
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get utility methods.
|
|
272
|
+
*/
|
|
273
|
+
get utils() {
|
|
274
|
+
const backend = this.backend
|
|
275
|
+
return {
|
|
276
|
+
async waitingForChunks(): Promise<void> {
|
|
277
|
+
if ((backend as any)?.worldState?.allChunksLoaded) return
|
|
278
|
+
|
|
279
|
+
return new Promise<void>((resolve) => {
|
|
280
|
+
const interval = setInterval(() => {
|
|
281
|
+
if ((backend as any)?.worldState?.allChunksLoaded) {
|
|
282
|
+
clearInterval(interval)
|
|
283
|
+
resolve()
|
|
284
|
+
}
|
|
285
|
+
}, 100)
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Destroy the viewer and cleanup resources.
|
|
293
|
+
*/
|
|
294
|
+
destroy(): void {
|
|
295
|
+
this.disconnectBackend(true)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default configurations for the graphics backend and world renderer.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { proxy } from 'valtio'
|
|
6
|
+
import type {
|
|
7
|
+
WorldRendererConfig,
|
|
8
|
+
GraphicsBackendConfig,
|
|
9
|
+
RendererReactiveState,
|
|
10
|
+
NonReactiveState
|
|
11
|
+
} from './types'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default world renderer configuration.
|
|
15
|
+
* These settings control rendering behavior and visual options.
|
|
16
|
+
*/
|
|
17
|
+
export const defaultWorldRendererConfig: WorldRendererConfig = {
|
|
18
|
+
paused: false,
|
|
19
|
+
|
|
20
|
+
// Debug settings
|
|
21
|
+
showChunkBorders: false,
|
|
22
|
+
enableDebugOverlay: false,
|
|
23
|
+
debugModelVariant: undefined,
|
|
24
|
+
|
|
25
|
+
// Performance settings
|
|
26
|
+
mesherWorkers: 4,
|
|
27
|
+
addChunksBatchWaitTime: 200,
|
|
28
|
+
_experimentalSmoothChunkLoading: true,
|
|
29
|
+
_renderByChunks: false,
|
|
30
|
+
|
|
31
|
+
// Rendering engine settings
|
|
32
|
+
dayCycle: true,
|
|
33
|
+
smoothLighting: true,
|
|
34
|
+
enableLighting: true,
|
|
35
|
+
starfield: true,
|
|
36
|
+
defaultSkybox: true,
|
|
37
|
+
renderEntities: true,
|
|
38
|
+
extraBlockRenderers: true,
|
|
39
|
+
foreground: true,
|
|
40
|
+
fov: 75,
|
|
41
|
+
volume: 1,
|
|
42
|
+
|
|
43
|
+
// Camera visual related settings
|
|
44
|
+
showHand: false,
|
|
45
|
+
viewBobbing: false,
|
|
46
|
+
renderEars: true,
|
|
47
|
+
highlightBlockColor: 'blue',
|
|
48
|
+
|
|
49
|
+
// Player models
|
|
50
|
+
fetchPlayerSkins: true,
|
|
51
|
+
skinTexturesProxy: undefined,
|
|
52
|
+
|
|
53
|
+
// VR settings
|
|
54
|
+
vrSupport: true,
|
|
55
|
+
vrPageGameRendering: true,
|
|
56
|
+
|
|
57
|
+
// World settings
|
|
58
|
+
clipWorldBelowY: undefined,
|
|
59
|
+
isPlayground: false,
|
|
60
|
+
instantCameraUpdate: false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Default graphics backend configuration.
|
|
65
|
+
*/
|
|
66
|
+
export const defaultGraphicsBackendConfig: GraphicsBackendConfig = {
|
|
67
|
+
fpsLimit: undefined,
|
|
68
|
+
powerPreference: undefined,
|
|
69
|
+
sceneBackground: 'lightblue',
|
|
70
|
+
timeoutRendering: false
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Creates a new proxied world renderer config with default values.
|
|
75
|
+
*/
|
|
76
|
+
export const createWorldRendererConfig = (overrides: Partial<WorldRendererConfig> = {}): WorldRendererConfig => {
|
|
77
|
+
return proxy({
|
|
78
|
+
...defaultWorldRendererConfig,
|
|
79
|
+
...overrides
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get default renderer reactive state.
|
|
85
|
+
*/
|
|
86
|
+
export const getDefaultRendererState = (): {
|
|
87
|
+
reactive: RendererReactiveState
|
|
88
|
+
nonReactive: NonReactiveState
|
|
89
|
+
} => {
|
|
90
|
+
return {
|
|
91
|
+
reactive: proxy({
|
|
92
|
+
world: {
|
|
93
|
+
chunksLoaded: new Set<string>(),
|
|
94
|
+
heightmaps: new Map<string, Uint8Array>(),
|
|
95
|
+
allChunksLoaded: false,
|
|
96
|
+
mesherWork: false,
|
|
97
|
+
intersectMedia: null
|
|
98
|
+
},
|
|
99
|
+
renderer: '...',
|
|
100
|
+
preventEscapeMenu: false
|
|
101
|
+
}),
|
|
102
|
+
nonReactive: {
|
|
103
|
+
fps: 0,
|
|
104
|
+
worstRenderTime: 0,
|
|
105
|
+
avgRenderTime: 0,
|
|
106
|
+
world: {
|
|
107
|
+
chunksLoaded: new Set(),
|
|
108
|
+
chunksTotalNumber: 0
|
|
109
|
+
},
|
|
110
|
+
renderer: {
|
|
111
|
+
timeline: {
|
|
112
|
+
live: [],
|
|
113
|
+
frozen: [],
|
|
114
|
+
lastSecond: []
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Player State - Initial player state for renderer.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { proxy } from 'valtio'
|
|
6
|
+
import type { PlayerStateReactive } from './types'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get initial player state with default values.
|
|
10
|
+
*/
|
|
11
|
+
export const getInitialPlayerState = (): PlayerStateReactive => proxy({
|
|
12
|
+
playerSkin: undefined,
|
|
13
|
+
inWater: false,
|
|
14
|
+
waterBreathing: false,
|
|
15
|
+
backgroundColor: [0, 0, 0] as [number, number, number],
|
|
16
|
+
ambientLight: 0,
|
|
17
|
+
directionalLight: 0,
|
|
18
|
+
eyeHeight: 0,
|
|
19
|
+
gameMode: undefined,
|
|
20
|
+
lookingAtBlock: undefined,
|
|
21
|
+
diggingBlock: undefined,
|
|
22
|
+
movementState: 'NOT_MOVING',
|
|
23
|
+
onGround: true,
|
|
24
|
+
sneaking: false,
|
|
25
|
+
flying: false,
|
|
26
|
+
sprinting: false,
|
|
27
|
+
itemUsageTicks: 0,
|
|
28
|
+
username: '',
|
|
29
|
+
onlineMode: false,
|
|
30
|
+
lightingDisabled: false,
|
|
31
|
+
shouldHideHand: false,
|
|
32
|
+
heldItemMain: undefined,
|
|
33
|
+
heldItemOff: undefined,
|
|
34
|
+
perspective: 'first_person',
|
|
35
|
+
onFire: false,
|
|
36
|
+
cameraSpectatingEntity: undefined,
|
|
37
|
+
team: undefined,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get player state utils.
|
|
42
|
+
*/
|
|
43
|
+
export const getPlayerStateUtils = (reactive: PlayerStateReactive) => ({
|
|
44
|
+
isSpectator() {
|
|
45
|
+
return reactive.gameMode === 'spectator'
|
|
46
|
+
},
|
|
47
|
+
isSpectatingEntity() {
|
|
48
|
+
return reactive.cameraSpectatingEntity !== undefined && reactive.gameMode === 'spectator'
|
|
49
|
+
},
|
|
50
|
+
isThirdPerson() {
|
|
51
|
+
if (this.isSpectatingEntity()) return false
|
|
52
|
+
return reactive.perspective === 'third_person_back' || reactive.perspective === 'third_person_front'
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get initial player state for renderer.
|
|
58
|
+
*/
|
|
59
|
+
export const getInitialPlayerStateRenderer = () => ({
|
|
60
|
+
reactive: getInitialPlayerState()
|
|
61
|
+
})
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphics Backend Types
|
|
3
|
+
*
|
|
4
|
+
* Core types for the graphics backend system.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { WorldRendererConfig } from '@/lib/worldrendererCommon'
|
|
8
|
+
import { PlayerStateReactive } from '@/playerState/playerState'
|
|
9
|
+
import { ResourcesManagerTransferred } from '@/resourcesManager'
|
|
10
|
+
import { WorldViewWorker } from '@/worldView'
|
|
11
|
+
import { Vec3 } from 'vec3'
|
|
12
|
+
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Graphics Backend Configuration
|
|
15
|
+
// ============================================================================
|
|
16
|
+
|
|
17
|
+
export type MaybePromise<T> = Promise<T> | T
|
|
18
|
+
|
|
19
|
+
export interface SoundSystem {
|
|
20
|
+
playSound: (position: { x: number, y: number, z: number }, path: string, volume?: number, pitch?: number, timeout?: number) => void
|
|
21
|
+
destroy: () => void
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Graphics backend configuration */
|
|
25
|
+
export interface GraphicsBackendConfig {
|
|
26
|
+
fpsLimit?: number
|
|
27
|
+
powerPreference?: 'high-performance' | 'low-power'
|
|
28
|
+
statsVisible?: number
|
|
29
|
+
sceneBackground: string
|
|
30
|
+
timeoutRendering?: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// World Renderer Configuration
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// State Types
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
/** Frame timing event for performance monitoring */
|
|
42
|
+
export interface FrameTimingEvent {
|
|
43
|
+
type: 'frameStart' | 'frameEnd' | 'cameraUpdate' | 'frameDisplay'
|
|
44
|
+
timestamp: number
|
|
45
|
+
duration?: number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Non-reactive state for performance data */
|
|
49
|
+
export interface NonReactiveState {
|
|
50
|
+
fps: number
|
|
51
|
+
worstRenderTime: number
|
|
52
|
+
avgRenderTime: number
|
|
53
|
+
world: {
|
|
54
|
+
chunksLoaded: Set<string>
|
|
55
|
+
chunksTotalNumber: number
|
|
56
|
+
allChunksLoaded?: boolean
|
|
57
|
+
}
|
|
58
|
+
renderer: {
|
|
59
|
+
timeline: {
|
|
60
|
+
live: FrameTimingEvent[]
|
|
61
|
+
frozen: FrameTimingEvent[]
|
|
62
|
+
lastSecond: FrameTimingEvent[]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Renderer reactive state */
|
|
68
|
+
export interface RendererReactiveState {
|
|
69
|
+
world: {
|
|
70
|
+
chunksLoaded: Set<string>
|
|
71
|
+
heightmaps: Map<string, Uint8Array>
|
|
72
|
+
allChunksLoaded: boolean
|
|
73
|
+
mesherWork: boolean
|
|
74
|
+
intersectMedia: any | null
|
|
75
|
+
}
|
|
76
|
+
renderer: string
|
|
77
|
+
preventEscapeMenu: boolean
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ============================================================================
|
|
81
|
+
// Player State Types
|
|
82
|
+
// ============================================================================
|
|
83
|
+
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// Graphics Backend Interfaces
|
|
86
|
+
// ============================================================================
|
|
87
|
+
|
|
88
|
+
/** Graphics initialization options */
|
|
89
|
+
export interface GraphicsInitOptions<S = any> {
|
|
90
|
+
resourcesManager: ResourcesManagerTransferred
|
|
91
|
+
config: GraphicsBackendConfig
|
|
92
|
+
rendererSpecificSettings: S
|
|
93
|
+
callbacks: {
|
|
94
|
+
displayCriticalError: (error: Error) => void
|
|
95
|
+
setRendererSpecificSettings: (key: string, value: any) => void
|
|
96
|
+
fireCustomEvent: (eventName: string, ...args: any[]) => void
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Display world options for starting world rendering */
|
|
101
|
+
export interface DisplayWorldOptions {
|
|
102
|
+
version: string
|
|
103
|
+
worldView: WorldViewWorker
|
|
104
|
+
inWorldRenderingConfig: WorldRendererConfig
|
|
105
|
+
playerStateReactive: PlayerStateReactive
|
|
106
|
+
rendererState: RendererReactiveState
|
|
107
|
+
nonReactiveState: NonReactiveState
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Graphics backend interface */
|
|
111
|
+
export interface GraphicsBackend {
|
|
112
|
+
id: string
|
|
113
|
+
displayName: string
|
|
114
|
+
startPanorama(): Promise<void>
|
|
115
|
+
startWorld(options: DisplayWorldOptions): Promise<void>
|
|
116
|
+
disconnect(): void
|
|
117
|
+
setRendering(rendering: boolean): void
|
|
118
|
+
updateCamera(pos: Vec3 | null, yaw: number, pitch: number): void
|
|
119
|
+
soundSystem?: any
|
|
120
|
+
backendMethods?: any
|
|
121
|
+
getDebugOverlay?(): { entitiesString?: string }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Graphics backend loader function type */
|
|
125
|
+
export type GraphicsBackendLoader = ((options: GraphicsInitOptions) => MaybePromise<GraphicsBackend>) & {
|
|
126
|
+
id: string
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// World View Interface
|
|
131
|
+
// ============================================================================
|
|
132
|
+
|
|
133
|
+
/** World view interface for type compatibility */
|
|
134
|
+
export interface WorldViewLike {
|
|
135
|
+
isPlayground?: boolean
|
|
136
|
+
addWaitTime?: number
|
|
137
|
+
loadedChunks: Record<string, boolean>
|
|
138
|
+
init(pos: Vec3): Promise<void>
|
|
139
|
+
setBlockStateId(pos: Vec3, stateId: number): void
|
|
140
|
+
unloadAllChunks(): void
|
|
141
|
+
emit(event: string, ...args: any[]): boolean
|
|
142
|
+
on(event: string, callback: (...args: any[]) => void): void
|
|
143
|
+
}
|