minecraft-renderer 0.1.78 → 0.1.80
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 +29 -25
- package/dist/mesher.js +36 -36
- package/dist/mesher.js.map +4 -4
- package/dist/mesherWasm.js +217 -217
- package/dist/minecraft-renderer.js +32 -32
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +415 -415
- package/package.json +5 -2
- package/src/bundler/bundlePrepare.ts +3 -8
- package/src/graphicsBackend/appViewer.ts +10 -7
- package/src/graphicsBackend/config.ts +1 -5
- package/src/graphicsBackend/playerState.ts +35 -34
- package/src/graphicsBackend/preloadWorkers.ts +43 -41
- package/src/graphicsBackend/rendererDefaultOptions.ts +68 -70
- package/src/graphicsBackend/rendererOptionsSync.ts +24 -50
- package/src/graphicsBackend/types.ts +2 -2
- package/src/index.ts +6 -27
- package/src/lib/DebugGui.ts +34 -31
- package/src/lib/animationController.ts +9 -9
- package/src/lib/bakeLegacyLight.ts +1 -6
- package/src/lib/bindAbortableListener.test.ts +32 -12
- package/src/lib/bindAbortableListener.ts +14 -6
- package/src/lib/blockEntityLightRegistry.ts +11 -20
- package/src/lib/blockEntityLighting.test.ts +1 -6
- package/src/lib/blockEntityLighting.ts +5 -5
- package/src/lib/buildSharedConfig.mjs +4 -4
- package/src/lib/buildWorkerMcDataIndexes.test.ts +4 -4
- package/src/lib/buildWorkerMcDataIndexes.ts +11 -19
- package/src/lib/cameraBobbing.ts +1 -1
- package/src/lib/canvas2DOverlay.example.ts +13 -33
- package/src/lib/canvas2DOverlay.quickstart.ts +24 -54
- package/src/lib/canvas2DOverlay.ts +28 -47
- package/src/lib/cleanupDecorator.ts +2 -2
- package/src/lib/createPlayerObject.test.ts +2 -7
- package/src/lib/createPlayerObject.ts +18 -25
- package/src/lib/frameTimingCollector.ts +2 -5
- package/src/lib/guiRenderer.ts +57 -42
- package/src/lib/items.ts +15 -9
- package/src/lib/mesherlogReader.ts +5 -6
- package/src/lib/simpleUtils.ts +5 -5
- package/src/lib/skyLight.ts +3 -3
- package/src/lib/smoothSwitcher.ts +11 -18
- package/src/lib/ui/newStats.ts +10 -12
- package/src/lib/utils/proxy.ts +7 -1
- package/src/lib/utils/skins.ts +4 -4
- package/src/lib/utils.ts +1 -1
- package/src/lib/workerMessageSanitize.ts +5 -12
- package/src/lib/workerProxy.ts +52 -42
- package/src/lib/workerSyncOps.test.ts +58 -41
- package/src/lib/worldrendererCommon.reconfigure.test.ts +24 -21
- package/src/lib/worldrendererCommon.removeColumn.test.ts +11 -13
- package/src/lib/worldrendererCommon.ts +338 -211
- package/src/mesher-legacy/mesher.ts +9 -4
- package/src/mesher-legacy/test/a.ts +1 -1
- package/src/mesher-legacy/test/mesherTester.ts +2 -2
- package/src/mesher-legacy/test/playground.ts +1 -1
- package/src/mesher-legacy/test/run/test-js.ts +1 -1
- package/src/mesher-legacy/test/snapshotUtils.ts +3 -8
- package/src/mesher-legacy/test/test-perf.ts +1 -1
- package/src/mesher-legacy/test/tests.test.ts +2 -2
- package/src/mesher-shared/blockEntityMetadata.test.ts +7 -5
- package/src/mesher-shared/blockEntityMetadata.ts +28 -19
- package/src/mesher-shared/blockPropertiesForMeshing.ts +2 -2
- package/src/mesher-shared/computeHeightmap.ts +2 -4
- package/src/mesher-shared/exportedGeometryTypes.ts +3 -3
- package/src/mesher-shared/faceOcclusion.ts +324 -0
- package/src/mesher-shared/models.ts +80 -131
- package/src/mesher-shared/modelsGeometryCommon.ts +30 -15
- package/src/mesher-shared/shared.ts +46 -46
- package/src/mesher-shared/standaloneRenderer.ts +40 -44
- package/src/mesher-shared/tests/faceOcclusion.test.ts +179 -0
- package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +12 -8
- package/src/mesher-shared/vertexShading.ts +2 -11
- package/src/mesher-shared/world.ts +19 -19
- package/src/mesher-shared/worldLighting.test.ts +2 -2
- package/src/performanceMonitor/PerformanceMonitor.ts +4 -13
- package/src/performanceMonitor/formatPerformanceFactorsDebug.ts +2 -2
- package/src/performanceMonitor/index.ts +1 -5
- package/src/performanceMonitor/types.ts +1 -1
- package/src/playerState/playerState.ts +55 -50
- package/src/playerState/types.ts +2 -8
- package/src/playground/allEntitiesDebug.ts +19 -16
- package/src/playground/baseScene.ts +29 -32
- package/src/playground/mobileControls.tsx +133 -129
- package/src/playground/playground.html +76 -73
- package/src/playground/playground.ts +14 -1
- package/src/playground/playgroundUi.tsx +100 -74
- package/src/playground/reactUtils.ts +3 -7
- package/src/playground/scenes/entities.ts +10 -7
- package/src/playground/scenes/frequentUpdates.ts +5 -5
- package/src/playground/scenes/geometryExport.ts +6 -20
- package/src/playground/scenes/highPosEntityUpdates.ts +2 -10
- package/src/playground/scenes/index.ts +1 -1
- package/src/playground/scenes/lightingStarfield.ts +18 -12
- package/src/playground/scenes/main.ts +15 -11
- package/src/playground/scenes/partialBlockCulling.ts +31 -0
- package/src/playground/scenes/railsCobweb.ts +1 -1
- package/src/playground/scenes/rotationIssue.ts +1 -1
- package/src/playground/scenes/slabsOptimization.ts +1 -2
- package/src/playground/scenes/transparencyIssue.ts +1 -1
- package/src/playground/shared.ts +2 -2
- package/src/resourcesManager/resourcesManager.ts +29 -54
- package/src/resourcesManager/resourcesManager.worker.test.ts +6 -10
- package/src/shims/minecraftData.ts +70 -24
- package/src/sign-renderer/index.html +10 -12
- package/src/sign-renderer/index.ts +29 -29
- package/src/sign-renderer/playground.ts +22 -15
- package/src/sign-renderer/tests.test.ts +16 -13
- package/src/sign-renderer/vite.config.ts +2 -2
- package/src/three/appShared.ts +46 -25
- package/src/three/bannerRenderer.ts +33 -61
- package/src/three/cameraShake.ts +15 -6
- package/src/three/chunkMeshManager.ts +329 -301
- package/src/three/cinimaticScript.ts +26 -15
- package/src/three/cubeDrawSpans.ts +27 -37
- package/src/three/cubeMultiDraw.ts +9 -22
- package/src/three/documentRenderer.ts +15 -18
- package/src/three/entities.ts +175 -150
- package/src/three/entity/EntityMesh.ts +114 -108
- package/src/three/entity/animations.js +3 -3
- package/src/three/entity/armorModels.ts +15 -15
- package/src/three/entity/gltfAnimationUtils.ts +2 -5
- package/src/three/fireworks.ts +34 -32
- package/src/three/fireworksRenderer.ts +32 -29
- package/src/three/globalBlockBuffer.ts +174 -99
- package/src/three/globalLegacyBuffer.ts +465 -136
- package/src/three/graphicsBackendBase.ts +19 -25
- package/src/three/graphicsBackendOffThread.ts +12 -15
- package/src/three/hand.ts +21 -21
- package/src/three/handLegacy.ts +3 -13
- package/src/three/holdingBlock.ts +116 -79
- package/src/three/holdingBlockFactory.ts +1 -4
- package/src/three/holdingBlockItemIdentity.test.ts +25 -17
- package/src/three/holdingBlockItemIdentity.ts +9 -6
- package/src/three/holdingBlockLegacy.ts +113 -132
- package/src/three/itemMesh.ts +20 -29
- package/src/three/legacyMultiDraw.ts +93 -0
- package/src/three/legacySectionCull.ts +8 -14
- package/src/three/menuBackground/activeView.ts +1 -4
- package/src/three/menuBackground/assetUrl.ts +1 -1
- package/src/three/menuBackground/classic.ts +4 -12
- package/src/three/menuBackground/gpuPreference.ts +1 -3
- package/src/three/menuBackground/index.ts +2 -11
- package/src/three/menuBackground/renderer.ts +1 -5
- package/src/three/menuBackground/types.ts +1 -4
- package/src/three/menuBackground/v2.ts +196 -96
- package/src/three/menuBackground/v2Meta.ts +3 -3
- package/src/three/menuBackground/worldBlocks.ts +37 -35
- package/src/three/modules/blockBreakParticles.ts +59 -28
- package/src/three/modules/cameraBobbing.ts +3 -6
- package/src/three/modules/index.ts +1 -1
- package/src/three/modules/rain.ts +10 -23
- package/src/three/modules/sciFiWorldReveal.ts +11 -25
- package/src/three/modules/starfield.ts +7 -13
- package/src/three/renderSlot.ts +28 -16
- package/src/three/rendererModuleSystem.ts +1 -3
- package/src/three/sceneOrigin.ts +96 -33
- package/src/three/sectionRaycastAabb.ts +30 -18
- package/src/three/shaderCubeMesh.ts +6 -17
- package/src/three/shaders/cubeBlockShader.ts +85 -96
- package/src/three/shaders/legacyBlockShader.ts +21 -43
- package/src/three/shaders/textureIndexMapping.ts +89 -95
- package/src/three/shaders/tintPalette.ts +156 -170
- package/src/three/signTextureCache.ts +9 -12
- package/src/three/skyboxRenderer.ts +62 -70
- package/src/three/tests/chunkMeshManagerLegacy.test.ts +133 -25
- package/src/three/tests/cubeDrawSpans.test.ts +55 -25
- package/src/three/tests/globalBlockBuffer.test.ts +217 -0
- package/src/three/tests/globalLegacyBuffer.test.ts +460 -58
- package/src/three/tests/legacyMultiDraw.test.ts +88 -0
- package/src/three/tests/pr3PerFrameCpuCuts.test.ts +370 -0
- package/src/three/tests/signTextureCache.test.ts +4 -4
- package/src/three/threeJsMedia.ts +55 -72
- package/src/three/threeJsParticles.ts +32 -41
- package/src/three/threeJsSound.ts +3 -3
- package/src/three/threeJsUtils.ts +3 -3
- package/src/three/threeWorker.ts +2 -2
- package/src/three/waypointSprite.ts +55 -82
- package/src/three/waypoints.ts +20 -23
- package/src/three/world/cursorBlock.ts +25 -12
- package/src/three/world/vr.ts +11 -17
- package/src/three/worldGeometryExport.ts +15 -34
- package/src/three/worldRendererThree.ts +131 -133
- package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
- package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
- package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
- package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
- package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
- package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
- package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +17 -4
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
- package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
- package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
- package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
- package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
- package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
- package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
- package/src/worldView/worldView.spiral.test.ts +1 -1
- package/src/worldView/worldView.ts +34 -39
- package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
|
@@ -3,57 +3,62 @@ import { proxy } from 'valtio'
|
|
|
3
3
|
import type { GameMode, HandItemBlock, BlocksShapes, BlockShape, MovementState, CameraPerspective, Team, ItemSpecificContextProperties } from './types'
|
|
4
4
|
|
|
5
5
|
// edit src/mineflayer/playerState.ts for implementation of player state from mineflayer
|
|
6
|
-
export const getInitialPlayerState = () =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
6
|
+
export const getInitialPlayerState = () =>
|
|
7
|
+
proxy({
|
|
8
|
+
playerSkin: undefined as string | undefined,
|
|
9
|
+
inWater: false,
|
|
10
|
+
waterBreathing: false,
|
|
11
|
+
backgroundColor: [0, 0, 0] as [number, number, number],
|
|
12
|
+
ambientLight: 0,
|
|
13
|
+
directionalLight: 0,
|
|
14
|
+
eyeHeight: 0,
|
|
15
|
+
gameMode: undefined as GameMode | undefined,
|
|
16
|
+
lookingAtBlock: undefined as
|
|
17
|
+
| {
|
|
18
|
+
x: number
|
|
19
|
+
y: number
|
|
20
|
+
z: number
|
|
21
|
+
face?: number
|
|
22
|
+
shapes: BlocksShapes
|
|
23
|
+
}
|
|
24
|
+
| undefined,
|
|
25
|
+
diggingBlock: undefined as
|
|
26
|
+
| {
|
|
27
|
+
x: number
|
|
28
|
+
y: number
|
|
29
|
+
z: number
|
|
30
|
+
stage: number
|
|
31
|
+
face?: number
|
|
32
|
+
mergedShape: BlockShape | undefined
|
|
33
|
+
}
|
|
34
|
+
| undefined,
|
|
35
|
+
movementState: 'NOT_MOVING' as MovementState,
|
|
36
|
+
onGround: true,
|
|
37
|
+
sneaking: false,
|
|
38
|
+
flying: false,
|
|
39
|
+
sprinting: false,
|
|
40
|
+
walkDist: 0,
|
|
41
|
+
prevWalkDist: 0,
|
|
42
|
+
bob: 0,
|
|
43
|
+
prevBob: 0,
|
|
44
|
+
itemUsageTicks: 0,
|
|
45
|
+
username: '',
|
|
46
|
+
onlineMode: false,
|
|
47
|
+
/** Dimension ambient lighting preset (e.g. nether) — from login/respawn dimension data when available */
|
|
48
|
+
cardinalLight: 'default' as string,
|
|
49
|
+
lightingDisabled: false,
|
|
50
|
+
shouldHideHand: false,
|
|
51
|
+
heldItemMain: undefined as HandItemBlock | undefined,
|
|
52
|
+
heldItemOff: undefined as HandItemBlock | undefined,
|
|
53
|
+
perspective: 'first_person' as CameraPerspective,
|
|
54
|
+
onFire: false,
|
|
55
|
+
/** Gameplay FOV scale (sprint, bow, zoom, etc.); base FOV comes from renderer options. */
|
|
56
|
+
fovMultiplier: 1,
|
|
52
57
|
|
|
53
|
-
|
|
58
|
+
cameraSpectatingEntity: undefined as number | undefined,
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
})
|
|
60
|
+
team: undefined as Team | undefined
|
|
61
|
+
})
|
|
57
62
|
|
|
58
63
|
export const getPlayerStateUtils = (reactive: PlayerStateReactive) => ({
|
|
59
64
|
isSpectator() {
|
|
@@ -80,7 +85,7 @@ export type PlayerStateRenderer = PlayerStateReactive
|
|
|
80
85
|
export const getItemSelector = (playerState: PlayerStateRenderer, specificProperties: ItemSpecificContextProperties, item?: import('prismarine-item').Item) => {
|
|
81
86
|
return {
|
|
82
87
|
...specificProperties,
|
|
83
|
-
'minecraft:date': new Date()
|
|
88
|
+
'minecraft:date': new Date()
|
|
84
89
|
// "minecraft:context_dimension": bot.entityp,
|
|
85
90
|
// 'minecraft:time': bot.time.timeOfDay / 24_000,
|
|
86
91
|
}
|
package/src/playerState/types.ts
CHANGED
|
@@ -23,15 +23,9 @@ export interface HandItemBlock {
|
|
|
23
23
|
|
|
24
24
|
export type MovementState = 'NOT_MOVING' | 'WALKING' | 'SPRINTING' | 'SNEAKING'
|
|
25
25
|
export type ItemSpecificContextProperties = Partial<
|
|
26
|
-
Pick<
|
|
27
|
-
ItemSelector['properties'],
|
|
28
|
-
| 'minecraft:using_item'
|
|
29
|
-
| 'minecraft:use_duration'
|
|
30
|
-
| 'minecraft:use_cycle'
|
|
31
|
-
| 'minecraft:display_context'
|
|
32
|
-
>
|
|
26
|
+
Pick<ItemSelector['properties'], 'minecraft:using_item' | 'minecraft:use_duration' | 'minecraft:use_cycle' | 'minecraft:display_context'>
|
|
33
27
|
>
|
|
34
28
|
export type CameraPerspective = 'first_person' | 'third_person_back' | 'third_person_front'
|
|
35
29
|
|
|
36
|
-
export type BlockShape = { position: { x: number
|
|
30
|
+
export type BlockShape = { position: { x: number; y: number; z: number }; width: number; height: number; depth: number }
|
|
37
31
|
export type BlocksShapes = BlockShape[]
|
|
@@ -32,17 +32,19 @@ export const displayEntitiesDebugList = (mcData: IndexedData) => {
|
|
|
32
32
|
|
|
33
33
|
// Test entities
|
|
34
34
|
const results: Array<{
|
|
35
|
-
entity: string
|
|
36
|
-
supported: boolean
|
|
37
|
-
type?: 'obj' | 'bedrock' | 'gltf' | 'special'
|
|
38
|
-
mappedFrom?: string
|
|
39
|
-
textureMap?: boolean
|
|
40
|
-
errors?: string[]
|
|
35
|
+
entity: string
|
|
36
|
+
supported: boolean
|
|
37
|
+
type?: 'obj' | 'bedrock' | 'gltf' | 'special'
|
|
38
|
+
mappedFrom?: string
|
|
39
|
+
textureMap?: boolean
|
|
40
|
+
errors?: string[]
|
|
41
41
|
}> = []
|
|
42
|
-
const entityNames = Object.keys(
|
|
43
|
-
acc
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
const entityNames = Object.keys(
|
|
43
|
+
mcData.entitiesArray.reduce((acc, entity) => {
|
|
44
|
+
acc[entity.name] = true
|
|
45
|
+
return acc
|
|
46
|
+
}, {})
|
|
47
|
+
)
|
|
46
48
|
|
|
47
49
|
// Add loading indicator
|
|
48
50
|
const loading = document.createElement('div')
|
|
@@ -57,13 +59,12 @@ export const displayEntitiesDebugList = (mcData: IndexedData) => {
|
|
|
57
59
|
results.push({
|
|
58
60
|
entity,
|
|
59
61
|
supported: true,
|
|
60
|
-
type: 'special'
|
|
62
|
+
type: 'special'
|
|
61
63
|
})
|
|
62
64
|
continue
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
try {
|
|
66
|
-
|
|
67
68
|
const { mesh: entityMesh } = new EntityMesh(version, entity, undefined, {}, debugFlags)
|
|
68
69
|
// find the most distant pos child
|
|
69
70
|
globalThis.objects ??= {}
|
|
@@ -165,9 +166,11 @@ export const displayEntitiesDebugList = (mcData: IndexedData) => {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
// log object with errors per entity
|
|
168
|
-
const errors = results
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
const errors = results
|
|
170
|
+
.filter(r => r.errors)
|
|
171
|
+
.map(r => ({
|
|
172
|
+
entity: r.entity,
|
|
173
|
+
errors: r.errors
|
|
174
|
+
}))
|
|
172
175
|
console.log(errors)
|
|
173
176
|
}
|
|
@@ -35,7 +35,7 @@ export interface PlaygroundSceneConfig {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const appGraphicBackends = [
|
|
38
|
-
createGraphicsBackendSingleThread
|
|
38
|
+
createGraphicsBackendSingleThread
|
|
39
39
|
// createGraphicsBackendOffThread
|
|
40
40
|
]
|
|
41
41
|
|
|
@@ -44,7 +44,7 @@ const includedVersions = globalThis.includedVersions
|
|
|
44
44
|
export class BasePlaygroundScene {
|
|
45
45
|
appViewer = new AppViewer({
|
|
46
46
|
config: {
|
|
47
|
-
statsVisible: 2
|
|
47
|
+
statsVisible: 2
|
|
48
48
|
}
|
|
49
49
|
})
|
|
50
50
|
|
|
@@ -68,13 +68,18 @@ export class BasePlaygroundScene {
|
|
|
68
68
|
// GUI
|
|
69
69
|
gui = new GUI()
|
|
70
70
|
params = {} as Record<string, any>
|
|
71
|
-
paramOptions = {} as Partial<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
paramOptions = {} as Partial<
|
|
72
|
+
Record<
|
|
73
|
+
keyof typeof this.params,
|
|
74
|
+
{
|
|
75
|
+
hide?: boolean
|
|
76
|
+
options?: string[]
|
|
77
|
+
min?: number
|
|
78
|
+
max?: number
|
|
79
|
+
reloadOnChange?: boolean
|
|
80
|
+
}
|
|
81
|
+
>
|
|
82
|
+
>
|
|
78
83
|
onParamUpdate = {} as Record<string, () => void>
|
|
79
84
|
alwaysIgnoreQs = [] as string[]
|
|
80
85
|
skipUpdateQs = false
|
|
@@ -141,7 +146,7 @@ export class BasePlaygroundScene {
|
|
|
141
146
|
})
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
onParamsUpdate(paramName: string, object: any) {
|
|
149
|
+
onParamsUpdate(paramName: string, object: any) {}
|
|
145
150
|
|
|
146
151
|
updateQs(paramName: string, valueSet: any) {
|
|
147
152
|
if (this.skipUpdateQs) return
|
|
@@ -201,16 +206,15 @@ export class BasePlaygroundScene {
|
|
|
201
206
|
}
|
|
202
207
|
|
|
203
208
|
// Overridable methods
|
|
204
|
-
setupWorld() {
|
|
205
|
-
sceneReset() {
|
|
209
|
+
setupWorld() {}
|
|
210
|
+
sceneReset() {}
|
|
206
211
|
|
|
207
212
|
// eslint-disable-next-line max-params
|
|
208
213
|
addWorldBlock(xOffset: number, yOffset: number, zOffset: number, blockName: BlockNames, properties?: Record<string, any>) {
|
|
209
214
|
if (xOffset > 16 || yOffset > 16 || zOffset > 16) throw new Error('Offset too big')
|
|
210
|
-
const block =
|
|
211
|
-
properties
|
|
212
|
-
|
|
213
|
-
this.Block.fromStateId(this.mcData.blocksByName[blockName].defaultState, 0)
|
|
215
|
+
const block = properties
|
|
216
|
+
? this.Block.fromProperties(this.mcData.blocksByName[blockName].id, properties ?? {}, 0)
|
|
217
|
+
: this.Block.fromStateId(this.mcData.blocksByName[blockName].defaultState, 0)
|
|
214
218
|
this.world.setBlock(this.targetPos.offset(xOffset, yOffset, zOffset), block)
|
|
215
219
|
}
|
|
216
220
|
|
|
@@ -291,12 +295,7 @@ export class BasePlaygroundScene {
|
|
|
291
295
|
|
|
292
296
|
// Create our own camera for OrbitControls - this is separate from the internal worldRenderer camera
|
|
293
297
|
// We sync our camera state to the backend via updateCamera()
|
|
294
|
-
this.camera = new THREE.PerspectiveCamera(
|
|
295
|
-
this.appViewer.inWorldRenderingConfig.fov || 75,
|
|
296
|
-
window.innerWidth / window.innerHeight,
|
|
297
|
-
0.1,
|
|
298
|
-
1000
|
|
299
|
-
)
|
|
298
|
+
this.camera = new THREE.PerspectiveCamera(this.appViewer.inWorldRenderingConfig.fov || 75, window.innerWidth / window.innerHeight, 0.1, 1000)
|
|
300
299
|
|
|
301
300
|
// Setup world (adds blocks, etc.)
|
|
302
301
|
this.setupWorld()
|
|
@@ -311,9 +310,7 @@ export class BasePlaygroundScene {
|
|
|
311
310
|
if (this.enableCameraControls) {
|
|
312
311
|
const canvas = document.querySelector('#viewer-canvas')
|
|
313
312
|
if (canvas) {
|
|
314
|
-
const controls = this.enableCameraOrbitControl
|
|
315
|
-
? new OrbitControls(this.camera, canvas as HTMLElement)
|
|
316
|
-
: undefined
|
|
313
|
+
const controls = this.enableCameraOrbitControl ? new OrbitControls(this.camera, canvas as HTMLElement) : undefined
|
|
317
314
|
this.controls = controls
|
|
318
315
|
|
|
319
316
|
this.resetCamera()
|
|
@@ -335,7 +332,7 @@ export class BasePlaygroundScene {
|
|
|
335
332
|
this.camera.position.y.toFixed(2),
|
|
336
333
|
this.camera.position.z.toFixed(2),
|
|
337
334
|
this.camera.rotation.x.toFixed(2),
|
|
338
|
-
this.camera.rotation.y.toFixed(2)
|
|
335
|
+
this.camera.rotation.y.toFixed(2)
|
|
339
336
|
].join(',')
|
|
340
337
|
}, 200)
|
|
341
338
|
|
|
@@ -483,9 +480,7 @@ export class BasePlaygroundScene {
|
|
|
483
480
|
this.currentFps = fps
|
|
484
481
|
|
|
485
482
|
const isSeriousDelay = this.maxFrameDelay > 150
|
|
486
|
-
const delayText = isSeriousDelay
|
|
487
|
-
? `<span style="color: #ff4444;">${this.maxFrameDelay.toFixed(0)}ms</span>`
|
|
488
|
-
: `${this.maxFrameDelay.toFixed(0)}ms`
|
|
483
|
+
const delayText = isSeriousDelay ? `<span style="color: #ff4444;">${this.maxFrameDelay.toFixed(0)}ms</span>` : `${this.maxFrameDelay.toFixed(0)}ms`
|
|
489
484
|
|
|
490
485
|
// Update the DOM element directly - single line format
|
|
491
486
|
this.debugFpsElement.innerHTML = `FPS: ${fps} | Max Delay: ${delayText}`
|
|
@@ -502,16 +497,18 @@ export class BasePlaygroundScene {
|
|
|
502
497
|
}
|
|
503
498
|
|
|
504
499
|
addKeyboardShortcuts() {
|
|
505
|
-
document.addEventListener('keydown',
|
|
500
|
+
document.addEventListener('keydown', e => {
|
|
506
501
|
if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
|
|
507
502
|
if (e.code === 'KeyR') {
|
|
508
503
|
this.controls?.reset()
|
|
509
504
|
this.resetCamera()
|
|
510
505
|
}
|
|
511
|
-
if (e.code === 'KeyE') {
|
|
506
|
+
if (e.code === 'KeyE') {
|
|
507
|
+
// refresh block (main)
|
|
512
508
|
this.worldView!.setBlockStateId(this.targetPos, this.world.getBlockStateId(this.targetPos))
|
|
513
509
|
}
|
|
514
|
-
if (e.code === 'KeyF') {
|
|
510
|
+
if (e.code === 'KeyF') {
|
|
511
|
+
// reload all chunks
|
|
515
512
|
this.sceneReset()
|
|
516
513
|
this.worldView!.unloadAllChunks()
|
|
517
514
|
void this.worldView!.init(this.targetPos)
|
|
@@ -4,15 +4,15 @@ import { proxy, ref, useSnapshot } from 'valtio'
|
|
|
4
4
|
export type ButtonName = 'jump' | 'sneak'
|
|
5
5
|
|
|
6
6
|
export const joystickPointer = proxy({
|
|
7
|
-
pointer: null as { x: number
|
|
8
|
-
joystickInner: null as HTMLDivElement | null
|
|
7
|
+
pointer: null as { x: number; y: number; pointerId: number } | null,
|
|
8
|
+
joystickInner: null as HTMLDivElement | null
|
|
9
9
|
})
|
|
10
10
|
|
|
11
11
|
export const cameraPointer = proxy({
|
|
12
|
-
pointer: null as { x: number
|
|
12
|
+
pointer: null as { x: number; y: number; pointerId: number } | null
|
|
13
13
|
})
|
|
14
14
|
|
|
15
|
-
export const handleMovementStickDelta = (e?: { clientX: number
|
|
15
|
+
export const handleMovementStickDelta = (e?: { clientX: number; clientY: number }) => {
|
|
16
16
|
const max = 32
|
|
17
17
|
let x = 0
|
|
18
18
|
let y = 0
|
|
@@ -31,7 +31,7 @@ export const handleMovementStickDelta = (e?: { clientX: number, clientY: number
|
|
|
31
31
|
const vector = {
|
|
32
32
|
x: x / max,
|
|
33
33
|
y: 0,
|
|
34
|
-
z: y / max
|
|
34
|
+
z: y / max
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
console.log('Movement vector:', vector)
|
|
@@ -81,12 +81,12 @@ export const MobileControls = () => {
|
|
|
81
81
|
|
|
82
82
|
const buttonPositions = {
|
|
83
83
|
jump: [85, 60],
|
|
84
|
-
sneak: [85, 75]
|
|
84
|
+
sneak: [85, 75]
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const buttonIcons = {
|
|
88
88
|
jump: '↑',
|
|
89
|
-
sneak: '↓'
|
|
89
|
+
sneak: '↓'
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
return {
|
|
@@ -107,7 +107,7 @@ export const MobileControls = () => {
|
|
|
107
107
|
fontSize: '16px',
|
|
108
108
|
userSelect: 'none',
|
|
109
109
|
transform: 'translate(-50%, -50%)',
|
|
110
|
-
border: '2px solid rgba(255, 255, 255, 0.3)'
|
|
110
|
+
border: '2px solid rgba(255, 255, 255, 0.3)'
|
|
111
111
|
} satisfies CSSProperties,
|
|
112
112
|
onPointerDown(e: PType) {
|
|
113
113
|
const elem = e.currentTarget as HTMLElement
|
|
@@ -117,7 +117,7 @@ export const MobileControls = () => {
|
|
|
117
117
|
},
|
|
118
118
|
onPointerUp: pointerup,
|
|
119
119
|
onLostPointerCapture: pointerup,
|
|
120
|
-
children: buttonIcons[name]
|
|
120
|
+
children: buttonIcons[name]
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -129,140 +129,144 @@ export const MobileControls = () => {
|
|
|
129
129
|
|
|
130
130
|
if (!usingTouch) return null
|
|
131
131
|
|
|
132
|
-
return
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
className='movement_joystick_outer'
|
|
136
|
-
ref={joystickOuter}
|
|
137
|
-
style={{
|
|
138
|
-
display: movementPointer ? 'flex' : 'none',
|
|
139
|
-
borderRadius: '50%',
|
|
140
|
-
width: joystickSize,
|
|
141
|
-
height: joystickSize,
|
|
142
|
-
border: '2px solid rgba(0, 0, 0, 0.5)',
|
|
143
|
-
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
|
144
|
-
position: 'fixed',
|
|
145
|
-
justifyContent: 'center',
|
|
146
|
-
alignItems: 'center',
|
|
147
|
-
transform: 'translate(-50%, -50%)',
|
|
148
|
-
zIndex: Z_INDEX_INTERACTIBLE,
|
|
149
|
-
...(movementPointer ? {
|
|
150
|
-
left: `${movementPointer.x / window.innerWidth * 100}%`,
|
|
151
|
-
top: `${movementPointer.y / window.innerHeight * 100}%`
|
|
152
|
-
} : {}),
|
|
153
|
-
}}
|
|
154
|
-
>
|
|
132
|
+
return (
|
|
133
|
+
<div>
|
|
134
|
+
{/* Movement Joystick */}
|
|
155
135
|
<div
|
|
156
|
-
className=
|
|
136
|
+
className="movement_joystick_outer"
|
|
137
|
+
ref={joystickOuter}
|
|
157
138
|
style={{
|
|
139
|
+
display: movementPointer ? 'flex' : 'none',
|
|
158
140
|
borderRadius: '50%',
|
|
159
|
-
width: joystickSize
|
|
160
|
-
height: joystickSize
|
|
161
|
-
|
|
162
|
-
|
|
141
|
+
width: joystickSize,
|
|
142
|
+
height: joystickSize,
|
|
143
|
+
border: '2px solid rgba(0, 0, 0, 0.5)',
|
|
144
|
+
backgroundColor: 'rgba(255, 255, 255, 0.3)',
|
|
145
|
+
position: 'fixed',
|
|
146
|
+
justifyContent: 'center',
|
|
147
|
+
alignItems: 'center',
|
|
148
|
+
transform: 'translate(-50%, -50%)',
|
|
149
|
+
zIndex: Z_INDEX_INTERACTIBLE,
|
|
150
|
+
...(movementPointer
|
|
151
|
+
? {
|
|
152
|
+
left: `${(movementPointer.x / window.innerWidth) * 100}%`,
|
|
153
|
+
top: `${(movementPointer.y / window.innerHeight) * 100}%`
|
|
154
|
+
}
|
|
155
|
+
: {})
|
|
163
156
|
}}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
>
|
|
158
|
+
<div
|
|
159
|
+
className="movement_joystick_inner"
|
|
160
|
+
style={{
|
|
161
|
+
borderRadius: '50%',
|
|
162
|
+
width: joystickSize * 0.35,
|
|
163
|
+
height: joystickSize * 0.35,
|
|
164
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
165
|
+
position: 'absolute'
|
|
166
|
+
}}
|
|
167
|
+
ref={joystickInner}
|
|
168
|
+
/>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
{/* Up/Down Action Buttons */}
|
|
172
|
+
<div {...buttonProps('jump')} />
|
|
173
|
+
<div {...buttonProps('sneak')} />
|
|
174
|
+
|
|
175
|
+
{/* Movement touch area (left half of screen) */}
|
|
176
|
+
<div
|
|
177
|
+
style={{
|
|
178
|
+
position: 'fixed',
|
|
179
|
+
left: '0',
|
|
180
|
+
top: '0',
|
|
181
|
+
width: '50%',
|
|
182
|
+
height: '100%',
|
|
183
|
+
zIndex: Z_INDEX_INTERACTIBLE - 1
|
|
184
|
+
}}
|
|
185
|
+
onPointerDown={e => {
|
|
186
|
+
if (joystickPointer.pointer) return
|
|
167
187
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
188
|
+
joystickPointer.pointer = {
|
|
189
|
+
x: e.clientX,
|
|
190
|
+
y: e.clientY,
|
|
191
|
+
pointerId: e.pointerId
|
|
192
|
+
}
|
|
171
193
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
top: '0',
|
|
178
|
-
width: '50%',
|
|
179
|
-
height: '100%',
|
|
180
|
-
zIndex: Z_INDEX_INTERACTIBLE - 1,
|
|
181
|
-
}}
|
|
182
|
-
onPointerDown={(e) => {
|
|
183
|
-
if (joystickPointer.pointer) return
|
|
184
|
-
|
|
185
|
-
joystickPointer.pointer = {
|
|
186
|
-
x: e.clientX,
|
|
187
|
-
y: e.clientY,
|
|
188
|
-
pointerId: e.pointerId,
|
|
189
|
-
}
|
|
194
|
+
const elem = e.currentTarget as HTMLElement
|
|
195
|
+
elem.setPointerCapture(e.pointerId)
|
|
196
|
+
}}
|
|
197
|
+
onPointerMove={e => {
|
|
198
|
+
if (!joystickPointer.pointer || e.pointerId !== joystickPointer.pointer.pointerId) return
|
|
190
199
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
200
|
+
handleMovementStickDelta({
|
|
201
|
+
clientX: e.clientX,
|
|
202
|
+
clientY: e.clientY
|
|
203
|
+
})
|
|
204
|
+
}}
|
|
205
|
+
onPointerUp={e => {
|
|
206
|
+
if (!joystickPointer.pointer || e.pointerId !== joystickPointer.pointer.pointerId) return
|
|
196
207
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
clientY: e.clientY,
|
|
200
|
-
})
|
|
201
|
-
}}
|
|
202
|
-
onPointerUp={(e) => {
|
|
203
|
-
if (!joystickPointer.pointer || e.pointerId !== joystickPointer.pointer.pointerId) return
|
|
208
|
+
joystickPointer.pointer = null
|
|
209
|
+
handleMovementStickDelta() // Reset position
|
|
204
210
|
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
const elem = e.currentTarget as HTMLElement
|
|
212
|
+
elem.releasePointerCapture(e.pointerId)
|
|
213
|
+
}}
|
|
214
|
+
onLostPointerCapture={e => {
|
|
215
|
+
if (!joystickPointer.pointer || e.pointerId !== joystickPointer.pointer.pointerId) return
|
|
207
216
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (!joystickPointer.pointer || e.pointerId !== joystickPointer.pointer.pointerId) return
|
|
213
|
-
|
|
214
|
-
joystickPointer.pointer = null
|
|
215
|
-
handleMovementStickDelta() // Reset position
|
|
216
|
-
}}
|
|
217
|
-
/>
|
|
218
|
-
|
|
219
|
-
{/* Camera rotation touch area (right half of screen, excluding buttons) */}
|
|
220
|
-
<div
|
|
221
|
-
style={{
|
|
222
|
-
position: 'fixed',
|
|
223
|
-
right: '0',
|
|
224
|
-
top: '0',
|
|
225
|
-
width: '50%',
|
|
226
|
-
height: '100%',
|
|
227
|
-
zIndex: Z_INDEX_INTERACTIBLE - 2,
|
|
228
|
-
}}
|
|
229
|
-
onPointerDown={(e) => {
|
|
230
|
-
if (cameraPointer.pointer) return
|
|
231
|
-
|
|
232
|
-
cameraPointer.pointer = {
|
|
233
|
-
x: e.clientX,
|
|
234
|
-
y: e.clientY,
|
|
235
|
-
pointerId: e.pointerId,
|
|
236
|
-
}
|
|
217
|
+
joystickPointer.pointer = null
|
|
218
|
+
handleMovementStickDelta() // Reset position
|
|
219
|
+
}}
|
|
220
|
+
/>
|
|
237
221
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
222
|
+
{/* Camera rotation touch area (right half of screen, excluding buttons) */}
|
|
223
|
+
<div
|
|
224
|
+
style={{
|
|
225
|
+
position: 'fixed',
|
|
226
|
+
right: '0',
|
|
227
|
+
top: '0',
|
|
228
|
+
width: '50%',
|
|
229
|
+
height: '100%',
|
|
230
|
+
zIndex: Z_INDEX_INTERACTIBLE - 2
|
|
231
|
+
}}
|
|
232
|
+
onPointerDown={e => {
|
|
233
|
+
if (cameraPointer.pointer) return
|
|
234
|
+
|
|
235
|
+
cameraPointer.pointer = {
|
|
236
|
+
x: e.clientX,
|
|
237
|
+
y: e.clientY,
|
|
238
|
+
pointerId: e.pointerId
|
|
239
|
+
}
|
|
243
240
|
|
|
244
|
-
|
|
245
|
-
|
|
241
|
+
const elem = e.currentTarget as HTMLElement
|
|
242
|
+
elem.setPointerCapture(e.pointerId)
|
|
243
|
+
}}
|
|
244
|
+
onPointerMove={e => {
|
|
245
|
+
if (!cameraPointer.pointer || e.pointerId !== cameraPointer.pointer.pointerId) return
|
|
246
246
|
|
|
247
|
-
|
|
247
|
+
const deltaX = e.clientX - cameraPointer.pointer.x
|
|
248
|
+
const deltaY = e.clientY - cameraPointer.pointer.y
|
|
248
249
|
|
|
249
|
-
|
|
250
|
-
cameraPointer.pointer.x = e.clientX
|
|
251
|
-
cameraPointer.pointer.y = e.clientY
|
|
252
|
-
}}
|
|
253
|
-
onPointerUp={(e) => {
|
|
254
|
-
if (!cameraPointer.pointer || e.pointerId !== cameraPointer.pointer.pointerId) return
|
|
250
|
+
handleCameraRotation(deltaX, deltaY)
|
|
255
251
|
|
|
256
|
-
|
|
252
|
+
// Update pointer position for continuous rotation
|
|
253
|
+
cameraPointer.pointer.x = e.clientX
|
|
254
|
+
cameraPointer.pointer.y = e.clientY
|
|
255
|
+
}}
|
|
256
|
+
onPointerUp={e => {
|
|
257
|
+
if (!cameraPointer.pointer || e.pointerId !== cameraPointer.pointer.pointerId) return
|
|
257
258
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
259
|
+
cameraPointer.pointer = null
|
|
260
|
+
|
|
261
|
+
const elem = e.currentTarget as HTMLElement
|
|
262
|
+
elem.releasePointerCapture(e.pointerId)
|
|
263
|
+
}}
|
|
264
|
+
onLostPointerCapture={e => {
|
|
265
|
+
if (!cameraPointer.pointer || e.pointerId !== cameraPointer.pointer.pointerId) return
|
|
266
|
+
|
|
267
|
+
cameraPointer.pointer = null
|
|
268
|
+
}}
|
|
269
|
+
/>
|
|
270
|
+
</div>
|
|
271
|
+
)
|
|
268
272
|
}
|