minecraft-renderer 0.1.79 → 0.1.81
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 +66 -26
- package/dist/mesher.js +36 -36
- package/dist/mesher.js.map +4 -4
- package/dist/mesherWasm.js +217 -217
- package/dist/minecraft-renderer.js +66 -66
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +450 -450
- 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 +349 -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/cameraCollisionBlockCache.ts +156 -0
- package/src/three/cameraCollisionSolidity.ts +50 -0
- package/src/three/cameraShake.ts +15 -6
- package/src/three/chunkMeshManager.ts +223 -390
- 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 +167 -100
- package/src/three/globalLegacyBuffer.ts +248 -264
- 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 +10 -16
- 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 +24 -110
- 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 +34 -64
- 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 +300 -41
- package/src/three/tests/legacyMultiDraw.test.ts +8 -29
- package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
- package/src/three/tests/signTextureCache.test.ts +4 -4
- package/src/three/thirdPersonVoxelRaycast.ts +120 -0
- 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 +144 -166
- 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/cameraCollisionBlockCache.test.ts +82 -0
- 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 +1 -93
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
- package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
- package/src/wasm-mesher/tests/thirdPersonVoxelRaycast.test.ts +63 -0
- 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
|
@@ -12,7 +12,7 @@ export type BlockLightmapParams = {
|
|
|
12
12
|
export const DEFAULT_LIGHTMAP_PARAMS: Required<BlockLightmapParams> = {
|
|
13
13
|
curve: 0,
|
|
14
14
|
minBrightness: 0.12,
|
|
15
|
-
gamma: 1
|
|
15
|
+
gamma: 1
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/** GLSL body for applyLightmap — requires u_lightCurve, u_minBrightness, u_lightGamma uniforms. */
|
|
@@ -25,7 +25,7 @@ float applyLightmap(float L) {
|
|
|
25
25
|
}
|
|
26
26
|
`
|
|
27
27
|
|
|
28
|
-
export function applyLightmap
|
|
28
|
+
export function applyLightmap(L: number, params: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS): number {
|
|
29
29
|
const curve = params.curve ?? DEFAULT_LIGHTMAP_PARAMS.curve
|
|
30
30
|
const minBrightness = params.minBrightness ?? DEFAULT_LIGHTMAP_PARAMS.minBrightness
|
|
31
31
|
const gamma = params.gamma ?? DEFAULT_LIGHTMAP_PARAMS.gamma
|
|
@@ -37,16 +37,16 @@ export function applyLightmap (L: number, params: BlockLightmapParams = DEFAULT_
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/** Same cap as block shaders: max(block, min(sky, skyLevel)). */
|
|
40
|
-
export function combinedBlockLight
|
|
40
|
+
export function combinedBlockLight(block: number, sky: number, skyLevel: number): number {
|
|
41
41
|
return Math.max(block, Math.min(sky, skyLevel))
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/** 0..1 brightness for MeshBasicMaterial.color.setScalar on block-entity overlays. */
|
|
45
|
-
export function blockEntityBrightness
|
|
45
|
+
export function blockEntityBrightness(
|
|
46
46
|
blockNorm: number,
|
|
47
47
|
skyNorm: number,
|
|
48
48
|
skyLevel: number,
|
|
49
|
-
lightmapParams: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS
|
|
49
|
+
lightmapParams: BlockLightmapParams = DEFAULT_LIGHTMAP_PARAMS
|
|
50
50
|
): number {
|
|
51
51
|
const L = combinedBlockLight(blockNorm, skyNorm, skyLevel)
|
|
52
52
|
return applyLightmap(L, lightmapParams)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const dynamicMcDataFiles = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
blocks: 'blocksArray',
|
|
3
|
+
blockCollisionShapes: 'blockCollisionShapes',
|
|
4
|
+
biomes: 'biomesArray',
|
|
5
|
+
tints: 'tints'
|
|
6
6
|
}
|
|
@@ -6,7 +6,7 @@ describe('augmentWorkerMcData', () => {
|
|
|
6
6
|
it('is idempotent when mcData is augmented twice (menu then world)', () => {
|
|
7
7
|
const mcData: Record<string, unknown> = {
|
|
8
8
|
entities: [{ name: 'bat', id: 1, type: 'mob' }],
|
|
9
|
-
blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
|
|
9
|
+
blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
|
|
10
10
|
}
|
|
11
11
|
augmentWorkerMcData(mcData)
|
|
12
12
|
expect(() => augmentWorkerMcData(mcData)).not.toThrow()
|
|
@@ -16,7 +16,7 @@ describe('augmentWorkerMcData', () => {
|
|
|
16
16
|
|
|
17
17
|
it('keeps *Array sources after indexing (esbuild mc-data plugin reads blocksArray)', () => {
|
|
18
18
|
const mcData: Record<string, unknown> = {
|
|
19
|
-
blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
|
|
19
|
+
blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
|
|
20
20
|
}
|
|
21
21
|
augmentWorkerMcData(mcData)
|
|
22
22
|
expect(Array.isArray(mcData.blocksArray)).toBe(true)
|
|
@@ -26,7 +26,7 @@ describe('augmentWorkerMcData', () => {
|
|
|
26
26
|
|
|
27
27
|
it('coerces valtio-style dense objects into arrays', () => {
|
|
28
28
|
const mcData: Record<string, unknown> = {
|
|
29
|
-
entities: { 0: { name: 'bat', id: 1, type: 'mob' } }
|
|
29
|
+
entities: { 0: { name: 'bat', id: 1, type: 'mob' } }
|
|
30
30
|
}
|
|
31
31
|
augmentWorkerMcData(mcData)
|
|
32
32
|
expect((mcData.entitiesByName as Record<string, { name: string }>).bat?.name).toBe('bat')
|
|
@@ -36,7 +36,7 @@ describe('augmentWorkerMcData', () => {
|
|
|
36
36
|
const mcData: Record<string, unknown> = {
|
|
37
37
|
entities: [{ name: 'bat', id: 1, type: 'mob' }],
|
|
38
38
|
items: [{ name: 'dirt', id: 2 }],
|
|
39
|
-
blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
|
|
39
|
+
blocks: [{ name: 'stone', id: 3, minStateId: 48, maxStateId: 63, defaultState: 48 }]
|
|
40
40
|
}
|
|
41
41
|
augmentWorkerMcData(mcData)
|
|
42
42
|
expect((mcData.entitiesByName as Record<string, { name: string }>).bat?.name).toBe('bat')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
type McElement = Record<string, unknown>
|
|
3
3
|
|
|
4
|
-
function coerceDenseArray
|
|
4
|
+
function coerceDenseArray(value: unknown): McElement[] | undefined {
|
|
5
5
|
if (Array.isArray(value)) {
|
|
6
6
|
return value as McElement[]
|
|
7
7
|
}
|
|
@@ -9,7 +9,10 @@ function coerceDenseArray (value: unknown): McElement[] | undefined {
|
|
|
9
9
|
return undefined
|
|
10
10
|
}
|
|
11
11
|
const record = value as Record<string, McElement>
|
|
12
|
-
const keys = Object.keys(record)
|
|
12
|
+
const keys = Object.keys(record)
|
|
13
|
+
.filter(k => /^\d+$/.test(k))
|
|
14
|
+
.map(Number)
|
|
15
|
+
.sort((a, b) => a - b)
|
|
13
16
|
if (!keys.length || keys[0] !== 0) {
|
|
14
17
|
return undefined
|
|
15
18
|
}
|
|
@@ -18,13 +21,10 @@ function coerceDenseArray (value: unknown): McElement[] | undefined {
|
|
|
18
21
|
return undefined
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
|
-
return keys.map(
|
|
24
|
+
return keys.map(k => record[String(k)])
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
function buildIndexFromArray<T extends McElement>
|
|
25
|
-
array: T[],
|
|
26
|
-
field: keyof T
|
|
27
|
-
): Record<string | number, T> {
|
|
27
|
+
function buildIndexFromArray<T extends McElement>(array: T[], field: keyof T): Record<string | number, T> {
|
|
28
28
|
if (!Array.isArray(array)) {
|
|
29
29
|
console.warn('[augmentWorkerMcData] buildIndexFromArray expected array, got', typeof array)
|
|
30
30
|
return {}
|
|
@@ -35,11 +35,7 @@ function buildIndexFromArray<T extends McElement> (
|
|
|
35
35
|
}, {})
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function buildIndexFromArrayWithRanges<T extends McElement>
|
|
39
|
-
array: T[],
|
|
40
|
-
minField: keyof T,
|
|
41
|
-
maxField: keyof T
|
|
42
|
-
): Record<number, T> {
|
|
38
|
+
function buildIndexFromArrayWithRanges<T extends McElement>(array: T[], minField: keyof T, maxField: keyof T): Record<number, T> {
|
|
43
39
|
if (!Array.isArray(array)) {
|
|
44
40
|
console.warn('[augmentWorkerMcData] buildIndexFromArrayWithRanges expected array, got', typeof array)
|
|
45
41
|
return {}
|
|
@@ -54,7 +50,7 @@ function buildIndexFromArrayWithRanges<T extends McElement> (
|
|
|
54
50
|
}, {})
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
function ensureBlockStateIds
|
|
53
|
+
function ensureBlockStateIds(blocks: McElement[]) {
|
|
58
54
|
if (!blocks.length) return
|
|
59
55
|
if ('minStateId' in blocks[0] && 'defaultState' in blocks[0]) return
|
|
60
56
|
for (const block of blocks) {
|
|
@@ -65,11 +61,7 @@ function ensureBlockStateIds (blocks: McElement[]) {
|
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
|
|
68
|
-
function getSourceArray
|
|
69
|
-
mcData: Record<string, unknown>,
|
|
70
|
-
arrayKey: string,
|
|
71
|
-
rawKey: string
|
|
72
|
-
): McElement[] | undefined {
|
|
64
|
+
function getSourceArray(mcData: Record<string, unknown>, arrayKey: string, rawKey: string): McElement[] | undefined {
|
|
73
65
|
const fromArrayKey = coerceDenseArray(mcData[arrayKey])
|
|
74
66
|
if (fromArrayKey?.length) {
|
|
75
67
|
return fromArrayKey
|
|
@@ -81,7 +73,7 @@ function getSourceArray (
|
|
|
81
73
|
return undefined
|
|
82
74
|
}
|
|
83
75
|
|
|
84
|
-
export function augmentWorkerMcData
|
|
76
|
+
export function augmentWorkerMcData(mcData: Record<string, unknown>) {
|
|
85
77
|
if (mcData.__workerIndexesBuilt) {
|
|
86
78
|
return mcData
|
|
87
79
|
}
|
package/src/lib/cameraBobbing.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface CameraBobInput {
|
|
|
14
14
|
|
|
15
15
|
const DEG_TO_RAD = Math.PI / 180
|
|
16
16
|
|
|
17
|
-
export function computeCameraBob
|
|
17
|
+
export function computeCameraBob(input: CameraBobInput): CameraBobResult {
|
|
18
18
|
const { walkDist, prevWalkDist, bob, prevBob, partialTick } = input
|
|
19
19
|
|
|
20
20
|
// Vanilla uses "backwards interpolation": -(walkDist + delta * partialTick)
|
|
@@ -15,7 +15,7 @@ export function example1_SimpleBlackBox(documentRenderer: DocumentRenderer) {
|
|
|
15
15
|
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
16
16
|
|
|
17
17
|
// Register to render overlay after main scene
|
|
18
|
-
documentRenderer.onRender.push(
|
|
18
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
19
19
|
if (sizeChanged) {
|
|
20
20
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
21
21
|
}
|
|
@@ -46,7 +46,7 @@ export function example2_FPSCounter(documentRenderer: DocumentRenderer) {
|
|
|
46
46
|
let lastTime = performance.now()
|
|
47
47
|
let frameCount = 0
|
|
48
48
|
|
|
49
|
-
documentRenderer.onRender.push(
|
|
49
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
50
50
|
if (sizeChanged) {
|
|
51
51
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
52
52
|
}
|
|
@@ -82,13 +82,10 @@ export function example2_FPSCounter(documentRenderer: DocumentRenderer) {
|
|
|
82
82
|
// ============================================
|
|
83
83
|
// EXAMPLE 3: Coordinate Display (Bottom-Left)
|
|
84
84
|
// ============================================
|
|
85
|
-
export function example3_CoordinateDisplay(
|
|
86
|
-
documentRenderer: DocumentRenderer,
|
|
87
|
-
getPosition: () => { x: number; y: number; z: number }
|
|
88
|
-
) {
|
|
85
|
+
export function example3_CoordinateDisplay(documentRenderer: DocumentRenderer, getPosition: () => { x: number; y: number; z: number }) {
|
|
89
86
|
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
90
87
|
|
|
91
|
-
documentRenderer.onRender.push(
|
|
88
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
92
89
|
if (sizeChanged) {
|
|
93
90
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
94
91
|
}
|
|
@@ -130,13 +127,10 @@ export function example3_CoordinateDisplay(
|
|
|
130
127
|
// ============================================
|
|
131
128
|
// EXAMPLE 4: Mini-map (Top-Right Corner)
|
|
132
129
|
// ============================================
|
|
133
|
-
export function example4_MiniMap(
|
|
134
|
-
documentRenderer: DocumentRenderer,
|
|
135
|
-
playerPos: { x: number; z: number }
|
|
136
|
-
) {
|
|
130
|
+
export function example4_MiniMap(documentRenderer: DocumentRenderer, playerPos: { x: number; z: number }) {
|
|
137
131
|
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
138
132
|
|
|
139
|
-
documentRenderer.onRender.push(
|
|
133
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
140
134
|
if (sizeChanged) {
|
|
141
135
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
142
136
|
}
|
|
@@ -197,13 +191,10 @@ export function example5_DirectWebGL(documentRenderer: DocumentRenderer) {
|
|
|
197
191
|
// ============================================
|
|
198
192
|
// EXAMPLE 6: Health/Status Bar
|
|
199
193
|
// ============================================
|
|
200
|
-
export function example6_HealthBar(
|
|
201
|
-
documentRenderer: DocumentRenderer,
|
|
202
|
-
getHealth: () => { current: number; max: number }
|
|
203
|
-
) {
|
|
194
|
+
export function example6_HealthBar(documentRenderer: DocumentRenderer, getHealth: () => { current: number; max: number }) {
|
|
204
195
|
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
205
196
|
|
|
206
|
-
documentRenderer.onRender.push(
|
|
197
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
207
198
|
if (sizeChanged) {
|
|
208
199
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
209
200
|
}
|
|
@@ -249,7 +240,7 @@ export function example6_HealthBar(
|
|
|
249
240
|
export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
|
|
250
241
|
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
251
242
|
|
|
252
|
-
documentRenderer.onRender.push(
|
|
243
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
253
244
|
if (sizeChanged) {
|
|
254
245
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
255
246
|
}
|
|
@@ -262,10 +253,7 @@ export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
|
|
|
262
253
|
|
|
263
254
|
// Draw vertical lines
|
|
264
255
|
for (let x = 0; x < width; x += gridSize) {
|
|
265
|
-
const points = [
|
|
266
|
-
new THREE.Vector3(x, 0, 0),
|
|
267
|
-
new THREE.Vector3(x, height, 0)
|
|
268
|
-
]
|
|
256
|
+
const points = [new THREE.Vector3(x, 0, 0), new THREE.Vector3(x, height, 0)]
|
|
269
257
|
const geometry = new THREE.BufferGeometry().setFromPoints(points)
|
|
270
258
|
const material = new THREE.LineBasicMaterial({ color: 0x333333, opacity: 0.3, transparent: true })
|
|
271
259
|
const line = new THREE.Line(geometry, material)
|
|
@@ -275,10 +263,7 @@ export function example7_DebugGrid(documentRenderer: DocumentRenderer) {
|
|
|
275
263
|
|
|
276
264
|
// Draw horizontal lines
|
|
277
265
|
for (let y = 0; y < height; y += gridSize) {
|
|
278
|
-
const points = [
|
|
279
|
-
new THREE.Vector3(0, y, 0),
|
|
280
|
-
new THREE.Vector3(width, y, 0)
|
|
281
|
-
]
|
|
266
|
+
const points = [new THREE.Vector3(0, y, 0), new THREE.Vector3(width, y, 0)]
|
|
282
267
|
const geometry = new THREE.BufferGeometry().setFromPoints(points)
|
|
283
268
|
const material = new THREE.LineBasicMaterial({ color: 0x333333, opacity: 0.3, transparent: true })
|
|
284
269
|
const line = new THREE.Line(geometry, material)
|
|
@@ -301,7 +286,7 @@ export function integrateWithDocumentRenderer(documentRenderer: DocumentRenderer
|
|
|
301
286
|
|
|
302
287
|
// Add to render loop
|
|
303
288
|
const originalRender = documentRenderer.render
|
|
304
|
-
documentRenderer.render =
|
|
289
|
+
documentRenderer.render = sizeChanged => {
|
|
305
290
|
// Call original render
|
|
306
291
|
originalRender.call(documentRenderer, sizeChanged)
|
|
307
292
|
|
|
@@ -333,7 +318,7 @@ export function workerCompatibleOverlay(documentRenderer: DocumentRenderer) {
|
|
|
333
318
|
// This works the same in both main thread and worker!
|
|
334
319
|
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
335
320
|
|
|
336
|
-
documentRenderer.onRender.push(
|
|
321
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
337
322
|
if (sizeChanged) {
|
|
338
323
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
339
324
|
}
|
|
@@ -355,8 +340,3 @@ export function workerCompatibleOverlay(documentRenderer: DocumentRenderer) {
|
|
|
355
340
|
|
|
356
341
|
return overlay
|
|
357
342
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
@@ -13,21 +13,15 @@ import { Canvas2DOverlay } from './canvas2DOverlay'
|
|
|
13
13
|
// STEP 1: Create the overlay
|
|
14
14
|
// ============================================
|
|
15
15
|
export function addBlackBoxOverlay(documentRenderer: DocumentRenderer) {
|
|
16
|
-
const overlay = new Canvas2DOverlay(
|
|
17
|
-
documentRenderer.renderer,
|
|
18
|
-
documentRenderer.canvas
|
|
19
|
-
)
|
|
16
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
20
17
|
|
|
21
18
|
// ============================================
|
|
22
19
|
// STEP 2: Hook into the render loop
|
|
23
20
|
// ============================================
|
|
24
|
-
documentRenderer.onRender.push(
|
|
21
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
25
22
|
// Update overlay camera when canvas size changes
|
|
26
23
|
if (sizeChanged) {
|
|
27
|
-
overlay.updateSize(
|
|
28
|
-
documentRenderer.canvas.width,
|
|
29
|
-
documentRenderer.canvas.height
|
|
30
|
-
)
|
|
24
|
+
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
31
25
|
}
|
|
32
26
|
|
|
33
27
|
// Clear previous frame's overlay
|
|
@@ -43,12 +37,12 @@ export function addBlackBoxOverlay(documentRenderer: DocumentRenderer) {
|
|
|
43
37
|
const y = documentRenderer.canvas.height - boxSize - 10 // 10px from bottom
|
|
44
38
|
|
|
45
39
|
overlay.drawRect(
|
|
46
|
-
x,
|
|
47
|
-
y,
|
|
48
|
-
boxSize,
|
|
49
|
-
boxSize,
|
|
40
|
+
x, // x position
|
|
41
|
+
y, // y position
|
|
42
|
+
boxSize, // width
|
|
43
|
+
boxSize, // height
|
|
50
44
|
0x000000, // color (black)
|
|
51
|
-
0.8
|
|
45
|
+
0.8 // opacity (80%)
|
|
52
46
|
)
|
|
53
47
|
|
|
54
48
|
// ============================================
|
|
@@ -82,12 +76,9 @@ const overlay = addBlackBoxOverlay(documentRenderer)
|
|
|
82
76
|
// Add More Elements
|
|
83
77
|
// ============================================
|
|
84
78
|
export function addMultipleElements(documentRenderer: DocumentRenderer) {
|
|
85
|
-
const overlay = new Canvas2DOverlay(
|
|
86
|
-
documentRenderer.renderer,
|
|
87
|
-
documentRenderer.canvas
|
|
88
|
-
)
|
|
79
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
89
80
|
|
|
90
|
-
documentRenderer.onRender.push(
|
|
81
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
91
82
|
if (sizeChanged) {
|
|
92
83
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
93
84
|
}
|
|
@@ -96,14 +87,7 @@ export function addMultipleElements(documentRenderer: DocumentRenderer) {
|
|
|
96
87
|
|
|
97
88
|
// Bottom-left black box
|
|
98
89
|
const boxSize = 100
|
|
99
|
-
overlay.drawRect(
|
|
100
|
-
10,
|
|
101
|
-
documentRenderer.canvas.height - boxSize - 10,
|
|
102
|
-
boxSize,
|
|
103
|
-
boxSize,
|
|
104
|
-
0x000000,
|
|
105
|
-
0.8
|
|
106
|
-
)
|
|
90
|
+
overlay.drawRect(10, documentRenderer.canvas.height - boxSize - 10, boxSize, boxSize, 0x000000, 0.8)
|
|
107
91
|
|
|
108
92
|
// Add label inside the box
|
|
109
93
|
overlay.drawText('Info', 15, documentRenderer.canvas.height - boxSize, {
|
|
@@ -144,16 +128,10 @@ export function addMultipleElements(documentRenderer: DocumentRenderer) {
|
|
|
144
128
|
// ============================================
|
|
145
129
|
// Dynamic Data Example
|
|
146
130
|
// ============================================
|
|
147
|
-
export function addDynamicOverlay(
|
|
148
|
-
documentRenderer
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const overlay = new Canvas2DOverlay(
|
|
152
|
-
documentRenderer.renderer,
|
|
153
|
-
documentRenderer.canvas
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
documentRenderer.onRender.push((sizeChanged) => {
|
|
131
|
+
export function addDynamicOverlay(documentRenderer: DocumentRenderer, getData: () => { fps: number; x: number; y: number; z: number }) {
|
|
132
|
+
const overlay = new Canvas2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
133
|
+
|
|
134
|
+
documentRenderer.onRender.push(sizeChanged => {
|
|
157
135
|
if (sizeChanged) {
|
|
158
136
|
overlay.updateSize(documentRenderer.canvas.width, documentRenderer.canvas.height)
|
|
159
137
|
}
|
|
@@ -208,10 +186,7 @@ export function addDynamicOverlay(
|
|
|
208
186
|
import { WebGLDirect2DOverlay } from './canvas2DOverlay'
|
|
209
187
|
|
|
210
188
|
export function addHighPerformanceOverlay(documentRenderer: DocumentRenderer) {
|
|
211
|
-
const overlay = new WebGLDirect2DOverlay(
|
|
212
|
-
documentRenderer.renderer,
|
|
213
|
-
documentRenderer.canvas
|
|
214
|
-
)
|
|
189
|
+
const overlay = new WebGLDirect2DOverlay(documentRenderer.renderer, documentRenderer.canvas)
|
|
215
190
|
|
|
216
191
|
documentRenderer.onRender.push(() => {
|
|
217
192
|
// Direct WebGL rendering - very fast!
|
|
@@ -223,21 +198,16 @@ export function addHighPerformanceOverlay(documentRenderer: DocumentRenderer) {
|
|
|
223
198
|
const y = documentRenderer.canvas.height - boxSize - 10
|
|
224
199
|
|
|
225
200
|
overlay.drawRect(
|
|
226
|
-
x,
|
|
227
|
-
y,
|
|
228
|
-
boxSize,
|
|
229
|
-
boxSize,
|
|
230
|
-
0,
|
|
231
|
-
0,
|
|
232
|
-
0,
|
|
233
|
-
0.8
|
|
201
|
+
x, // x
|
|
202
|
+
y, // y
|
|
203
|
+
boxSize, // width
|
|
204
|
+
boxSize, // height
|
|
205
|
+
0, // red (0-1)
|
|
206
|
+
0, // green (0-1)
|
|
207
|
+
0, // blue (0-1)
|
|
208
|
+
0.8 // alpha (0-1)
|
|
234
209
|
)
|
|
235
210
|
})
|
|
236
211
|
|
|
237
212
|
return overlay
|
|
238
213
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
@@ -123,22 +123,20 @@ export class Canvas2DOverlay {
|
|
|
123
123
|
/**
|
|
124
124
|
* Draw text using canvas texture (works in worker with OffscreenCanvas)
|
|
125
125
|
*/
|
|
126
|
-
drawText(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
opacity = 1
|
|
141
|
-
} = options
|
|
126
|
+
drawText(
|
|
127
|
+
text: string,
|
|
128
|
+
x: number,
|
|
129
|
+
y: number,
|
|
130
|
+
options: {
|
|
131
|
+
fontSize?: number
|
|
132
|
+
fontFamily?: string
|
|
133
|
+
color?: string
|
|
134
|
+
backgroundColor?: string
|
|
135
|
+
padding?: number
|
|
136
|
+
opacity?: number
|
|
137
|
+
} = {}
|
|
138
|
+
) {
|
|
139
|
+
const { fontSize = 16, fontFamily = 'Arial', color = '#ffffff', backgroundColor = '#000000', padding = 4, opacity = 1 } = options
|
|
142
140
|
|
|
143
141
|
// Create a temporary canvas for text rendering
|
|
144
142
|
// OffscreenCanvas works in workers!
|
|
@@ -178,11 +176,7 @@ export class Canvas2DOverlay {
|
|
|
178
176
|
const geometry = new THREE.PlaneGeometry(textCanvas.width, textCanvas.height)
|
|
179
177
|
const mesh = new THREE.Mesh(geometry, material)
|
|
180
178
|
|
|
181
|
-
mesh.position.set(
|
|
182
|
-
x + textCanvas.width / 2,
|
|
183
|
-
y + textCanvas.height / 2,
|
|
184
|
-
0
|
|
185
|
-
)
|
|
179
|
+
mesh.position.set(x + textCanvas.width / 2, y + textCanvas.height / 2, 0)
|
|
186
180
|
|
|
187
181
|
this.overlayScene.add(mesh)
|
|
188
182
|
this.overlayObjects.push(mesh)
|
|
@@ -252,7 +246,9 @@ export class WebGLDirect2DOverlay {
|
|
|
252
246
|
this.gl = this.renderer.getContext()
|
|
253
247
|
|
|
254
248
|
// Create shader program for 2D rendering
|
|
255
|
-
const vertexShader = this.createShader(
|
|
249
|
+
const vertexShader = this.createShader(
|
|
250
|
+
this.gl.VERTEX_SHADER,
|
|
251
|
+
`
|
|
256
252
|
attribute vec2 position;
|
|
257
253
|
attribute vec4 color;
|
|
258
254
|
varying vec4 vColor;
|
|
@@ -264,16 +260,20 @@ export class WebGLDirect2DOverlay {
|
|
|
264
260
|
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
|
|
265
261
|
vColor = color;
|
|
266
262
|
}
|
|
267
|
-
`
|
|
263
|
+
`
|
|
264
|
+
)
|
|
268
265
|
|
|
269
|
-
const fragmentShader = this.createShader(
|
|
266
|
+
const fragmentShader = this.createShader(
|
|
267
|
+
this.gl.FRAGMENT_SHADER,
|
|
268
|
+
`
|
|
270
269
|
precision mediump float;
|
|
271
270
|
varying vec4 vColor;
|
|
272
271
|
|
|
273
272
|
void main() {
|
|
274
273
|
gl_FragColor = vColor;
|
|
275
274
|
}
|
|
276
|
-
`
|
|
275
|
+
`
|
|
276
|
+
)
|
|
277
277
|
|
|
278
278
|
this.program = this.createProgram(vertexShader, fragmentShader)
|
|
279
279
|
|
|
@@ -318,23 +318,9 @@ export class WebGLDirect2DOverlay {
|
|
|
318
318
|
const x2 = x + width
|
|
319
319
|
const y2 = y + height
|
|
320
320
|
|
|
321
|
-
const positions = new Float32Array([
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
x1, y2,
|
|
325
|
-
x1, y2,
|
|
326
|
-
x2, y1,
|
|
327
|
-
x2, y2
|
|
328
|
-
])
|
|
329
|
-
|
|
330
|
-
const colors = new Float32Array([
|
|
331
|
-
r, g, b, a,
|
|
332
|
-
r, g, b, a,
|
|
333
|
-
r, g, b, a,
|
|
334
|
-
r, g, b, a,
|
|
335
|
-
r, g, b, a,
|
|
336
|
-
r, g, b, a
|
|
337
|
-
])
|
|
321
|
+
const positions = new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2])
|
|
322
|
+
|
|
323
|
+
const colors = new Float32Array([r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a])
|
|
338
324
|
|
|
339
325
|
this.gl.useProgram(this.program)
|
|
340
326
|
|
|
@@ -375,8 +361,3 @@ export class WebGLDirect2DOverlay {
|
|
|
375
361
|
this.gl.deleteProgram(this.program)
|
|
376
362
|
}
|
|
377
363
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
|
-
export function buildCleanupDecorator
|
|
2
|
+
export function buildCleanupDecorator(cleanupMethod: string) {
|
|
3
3
|
return function () {
|
|
4
4
|
return function (_target: { snapshotInitialValues }, propertyKey: string) {
|
|
5
5
|
const target = _target as any
|
|
@@ -13,7 +13,7 @@ export function buildCleanupDecorator (cleanupMethod: string) {
|
|
|
13
13
|
}
|
|
14
14
|
target._snapshotMethodPatched = true
|
|
15
15
|
}
|
|
16
|
-
(target._toCleanup ??= []).push(propertyKey)
|
|
16
|
+
;(target._toCleanup ??= []).push(propertyKey)
|
|
17
17
|
if (!target._cleanupPatched) {
|
|
18
18
|
const originalMethod = target[cleanupMethod]
|
|
19
19
|
target[cleanupMethod] = function () {
|
|
@@ -3,7 +3,7 @@ import { describe, expect, it, vi } from 'vitest'
|
|
|
3
3
|
|
|
4
4
|
vi.mock('./utils/skins', () => ({
|
|
5
5
|
stevePngUrl: '',
|
|
6
|
-
loadSkinImage: vi.fn()
|
|
6
|
+
loadSkinImage: vi.fn()
|
|
7
7
|
}))
|
|
8
8
|
|
|
9
9
|
import { PlayerObject } from 'skinview3d'
|
|
@@ -16,12 +16,7 @@ describe('configurePlayerSkinMaterials', () => {
|
|
|
16
16
|
|
|
17
17
|
configurePlayerSkinMaterials(playerObject)
|
|
18
18
|
|
|
19
|
-
const allMaterials = [
|
|
20
|
-
skin.layer1Material,
|
|
21
|
-
skin.layer1MaterialBiased,
|
|
22
|
-
skin.layer2Material,
|
|
23
|
-
skin.layer2MaterialBiased,
|
|
24
|
-
]
|
|
19
|
+
const allMaterials = [skin.layer1Material, skin.layer1MaterialBiased, skin.layer2Material, skin.layer2MaterialBiased]
|
|
25
20
|
for (const mat of allMaterials) {
|
|
26
21
|
expect(mat.transparent).toBe(false)
|
|
27
22
|
expect(mat.alphaTest).toBe(0.1)
|
|
@@ -12,7 +12,7 @@ export type PlayerObjectType = PlayerObject & {
|
|
|
12
12
|
|
|
13
13
|
const LOG_DEPTH_BIAS = -2e-4 // tune visually; negative ≈ polygonOffset “closer”
|
|
14
14
|
|
|
15
|
-
function patchLogDepthBiasShader
|
|
15
|
+
function patchLogDepthBiasShader(shader: THREE.WebGLProgramParametersWithUniforms): void {
|
|
16
16
|
shader.uniforms.uLogDepthBias = { value: LOG_DEPTH_BIAS }
|
|
17
17
|
shader.fragmentShader = shader.fragmentShader.replace(
|
|
18
18
|
'#include <logdepthbuf_pars_fragment>',
|
|
@@ -26,7 +26,7 @@ function patchLogDepthBiasShader (shader: THREE.WebGLProgramParametersWithUnifor
|
|
|
26
26
|
)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function applyLogDepthBias
|
|
29
|
+
function applyLogDepthBias(material: THREE.Material): void {
|
|
30
30
|
if (material.userData.logDepthBiasApplied) return
|
|
31
31
|
material.userData.logDepthBiasApplied = true
|
|
32
32
|
material.onBeforeCompile = patchLogDepthBiasShader
|
|
@@ -34,14 +34,9 @@ function applyLogDepthBias (material: THREE.Material): void {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/** Log-depth world: opaque cutout mats (alphaTest + depthWrite, not transparent sort). */
|
|
37
|
-
export function configurePlayerSkinMaterials
|
|
37
|
+
export function configurePlayerSkinMaterials(playerObject: PlayerObject): void {
|
|
38
38
|
const skin = playerObject.skin as any
|
|
39
|
-
const materials = [
|
|
40
|
-
skin.layer1Material,
|
|
41
|
-
skin.layer1MaterialBiased,
|
|
42
|
-
skin.layer2Material,
|
|
43
|
-
skin.layer2MaterialBiased,
|
|
44
|
-
]
|
|
39
|
+
const materials = [skin.layer1Material, skin.layer1MaterialBiased, skin.layer2Material, skin.layer2MaterialBiased]
|
|
45
40
|
for (const mat of materials) {
|
|
46
41
|
mat.transparent = false
|
|
47
42
|
mat.alphaTest = 0.1
|
|
@@ -51,14 +46,10 @@ export function configurePlayerSkinMaterials (playerObject: PlayerObject): void
|
|
|
51
46
|
applyLogDepthBias(skin.layer2MaterialBiased)
|
|
52
47
|
}
|
|
53
48
|
|
|
54
|
-
export function createPlayerObject
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}): {
|
|
59
|
-
playerObject: PlayerObjectType
|
|
60
|
-
wrapper: THREE.Group
|
|
61
|
-
} {
|
|
49
|
+
export function createPlayerObject(options: { username?: string; uuid?: string; scale?: number }): {
|
|
50
|
+
playerObject: PlayerObjectType
|
|
51
|
+
wrapper: THREE.Group
|
|
52
|
+
} {
|
|
62
53
|
const wrapper = new THREE.Group()
|
|
63
54
|
const playerObject = new PlayerObject() as PlayerObjectType
|
|
64
55
|
|
|
@@ -69,7 +60,7 @@ export function createPlayerObject (options: {
|
|
|
69
60
|
configurePlayerSkinMaterials(playerObject)
|
|
70
61
|
|
|
71
62
|
wrapper.add(playerObject as any)
|
|
72
|
-
const scale = options.scale ??
|
|
63
|
+
const scale = options.scale ?? 1 / 16
|
|
73
64
|
wrapper.scale.set(scale, scale, scale)
|
|
74
65
|
wrapper.rotation.set(0, Math.PI, 0)
|
|
75
66
|
|
|
@@ -82,11 +73,13 @@ export function createPlayerObject (options: {
|
|
|
82
73
|
}
|
|
83
74
|
|
|
84
75
|
export const applySkinToPlayerObject = async (playerObject: PlayerObjectType, skinUrl: string) => {
|
|
85
|
-
return loadSkinImage(skinUrl || stevePngUrl)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
return loadSkinImage(skinUrl || stevePngUrl)
|
|
77
|
+
.then(({ canvas }) => {
|
|
78
|
+
const skinTexture = new THREE.CanvasTexture(canvas)
|
|
79
|
+
skinTexture.magFilter = THREE.NearestFilter
|
|
80
|
+
skinTexture.minFilter = THREE.NearestFilter
|
|
81
|
+
skinTexture.needsUpdate = true
|
|
82
|
+
playerObject.skin.map = skinTexture as any
|
|
83
|
+
})
|
|
84
|
+
.catch(console.error)
|
|
92
85
|
}
|