minecraft-renderer 0.1.43 → 0.1.44
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/dist/minecraft-renderer.js +59 -59
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +458 -458
- package/package.json +1 -1
- package/src/graphicsBackend/appViewer.ts +19 -7
- package/src/graphicsBackend/types.ts +5 -1
- package/src/index.ts +33 -0
- package/src/lib/ui/newStats.ts +16 -2
- package/src/lib/worldrendererCommon.ts +2 -2
- package/src/three/entities.ts +22 -6
- package/src/three/graphicsBackendBase.ts +28 -20
- package/src/three/graphicsBackendOffThread.ts +1 -2
- package/src/three/menuBackground/activeView.ts +19 -0
- package/src/three/menuBackground/classic.ts +148 -0
- package/src/three/menuBackground/config.ts +23 -0
- package/src/three/menuBackground/defaultOptions.ts +141 -0
- package/src/three/menuBackground/futuristic.ts +859 -0
- package/src/three/menuBackground/index.ts +36 -0
- package/src/three/menuBackground/renderer.ts +97 -0
- package/src/three/menuBackground/shared.ts +3 -0
- package/src/three/menuBackground/types.ts +37 -0
- package/src/three/menuBackground/worldBlocks.ts +144 -0
- package/src/three/waypointSprite.ts +108 -106
- package/src/three/worldRendererThree.ts +9 -12
- package/src/three/panorama.ts +0 -312
- package/src/three/panoramaShared.ts +0 -2
|
@@ -9,7 +9,7 @@ import { renderSign } from '../sign-renderer'
|
|
|
9
9
|
import { DisplayWorldOptions, GraphicsInitOptions } from '../graphicsBackend/types'
|
|
10
10
|
import { chunkPos, sectionPos } from '../lib/simpleUtils'
|
|
11
11
|
import { WorldRendererCommon } from '../lib/worldrendererCommon'
|
|
12
|
-
import { addNewStat } from '../lib/ui/newStats'
|
|
12
|
+
import { addNewStat, MC_RENDERER_DEBUG_OVERLAY_CLASS } from '../lib/ui/newStats'
|
|
13
13
|
import { MesherGeometryOutput } from '../mesher-shared/shared'
|
|
14
14
|
import { ItemSpecificContextProperties } from '../playerState/types'
|
|
15
15
|
import { setBlockPosition } from '../mesher-shared/standaloneRenderer'
|
|
@@ -387,7 +387,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
387
387
|
if ((prop === 'x' || prop === 'y' || prop === 'z') && typeof value === 'number' && Math.abs(value) > WORLD_COORD_THRESHOLD) {
|
|
388
388
|
warnOnce()
|
|
389
389
|
}
|
|
390
|
-
;(target as any)[prop] = value
|
|
390
|
+
; (target as any)[prop] = value
|
|
391
391
|
return true
|
|
392
392
|
},
|
|
393
393
|
get(target, prop, receiver) {
|
|
@@ -701,22 +701,19 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
701
701
|
addDebugOverlay() {
|
|
702
702
|
if (this.debugOverlayAdded) return
|
|
703
703
|
this.debugOverlayAdded = true
|
|
704
|
-
const pane = addNewStat('debug-overlay')
|
|
704
|
+
const pane = addNewStat('debug-overlay', 80, 0, undefined, { className: MC_RENDERER_DEBUG_OVERLAY_CLASS })
|
|
705
705
|
setInterval(() => {
|
|
706
706
|
pane.setVisibility(this.displayAdvancedStats)
|
|
707
707
|
if (this.displayAdvancedStats) {
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
}
|
|
708
|
+
const formatFull = (num: number) => new Intl.NumberFormat('en-US', {}).format(num)
|
|
709
|
+
const formatCompact = (num: number) => new Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 1 }).format(num)
|
|
711
710
|
let text = ''
|
|
712
|
-
text += `
|
|
713
|
-
text += `
|
|
714
|
-
text += `
|
|
715
|
-
text += `F: ${formatBigNumber(this.tilesRendered)} `
|
|
716
|
-
text += `B: ${formatBigNumber(this.blocksRendered)} `
|
|
711
|
+
text += `TE: ${formatFull(this.renderer.info.memory.textures)} `
|
|
712
|
+
text += `F: ${formatCompact(this.tilesRendered)} `
|
|
713
|
+
text += `B: ${formatCompact(this.blocksRendered)} `
|
|
717
714
|
text += `MEM: ${this.chunkMeshManager.getEstimatedMemoryUsage().total} `
|
|
718
715
|
const poolStats = this.chunkMeshManager.getStats()
|
|
719
|
-
text += `POOL: ${poolStats.activeCount}/${poolStats.poolSize}
|
|
716
|
+
text += `POOL: ${poolStats.activeCount}/${poolStats.poolSize}`
|
|
720
717
|
pane.updateText(text)
|
|
721
718
|
this.backendInfoReport = text
|
|
722
719
|
}
|
package/src/three/panorama.ts
DELETED
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
//@ts-nocheck
|
|
2
|
-
import { join } from 'path'
|
|
3
|
-
import * as THREE from 'three'
|
|
4
|
-
import { getSyncWorld } from '../playground/shared'
|
|
5
|
-
import { Vec3 } from 'vec3'
|
|
6
|
-
import * as tweenJs from '@tweenjs/tween.js'
|
|
7
|
-
import type { GraphicsInitOptions } from '../graphicsBackend/types'
|
|
8
|
-
import { WorldRendererCommon } from '../lib/worldrendererCommon'
|
|
9
|
-
import { defaultWorldRendererConfig, getDefaultRendererState } from '../graphicsBackend/config'
|
|
10
|
-
import { ResourcesManager, ResourcesManagerTransferred } from '../resourcesManager/resourcesManager'
|
|
11
|
-
import { getInitialPlayerStateRenderer } from '../graphicsBackend/playerState'
|
|
12
|
-
import { loadThreeJsTextureFromUrl, loadThreeJsTextureFromUrlSync } from './threeJsUtils'
|
|
13
|
-
import { WorldRendererThree } from './worldRendererThree'
|
|
14
|
-
import { EntityMesh } from './entity/EntityMesh'
|
|
15
|
-
import { DocumentRenderer } from './documentRenderer'
|
|
16
|
-
import { PANORAMA_VERSION } from './panoramaShared'
|
|
17
|
-
import { WorldView } from '../worldView'
|
|
18
|
-
|
|
19
|
-
const date = new Date()
|
|
20
|
-
const isChristmas = date.getMonth() === 11 && date.getDate() >= 24 && date.getDate() <= 26
|
|
21
|
-
|
|
22
|
-
const panoramaFiles = [
|
|
23
|
-
'panorama_3.webp', // right (+x)
|
|
24
|
-
'panorama_1.webp', // left (-x)
|
|
25
|
-
'panorama_4.webp', // top (+y)
|
|
26
|
-
'panorama_5.webp', // bottom (-y)
|
|
27
|
-
'panorama_0.webp', // front (+z)
|
|
28
|
-
'panorama_2.webp', // back (-z)
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
export class PanoramaRenderer {
|
|
32
|
-
private readonly camera: THREE.PerspectiveCamera
|
|
33
|
-
private scene: THREE.Scene
|
|
34
|
-
private readonly ambientLight: THREE.AmbientLight
|
|
35
|
-
private readonly directionalLight: THREE.DirectionalLight
|
|
36
|
-
private panoramaGroup: THREE.Object3D | null = null
|
|
37
|
-
private time = 0
|
|
38
|
-
private readonly abortController = new AbortController()
|
|
39
|
-
private worldRenderer: WorldRendererCommon | WorldRendererThree | undefined
|
|
40
|
-
public WorldRendererClass = WorldRendererThree
|
|
41
|
-
public startTimes = new Map<THREE.MeshBasicMaterial, number>()
|
|
42
|
-
|
|
43
|
-
constructor(private readonly documentRenderer: DocumentRenderer, private readonly options: GraphicsInitOptions, private readonly doWorldBlocksPanorama = false) {
|
|
44
|
-
this.scene = new THREE.Scene()
|
|
45
|
-
// #324568
|
|
46
|
-
this.scene.background = new THREE.Color(0x32_45_68)
|
|
47
|
-
|
|
48
|
-
// Add ambient light
|
|
49
|
-
this.ambientLight = new THREE.AmbientLight(0xcc_cc_cc)
|
|
50
|
-
this.scene.add(this.ambientLight)
|
|
51
|
-
|
|
52
|
-
// Add directional light
|
|
53
|
-
this.directionalLight = new THREE.DirectionalLight(0xff_ff_ff, 0.5)
|
|
54
|
-
this.directionalLight.position.set(1, 1, 0.5).normalize()
|
|
55
|
-
this.directionalLight.castShadow = true
|
|
56
|
-
this.scene.add(this.directionalLight)
|
|
57
|
-
|
|
58
|
-
this.camera = new THREE.PerspectiveCamera(85, this.documentRenderer.canvas.width / this.documentRenderer.canvas.height, 0.05, 1000)
|
|
59
|
-
this.camera.position.set(0, 0, 0)
|
|
60
|
-
this.camera.rotation.set(0, 0, 0)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async start() {
|
|
64
|
-
if (this.doWorldBlocksPanorama) {
|
|
65
|
-
await this.worldBlocksPanorama()
|
|
66
|
-
} else {
|
|
67
|
-
this.addClassicPanorama()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.documentRenderer.render = (sizeChanged = false) => {
|
|
72
|
-
if (sizeChanged) {
|
|
73
|
-
this.camera.aspect = this.documentRenderer.canvas.width / this.documentRenderer.canvas.height
|
|
74
|
-
this.camera.updateProjectionMatrix()
|
|
75
|
-
}
|
|
76
|
-
this.documentRenderer.renderer.render(this.scene, this.camera)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async debugImageInFrontOfCamera() {
|
|
81
|
-
const image = await loadThreeJsTextureFromUrl(join('background', 'panorama_0.webp'))
|
|
82
|
-
const mesh = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000), new THREE.MeshBasicMaterial({ map: image }))
|
|
83
|
-
mesh.position.set(0, 0, -500)
|
|
84
|
-
mesh.rotation.set(0, 0, 0)
|
|
85
|
-
this.scene.add(mesh)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
addClassicPanorama() {
|
|
89
|
-
const panorGeo = new THREE.BoxGeometry(1000, 1000, 1000)
|
|
90
|
-
const panorMaterials = [] as THREE.MeshBasicMaterial[]
|
|
91
|
-
const fadeInDuration = 200
|
|
92
|
-
|
|
93
|
-
// void this.debugImageInFrontOfCamera()
|
|
94
|
-
|
|
95
|
-
for (const file of panoramaFiles) {
|
|
96
|
-
const load = async () => {
|
|
97
|
-
const { texture } = loadThreeJsTextureFromUrlSync(join('background', isChristmas ? 'christmas' : '', file))
|
|
98
|
-
|
|
99
|
-
// Instead of using repeat/offset to flip, we'll use the texture matrix
|
|
100
|
-
texture.matrixAutoUpdate = false
|
|
101
|
-
texture.matrix.set(
|
|
102
|
-
-1, 0, 1, 0, 1, 0, 0, 0, 1
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
texture.wrapS = THREE.ClampToEdgeWrapping
|
|
106
|
-
texture.wrapT = THREE.ClampToEdgeWrapping
|
|
107
|
-
texture.minFilter = THREE.LinearFilter
|
|
108
|
-
texture.magFilter = THREE.LinearFilter
|
|
109
|
-
|
|
110
|
-
const material = new THREE.MeshBasicMaterial({
|
|
111
|
-
map: texture,
|
|
112
|
-
transparent: true,
|
|
113
|
-
side: THREE.DoubleSide,
|
|
114
|
-
depthWrite: false,
|
|
115
|
-
opacity: 0 // Start with 0 opacity
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
// Start fade-in when texture is loaded
|
|
119
|
-
this.startTimes.set(material, Date.now())
|
|
120
|
-
panorMaterials.push(material)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
void load()
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const panoramaBox = new THREE.Mesh(panorGeo, panorMaterials)
|
|
127
|
-
panoramaBox.onBeforeRender = () => {
|
|
128
|
-
this.time += 0.01
|
|
129
|
-
panoramaBox.rotation.y = Math.PI + this.time * 0.01
|
|
130
|
-
panoramaBox.rotation.z = Math.sin(-this.time * 0.001) * 0.001
|
|
131
|
-
|
|
132
|
-
// Time-based fade in animation for each material
|
|
133
|
-
for (const material of panorMaterials) {
|
|
134
|
-
const startTime = this.startTimes.get(material)
|
|
135
|
-
if (startTime) {
|
|
136
|
-
const elapsed = Date.now() - startTime
|
|
137
|
-
const progress = Math.min(1, elapsed / fadeInDuration)
|
|
138
|
-
material.opacity = progress
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const group = new THREE.Object3D()
|
|
144
|
-
group.add(panoramaBox)
|
|
145
|
-
|
|
146
|
-
if (!isChristmas) {
|
|
147
|
-
// Add entities
|
|
148
|
-
for (let i = 0; i < 20; i++) {
|
|
149
|
-
const m = new EntityMesh('1.16.4', 'squid').mesh
|
|
150
|
-
m.position.set(Math.random() * 30 - 15, Math.random() * 20 - 10, Math.random() * 10 - 17)
|
|
151
|
-
m.rotation.set(0, Math.PI + Math.random(), -Math.PI / 4, 'ZYX')
|
|
152
|
-
const v = Math.random() * 0.01
|
|
153
|
-
m.children[0].onBeforeRender = () => {
|
|
154
|
-
m.rotation.y += v
|
|
155
|
-
m.rotation.z = Math.cos(panoramaBox.rotation.y * 3) * Math.PI / 4 - Math.PI / 2
|
|
156
|
-
}
|
|
157
|
-
group.add(m)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
this.scene.add(group)
|
|
162
|
-
this.panoramaGroup = group
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async worldBlocksPanorama() {
|
|
166
|
-
const version = PANORAMA_VERSION
|
|
167
|
-
|
|
168
|
-
const fullResourceManager = new ResourcesManager()
|
|
169
|
-
|
|
170
|
-
fullResourceManager.currentConfig = { version, noInventoryGui: true, }
|
|
171
|
-
await fullResourceManager.updateAssetsData?.({})
|
|
172
|
-
if (this.abortController.signal.aborted) return
|
|
173
|
-
console.time('load panorama scene')
|
|
174
|
-
const world = getSyncWorld(version)
|
|
175
|
-
const PrismarineBlock = require('prismarine-block')
|
|
176
|
-
const Block = PrismarineBlock(version)
|
|
177
|
-
const mcData = (globalThis as any).mcData
|
|
178
|
-
const fullBlocks = mcData.blocksArray.filter(block => {
|
|
179
|
-
// if (block.name.includes('leaves')) return false
|
|
180
|
-
if (/* !block.name.includes('wool') && */!block.name.includes('stained_glass')/* && !block.name.includes('terracotta') */) return false
|
|
181
|
-
const b = Block.fromStateId(block.defaultState, 0)
|
|
182
|
-
if (b.shapes?.length !== 1) return false
|
|
183
|
-
const shape = b.shapes[0]
|
|
184
|
-
return shape[0] === 0 && shape[1] === 0 && shape[2] === 0 && shape[3] === 1 && shape[4] === 1 && shape[5] === 1
|
|
185
|
-
})
|
|
186
|
-
const Z = -15
|
|
187
|
-
const sizeX = 100
|
|
188
|
-
const sizeY = 100
|
|
189
|
-
for (let x = -sizeX; x < sizeX; x++) {
|
|
190
|
-
for (let y = -sizeY; y < sizeY; y++) {
|
|
191
|
-
const block = fullBlocks[Math.floor(Math.random() * fullBlocks.length)]
|
|
192
|
-
world.setBlockStateId(new Vec3(x, y, Z), block.defaultState)
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
this.camera.updateProjectionMatrix()
|
|
196
|
-
this.camera.position.set(0.5, sizeY / 2 + 0.5, 0.5)
|
|
197
|
-
this.camera.rotation.set(0, 0, 0)
|
|
198
|
-
const initPos = new Vec3(...this.camera.position.toArray())
|
|
199
|
-
const worldView = new WorldView(world, 2, initPos)
|
|
200
|
-
// worldView.addWaitTime = 0
|
|
201
|
-
if (this.abortController.signal.aborted) return
|
|
202
|
-
|
|
203
|
-
this.worldRenderer = new this.WorldRendererClass(
|
|
204
|
-
this.documentRenderer.renderer,
|
|
205
|
-
this.options,
|
|
206
|
-
{
|
|
207
|
-
version,
|
|
208
|
-
worldView,
|
|
209
|
-
inWorldRenderingConfig: defaultWorldRendererConfig,
|
|
210
|
-
playerStateReactive: getInitialPlayerStateRenderer().reactive,
|
|
211
|
-
rendererState: getDefaultRendererState().reactive,
|
|
212
|
-
nonReactiveState: getDefaultRendererState().nonReactive,
|
|
213
|
-
resourcesManager: fullResourceManager as ResourcesManagerTransferred // todo use guard instead
|
|
214
|
-
}
|
|
215
|
-
)
|
|
216
|
-
if (this.worldRenderer instanceof WorldRendererThree) {
|
|
217
|
-
this.scene = this.worldRenderer.realScene
|
|
218
|
-
}
|
|
219
|
-
void worldView.init(initPos)
|
|
220
|
-
|
|
221
|
-
await this.worldRenderer.waitForChunksToRender()
|
|
222
|
-
if (this.abortController.signal.aborted) return
|
|
223
|
-
// add small camera rotation to side on mouse move depending on absolute position of the cursor
|
|
224
|
-
const { camera } = this
|
|
225
|
-
const initX = camera.position.x
|
|
226
|
-
const initY = camera.position.y
|
|
227
|
-
let prevTwin: tweenJs.Tween<THREE.Vector3> | undefined
|
|
228
|
-
document.body.addEventListener('pointermove', (e) => {
|
|
229
|
-
if (e.pointerType !== 'mouse') return
|
|
230
|
-
const pos = new THREE.Vector2(e.clientX, e.clientY)
|
|
231
|
-
const SCALE = 0.2
|
|
232
|
-
/* -0.5 - 0.5 */
|
|
233
|
-
const xRel = pos.x / window.innerWidth - 0.5
|
|
234
|
-
const yRel = -(pos.y / window.innerHeight - 0.5)
|
|
235
|
-
prevTwin?.stop()
|
|
236
|
-
const to = {
|
|
237
|
-
x: initX + (xRel * SCALE),
|
|
238
|
-
y: initY + (yRel * SCALE)
|
|
239
|
-
}
|
|
240
|
-
prevTwin = new tweenJs.Tween(camera.position).to(to, 0) // todo use the number depending on diff // todo use the number depending on diff
|
|
241
|
-
// prevTwin.easing(tweenJs.Easing.Exponential.InOut)
|
|
242
|
-
prevTwin.start()
|
|
243
|
-
camera.updateProjectionMatrix()
|
|
244
|
-
}, {
|
|
245
|
-
signal: this.abortController.signal
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
console.timeEnd('load panorama scene')
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
dispose() {
|
|
252
|
-
this.scene.clear()
|
|
253
|
-
this.worldRenderer?.destroy()
|
|
254
|
-
this.abortController.abort()
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// export class ClassicPanoramaRenderer {
|
|
259
|
-
// panoramaGroup: THREE.Object3D
|
|
260
|
-
|
|
261
|
-
// constructor (private readonly backgroundFiles: string[], onRender: Array<(sizeChanged: boolean) => void>, addSquids = true) {
|
|
262
|
-
// const panorGeo = new THREE.BoxGeometry(1000, 1000, 1000)
|
|
263
|
-
// const loader = new THREE.TextureLoader()
|
|
264
|
-
// const panorMaterials = [] as THREE.MeshBasicMaterial[]
|
|
265
|
-
|
|
266
|
-
// for (const file of this.backgroundFiles) {
|
|
267
|
-
// const texture = loader.load(file)
|
|
268
|
-
|
|
269
|
-
// // Instead of using repeat/offset to flip, we'll use the texture matrix
|
|
270
|
-
// texture.matrixAutoUpdate = false
|
|
271
|
-
// texture.matrix.set(
|
|
272
|
-
// -1, 0, 1, 0, 1, 0, 0, 0, 1
|
|
273
|
-
// )
|
|
274
|
-
|
|
275
|
-
// texture.wrapS = THREE.ClampToEdgeWrapping // Changed from RepeatWrapping
|
|
276
|
-
// texture.wrapT = THREE.ClampToEdgeWrapping // Changed from RepeatWrapping
|
|
277
|
-
// texture.minFilter = THREE.LinearFilter
|
|
278
|
-
// texture.magFilter = THREE.LinearFilter
|
|
279
|
-
|
|
280
|
-
// panorMaterials.push(new THREE.MeshBasicMaterial({
|
|
281
|
-
// map: texture,
|
|
282
|
-
// transparent: true,
|
|
283
|
-
// side: THREE.DoubleSide,
|
|
284
|
-
// depthWrite: false,
|
|
285
|
-
// }))
|
|
286
|
-
// }
|
|
287
|
-
|
|
288
|
-
// const panoramaBox = new THREE.Mesh(panorGeo, panorMaterials)
|
|
289
|
-
// panoramaBox.onBeforeRender = () => {
|
|
290
|
-
// }
|
|
291
|
-
|
|
292
|
-
// const group = new THREE.Object3D()
|
|
293
|
-
// group.add(panoramaBox)
|
|
294
|
-
|
|
295
|
-
// if (addSquids) {
|
|
296
|
-
// // Add squids
|
|
297
|
-
// for (let i = 0; i < 20; i++) {
|
|
298
|
-
// const m = new EntityMesh('1.16.4', 'squid').mesh
|
|
299
|
-
// m.position.set(Math.random() * 30 - 15, Math.random() * 20 - 10, Math.random() * 10 - 17)
|
|
300
|
-
// m.rotation.set(0, Math.PI + Math.random(), -Math.PI / 4, 'ZYX')
|
|
301
|
-
// const v = Math.random() * 0.01
|
|
302
|
-
// onRender.push(() => {
|
|
303
|
-
// m.rotation.y += v
|
|
304
|
-
// m.rotation.z = Math.cos(panoramaBox.rotation.y * 3) * Math.PI / 4 - Math.PI / 2
|
|
305
|
-
// })
|
|
306
|
-
// group.add(m)
|
|
307
|
-
// }
|
|
308
|
-
// }
|
|
309
|
-
|
|
310
|
-
// this.panoramaGroup = group
|
|
311
|
-
// }
|
|
312
|
-
// }
|