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
package/src/index.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minecraft Renderer
|
|
3
|
+
*
|
|
4
|
+
* A modular Minecraft world renderer with Three.js WebGL backend.
|
|
5
|
+
*
|
|
6
|
+
* ## Quick Start
|
|
7
|
+
*
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { AppViewer, createGraphicsBackend } from 'minecraft-renderer'
|
|
10
|
+
* import { WorldView } from 'minecraft-renderer'
|
|
11
|
+
*
|
|
12
|
+
* // Create viewer
|
|
13
|
+
* const viewer = new AppViewer()
|
|
14
|
+
*
|
|
15
|
+
* // Load backend
|
|
16
|
+
* await viewer.loadBackend(createGraphicsBackend)
|
|
17
|
+
*
|
|
18
|
+
* // Start world
|
|
19
|
+
* await viewer.startWorld(world, renderDistance)
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* ## Architecture
|
|
23
|
+
*
|
|
24
|
+
* The renderer is split into several modules:
|
|
25
|
+
*
|
|
26
|
+
* - **Core**: Types, configuration, player state, world view
|
|
27
|
+
* - **Three.js Backend**: WebGL rendering using Three.js
|
|
28
|
+
* - **Playground**: Testing and development environment
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Graphics Backend (Core)
|
|
33
|
+
// ============================================================================
|
|
34
|
+
export * from './graphicsBackend'
|
|
35
|
+
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// World View
|
|
38
|
+
// ============================================================================
|
|
39
|
+
export {
|
|
40
|
+
WorldView,
|
|
41
|
+
WorldViewWorker,
|
|
42
|
+
chunkPos,
|
|
43
|
+
sectionPos,
|
|
44
|
+
generateSpiralMatrix,
|
|
45
|
+
delayedIterator
|
|
46
|
+
} from './worldView'
|
|
47
|
+
export type { WorldProvider } from './worldView'
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Player State
|
|
51
|
+
// ============================================================================
|
|
52
|
+
export {
|
|
53
|
+
getInitialPlayerState,
|
|
54
|
+
getPlayerStateUtils,
|
|
55
|
+
getInitialPlayerStateRenderer
|
|
56
|
+
} from './playerState/playerState'
|
|
57
|
+
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Resource Manager
|
|
60
|
+
// ============================================================================
|
|
61
|
+
export {
|
|
62
|
+
ResourcesManager,
|
|
63
|
+
LoadedResourcesTransferrable
|
|
64
|
+
} from './resourcesManager'
|
|
65
|
+
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Modules System
|
|
68
|
+
// ============================================================================
|
|
69
|
+
export * from './modules'
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Three.js Backend (re-exported for convenience)
|
|
73
|
+
// ============================================================================
|
|
74
|
+
export {
|
|
75
|
+
createGraphicsBackend,
|
|
76
|
+
createGraphicsBackendBase
|
|
77
|
+
} from './three/graphicsBackend'
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
DocumentRenderer,
|
|
81
|
+
addCanvasForWorker,
|
|
82
|
+
isWebWorker
|
|
83
|
+
} from './three/documentRenderer'
|
|
84
|
+
|
|
85
|
+
// export {
|
|
86
|
+
// WorldGeometryHandler,
|
|
87
|
+
// estimateGeometryMemoryUsage,
|
|
88
|
+
// disposeObject
|
|
89
|
+
// } from './three/worldGeometryHandler'
|
|
90
|
+
|
|
91
|
+
export { StarField } from './three/starField'
|
|
92
|
+
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Examples (for reference and testing)
|
|
95
|
+
// ============================================================================
|
|
96
|
+
export { AppViewerExample, runExample } from './examples/appViewerExample'
|
|
97
|
+
export { appViewer, initialMenuStart, initialize } from './examples/initialMenuStart'
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-named-as-default
|
|
2
|
+
import GUI from 'lil-gui'
|
|
3
|
+
import { isWebWorker } from '../three/documentRenderer'
|
|
4
|
+
|
|
5
|
+
export interface ParamMeta {
|
|
6
|
+
min?: number
|
|
7
|
+
max?: number
|
|
8
|
+
step?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class DebugGui {
|
|
12
|
+
private gui: GUI | null = null
|
|
13
|
+
private readonly storageKey: string = ''
|
|
14
|
+
private target: any
|
|
15
|
+
private readonly params: string[] = []
|
|
16
|
+
private readonly paramsMeta: Record<string, ParamMeta> = {}
|
|
17
|
+
private _visible = false // Default to not visible
|
|
18
|
+
private readonly initialValues: Record<string, any> = {} // Store initial values
|
|
19
|
+
private initialized = false
|
|
20
|
+
|
|
21
|
+
constructor (id: string, target: any, params?: string[], paramsMeta?: Record<string, ParamMeta>) {
|
|
22
|
+
// If in web worker, don't initialize anything
|
|
23
|
+
if (isWebWorker) return
|
|
24
|
+
|
|
25
|
+
this.gui = new GUI()
|
|
26
|
+
this.storageKey = `debug_params_${id}`
|
|
27
|
+
this.target = target
|
|
28
|
+
this.paramsMeta = paramsMeta ?? {}
|
|
29
|
+
this.params = params ?? Object.keys(target)
|
|
30
|
+
|
|
31
|
+
// Store initial values
|
|
32
|
+
for (const param of this.params) {
|
|
33
|
+
this.initialValues[param] = target[param]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Hide by default
|
|
37
|
+
this.gui.domElement.style.display = 'none'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Initialize and show the GUI
|
|
41
|
+
activate () {
|
|
42
|
+
if (isWebWorker) return this
|
|
43
|
+
|
|
44
|
+
if (!this.initialized && this.gui) {
|
|
45
|
+
this.loadSavedValues()
|
|
46
|
+
this.setupControls()
|
|
47
|
+
this.initialized = true
|
|
48
|
+
}
|
|
49
|
+
this.show()
|
|
50
|
+
return this
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Getter for visibility
|
|
54
|
+
get visible (): boolean {
|
|
55
|
+
if (isWebWorker) return false
|
|
56
|
+
return this._visible
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Setter for visibility
|
|
60
|
+
set visible (value: boolean) {
|
|
61
|
+
if (isWebWorker || !this.gui) return
|
|
62
|
+
this._visible = value
|
|
63
|
+
this.gui.domElement.style.display = value ? 'block' : 'none'
|
|
64
|
+
this.saveVisibility()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private loadSavedValues () {
|
|
68
|
+
if (isWebWorker) return
|
|
69
|
+
try {
|
|
70
|
+
const saved = localStorage.getItem(this.storageKey)
|
|
71
|
+
if (saved) {
|
|
72
|
+
const values = JSON.parse(saved)
|
|
73
|
+
// Apply saved values to target
|
|
74
|
+
for (const param of this.params) {
|
|
75
|
+
if (param in values) {
|
|
76
|
+
const value = values[param]
|
|
77
|
+
if (value !== null) {
|
|
78
|
+
this.target[param] = value
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
console.warn('Failed to load debug values:', e)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private saveValues (deleteKey = false) {
|
|
89
|
+
if (isWebWorker) return
|
|
90
|
+
try {
|
|
91
|
+
const values = {}
|
|
92
|
+
for (const param of this.params) {
|
|
93
|
+
values[param] = this.target[param]
|
|
94
|
+
}
|
|
95
|
+
if (deleteKey) {
|
|
96
|
+
localStorage.removeItem(this.storageKey)
|
|
97
|
+
} else {
|
|
98
|
+
localStorage.setItem(this.storageKey, JSON.stringify(values))
|
|
99
|
+
}
|
|
100
|
+
} catch (e) {
|
|
101
|
+
console.warn('Failed to save debug values:', e)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private saveVisibility () {
|
|
106
|
+
if (isWebWorker) return
|
|
107
|
+
try {
|
|
108
|
+
localStorage.setItem(`${this.storageKey}_visible`, this._visible.toString())
|
|
109
|
+
} catch (e) {
|
|
110
|
+
console.warn('Failed to save debug visibility:', e)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private setupControls () {
|
|
115
|
+
if (isWebWorker || !this.gui) return
|
|
116
|
+
|
|
117
|
+
// Add visibility toggle at the top
|
|
118
|
+
this.gui.add(this, 'visible').name('Show Controls')
|
|
119
|
+
this.gui.add({ resetAll: () => {
|
|
120
|
+
if (!this.gui) return
|
|
121
|
+
for (const param of this.params) {
|
|
122
|
+
this.target[param] = this.initialValues[param]
|
|
123
|
+
}
|
|
124
|
+
this.saveValues(true)
|
|
125
|
+
this.gui.destroy()
|
|
126
|
+
this.gui = new GUI()
|
|
127
|
+
this.setupControls()
|
|
128
|
+
} }, 'resetAll').name('Reset All Parameters')
|
|
129
|
+
|
|
130
|
+
for (const param of this.params) {
|
|
131
|
+
const value = this.target[param]
|
|
132
|
+
const meta = this.paramsMeta[param] ?? {}
|
|
133
|
+
|
|
134
|
+
if (typeof value === 'number') {
|
|
135
|
+
// For numbers, use meta values or calculate reasonable defaults
|
|
136
|
+
const min = meta.min ?? value - Math.abs(value * 2)
|
|
137
|
+
const max = meta.max ?? value + Math.abs(value * 2)
|
|
138
|
+
const step = meta.step ?? Math.abs(value) / 100
|
|
139
|
+
|
|
140
|
+
this.gui.add(this.target, param, min, max, step)
|
|
141
|
+
.onChange(() => this.saveValues())
|
|
142
|
+
} else if (typeof value === 'boolean') {
|
|
143
|
+
// For booleans, create a checkbox
|
|
144
|
+
this.gui.add(this.target, param)
|
|
145
|
+
.onChange(() => this.saveValues())
|
|
146
|
+
} else if (typeof value === 'string' && ['x', 'y', 'z'].includes(param)) {
|
|
147
|
+
// Special case for xyz coordinates
|
|
148
|
+
const min = meta.min ?? -10
|
|
149
|
+
const max = meta.max ?? 10
|
|
150
|
+
const step = meta.step ?? 0.1
|
|
151
|
+
|
|
152
|
+
this.gui.add(this.target, param, min, max, step)
|
|
153
|
+
.onChange(() => this.saveValues())
|
|
154
|
+
} else if (Array.isArray(value)) {
|
|
155
|
+
// For arrays, create a dropdown
|
|
156
|
+
this.gui.add(this.target, param, value)
|
|
157
|
+
.onChange(() => this.saveValues())
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Method to manually trigger save
|
|
163
|
+
save () {
|
|
164
|
+
if (isWebWorker) return
|
|
165
|
+
this.saveValues()
|
|
166
|
+
this.saveVisibility()
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Method to destroy the GUI and clean up
|
|
170
|
+
destroy () {
|
|
171
|
+
if (isWebWorker || !this.gui) return
|
|
172
|
+
this.saveVisibility()
|
|
173
|
+
this.gui.destroy()
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Toggle visibility
|
|
177
|
+
toggle () {
|
|
178
|
+
this.visible = !this.visible
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Show the GUI
|
|
182
|
+
show () {
|
|
183
|
+
this.visible = true
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Hide the GUI
|
|
187
|
+
hide () {
|
|
188
|
+
this.visible = false
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as tweenJs from '@tweenjs/tween.js'
|
|
2
|
+
|
|
3
|
+
export class AnimationController {
|
|
4
|
+
private currentAnimation: tweenJs.Group | null = null
|
|
5
|
+
private isAnimating = false
|
|
6
|
+
private cancelRequested = false
|
|
7
|
+
private completionCallbacks: Array<() => void> = []
|
|
8
|
+
private currentCancelCallback: (() => void) | null = null
|
|
9
|
+
|
|
10
|
+
/** Main method */
|
|
11
|
+
async startAnimation (createAnimation: () => tweenJs.Group, onCancelled?: () => void): Promise<void> {
|
|
12
|
+
if (this.isAnimating) {
|
|
13
|
+
await this.cancelCurrentAnimation()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
this.isAnimating = true
|
|
18
|
+
this.cancelRequested = false
|
|
19
|
+
this.currentCancelCallback = onCancelled ?? null
|
|
20
|
+
this.currentAnimation = createAnimation()
|
|
21
|
+
|
|
22
|
+
this.completionCallbacks.push(() => {
|
|
23
|
+
this.isAnimating = false
|
|
24
|
+
this.currentAnimation = null
|
|
25
|
+
resolve()
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Main method */
|
|
31
|
+
async cancelCurrentAnimation (): Promise<void> {
|
|
32
|
+
if (!this.isAnimating) return
|
|
33
|
+
|
|
34
|
+
if (this.currentCancelCallback) {
|
|
35
|
+
const callback = this.currentCancelCallback
|
|
36
|
+
this.currentCancelCallback = null
|
|
37
|
+
callback()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
this.cancelRequested = true
|
|
42
|
+
this.completionCallbacks.push(() => {
|
|
43
|
+
resolve()
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
animationCycleFinish () {
|
|
49
|
+
if (this.cancelRequested) this.forceFinish()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
forceFinish (callComplete = true) {
|
|
53
|
+
if (!this.isAnimating) return
|
|
54
|
+
|
|
55
|
+
if (this.currentAnimation) {
|
|
56
|
+
for (const tween of this.currentAnimation.getAll()) tween.stop()
|
|
57
|
+
this.currentAnimation.removeAll()
|
|
58
|
+
this.currentAnimation = null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this.isAnimating = false
|
|
62
|
+
this.cancelRequested = false
|
|
63
|
+
|
|
64
|
+
const callbacks = [...this.completionCallbacks]
|
|
65
|
+
this.completionCallbacks = []
|
|
66
|
+
if (callComplete) {
|
|
67
|
+
for (const cb of callbacks) cb()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Required method */
|
|
72
|
+
update () {
|
|
73
|
+
if (this.currentAnimation) {
|
|
74
|
+
this.currentAnimation.update()
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
get isActive () {
|
|
79
|
+
return this.isAnimating
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get shouldCancel () {
|
|
83
|
+
return this.cancelRequested
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const dynamicMcDataFiles = ['blocks', 'blockCollisionShapes', 'biomes', 'version']
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export class CameraBobbing {
|
|
2
|
+
private walkDistance = 0
|
|
3
|
+
private prevWalkDistance = 0
|
|
4
|
+
private bobAmount = 0
|
|
5
|
+
private prevBobAmount = 0
|
|
6
|
+
private readonly gameTimer = new GameTimer()
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line max-params
|
|
9
|
+
constructor (
|
|
10
|
+
private readonly BOB_FREQUENCY: number = Math.PI, // How fast the bob cycles
|
|
11
|
+
private readonly BOB_BASE_AMPLITUDE: number = 0.5, // Base amplitude of the bob
|
|
12
|
+
private readonly VERTICAL_MULTIPLIER: number = 1, // Vertical movement multiplier
|
|
13
|
+
private readonly ROTATION_MULTIPLIER_Z: number = 3, // Roll rotation multiplier
|
|
14
|
+
private readonly ROTATION_MULTIPLIER_X: number = 5 // Pitch rotation multiplier
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
// Call this when player is moving
|
|
18
|
+
public updateWalkDistance (distance: number): void {
|
|
19
|
+
this.prevWalkDistance = this.walkDistance
|
|
20
|
+
this.walkDistance = distance
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Call this when player is moving to update bob amount
|
|
24
|
+
public updateBobAmount (isMoving: boolean): void {
|
|
25
|
+
const targetBob = isMoving ? 1 : 0
|
|
26
|
+
this.prevBobAmount = this.bobAmount
|
|
27
|
+
|
|
28
|
+
// Update timing
|
|
29
|
+
const ticks = this.gameTimer.update()
|
|
30
|
+
const deltaTime = ticks / 20 // Convert ticks to seconds assuming 20 TPS
|
|
31
|
+
|
|
32
|
+
// Smooth transition for bob amount
|
|
33
|
+
const bobDelta = (targetBob - this.bobAmount) * Math.min(1, deltaTime * 10)
|
|
34
|
+
this.bobAmount += bobDelta
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Call this in your render/animation loop
|
|
38
|
+
public getBobbing (): { position: { x: number, y: number }, rotation: { x: number, z: number } } {
|
|
39
|
+
// Interpolate walk distance
|
|
40
|
+
const walkDist = this.prevWalkDistance +
|
|
41
|
+
(this.walkDistance - this.prevWalkDistance) * this.gameTimer.partialTick
|
|
42
|
+
|
|
43
|
+
// Interpolate bob amount
|
|
44
|
+
const bob = this.prevBobAmount +
|
|
45
|
+
(this.bobAmount - this.prevBobAmount) * this.gameTimer.partialTick
|
|
46
|
+
|
|
47
|
+
// Calculate total distance for bob cycle
|
|
48
|
+
const totalDist = -(walkDist * this.BOB_FREQUENCY)
|
|
49
|
+
|
|
50
|
+
// Calculate offsets
|
|
51
|
+
const xOffset = Math.sin(totalDist) * bob * this.BOB_BASE_AMPLITUDE
|
|
52
|
+
const yOffset = -Math.abs(Math.cos(totalDist) * bob) * this.VERTICAL_MULTIPLIER
|
|
53
|
+
|
|
54
|
+
// Calculate rotations (in radians)
|
|
55
|
+
const zRot = (Math.sin(totalDist) * bob * this.ROTATION_MULTIPLIER_Z) * (Math.PI / 180)
|
|
56
|
+
const xRot = (Math.abs(Math.cos(totalDist - 0.2) * bob) * this.ROTATION_MULTIPLIER_X) * (Math.PI / 180)
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
position: { x: xOffset, y: yOffset },
|
|
60
|
+
rotation: { x: xRot, z: zRot }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
class GameTimer {
|
|
66
|
+
private readonly msPerTick: number
|
|
67
|
+
private lastMs: number
|
|
68
|
+
public partialTick = 0
|
|
69
|
+
|
|
70
|
+
constructor (tickRate = 20) {
|
|
71
|
+
this.msPerTick = 1000 / tickRate
|
|
72
|
+
this.lastMs = performance.now()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
update (): number {
|
|
76
|
+
const currentMs = performance.now()
|
|
77
|
+
const deltaSinceLastTick = currentMs - this.lastMs
|
|
78
|
+
|
|
79
|
+
// Calculate how much of a tick has passed
|
|
80
|
+
const tickDelta = deltaSinceLastTick / this.msPerTick
|
|
81
|
+
this.lastMs = currentMs
|
|
82
|
+
|
|
83
|
+
// Add to accumulated partial ticks
|
|
84
|
+
this.partialTick += tickDelta
|
|
85
|
+
|
|
86
|
+
// Get whole number of ticks that should occur
|
|
87
|
+
const wholeTicks = Math.floor(this.partialTick)
|
|
88
|
+
|
|
89
|
+
// Keep the remainder as the new partial tick
|
|
90
|
+
this.partialTick -= wholeTicks
|
|
91
|
+
|
|
92
|
+
return wholeTicks
|
|
93
|
+
}
|
|
94
|
+
}
|