minecraft-renderer 0.1.42 → 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.
Files changed (38) hide show
  1. package/dist/mesher.js +52 -52
  2. package/dist/mesher.js.map +3 -3
  3. package/dist/mesherWasm.js +51 -51
  4. package/dist/minecraft-renderer.js +59 -59
  5. package/dist/minecraft-renderer.js.meta.json +1 -1
  6. package/dist/threeWorker.js +458 -458
  7. package/package.json +1 -1
  8. package/src/graphicsBackend/appViewer.ts +19 -7
  9. package/src/graphicsBackend/types.ts +5 -1
  10. package/src/index.ts +33 -0
  11. package/src/lib/ui/newStats.ts +16 -2
  12. package/src/lib/worldrendererCommon.ts +3 -2
  13. package/src/mesher-legacy/mesher.ts +10 -1
  14. package/src/mesher-shared/models.ts +41 -0
  15. package/src/mesher-shared/shared.ts +2 -0
  16. package/src/three/entities.ts +22 -6
  17. package/src/three/graphicsBackendBase.ts +28 -20
  18. package/src/three/graphicsBackendOffThread.ts +1 -2
  19. package/src/three/menuBackground/activeView.ts +19 -0
  20. package/src/three/menuBackground/classic.ts +148 -0
  21. package/src/three/menuBackground/config.ts +23 -0
  22. package/src/three/menuBackground/defaultOptions.ts +141 -0
  23. package/src/three/menuBackground/futuristic.ts +859 -0
  24. package/src/three/menuBackground/index.ts +36 -0
  25. package/src/three/menuBackground/renderer.ts +97 -0
  26. package/src/three/menuBackground/shared.ts +3 -0
  27. package/src/three/menuBackground/types.ts +37 -0
  28. package/src/three/menuBackground/worldBlocks.ts +144 -0
  29. package/src/three/modules/sciFiWorldReveal.ts +6 -0
  30. package/src/three/waypointSprite.ts +108 -106
  31. package/src/three/worldRendererThree.ts +10 -13
  32. package/src/wasm-mesher/runtime-build/wasm_mesher.d.ts +25 -0
  33. package/src/wasm-mesher/runtime-build/wasm_mesher.js +68 -0
  34. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm +0 -0
  35. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm.d.ts +2 -0
  36. package/src/wasm-mesher/worker/mesherWasm.ts +14 -0
  37. package/src/three/panorama.ts +0 -312
  38. 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 formatBigNumber = (num: number) => {
709
- return new Intl.NumberFormat('en-US', {}).format(num)
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 += `C: ${formatBigNumber(this.renderer.info.render.calls)} `
713
- text += `TR: ${formatBigNumber(this.renderer.info.render.triangles)} `
714
- text += `TE: ${formatBigNumber(this.renderer.info.memory.textures)} `
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} HR: ${poolStats.hitRate}`
716
+ text += `POOL: ${poolStats.activeCount}/${poolStats.poolSize}`
720
717
  pane.updateText(text)
721
718
  this.backendInfoReport = text
722
719
  }
@@ -909,7 +906,7 @@ export class WorldRendererThree extends WorldRendererCommon {
909
906
  const yOffset = this.playerStateReactive.eyeHeight
910
907
 
911
908
  this.updateCamera(pos?.offset(0, yOffset, 0) ?? null, yaw, pitch)
912
- this.media.tryIntersectMedia()
909
+ // this.media.tryIntersectMedia()
913
910
  this.updateCameraSectionPos()
914
911
  }
915
912
 
@@ -2,6 +2,29 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
+ /**
6
+ * Compute wireframe edge positions from a triangle mesh.
7
+ *
8
+ * Takes flat position and index arrays from an assembled mesh and returns a
9
+ * flat array of line-segment positions (x1,y1,z1,x2,y2,z2, ...) representing
10
+ * the unique edges of the mesh. Edge deduplication uses a `HashSet<(u32,u32)>`
11
+ * keyed on (min_vertex_index, max_vertex_index).
12
+ *
13
+ * `positions` — flat `Float32Array` of vertex positions (3 floats per vertex).
14
+ * `indices` — flat `Uint32Array` of triangle indices (3 indices per triangle).
15
+ * For 16-bit index arrays, prefer [`compute_wireframe_edges_u16`]
16
+ * to avoid an extra JS-side `Uint32Array` allocation.
17
+ */
18
+ export function computeWireframeEdges(positions: Float32Array, indices: Uint32Array): Float32Array;
19
+
20
+ /**
21
+ * Same as [`compute_wireframe_edges`] but accepts a `Uint16Array` of indices.
22
+ *
23
+ * Avoids the JS-side `new Uint32Array(uint16)` allocation when the assembled
24
+ * section uses 16-bit indices (typical for sections with < 65k vertices).
25
+ */
26
+ export function computeWireframeEdgesU16(positions: Float32Array, indices: Uint16Array): Float32Array;
27
+
5
28
  /**
6
29
  * VITALY's path: parse 1.18+ dump + light → run the mesher → return ONLY the final
7
30
  * geometry. Avoids marshalling the intermediate ~300KB block_states/biomes/lights
@@ -218,6 +241,8 @@ export interface InitOutput {
218
241
  readonly generateGeometryFromParsedV16V17: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number) => any;
219
242
  readonly generateGeometryFromMapChunkV18PlusMulti: (a: any, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number) => any;
220
243
  readonly generateGeometryFromParsedV16V17Multi: (a: any, b: number, c: number, d: number, e: number, f: number, g: any, h: number, i: any, j: any, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number) => any;
244
+ readonly computeWireframeEdges: (a: number, b: number, c: number, d: number) => [number, number];
245
+ readonly computeWireframeEdgesU16: (a: number, b: number, c: number, d: number) => [number, number];
221
246
  readonly parseUpdateLightV17: (a: number, b: number, c: number) => any;
222
247
  readonly __wbindgen_malloc: (a: number, b: number) => number;
223
248
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
@@ -71,6 +71,11 @@ function debugString(val) {
71
71
  return className;
72
72
  }
73
73
 
74
+ function getArrayF32FromWasm0(ptr, len) {
75
+ ptr = ptr >>> 0;
76
+ return getFloat32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
77
+ }
78
+
74
79
  function getArrayI32FromWasm0(ptr, len) {
75
80
  ptr = ptr >>> 0;
76
81
  return getInt32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
@@ -94,6 +99,14 @@ function getDataViewMemory0() {
94
99
  return cachedDataViewMemory0;
95
100
  }
96
101
 
102
+ let cachedFloat32ArrayMemory0 = null;
103
+ function getFloat32ArrayMemory0() {
104
+ if (cachedFloat32ArrayMemory0 === null || cachedFloat32ArrayMemory0.byteLength === 0) {
105
+ cachedFloat32ArrayMemory0 = new Float32Array(wasm.memory.buffer);
106
+ }
107
+ return cachedFloat32ArrayMemory0;
108
+ }
109
+
97
110
  let cachedInt32ArrayMemory0 = null;
98
111
  function getInt32ArrayMemory0() {
99
112
  if (cachedInt32ArrayMemory0 === null || cachedInt32ArrayMemory0.byteLength === 0) {
@@ -161,6 +174,13 @@ function passArray8ToWasm0(arg, malloc) {
161
174
  return ptr;
162
175
  }
163
176
 
177
+ function passArrayF32ToWasm0(arg, malloc) {
178
+ const ptr = malloc(arg.length * 4, 4) >>> 0;
179
+ getFloat32ArrayMemory0().set(arg, ptr / 4);
180
+ WASM_VECTOR_LEN = arg.length;
181
+ return ptr;
182
+ }
183
+
164
184
  function passStringToWasm0(arg, malloc, realloc) {
165
185
  if (realloc === undefined) {
166
186
  const buf = cachedTextEncoder.encode(arg);
@@ -227,6 +247,53 @@ if (!('encodeInto' in cachedTextEncoder)) {
227
247
 
228
248
  let WASM_VECTOR_LEN = 0;
229
249
 
250
+ /**
251
+ * Compute wireframe edge positions from a triangle mesh.
252
+ *
253
+ * Takes flat position and index arrays from an assembled mesh and returns a
254
+ * flat array of line-segment positions (x1,y1,z1,x2,y2,z2, ...) representing
255
+ * the unique edges of the mesh. Edge deduplication uses a `HashSet<(u32,u32)>`
256
+ * keyed on (min_vertex_index, max_vertex_index).
257
+ *
258
+ * `positions` — flat `Float32Array` of vertex positions (3 floats per vertex).
259
+ * `indices` — flat `Uint32Array` of triangle indices (3 indices per triangle).
260
+ * For 16-bit index arrays, prefer [`compute_wireframe_edges_u16`]
261
+ * to avoid an extra JS-side `Uint32Array` allocation.
262
+ * @param {Float32Array} positions
263
+ * @param {Uint32Array} indices
264
+ * @returns {Float32Array}
265
+ */
266
+ export function computeWireframeEdges(positions, indices) {
267
+ const ptr0 = passArrayF32ToWasm0(positions, wasm.__wbindgen_malloc);
268
+ const len0 = WASM_VECTOR_LEN;
269
+ const ptr1 = passArray32ToWasm0(indices, wasm.__wbindgen_malloc);
270
+ const len1 = WASM_VECTOR_LEN;
271
+ const ret = wasm.computeWireframeEdges(ptr0, len0, ptr1, len1);
272
+ var v3 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
273
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
274
+ return v3;
275
+ }
276
+
277
+ /**
278
+ * Same as [`compute_wireframe_edges`] but accepts a `Uint16Array` of indices.
279
+ *
280
+ * Avoids the JS-side `new Uint32Array(uint16)` allocation when the assembled
281
+ * section uses 16-bit indices (typical for sections with < 65k vertices).
282
+ * @param {Float32Array} positions
283
+ * @param {Uint16Array} indices
284
+ * @returns {Float32Array}
285
+ */
286
+ export function computeWireframeEdgesU16(positions, indices) {
287
+ const ptr0 = passArrayF32ToWasm0(positions, wasm.__wbindgen_malloc);
288
+ const len0 = WASM_VECTOR_LEN;
289
+ const ptr1 = passArray16ToWasm0(indices, wasm.__wbindgen_malloc);
290
+ const len1 = WASM_VECTOR_LEN;
291
+ const ret = wasm.computeWireframeEdgesU16(ptr0, len0, ptr1, len1);
292
+ var v3 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
293
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
294
+ return v3;
295
+ }
296
+
230
297
  /**
231
298
  * VITALY's path: parse 1.18+ dump + light → run the mesher → return ONLY the final
232
299
  * geometry. Avoids marshalling the intermediate ~300KB block_states/biomes/lights
@@ -1001,6 +1068,7 @@ function __wbg_finalize_init(instance, module) {
1001
1068
  wasm = instance.exports;
1002
1069
  __wbg_init.__wbindgen_wasm_module = module;
1003
1070
  cachedDataViewMemory0 = null;
1071
+ cachedFloat32ArrayMemory0 = null;
1004
1072
  cachedInt32ArrayMemory0 = null;
1005
1073
  cachedUint16ArrayMemory0 = null;
1006
1074
  cachedUint32ArrayMemory0 = null;
@@ -16,6 +16,8 @@ export const parseChunkSectionsV16V17: (a: number, b: number, c: number, d: numb
16
16
  export const generateGeometryFromParsedV16V17: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number) => any;
17
17
  export const generateGeometryFromMapChunkV18PlusMulti: (a: any, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number) => any;
18
18
  export const generateGeometryFromParsedV16V17Multi: (a: any, b: number, c: number, d: number, e: number, f: number, g: any, h: number, i: any, j: any, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number) => any;
19
+ export const computeWireframeEdges: (a: number, b: number, c: number, d: number) => [number, number];
20
+ export const computeWireframeEdgesU16: (a: number, b: number, c: number, d: number) => [number, number];
19
21
  export const parseUpdateLightV17: (a: number, b: number, c: number) => any;
20
22
  export const __wbindgen_malloc: (a: number, b: number) => number;
21
23
  export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
@@ -1347,6 +1347,20 @@ function processColumnTick() {
1347
1347
  //@ts-ignore
1348
1348
  geometry.indices?.buffer,
1349
1349
  ].filter(Boolean)
1350
+
1351
+ if (exported.geometry.indices.length > 0 && config.computeWireframeEdges) {
1352
+ try {
1353
+ const wireframeF32 = geometry.indices instanceof Uint32Array
1354
+ ? wasm!.computeWireframeEdges(geometry.positions as Float32Array, geometry.indices)
1355
+ : wasm!.computeWireframeEdgesU16(geometry.positions as Float32Array, geometry.indices as Uint16Array)
1356
+ if (wireframeF32.length > 0) {
1357
+ geometry.wireframePositions = wireframeF32
1358
+ transferable.push(wireframeF32.buffer)
1359
+ }
1360
+ } catch (err) {
1361
+ // Fall through — sciFiWorldReveal will fall back to main-thread computation
1362
+ }
1363
+ }
1350
1364
  } else {
1351
1365
  geometry = makeEmptyColumnGeometry(sx, sy, sz, sectionHeight, false)
1352
1366
  // Still attach block entity metadata so the main thread sees
@@ -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
- // }
@@ -1,2 +0,0 @@
1
- //@ts-nocheck
2
- export const PANORAMA_VERSION = '1.21.4'