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
|
@@ -21,19 +21,19 @@ export const WAYPOINT_CONFIG = {
|
|
|
21
21
|
LAYOUT: {
|
|
22
22
|
DOT_Y: 0.3,
|
|
23
23
|
NAME_Y: 0.45,
|
|
24
|
-
DISTANCE_Y: 0.55
|
|
24
|
+
DISTANCE_Y: 0.55
|
|
25
25
|
},
|
|
26
26
|
// Multiplier for canvas internal resolution to keep text crisp
|
|
27
27
|
CANVAS_SCALE: 2,
|
|
28
28
|
ARROW: {
|
|
29
29
|
enabledDefault: false,
|
|
30
30
|
pixelSize: 50,
|
|
31
|
-
paddingPx: 50
|
|
31
|
+
paddingPx: 50
|
|
32
32
|
},
|
|
33
33
|
// Default visual scale factor (can be overridden globally or per-waypoint)
|
|
34
34
|
DEFAULT_VISUAL_SCALE: 1,
|
|
35
35
|
// Default opacity (can be overridden globally or per-waypoint)
|
|
36
|
-
DEFAULT_OPACITY: 1
|
|
36
|
+
DEFAULT_OPACITY: 1
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export type WaypointSprite = {
|
|
@@ -43,12 +43,7 @@ export type WaypointSprite = {
|
|
|
43
43
|
enableOffscreenArrow: (enabled: boolean) => void
|
|
44
44
|
setArrowParent: (parent: THREE.Object3D | null) => void
|
|
45
45
|
// Convenience combined updater
|
|
46
|
-
updateForCamera: (
|
|
47
|
-
cameraPosition: THREE.Vector3,
|
|
48
|
-
camera: THREE.PerspectiveCamera,
|
|
49
|
-
viewportWidthPx: number,
|
|
50
|
-
viewportHeightPx: number
|
|
51
|
-
) => boolean
|
|
46
|
+
updateForCamera: (cameraPosition: THREE.Vector3, camera: THREE.PerspectiveCamera, viewportWidthPx: number, viewportHeightPx: number) => boolean
|
|
52
47
|
// Utilities
|
|
53
48
|
setColor: (color: number) => void
|
|
54
49
|
setLabel: (label?: string) => void
|
|
@@ -58,33 +53,35 @@ export type WaypointSprite = {
|
|
|
58
53
|
dispose: () => void
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
export function createWaypointSprite
|
|
62
|
-
position: THREE.Vector3 | { x: number
|
|
63
|
-
color?: number
|
|
64
|
-
label?: string
|
|
65
|
-
depthTest?: boolean
|
|
56
|
+
export function createWaypointSprite(options: {
|
|
57
|
+
position: THREE.Vector3 | { x: number; y: number; z: number }
|
|
58
|
+
color?: number
|
|
59
|
+
label?: string
|
|
60
|
+
depthTest?: boolean
|
|
66
61
|
// Y offset in world units used by updateScaleWorld only (screen-pixel API ignores this)
|
|
67
|
-
labelYOffset?: number
|
|
68
|
-
metadata?: any
|
|
69
|
-
visualScale?: number
|
|
70
|
-
opacity?: number
|
|
62
|
+
labelYOffset?: number
|
|
63
|
+
metadata?: any
|
|
64
|
+
visualScale?: number
|
|
65
|
+
opacity?: number
|
|
71
66
|
}): WaypointSprite {
|
|
72
|
-
let displayColor = options.color ??
|
|
67
|
+
let displayColor = options.color ?? 0xff_00_00
|
|
73
68
|
const depthTest = options.depthTest ?? false
|
|
74
69
|
|
|
75
70
|
// Get visual scale from options, metadata, server metadata, or default
|
|
76
71
|
// Priority: options.visualScale > metadata.visualScale > window.serverMetadata?.waypointVisualScale > DEFAULT
|
|
77
|
-
const visualScale =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
const visualScale =
|
|
73
|
+
options.visualScale ??
|
|
74
|
+
options.metadata?.visualScale ??
|
|
75
|
+
(typeof window === 'undefined' ? undefined : (window as any).serverMetadata?.waypointVisualScale) ??
|
|
76
|
+
WAYPOINT_CONFIG.DEFAULT_VISUAL_SCALE
|
|
81
77
|
|
|
82
78
|
// Get opacity from options, metadata, server metadata, or default
|
|
83
79
|
// Priority: options.opacity > metadata.opacity > window.serverMetadata?.waypointOpacity > DEFAULT
|
|
84
|
-
const opacity =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
const opacity =
|
|
81
|
+
options.opacity ??
|
|
82
|
+
options.metadata?.opacity ??
|
|
83
|
+
(typeof window === 'undefined' ? undefined : (window as any).serverMetadata?.waypointOpacity) ??
|
|
84
|
+
WAYPOINT_CONFIG.DEFAULT_OPACITY
|
|
88
85
|
|
|
89
86
|
const labelCanvas = createCanvas(getLabelCanvasSize(), getLabelCanvasSize())
|
|
90
87
|
drawCombinedOntoCanvas(labelCanvas, displayColor, options.label ?? '', '0m', visualScale)
|
|
@@ -98,7 +95,7 @@ export function createWaypointSprite (options: {
|
|
|
98
95
|
transparent: true,
|
|
99
96
|
opacity: 1,
|
|
100
97
|
depthTest,
|
|
101
|
-
depthWrite: false
|
|
98
|
+
depthWrite: false
|
|
102
99
|
})
|
|
103
100
|
const sprite = new THREE.Sprite(material)
|
|
104
101
|
sprite.position.set(0, 0, 0)
|
|
@@ -122,11 +119,11 @@ export function createWaypointSprite (options: {
|
|
|
122
119
|
const { x, y, z } = options.position
|
|
123
120
|
group.position.set(x, y, z)
|
|
124
121
|
|
|
125
|
-
function refreshLabelTexture
|
|
122
|
+
function refreshLabelTexture() {
|
|
126
123
|
labelTexture.needsUpdate = true
|
|
127
124
|
}
|
|
128
125
|
|
|
129
|
-
function paintArrowOnCanvas
|
|
126
|
+
function paintArrowOnCanvas() {
|
|
130
127
|
if (!arrowCanvas || !arrowCtx) return
|
|
131
128
|
const size = arrowCanvas.width
|
|
132
129
|
arrowCtx.clearRect(0, 0, size, size)
|
|
@@ -144,7 +141,7 @@ export function createWaypointSprite (options: {
|
|
|
144
141
|
if (arrowTexture) arrowTexture.needsUpdate = true
|
|
145
142
|
}
|
|
146
143
|
|
|
147
|
-
function setColor
|
|
144
|
+
function setColor(newColor: number) {
|
|
148
145
|
displayColor = newColor
|
|
149
146
|
lastDistanceText = '0m'
|
|
150
147
|
lastDistanceBucket = 0
|
|
@@ -153,13 +150,13 @@ export function createWaypointSprite (options: {
|
|
|
153
150
|
if (arrowSprite) paintArrowOnCanvas()
|
|
154
151
|
}
|
|
155
152
|
|
|
156
|
-
function setLabel
|
|
153
|
+
function setLabel(newLabel?: string) {
|
|
157
154
|
currentLabel = newLabel ?? ''
|
|
158
155
|
drawCombinedOntoCanvas(labelCanvas, displayColor, currentLabel, lastDistanceText, visualScale)
|
|
159
156
|
refreshLabelTexture()
|
|
160
157
|
}
|
|
161
158
|
|
|
162
|
-
function updateDistanceText
|
|
159
|
+
function updateDistanceText(label: string, distanceText: string) {
|
|
163
160
|
if (distanceText === lastDistanceText) {
|
|
164
161
|
return
|
|
165
162
|
}
|
|
@@ -169,27 +166,22 @@ export function createWaypointSprite (options: {
|
|
|
169
166
|
refreshLabelTexture()
|
|
170
167
|
}
|
|
171
168
|
|
|
172
|
-
function setVisible
|
|
169
|
+
function setVisible(visible: boolean) {
|
|
173
170
|
sprite.visible = visible
|
|
174
171
|
}
|
|
175
172
|
|
|
176
|
-
function setPosition
|
|
173
|
+
function setPosition(nx: number, ny: number, nz: number) {
|
|
177
174
|
group.position.set(nx, ny, nz)
|
|
178
175
|
}
|
|
179
176
|
|
|
180
|
-
function updateScaleScreenPixels
|
|
181
|
-
|
|
182
|
-
cameraFov: number,
|
|
183
|
-
distance: number,
|
|
184
|
-
viewportHeightPx: number
|
|
185
|
-
) {
|
|
186
|
-
const vFovRad = cameraFov * Math.PI / 180
|
|
177
|
+
function updateScaleScreenPixels(cameraPosition: THREE.Vector3, cameraFov: number, distance: number, viewportHeightPx: number) {
|
|
178
|
+
const vFovRad = (cameraFov * Math.PI) / 180
|
|
187
179
|
const worldUnitsPerScreenHeightAtDist = Math.tan(vFovRad / 2) * 2 * distance
|
|
188
|
-
const scale = worldUnitsPerScreenHeightAtDist * (WAYPOINT_CONFIG.TARGET_SCREEN_PX * visualScale / viewportHeightPx)
|
|
180
|
+
const scale = worldUnitsPerScreenHeightAtDist * ((WAYPOINT_CONFIG.TARGET_SCREEN_PX * visualScale) / viewportHeightPx)
|
|
189
181
|
sprite.scale.set(scale, scale, 1)
|
|
190
182
|
}
|
|
191
183
|
|
|
192
|
-
function ensureArrow
|
|
184
|
+
function ensureArrow() {
|
|
193
185
|
if (arrowSprite) return
|
|
194
186
|
const size = 128
|
|
195
187
|
arrowCanvas = createCanvas(size, size)
|
|
@@ -206,22 +198,18 @@ export function createWaypointSprite (options: {
|
|
|
206
198
|
if (arrowParent) arrowParent.add(arrowSprite)
|
|
207
199
|
}
|
|
208
200
|
|
|
209
|
-
function enableOffscreenArrow
|
|
201
|
+
function enableOffscreenArrow(enabled: boolean) {
|
|
210
202
|
arrowEnabled = enabled
|
|
211
203
|
if (!enabled && arrowSprite) arrowSprite.visible = false
|
|
212
204
|
}
|
|
213
205
|
|
|
214
|
-
function setArrowParent
|
|
206
|
+
function setArrowParent(parent: THREE.Object3D | null) {
|
|
215
207
|
if (arrowSprite?.parent) arrowSprite.parent.remove(arrowSprite)
|
|
216
208
|
arrowParent = parent
|
|
217
209
|
if (arrowSprite && parent) parent.add(arrowSprite)
|
|
218
210
|
}
|
|
219
211
|
|
|
220
|
-
function updateOffscreenArrow
|
|
221
|
-
camera: THREE.PerspectiveCamera,
|
|
222
|
-
viewportWidthPx: number,
|
|
223
|
-
viewportHeightPx: number
|
|
224
|
-
): boolean {
|
|
212
|
+
function updateOffscreenArrow(camera: THREE.PerspectiveCamera, viewportWidthPx: number, viewportHeightPx: number): boolean {
|
|
225
213
|
if (!arrowEnabled) return true
|
|
226
214
|
ensureArrow()
|
|
227
215
|
if (!arrowSprite) return true
|
|
@@ -246,7 +234,7 @@ export function createWaypointSprite (options: {
|
|
|
246
234
|
const y = toWp.dot(upCam)
|
|
247
235
|
|
|
248
236
|
const aspect = viewportWidthPx / viewportHeightPx
|
|
249
|
-
const vFovRad = camera.fov * Math.PI / 180
|
|
237
|
+
const vFovRad = (camera.fov * Math.PI) / 180
|
|
250
238
|
const hFovRad = 2 * Math.atan(Math.tan(vFovRad / 2) * aspect)
|
|
251
239
|
|
|
252
240
|
// Determine if waypoint is inside view frustum using angular checks
|
|
@@ -294,8 +282,8 @@ export function createWaypointSprite (options: {
|
|
|
294
282
|
|
|
295
283
|
// Apply padding in pixel space by clamping
|
|
296
284
|
const padding = WAYPOINT_CONFIG.ARROW.paddingPx
|
|
297
|
-
const pxX = (
|
|
298
|
-
const pxY = (
|
|
285
|
+
const pxX = (ndcX + 1) * 0.5 * viewportWidthPx
|
|
286
|
+
const pxY = (1 - ndcY) * 0.5 * viewportHeightPx
|
|
299
287
|
const clampedPxX = Math.min(Math.max(pxX, padding), viewportWidthPx - padding)
|
|
300
288
|
const clampedPxY = Math.min(Math.max(pxY, padding), viewportHeightPx - padding)
|
|
301
289
|
ndcX = (clampedPxX / viewportWidthPx) * 2 - 1
|
|
@@ -305,7 +293,8 @@ export function createWaypointSprite (options: {
|
|
|
305
293
|
const placeDist = Math.max(2, camera.near * 4)
|
|
306
294
|
const halfPlaneHeight = Math.tan(vFovRad / 2) * placeDist
|
|
307
295
|
const halfPlaneWidth = halfPlaneHeight * aspect
|
|
308
|
-
const pos = camPos
|
|
296
|
+
const pos = camPos
|
|
297
|
+
.clone()
|
|
309
298
|
.add(forward.clone().multiplyScalar(placeDist))
|
|
310
299
|
.add(right.clone().multiplyScalar(ndcX * halfPlaneWidth))
|
|
311
300
|
.add(upCam.clone().multiplyScalar(ndcY * halfPlaneHeight))
|
|
@@ -320,21 +309,16 @@ export function createWaypointSprite (options: {
|
|
|
320
309
|
|
|
321
310
|
// Constant pixel size for arrow (use fixed placement distance) with visual scale
|
|
322
311
|
const worldUnitsPerScreenHeightAtDist = Math.tan(vFovRad / 2) * 2 * placeDist
|
|
323
|
-
const sPx = worldUnitsPerScreenHeightAtDist * (WAYPOINT_CONFIG.ARROW.pixelSize * visualScale / viewportHeightPx)
|
|
312
|
+
const sPx = worldUnitsPerScreenHeightAtDist * ((WAYPOINT_CONFIG.ARROW.pixelSize * visualScale) / viewportHeightPx)
|
|
324
313
|
arrowSprite.scale.set(sPx, sPx, 1)
|
|
325
314
|
return false
|
|
326
315
|
}
|
|
327
316
|
|
|
328
|
-
function computeDistance
|
|
317
|
+
function computeDistance(cameraPosition: THREE.Vector3): number {
|
|
329
318
|
return cameraPosition.distanceTo(group.position)
|
|
330
319
|
}
|
|
331
320
|
|
|
332
|
-
function updateForCamera
|
|
333
|
-
cameraPosition: THREE.Vector3,
|
|
334
|
-
camera: THREE.PerspectiveCamera,
|
|
335
|
-
viewportWidthPx: number,
|
|
336
|
-
viewportHeightPx: number
|
|
337
|
-
): boolean {
|
|
321
|
+
function updateForCamera(cameraPosition: THREE.Vector3, camera: THREE.PerspectiveCamera, viewportWidthPx: number, viewportHeightPx: number): boolean {
|
|
338
322
|
const distance = computeDistance(cameraPosition)
|
|
339
323
|
updateScaleScreenPixels(cameraPosition, camera.fov, distance, viewportHeightPx)
|
|
340
324
|
|
|
@@ -349,7 +333,7 @@ export function createWaypointSprite (options: {
|
|
|
349
333
|
return onScreen
|
|
350
334
|
}
|
|
351
335
|
|
|
352
|
-
function dispose
|
|
336
|
+
function dispose() {
|
|
353
337
|
const mat = sprite.material
|
|
354
338
|
mat.map?.dispose()
|
|
355
339
|
mat.dispose()
|
|
@@ -378,28 +362,22 @@ export function createWaypointSprite (options: {
|
|
|
378
362
|
updateDistanceText,
|
|
379
363
|
setVisible,
|
|
380
364
|
setPosition,
|
|
381
|
-
dispose
|
|
365
|
+
dispose
|
|
382
366
|
}
|
|
383
367
|
}
|
|
384
368
|
|
|
385
369
|
// Internal helpers
|
|
386
|
-
function computeLabelCanvasLineScale
|
|
370
|
+
function computeLabelCanvasLineScale(): number {
|
|
387
371
|
const dpr = globalThis.devicePixelRatio || 1
|
|
388
372
|
const effectiveDpr = Math.min(dpr, LABEL_CANVAS_MAX_DEVICE_PIXEL_RATIO)
|
|
389
373
|
return WAYPOINT_CONFIG.CANVAS_SCALE * effectiveDpr
|
|
390
374
|
}
|
|
391
375
|
|
|
392
|
-
function getLabelCanvasSize
|
|
376
|
+
function getLabelCanvasSize(): number {
|
|
393
377
|
return Math.round(WAYPOINT_CONFIG.CANVAS_SIZE * computeLabelCanvasLineScale())
|
|
394
378
|
}
|
|
395
379
|
|
|
396
|
-
function drawCombinedOntoCanvas
|
|
397
|
-
canvas: OffscreenCanvas,
|
|
398
|
-
color: number,
|
|
399
|
-
id: string,
|
|
400
|
-
distance: string,
|
|
401
|
-
visualScale: number
|
|
402
|
-
): void {
|
|
380
|
+
function drawCombinedOntoCanvas(canvas: OffscreenCanvas, color: number, id: string, distance: string, visualScale: number): void {
|
|
403
381
|
const size = canvas.width
|
|
404
382
|
const scale = computeLabelCanvasLineScale()
|
|
405
383
|
const ctx = canvas.getContext('2d')!
|
|
@@ -443,17 +421,12 @@ function drawCombinedOntoCanvas (
|
|
|
443
421
|
|
|
444
422
|
export const WaypointHelpers = {
|
|
445
423
|
// World-scale constant size helper
|
|
446
|
-
computeWorldScale
|
|
424
|
+
computeWorldScale(distance: number, fixedReference = 10) {
|
|
447
425
|
return Math.max(0.0001, distance / fixedReference)
|
|
448
426
|
},
|
|
449
427
|
// Screen-pixel constant size helper
|
|
450
|
-
computeScreenPixelScale
|
|
451
|
-
camera
|
|
452
|
-
distance: number,
|
|
453
|
-
pixelSize: number,
|
|
454
|
-
viewportHeightPx: number
|
|
455
|
-
) {
|
|
456
|
-
const vFovRad = camera.fov * Math.PI / 180
|
|
428
|
+
computeScreenPixelScale(camera: THREE.PerspectiveCamera, distance: number, pixelSize: number, viewportHeightPx: number) {
|
|
429
|
+
const vFovRad = (camera.fov * Math.PI) / 180
|
|
457
430
|
const worldUnitsPerScreenHeightAtDist = Math.tan(vFovRad / 2) * 2 * distance
|
|
458
431
|
return worldUnitsPerScreenHeightAtDist * (pixelSize / viewportHeightPx)
|
|
459
432
|
}
|
package/src/three/waypoints.ts
CHANGED
|
@@ -32,9 +32,7 @@ export class WaypointsRenderer {
|
|
|
32
32
|
private lastUpdateTime = 0
|
|
33
33
|
private readonly UPDATE_THROTTLE_MS = 16 // ~60fps max update rate
|
|
34
34
|
|
|
35
|
-
constructor(
|
|
36
|
-
private readonly worldRenderer: WorldRendererThree
|
|
37
|
-
) {
|
|
35
|
+
constructor(private readonly worldRenderer: WorldRendererThree) {
|
|
38
36
|
if (process.env.NODE_ENV !== 'production') {
|
|
39
37
|
// this.addWaypoint('spawn', 0, 0, 0, { })
|
|
40
38
|
}
|
|
@@ -60,8 +58,7 @@ export class WaypointsRenderer {
|
|
|
60
58
|
for (const waypoint of this.waypoints.values()) {
|
|
61
59
|
const waypointPos = new THREE.Vector3(waypoint.x, waypoint.y, waypoint.z)
|
|
62
60
|
const distance = playerPos.distanceTo(waypointPos)
|
|
63
|
-
const visible = (!waypoint.minDistance || distance >= waypoint.minDistance) &&
|
|
64
|
-
(waypoint.maxDistance === Infinity || distance <= waypoint.maxDistance)
|
|
61
|
+
const visible = (!waypoint.minDistance || distance >= waypoint.minDistance) && (waypoint.maxDistance === Infinity || distance <= waypoint.maxDistance)
|
|
65
62
|
|
|
66
63
|
waypoint.sprite.setVisible(visible)
|
|
67
64
|
|
|
@@ -90,17 +87,11 @@ export class WaypointsRenderer {
|
|
|
90
87
|
|
|
91
88
|
// Removed sprite/label texture creation. Use utils/waypointSprite.ts
|
|
92
89
|
|
|
93
|
-
addWaypoint(
|
|
94
|
-
id: string,
|
|
95
|
-
x: number,
|
|
96
|
-
y: number,
|
|
97
|
-
z: number,
|
|
98
|
-
options: WaypointOptions = {}
|
|
99
|
-
) {
|
|
90
|
+
addWaypoint(id: string, x: number, y: number, z: number, options: WaypointOptions = {}) {
|
|
100
91
|
// Remove existing waypoint if it exists
|
|
101
92
|
this.removeWaypoint(id)
|
|
102
93
|
|
|
103
|
-
const color = options.color ??
|
|
94
|
+
const color = options.color ?? 0xff_00_00
|
|
104
95
|
const { label, metadata } = options
|
|
105
96
|
const minDistance = options.minDistance ?? 0
|
|
106
97
|
const maxDistance = options.maxDistance ?? Infinity
|
|
@@ -108,8 +99,8 @@ export class WaypointsRenderer {
|
|
|
108
99
|
const sprite = createWaypointSprite({
|
|
109
100
|
position: new THREE.Vector3(x, y, z),
|
|
110
101
|
color,
|
|
111
|
-
label:
|
|
112
|
-
metadata
|
|
102
|
+
label: label || id,
|
|
103
|
+
metadata
|
|
113
104
|
})
|
|
114
105
|
sprite.enableOffscreenArrow(true)
|
|
115
106
|
sprite.setArrowParent(this.waypointScene)
|
|
@@ -117,9 +108,15 @@ export class WaypointsRenderer {
|
|
|
117
108
|
this.waypointScene.add(sprite.group)
|
|
118
109
|
|
|
119
110
|
this.waypoints.set(id, {
|
|
120
|
-
id,
|
|
121
|
-
|
|
122
|
-
|
|
111
|
+
id,
|
|
112
|
+
x: x + 0.5,
|
|
113
|
+
y: y + 0.5,
|
|
114
|
+
z: z + 0.5,
|
|
115
|
+
minDistance,
|
|
116
|
+
maxDistance,
|
|
117
|
+
color,
|
|
118
|
+
label,
|
|
119
|
+
sprite
|
|
123
120
|
})
|
|
124
121
|
}
|
|
125
122
|
|
|
@@ -139,11 +136,11 @@ export class WaypointsRenderer {
|
|
|
139
136
|
}
|
|
140
137
|
|
|
141
138
|
testWaypoint() {
|
|
142
|
-
this.addWaypoint('Test Point', 0, 70, 0, { color:
|
|
143
|
-
this.addWaypoint('Spawn', 0, 64, 0, { color:
|
|
144
|
-
this.addWaypoint('Far Point', 100, 70, 100, { color:
|
|
145
|
-
this.addWaypoint('Far Point 2', 180, 170, 100, { color:
|
|
146
|
-
this.addWaypoint('Far Point 3', 1000, 100, 1000, { color:
|
|
139
|
+
this.addWaypoint('Test Point', 0, 70, 0, { color: 0x00_ff_00, label: 'Test Point' })
|
|
140
|
+
this.addWaypoint('Spawn', 0, 64, 0, { color: 0xff_ff_00, label: 'Spawn' })
|
|
141
|
+
this.addWaypoint('Far Point', 100, 70, 100, { color: 0x00_00_ff, label: 'Far Point' })
|
|
142
|
+
this.addWaypoint('Far Point 2', 180, 170, 100, { color: 0x00_00_ff, label: 'Far Point 2' })
|
|
143
|
+
this.addWaypoint('Far Point 3', 1000, 100, 1000, { color: 0x00_00_ff, label: 'Far Point 3' })
|
|
147
144
|
}
|
|
148
145
|
|
|
149
146
|
getWaypoint(id: string): Waypoint | undefined {
|
|
@@ -29,7 +29,7 @@ export class CursorBlock {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
cursorLineMaterial!: LineMaterial
|
|
32
|
-
interactionLines: null | { blockPos: Vec3
|
|
32
|
+
interactionLines: null | { blockPos: Vec3; mesh: THREE.Group; shapePositions: BlocksShapes | undefined } = null
|
|
33
33
|
prevColor: string | undefined
|
|
34
34
|
blockBreakMesh: THREE.Mesh
|
|
35
35
|
breakTextures: THREE.Texture[] = []
|
|
@@ -37,12 +37,20 @@ export class CursorBlock {
|
|
|
37
37
|
constructor(public readonly worldRenderer: WorldRendererThree) {
|
|
38
38
|
// Initialize break mesh and textures
|
|
39
39
|
const destroyStagesImages = [
|
|
40
|
-
destroyStage0,
|
|
41
|
-
|
|
40
|
+
destroyStage0,
|
|
41
|
+
destroyStage1,
|
|
42
|
+
destroyStage2,
|
|
43
|
+
destroyStage3,
|
|
44
|
+
destroyStage4,
|
|
45
|
+
destroyStage5,
|
|
46
|
+
destroyStage6,
|
|
47
|
+
destroyStage7,
|
|
48
|
+
destroyStage8,
|
|
49
|
+
destroyStage9
|
|
42
50
|
]
|
|
43
51
|
|
|
44
52
|
for (let i = 0; i < 10; i++) {
|
|
45
|
-
void loadThreeJsTextureFromUrl(destroyStagesImages[i]).then(
|
|
53
|
+
void loadThreeJsTextureFromUrl(destroyStagesImages[i]).then(texture => {
|
|
46
54
|
texture.magFilter = THREE.NearestFilter
|
|
47
55
|
texture.minFilter = THREE.NearestFilter
|
|
48
56
|
this.breakTextures.push(texture)
|
|
@@ -53,7 +61,7 @@ export class CursorBlock {
|
|
|
53
61
|
transparent: true,
|
|
54
62
|
blending: THREE.MultiplyBlending,
|
|
55
63
|
premultipliedAlpha: true,
|
|
56
|
-
alphaTest: 0.5
|
|
64
|
+
alphaTest: 0.5
|
|
57
65
|
})
|
|
58
66
|
this.blockBreakMesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), breakMaterial)
|
|
59
67
|
this.blockBreakMesh.visible = false
|
|
@@ -92,14 +100,14 @@ export class CursorBlock {
|
|
|
92
100
|
return inCreative ? 0x40_80_ff : 0x00_00_00
|
|
93
101
|
}
|
|
94
102
|
})(),
|
|
95
|
-
linewidth: Math.max(pixelRatio * 0.7, 1) * 2
|
|
103
|
+
linewidth: Math.max(pixelRatio * 0.7, 1) * 2
|
|
96
104
|
// dashed: true,
|
|
97
105
|
// dashSize: 5,
|
|
98
106
|
})
|
|
99
107
|
this.prevColor = this.worldRenderer.worldRendererConfig.highlightBlockColor
|
|
100
108
|
}
|
|
101
109
|
|
|
102
|
-
updateBreakAnimation(blockPosition: { x: number
|
|
110
|
+
updateBreakAnimation(blockPosition: { x: number; y: number; z: number } | undefined, stage: number | null, mergedShape?: BlockShape) {
|
|
103
111
|
this.hideBreakAnimation()
|
|
104
112
|
if (stage === null || !blockPosition || !mergedShape) return
|
|
105
113
|
|
|
@@ -108,10 +116,9 @@ export class CursorBlock {
|
|
|
108
116
|
this.blockBreakMesh.scale.set(width * 1.001, height * 1.001, depth * 1.001)
|
|
109
117
|
position.add(new Vec3(blockPosition.x, blockPosition.y, blockPosition.z))
|
|
110
118
|
this.blockBreakMesh.position.set(position.x, position.y, position.z)
|
|
111
|
-
this.blockBreakMesh.visible = true
|
|
112
|
-
|
|
113
|
-
(this.blockBreakMesh.material as THREE.MeshBasicMaterial).
|
|
114
|
-
(this.blockBreakMesh.material as THREE.MeshBasicMaterial).needsUpdate = true
|
|
119
|
+
this.blockBreakMesh.visible = true
|
|
120
|
+
;(this.blockBreakMesh.material as THREE.MeshBasicMaterial).map = this.breakTextures[stage] ?? this.breakTextures.at(-1)
|
|
121
|
+
;(this.blockBreakMesh.material as THREE.MeshBasicMaterial).needsUpdate = true
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
hideBreakAnimation() {
|
|
@@ -129,7 +136,13 @@ export class CursorBlock {
|
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
setHighlightCursorBlock(blockPos: Vec3 | null, shapePositions?: BlocksShapes, force = false): void {
|
|
132
|
-
if (
|
|
139
|
+
if (
|
|
140
|
+
blockPos &&
|
|
141
|
+
this.interactionLines &&
|
|
142
|
+
blockPos.equals(this.interactionLines.blockPos) &&
|
|
143
|
+
sameArray(shapePositions ?? [], this.interactionLines.shapePositions ?? []) &&
|
|
144
|
+
!force
|
|
145
|
+
) {
|
|
133
146
|
return
|
|
134
147
|
}
|
|
135
148
|
if (this.interactionLines !== null) {
|
package/src/three/world/vr.ts
CHANGED
|
@@ -63,7 +63,7 @@ export async function initVR(worldRenderer: WorldRendererThree, documentRenderer
|
|
|
63
63
|
display: 'flex',
|
|
64
64
|
justifyContent: 'center',
|
|
65
65
|
zIndex: '8',
|
|
66
|
-
gap: '8px'
|
|
66
|
+
gap: '8px'
|
|
67
67
|
})
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -79,7 +79,7 @@ export async function initVR(worldRenderer: WorldRendererThree, documentRenderer
|
|
|
79
79
|
background: 'transparent',
|
|
80
80
|
border: '1px solid rgb(255, 255, 255)',
|
|
81
81
|
borderRadius: '4px',
|
|
82
|
-
opacity: '0.7'
|
|
82
|
+
opacity: '0.7'
|
|
83
83
|
})
|
|
84
84
|
|
|
85
85
|
closeButton.addEventListener('click', () => {
|
|
@@ -90,7 +90,6 @@ export async function initVR(worldRenderer: WorldRendererThree, documentRenderer
|
|
|
90
90
|
return closeButton
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
94
93
|
async function checkVRSupport() {
|
|
95
94
|
try {
|
|
96
95
|
const supported = await navigator.xr?.isSessionSupported('immersive-vr')
|
|
@@ -122,16 +121,16 @@ export async function initVR(worldRenderer: WorldRendererThree, documentRenderer
|
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
123
|
let hand1: any = controllerModelFactory.createControllerModel(controller1)
|
|
125
|
-
controller1.addEventListener('connected',
|
|
124
|
+
controller1.addEventListener('connected', event => {
|
|
126
125
|
hand1.xrInputSource = event.data
|
|
127
|
-
manageXrInputSource(event.data as { gamepad: Gamepad | undefined
|
|
126
|
+
manageXrInputSource(event.data as { gamepad: Gamepad | undefined; handedness?: string }, 'left')
|
|
128
127
|
user.add(controller1)
|
|
129
128
|
})
|
|
130
129
|
controller1.add(hand1)
|
|
131
130
|
let hand2: any = controllerModelFactory.createControllerModel(controller2)
|
|
132
|
-
controller2.addEventListener('connected',
|
|
131
|
+
controller2.addEventListener('connected', event => {
|
|
133
132
|
hand2.xrInputSource = event.data
|
|
134
|
-
manageXrInputSource(event.data as { gamepad: Gamepad | undefined
|
|
133
|
+
manageXrInputSource(event.data as { gamepad: Gamepad | undefined; handedness?: string }, 'right')
|
|
135
134
|
user.add(controller2)
|
|
136
135
|
})
|
|
137
136
|
controller2.add(hand2)
|
|
@@ -184,7 +183,7 @@ export async function initVR(worldRenderer: WorldRendererThree, documentRenderer
|
|
|
184
183
|
|
|
185
184
|
if (rotSnapReset) {
|
|
186
185
|
if (Math.abs(hand1.xAxis) > 0.8) {
|
|
187
|
-
yawOffset -= Math.PI / 4 * Math.sign(hand1.xAxis)
|
|
186
|
+
yawOffset -= (Math.PI / 4) * Math.sign(hand1.xAxis)
|
|
188
187
|
rotSnapReset = false
|
|
189
188
|
}
|
|
190
189
|
} else if (Math.abs(hand1.xAxis) < 0.1) {
|
|
@@ -220,7 +219,7 @@ const xrStandardRightButtonsMap = [
|
|
|
220
219
|
// need to think of a way to support touchpad input
|
|
221
220
|
[3 /* Thumbstick Press */, 'Right Stick'],
|
|
222
221
|
[4 /* A */, 'A'],
|
|
223
|
-
[5 /* B */, 'B']
|
|
222
|
+
[5 /* B */, 'B']
|
|
224
223
|
]
|
|
225
224
|
const xrStandardLeftButtonsMap = [
|
|
226
225
|
[0 /* trigger */, 'Left Trigger'],
|
|
@@ -228,14 +227,14 @@ const xrStandardLeftButtonsMap = [
|
|
|
228
227
|
// need to think of a way to support touchpad input
|
|
229
228
|
[3 /* Thumbstick Press */, 'Left Stick'],
|
|
230
229
|
[4 /* A */, 'X'],
|
|
231
|
-
[5 /* B */, 'Y']
|
|
230
|
+
[5 /* B */, 'Y']
|
|
232
231
|
]
|
|
233
232
|
const remapButtons = (rightButtons: any[], leftButtons: any[]) => {
|
|
234
233
|
// return remapped buttons
|
|
235
234
|
const remapped = [] as string[]
|
|
236
235
|
const remapWithMap = (buttons, map) => {
|
|
237
236
|
for (const [index, standardName] of map) {
|
|
238
|
-
const standardMappingIndex = standardButtonsMap.findIndex(
|
|
237
|
+
const standardMappingIndex = standardButtonsMap.findIndex(aliases => aliases.find(alias => standardName === alias))
|
|
239
238
|
remapped[standardMappingIndex] = buttons[index]
|
|
240
239
|
}
|
|
241
240
|
}
|
|
@@ -245,12 +244,7 @@ const remapButtons = (rightButtons: any[], leftButtons: any[]) => {
|
|
|
245
244
|
}
|
|
246
245
|
const remapAxes = (axesRight, axesLeft) => {
|
|
247
246
|
// 0, 1 are reserved for touch
|
|
248
|
-
return [
|
|
249
|
-
axesLeft[2],
|
|
250
|
-
axesLeft[3],
|
|
251
|
-
axesRight[2],
|
|
252
|
-
axesRight[3]
|
|
253
|
-
]
|
|
247
|
+
return [axesLeft[2], axesLeft[3], axesRight[2], axesRight[3]]
|
|
254
248
|
}
|
|
255
249
|
|
|
256
250
|
function typedAssign<T extends Record<string, any>>(target: T, source: Partial<T>) {
|