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
|
@@ -9,7 +9,7 @@ import { BlockElement, buildRotationMatrix, elemFaces, matmul3, matmulmat3, veca
|
|
|
9
9
|
|
|
10
10
|
type NeighborSide = 'up' | 'down' | 'east' | 'west' | 'north' | 'south'
|
|
11
11
|
|
|
12
|
-
function tintToGl
|
|
12
|
+
function tintToGl(tint) {
|
|
13
13
|
const r = (tint >> 16) & 0xff
|
|
14
14
|
const g = (tint >> 8) & 0xff
|
|
15
15
|
const b = tint & 0xff
|
|
@@ -17,7 +17,7 @@ function tintToGl (tint) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
type Neighbors = Partial<Record<NeighborSide, boolean>>
|
|
20
|
-
function renderElement
|
|
20
|
+
function renderElement(element: BlockElement, doAO: boolean, attr, globalMatrix, globalShift, block: Block | undefined, biome: string, neighbors: Neighbors) {
|
|
21
21
|
const cursor = new Vec3(0, 0, 0)
|
|
22
22
|
|
|
23
23
|
// const key = `${position.x},${position.y},${position.z}`
|
|
@@ -71,26 +71,17 @@ function renderElement (element: BlockElement, doAO: boolean, attr, globalMatrix
|
|
|
71
71
|
|
|
72
72
|
// UV rotation
|
|
73
73
|
const r = eFace.rotation || 0
|
|
74
|
-
const uvcs = Math.cos(r * Math.PI / 180)
|
|
75
|
-
const uvsn = -Math.sin(r * Math.PI / 180)
|
|
74
|
+
const uvcs = Math.cos((r * Math.PI) / 180)
|
|
75
|
+
const uvsn = -Math.sin((r * Math.PI) / 180)
|
|
76
76
|
|
|
77
77
|
let localMatrix = null as any
|
|
78
78
|
let localShift = null as any
|
|
79
79
|
|
|
80
80
|
if (element.rotation) {
|
|
81
81
|
// todo do we support rescale?
|
|
82
|
-
localMatrix = buildRotationMatrix(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
localShift = vecsub3(
|
|
88
|
-
element.rotation.origin,
|
|
89
|
-
matmul3(
|
|
90
|
-
localMatrix,
|
|
91
|
-
element.rotation.origin
|
|
92
|
-
)
|
|
93
|
-
)
|
|
82
|
+
localMatrix = buildRotationMatrix(element.rotation.axis, element.rotation.angle)
|
|
83
|
+
|
|
84
|
+
localShift = vecsub3(element.rotation.origin, matmul3(localMatrix, element.rotation.origin))
|
|
94
85
|
}
|
|
95
86
|
|
|
96
87
|
const aos: number[] = []
|
|
@@ -98,21 +89,13 @@ function renderElement (element: BlockElement, doAO: boolean, attr, globalMatrix
|
|
|
98
89
|
// const baseLight = world.getLight(neighborPos, undefined, undefined, block.name) / 15
|
|
99
90
|
const baseLight = 1
|
|
100
91
|
for (const pos of corners) {
|
|
101
|
-
let vertex = [
|
|
102
|
-
(pos[0] ? maxx : minx),
|
|
103
|
-
(pos[1] ? maxy : miny),
|
|
104
|
-
(pos[2] ? maxz : minz)
|
|
105
|
-
]
|
|
92
|
+
let vertex = [pos[0] ? maxx : minx, pos[1] ? maxy : miny, pos[2] ? maxz : minz]
|
|
106
93
|
|
|
107
94
|
vertex = vecadd3(matmul3(localMatrix, vertex), localShift)
|
|
108
95
|
vertex = vecadd3(matmul3(globalMatrix, vertex), globalShift)
|
|
109
96
|
vertex = vertex.map(v => v / 16)
|
|
110
97
|
|
|
111
|
-
attr.positions.push(
|
|
112
|
-
vertex[0]/* + (cursor.x & 15) - 8 */,
|
|
113
|
-
vertex[1]/* + (cursor.y & 15) x */,
|
|
114
|
-
vertex[2]/* + (cursor.z & 15) - 8 */
|
|
115
|
-
)
|
|
98
|
+
attr.positions.push(vertex[0] /* + (cursor.x & 15) - 8 */, vertex[1] /* + (cursor.y & 15) x */, vertex[2] /* + (cursor.z & 15) - 8 */)
|
|
116
99
|
|
|
117
100
|
attr.normals.push(...dir)
|
|
118
101
|
|
|
@@ -128,9 +111,9 @@ function renderElement (element: BlockElement, doAO: boolean, attr, globalMatrix
|
|
|
128
111
|
const side2Block = 0
|
|
129
112
|
const cornerBlock = 0
|
|
130
113
|
|
|
131
|
-
const ao =
|
|
114
|
+
const ao = side1Block && side2Block ? 0 : 3 - (side1Block + side2Block + cornerBlock)
|
|
132
115
|
// todo light should go upper on lower blocks
|
|
133
|
-
light = (ao + 1) / 4 * (cornerLightResult / 15)
|
|
116
|
+
light = ((ao + 1) / 4) * (cornerLightResult / 15)
|
|
134
117
|
aos.push(ao)
|
|
135
118
|
}
|
|
136
119
|
|
|
@@ -151,22 +134,21 @@ function renderElement (element: BlockElement, doAO: boolean, attr, globalMatrix
|
|
|
151
134
|
// }
|
|
152
135
|
|
|
153
136
|
if (doAO && aos[0] + aos[3] >= aos[1] + aos[2]) {
|
|
154
|
-
attr.indices.push(
|
|
155
|
-
|
|
156
|
-
ndx, ndx + 3, ndx + 2,
|
|
157
|
-
ndx, ndx + 1, ndx + 3
|
|
158
|
-
)
|
|
137
|
+
attr.indices.push(ndx, ndx + 3, ndx + 2, ndx, ndx + 1, ndx + 3)
|
|
159
138
|
} else {
|
|
160
|
-
attr.indices.push(
|
|
161
|
-
|
|
162
|
-
ndx, ndx + 1, ndx + 2,
|
|
163
|
-
ndx + 2, ndx + 1, ndx + 3
|
|
164
|
-
)
|
|
139
|
+
attr.indices.push(ndx, ndx + 1, ndx + 2, ndx + 2, ndx + 1, ndx + 3)
|
|
165
140
|
}
|
|
166
141
|
}
|
|
167
142
|
}
|
|
168
143
|
|
|
169
|
-
export const renderBlockThreeAttr = (
|
|
144
|
+
export const renderBlockThreeAttr = (
|
|
145
|
+
models: BlockModelPartsResolved,
|
|
146
|
+
block: Block | undefined,
|
|
147
|
+
biome: string,
|
|
148
|
+
mcData: IndexedData,
|
|
149
|
+
variants = [],
|
|
150
|
+
neighbors: Neighbors = {}
|
|
151
|
+
) => {
|
|
170
152
|
const sx = 0
|
|
171
153
|
const sy = 0
|
|
172
154
|
const sz = 0
|
|
@@ -184,7 +166,7 @@ export const renderBlockThreeAttr = (models: BlockModelPartsResolved, block: Blo
|
|
|
184
166
|
t_colors: [],
|
|
185
167
|
t_uvs: [],
|
|
186
168
|
indices: [],
|
|
187
|
-
tiles: {}
|
|
169
|
+
tiles: {}
|
|
188
170
|
} as Record<string, any>
|
|
189
171
|
|
|
190
172
|
for (const [i, modelVars] of models.entries()) {
|
|
@@ -194,7 +176,11 @@ export const renderBlockThreeAttr = (models: BlockModelPartsResolved, block: Blo
|
|
|
194
176
|
let globalShift = null as any
|
|
195
177
|
for (const axis of ['x', 'y', 'z'] as const) {
|
|
196
178
|
if (axis in model) {
|
|
197
|
-
if (globalMatrix) {
|
|
179
|
+
if (globalMatrix) {
|
|
180
|
+
globalMatrix = matmulmat3(globalMatrix, buildRotationMatrix(axis, -(model[axis] ?? 0)))
|
|
181
|
+
} else {
|
|
182
|
+
globalMatrix = buildRotationMatrix(axis, -(model[axis] ?? 0))
|
|
183
|
+
}
|
|
198
184
|
}
|
|
199
185
|
}
|
|
200
186
|
if (globalMatrix) {
|
|
@@ -212,9 +198,19 @@ export const renderBlockThreeAttr = (models: BlockModelPartsResolved, block: Blo
|
|
|
212
198
|
let ndx = attr.positions.length / 3
|
|
213
199
|
for (let i = 0; i < attr.t_positions.length / 12; i++) {
|
|
214
200
|
attr.indices.push(
|
|
215
|
-
ndx,
|
|
201
|
+
ndx,
|
|
202
|
+
ndx + 1,
|
|
203
|
+
ndx + 2,
|
|
204
|
+
ndx + 2,
|
|
205
|
+
ndx + 1,
|
|
206
|
+
ndx + 3,
|
|
216
207
|
// back face
|
|
217
|
-
ndx,
|
|
208
|
+
ndx,
|
|
209
|
+
ndx + 2,
|
|
210
|
+
ndx + 1,
|
|
211
|
+
ndx + 2,
|
|
212
|
+
ndx + 3,
|
|
213
|
+
ndx + 1
|
|
218
214
|
)
|
|
219
215
|
ndx += 4
|
|
220
216
|
}
|
|
@@ -266,6 +262,6 @@ export const getThreeBlockModelGroup = (material: THREE.Material, ...args: Param
|
|
|
266
262
|
// return new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshPhongMaterial({ color: 0x00_00_ff, transparent: true, opacity: 0.5 }))
|
|
267
263
|
}
|
|
268
264
|
|
|
269
|
-
export const setBlockPosition = (object: THREE.Object3D, position: { x: number
|
|
265
|
+
export const setBlockPosition = (object: THREE.Object3D, position: { x: number; y: number; z: number }) => {
|
|
270
266
|
object.position.set(position.x + 0.5, position.y + 0.5, position.z + 0.5)
|
|
271
267
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import { test, expect, beforeEach } from 'vitest'
|
|
3
|
+
import MinecraftData from 'minecraft-data'
|
|
4
|
+
import blocksAtlasesJson from 'mc-assets/dist/blocksAtlases.json'
|
|
5
|
+
import blockStatesModels from 'mc-assets/dist/blockStatesModels.json'
|
|
6
|
+
import worldBlockProvider from 'mc-assets/dist/worldBlockProvider'
|
|
7
|
+
import PrismarineBlockLoader from 'prismarine-block'
|
|
8
|
+
import Chunks from 'prismarine-chunk'
|
|
9
|
+
import { Vec3 } from 'vec3'
|
|
10
|
+
import { blockRendersSolid, getOcclusionShape, faceIsCulled, resetFaceOcclusionCache, oppositeDir, buildModelGlobalMatrix } from '../faceOcclusion'
|
|
11
|
+
import { elemFaces } from '../modelsGeometryCommon'
|
|
12
|
+
import { setBlockStatesData, getSectionGeometry } from '../models'
|
|
13
|
+
import { World } from '../world'
|
|
14
|
+
|
|
15
|
+
const VERSION = '1.18.2'
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
resetFaceOcclusionCache()
|
|
19
|
+
const mcData = MinecraftData(VERSION)
|
|
20
|
+
setBlockStatesData(blockStatesModels, blocksAtlasesJson, false, true, VERSION, { blocks: mcData.blocksArray })
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
function blockProvider() {
|
|
24
|
+
return (globalThis as any).blockProvider
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function farmlandElement(provider: ReturnType<typeof worldBlockProvider>) {
|
|
28
|
+
const mcData = MinecraftData(VERSION)
|
|
29
|
+
const farmlandId = mcData.blocksByName.farmland!.defaultState
|
|
30
|
+
const blockObj = PrismarineBlockLoader(VERSION).fromStateId(farmlandId, 1)
|
|
31
|
+
const models = provider.getAllResolvedModels0_1({ name: blockObj.name, properties: blockObj.getProperties() }, false)
|
|
32
|
+
return { farmlandId, element: models[0]![0]!.elements![0]! }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function stairStateId(props: Record<string, string | boolean>) {
|
|
36
|
+
const mcData = MinecraftData(VERSION)
|
|
37
|
+
const Block = PrismarineBlockLoader(VERSION)
|
|
38
|
+
for (let sid = mcData.blocksByName.cut_copper_stairs!.minStateId; sid <= mcData.blocksByName.cut_copper_stairs!.maxStateId; sid++) {
|
|
39
|
+
const p = Block.fromStateId(sid, 1).getProperties() as Record<string, string>
|
|
40
|
+
let match = true
|
|
41
|
+
for (const [k, v] of Object.entries(props)) {
|
|
42
|
+
if (p[k] !== v) {
|
|
43
|
+
match = false
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (match) return sid
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`no stair state for ${JSON.stringify(props)}`)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function stairModel(stateId: number, provider: ReturnType<typeof worldBlockProvider>) {
|
|
53
|
+
const blockObj = PrismarineBlockLoader(VERSION).fromStateId(stateId, 1)
|
|
54
|
+
return provider.getAllResolvedModels0_1({ name: blockObj.name, properties: blockObj.getProperties() }, false)[0]![0]!
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
test('blockRendersSolid: farmland opaque, glass and leaves not', () => {
|
|
58
|
+
const Block = PrismarineBlockLoader(VERSION)
|
|
59
|
+
const farmland = Block.fromStateId(MinecraftData(VERSION).blocksByName.farmland!.defaultState, 1)
|
|
60
|
+
const glass = Block.fromStateId(MinecraftData(VERSION).blocksByName.glass!.defaultState, 1)
|
|
61
|
+
const leaves = Block.fromStateId(MinecraftData(VERSION).blocksByName.oak_leaves!.defaultState, 1)
|
|
62
|
+
expect(blockRendersSolid(farmland)).toBe(true)
|
|
63
|
+
expect(blockRendersSolid(glass)).toBe(false)
|
|
64
|
+
expect(blockRendersSolid(leaves)).toBe(false)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('getOcclusionShape: full cube covers entire plane', () => {
|
|
68
|
+
const mcData = MinecraftData(VERSION)
|
|
69
|
+
const stoneId = mcData.blocksByName.stone!.defaultState
|
|
70
|
+
const shape = getOcclusionShape(VERSION, stoneId, [1, 0, 0], blockProvider())
|
|
71
|
+
for (let row = 0; row < 16; row++) {
|
|
72
|
+
expect(shape[row]).toBe(0xffff)
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('getOcclusionShape: farmland side is shorter than full height', () => {
|
|
77
|
+
const mcData = MinecraftData(VERSION)
|
|
78
|
+
const farmlandId = mcData.blocksByName.farmland!.defaultState
|
|
79
|
+
const eastShape = getOcclusionShape(VERSION, farmlandId, [1, 0, 0], blockProvider())
|
|
80
|
+
let covered = 0
|
|
81
|
+
for (let row = 0; row < 16; row++) {
|
|
82
|
+
for (let col = 0; col < 16; col++) {
|
|
83
|
+
if (eastShape[row]! & (1 << col)) covered++
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
expect(covered).toBeLessThan(16 * 16)
|
|
87
|
+
expect(covered).toBeGreaterThan(0)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test('getOcclusionShape: west-facing stair fully covers west plane (step on west side)', () => {
|
|
91
|
+
const westId = stairStateId({ facing: 'west', half: 'bottom', shape: 'straight', waterlogged: false })
|
|
92
|
+
const westShape = getOcclusionShape(VERSION, westId, [-1, 0, 0], blockProvider())
|
|
93
|
+
for (let row = 0; row < 16; row++) {
|
|
94
|
+
expect(westShape[row]).toBe(0xffff)
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('faceIsCulled: farmland east face culled by adjacent farmland', () => {
|
|
99
|
+
const provider = blockProvider()
|
|
100
|
+
const { farmlandId, element } = farmlandElement(provider)
|
|
101
|
+
expect(faceIsCulled(VERSION, element, 'east', farmlandId, { stateId: farmlandId, name: 'farmland' }, provider, [1, 0, 0], null)).toBe(true)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('faceIsCulled: farmland east face not culled by air', () => {
|
|
105
|
+
const provider = blockProvider()
|
|
106
|
+
const { farmlandId, element } = farmlandElement(provider)
|
|
107
|
+
expect(faceIsCulled(VERSION, element, 'east', 0, { stateId: farmlandId, name: 'farmland' }, provider, [1, 0, 0], null)).toBe(false)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
test('faceIsCulled: glass identical neighbor still culls', () => {
|
|
111
|
+
const mcData = MinecraftData(VERSION)
|
|
112
|
+
const glassId = mcData.blocksByName.glass!.defaultState
|
|
113
|
+
const provider = blockProvider()
|
|
114
|
+
const models = provider.getAllResolvedModels0_1({ name: 'glass', properties: {} }, false)
|
|
115
|
+
const element = models[0]![0]!.elements![0]!
|
|
116
|
+
expect(faceIsCulled(VERSION, element, 'north', glassId, { stateId: glassId, name: 'glass' }, provider, [0, 0, -1], null)).toBe(true)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('legacy mesher: adjacent farmland culled internal side', () => {
|
|
120
|
+
const mcData = MinecraftData(VERSION)
|
|
121
|
+
const Chunk = Chunks(VERSION) as any
|
|
122
|
+
const chunk = new Chunk(undefined as any)
|
|
123
|
+
const farmlandId = mcData.blocksByName.farmland!.defaultState
|
|
124
|
+
chunk.setBlockStateId(new Vec3(0, 0, 0), farmlandId)
|
|
125
|
+
chunk.setBlockStateId(new Vec3(1, 0, 0), farmlandId)
|
|
126
|
+
const world = new World(VERSION)
|
|
127
|
+
world.addColumn(0, 0, chunk.toJson())
|
|
128
|
+
const geo = getSectionGeometry(0, 0, 0, world, 16)
|
|
129
|
+
expect(geo.indicesCount / 6).toBe(10)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
test('faceIsCulled: east stair interior faces culled against identical stair', () => {
|
|
133
|
+
const stairId = stairStateId({ facing: 'east', half: 'bottom', shape: 'straight', waterlogged: false })
|
|
134
|
+
const provider = blockProvider()
|
|
135
|
+
const model = stairModel(stairId, provider)
|
|
136
|
+
const globalMatrix = buildModelGlobalMatrix(model)
|
|
137
|
+
let culled = 0
|
|
138
|
+
for (const element of model.elements ?? []) {
|
|
139
|
+
for (const face of Object.keys(element.faces)) {
|
|
140
|
+
const localDir = elemFaces[face as keyof typeof elemFaces].dir as [number, number, number]
|
|
141
|
+
const worldDir = [Math.round(localDir[0]), Math.round(localDir[1]), Math.round(localDir[2])] as [number, number, number]
|
|
142
|
+
if (faceIsCulled(VERSION, element, face, stairId, { stateId: stairId, name: 'cut_copper_stairs' }, provider, worldDir, globalMatrix)) {
|
|
143
|
+
culled++
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
expect(culled).toBeGreaterThan(0)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test('faceIsCulled: west stair interior faces culled against identical west stair', () => {
|
|
151
|
+
const stairId = stairStateId({ facing: 'west', half: 'bottom', shape: 'straight', waterlogged: false })
|
|
152
|
+
const provider = blockProvider()
|
|
153
|
+
const model = stairModel(stairId, provider)
|
|
154
|
+
const globalMatrix = buildModelGlobalMatrix(model)
|
|
155
|
+
expect(globalMatrix).not.toBeNull()
|
|
156
|
+
let culled = 0
|
|
157
|
+
for (const element of model.elements ?? []) {
|
|
158
|
+
for (const face of Object.keys(element.faces)) {
|
|
159
|
+
const localDir = elemFaces[face as keyof typeof elemFaces].dir
|
|
160
|
+
const rotated = globalMatrix
|
|
161
|
+
? [
|
|
162
|
+
globalMatrix[0][0] * localDir[0] + globalMatrix[0][1] * localDir[1] + globalMatrix[0][2] * localDir[2],
|
|
163
|
+
globalMatrix[1][0] * localDir[0] + globalMatrix[1][1] * localDir[1] + globalMatrix[1][2] * localDir[2],
|
|
164
|
+
globalMatrix[2][0] * localDir[0] + globalMatrix[2][1] * localDir[1] + globalMatrix[2][2] * localDir[2]
|
|
165
|
+
]
|
|
166
|
+
: localDir
|
|
167
|
+
const worldDir = [Math.round(rotated[0]), Math.round(rotated[1]), Math.round(rotated[2])] as [number, number, number]
|
|
168
|
+
if (faceIsCulled(VERSION, element, face, stairId, { stateId: stairId, name: 'cut_copper_stairs' }, provider, worldDir, globalMatrix)) {
|
|
169
|
+
culled++
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
expect(culled).toBeGreaterThan(0)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test('oppositeDir inverts cardinal directions', () => {
|
|
177
|
+
expect(oppositeDir([1, 0, 0])[0]).toBe(-1)
|
|
178
|
+
expect(oppositeDir([0, 1, 0])[1]).toBe(-1)
|
|
179
|
+
})
|
|
@@ -3,14 +3,18 @@ import { test, expect } from 'vitest'
|
|
|
3
3
|
import { setup } from '../../mesher-legacy/test/mesherTester'
|
|
4
4
|
|
|
5
5
|
test('renderLiquid blend output satisfies 6/4 quad invariant with both windings', () => {
|
|
6
|
-
const { getGeometry } = setup(
|
|
7
|
-
|
|
8
|
-
[
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
const { getGeometry } = setup(
|
|
7
|
+
'1.16.5',
|
|
8
|
+
[
|
|
9
|
+
[[0, 0, 0], 'water'],
|
|
10
|
+
[[0, -1, 0], 'stone'],
|
|
11
|
+
[[1, 0, 0], 'stone'],
|
|
12
|
+
[[-1, 0, 0], 'stone'],
|
|
13
|
+
[[0, 0, 1], 'stone'],
|
|
14
|
+
[[0, 0, -1], 'stone']
|
|
15
|
+
],
|
|
16
|
+
{ noDebugTiles: true }
|
|
17
|
+
)
|
|
14
18
|
|
|
15
19
|
const { attr } = getGeometry()
|
|
16
20
|
const blend = attr.blend
|
|
@@ -4,11 +4,7 @@ import type { MesherConfig } from './shared'
|
|
|
4
4
|
export type FaceDirection = readonly [number, number, number]
|
|
5
5
|
|
|
6
6
|
/** Directional face darkening (matches legacy `renderElement` in models.ts). */
|
|
7
|
-
export function getSideShading(
|
|
8
|
-
dir: FaceDirection,
|
|
9
|
-
shadingTheme: MesherConfig['shadingTheme'],
|
|
10
|
-
cardinalLight: MesherConfig['cardinalLight']
|
|
11
|
-
): number {
|
|
7
|
+
export function getSideShading(dir: FaceDirection, shadingTheme: MesherConfig['shadingTheme'], cardinalLight: MesherConfig['cardinalLight']): number {
|
|
12
8
|
if (shadingTheme === 'high-contrast') {
|
|
13
9
|
return 0.8 + 0.5 * Math.max(0, 0.66 * dir[0] + 0.66 * dir[1] + 0.33 * dir[2])
|
|
14
10
|
}
|
|
@@ -19,12 +15,7 @@ export function getSideShading(
|
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
/** Per-vertex brightness from AO (0–3) and corner light (0–15). */
|
|
22
|
-
export function vertexLightFromAo(
|
|
23
|
-
ao: number,
|
|
24
|
-
cornerLight15: number,
|
|
25
|
-
sideShading: number,
|
|
26
|
-
shadingTheme: MesherConfig['shadingTheme']
|
|
27
|
-
): number {
|
|
18
|
+
export function vertexLightFromAo(ao: number, cornerLight15: number, sideShading: number, shadingTheme: MesherConfig['shadingTheme']): number {
|
|
28
19
|
const lightNorm = cornerLight15 / 15
|
|
29
20
|
if (shadingTheme === 'high-contrast') {
|
|
30
21
|
return sideShading * ((ao + 1) / 4) * lightNorm
|
|
@@ -76,36 +76,31 @@ export class World {
|
|
|
76
76
|
this.config.version = version
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
getChannelLightNorm
|
|
80
|
-
if (!(pos instanceof Vec3)) pos = new Vec3(...pos as [number, number, number])
|
|
79
|
+
getChannelLightNorm(pos: Vec3): { block: number; sky: number } {
|
|
80
|
+
if (!(pos instanceof Vec3)) pos = new Vec3(...(pos as [number, number, number]))
|
|
81
81
|
if (!this.config.enableLighting) return { block: 0, sky: 1 }
|
|
82
82
|
const column = this.getColumnByPos(pos)
|
|
83
83
|
if (!column || !hasChunkSection(column, pos)) return { block: 0, sky: 1 }
|
|
84
84
|
const loc = posInChunk(pos)
|
|
85
85
|
return {
|
|
86
86
|
block: Math.min(15, column.getBlockLight(loc) + 2) / 15,
|
|
87
|
-
sky: Math.min(15, column.getSkyLight(loc) + 2) / 15
|
|
87
|
+
sky: Math.min(15, column.getSkyLight(loc) + 2) / 15
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
getLight(pos: Vec3, isNeighbor = false, skipMoreChecks = false, curBlockName = '') {
|
|
92
92
|
// for easier testing
|
|
93
|
-
if (!(pos instanceof Vec3)) pos = new Vec3(...pos as [number, number, number])
|
|
93
|
+
if (!(pos instanceof Vec3)) pos = new Vec3(...(pos as [number, number, number]))
|
|
94
94
|
const { enableLighting, skyLight } = this.config
|
|
95
95
|
if (!enableLighting) return 15
|
|
96
96
|
// const key = `${pos.x},${pos.y},${pos.z}`
|
|
97
97
|
// if (lightsCache.has(key)) return lightsCache.get(key)
|
|
98
98
|
const column = this.getColumnByPos(pos)
|
|
99
99
|
if (!column || !hasChunkSection(column, pos)) return 15
|
|
100
|
-
let result = Math.min(
|
|
101
|
-
15,
|
|
102
|
-
Math.max(
|
|
103
|
-
column.getBlockLight(posInChunk(pos)),
|
|
104
|
-
Math.min(skyLight, column.getSkyLight(posInChunk(pos)))
|
|
105
|
-
) + 2
|
|
106
|
-
)
|
|
100
|
+
let result = Math.min(15, Math.max(column.getBlockLight(posInChunk(pos)), Math.min(skyLight, column.getSkyLight(posInChunk(pos)))) + 2)
|
|
107
101
|
// lightsCache.set(key, result)
|
|
108
|
-
if (result === 2 && [this.getBlock(pos)?.name ?? '', curBlockName].some(x => /_stairs|slab|glass_pane/.exec(x)) && !skipMoreChecks) {
|
|
102
|
+
if (result === 2 && [this.getBlock(pos)?.name ?? '', curBlockName].some(x => /_stairs|slab|glass_pane/.exec(x)) && !skipMoreChecks) {
|
|
103
|
+
// todo this is obviously wrong
|
|
109
104
|
const lights = [
|
|
110
105
|
this.getLight(pos.offset(0, 1, 0), undefined, true),
|
|
111
106
|
this.getLight(pos.offset(0, -1, 0), undefined, true),
|
|
@@ -156,7 +151,7 @@ export class World {
|
|
|
156
151
|
|
|
157
152
|
getBlock(pos: Vec3, blockProvider?: WorldBlockProvider, attr?: { hadErrors?: boolean }): WorldBlock | null {
|
|
158
153
|
// for easier testing
|
|
159
|
-
if (!(pos instanceof Vec3)) pos = new Vec3(...pos as [number, number, number])
|
|
154
|
+
if (!(pos instanceof Vec3)) pos = new Vec3(...(pos as [number, number, number]))
|
|
160
155
|
const chunkKey = worldColumnKey(Math.floor(pos.x / 16) * 16, Math.floor(pos.z / 16) * 16)
|
|
161
156
|
const modelOverride = this.customBlockModels.get(chunkKey)?.[getBlockPosKey(pos)]
|
|
162
157
|
|
|
@@ -190,11 +185,16 @@ export class World {
|
|
|
190
185
|
b.name = namePropsStr.split('[')[0]
|
|
191
186
|
const propsStr = namePropsStr.split('[')?.[1]?.split(']')
|
|
192
187
|
if (propsStr) {
|
|
193
|
-
const newProperties = Object.fromEntries(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
188
|
+
const newProperties = Object.fromEntries(
|
|
189
|
+
propsStr
|
|
190
|
+
.join('')
|
|
191
|
+
.split(',')
|
|
192
|
+
.map(x => {
|
|
193
|
+
let [key, val] = x.split('=')
|
|
194
|
+
if (!isNaN(val)) val = parseInt(val, 10)
|
|
195
|
+
return [key, val]
|
|
196
|
+
})
|
|
197
|
+
)
|
|
198
198
|
b._properties = newProperties
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -228,7 +228,7 @@ export class World {
|
|
|
228
228
|
block.models = blockProvider.getAllResolvedModels0_1(
|
|
229
229
|
{
|
|
230
230
|
name: block.name,
|
|
231
|
-
properties: props
|
|
231
|
+
properties: props
|
|
232
232
|
},
|
|
233
233
|
useFallbackModel,
|
|
234
234
|
issues,
|
|
@@ -3,10 +3,10 @@ import { describe, expect, it } from 'vitest'
|
|
|
3
3
|
import { Vec3 } from 'vec3'
|
|
4
4
|
import { World } from './world'
|
|
5
5
|
|
|
6
|
-
function mockColumn
|
|
6
|
+
function mockColumn(blockLight: number, skyLight: number, withSection = true) {
|
|
7
7
|
return {
|
|
8
8
|
getBlockLight: () => blockLight,
|
|
9
|
-
getSkyLight: () => skyLight
|
|
9
|
+
getSkyLight: () => skyLight
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
LONG_RENDER_TIME_MS,
|
|
8
8
|
LOW_FPS_THRESHOLD,
|
|
9
9
|
RENDER_TIME_HISTORY_SIZE,
|
|
10
|
-
SLOW_ENTITIES_RENDER_MS
|
|
10
|
+
SLOW_ENTITIES_RENDER_MS
|
|
11
11
|
} from './constants'
|
|
12
12
|
import type { FramePerformanceSample, PerformanceInstabilityFactors } from './types'
|
|
13
13
|
|
|
@@ -40,22 +40,13 @@ export class PerformanceMonitor {
|
|
|
40
40
|
|
|
41
41
|
const historyLen = this.renderTimeHistory.length
|
|
42
42
|
const longFrames = this.renderTimeHistory.filter(t => t >= LONG_RENDER_TIME_MS).length
|
|
43
|
-
const constantLongRenderTime =
|
|
44
|
-
historyLen >= CONSTANT_LONG_RENDER_MIN_SAMPLES &&
|
|
45
|
-
longFrames / historyLen >= CONSTANT_LONG_RENDER_FRACTION
|
|
43
|
+
const constantLongRenderTime = historyLen >= CONSTANT_LONG_RENDER_MIN_SAMPLES && longFrames / historyLen >= CONSTANT_LONG_RENDER_FRACTION
|
|
46
44
|
|
|
47
45
|
const tooManyTextures = sample.loadedTextureCount >= HIGH_TEXTURE_COUNT
|
|
48
46
|
|
|
49
|
-
const tooManyEntities =
|
|
50
|
-
lowFps &&
|
|
51
|
-
sample.entitiesMs >= SLOW_ENTITIES_RENDER_MS &&
|
|
52
|
-
sceneWithoutEntitiesMs <= FAST_SCENE_WITHOUT_ENTITIES_MS
|
|
47
|
+
const tooManyEntities = lowFps && sample.entitiesMs >= SLOW_ENTITIES_RENDER_MS && sceneWithoutEntitiesMs <= FAST_SCENE_WITHOUT_ENTITIES_MS
|
|
53
48
|
|
|
54
|
-
const hasKnownCause =
|
|
55
|
-
longRenderTime ||
|
|
56
|
-
constantLongRenderTime ||
|
|
57
|
-
tooManyEntities ||
|
|
58
|
-
tooManyTextures
|
|
49
|
+
const hasKnownCause = longRenderTime || constantLongRenderTime || tooManyEntities || tooManyTextures
|
|
59
50
|
|
|
60
51
|
const unknownReason = lowFps && !hasKnownCause
|
|
61
52
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
import type { PerformanceInstabilityFactors } from './types'
|
|
3
3
|
|
|
4
|
-
const FACTOR_CODES: Array<{ key: keyof PerformanceInstabilityFactors
|
|
4
|
+
const FACTOR_CODES: Array<{ key: keyof PerformanceInstabilityFactors; code: string }> = [
|
|
5
5
|
{ key: 'longRenderTime', code: 'LR' },
|
|
6
6
|
{ key: 'constantLongRenderTime', code: 'CLR' },
|
|
7
7
|
{ key: 'tooManyEntities', code: 'ENT' },
|
|
8
8
|
{ key: 'tooManyTextures', code: 'TEX' },
|
|
9
|
-
{ key: 'unknownReason', code: 'UNK' }
|
|
9
|
+
{ key: 'unknownReason', code: 'UNK' }
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
/** Compact debug overlay fragment, e.g. `LR+ENT` or empty string. */
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
export type { FramePerformanceSample, PerformanceInstabilityFactors } from './types'
|
|
3
3
|
export { defaultPerformanceInstabilityFactors } from './types'
|
|
4
|
-
export {
|
|
5
|
-
LONG_RENDER_TIME_MS,
|
|
6
|
-
LOW_FPS_THRESHOLD,
|
|
7
|
-
HIGH_TEXTURE_COUNT,
|
|
8
|
-
} from './constants'
|
|
4
|
+
export { LONG_RENDER_TIME_MS, LOW_FPS_THRESHOLD, HIGH_TEXTURE_COUNT } from './constants'
|
|
9
5
|
export { PerformanceMonitor } from './PerformanceMonitor'
|
|
10
6
|
export { formatPerformanceFactorsDebug } from './formatPerformanceFactorsDebug'
|
|
@@ -13,7 +13,7 @@ export const defaultPerformanceInstabilityFactors = (): PerformanceInstabilityFa
|
|
|
13
13
|
constantLongRenderTime: false,
|
|
14
14
|
tooManyEntities: false,
|
|
15
15
|
tooManyTextures: false,
|
|
16
|
-
unknownReason: false
|
|
16
|
+
unknownReason: false
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
export interface FramePerformanceSample {
|