@woosh/meep-engine 2.74.0 → 2.75.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/meep.cjs +183 -187
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +183 -187
- package/package.json +1 -1
- package/src/core/binary/UINT32_MAX.js +5 -0
- package/src/core/bvh2/bvh3/BVH.js +44 -2
- package/src/core/bvh2/bvh3/BVH.spec.js +45 -0
- package/src/core/bvh2/bvh3/build_triangle_morton_codes.js +73 -0
- package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +5 -101
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy.js +59 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.js +31 -32
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.spec.js +64 -0
- package/src/core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js +1 -0
- package/src/core/geom/3d/aabb/aabb3_signed_distance_sqr_to_point.js +1 -0
- package/src/core/geom/3d/aabb/aabb3_unsigned_distance_sqr_to_point.js +36 -0
- package/src/core/process/worker/OnDemandWorkerManager.js +5 -1
- package/src/engine/asset/loaders/ArrayBufferLoader.js +13 -15
- package/src/engine/asset/loaders/image/ImageDecoderWorker.js +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +5 -7
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
- package/src/engine/asset/loaders/image/png/PNG.js +339 -332
- package/src/engine/asset/loaders/image/png/PNGReader.js +59 -16
- package/src/engine/asset/loaders/image/png/prototypePNG.js +13 -4
- package/src/engine/graphics/texture/virtual/v2/{SparseTexture.js → PageTexture.js} +62 -18
- package/src/engine/graphics/texture/virtual/v2/ResidentTileTexture.js +46 -0
- package/src/engine/graphics/texture/virtual/v2/{TileLoader.js → VirtualTextureTileLoader.js} +11 -8
- package/src/engine/graphics/texture/virtual/v2/{UsageMetadata.js → VirtualTextureUsage.js} +2 -8
- package/src/engine/graphics/texture/virtual/v2/{VirtualTextureManager.js → VirtualTextureUsageUpdater.js} +7 -5
- package/src/engine/graphics/texture/virtual/v2/debug/ResidencyDebugView.js +17 -5
- package/src/engine/graphics/texture/virtual/v2/debug/UsageDebugView.js +1 -1
- package/src/engine/graphics/texture/virtual/v2/debug/UsagePyramidDebugView.js +1 -1
- package/src/engine/graphics/texture/virtual/v2/prototype.js +78 -59
- package/src/engine/graphics/texture/virtual/v2/tile/{TextureTile.js → VirtualTextureTile.js} +2 -2
- package/src/engine/graphics/texture/virtual/v2/tile/compose_tile_address.js +4 -0
- /package/src/engine/graphics/texture/virtual/v2/{ShaderUsage.js → VirtualTextureUsageShader.js} +0 -0
|
@@ -140,6 +140,8 @@ PNGReader.prototype.decodeChunk = function () {
|
|
|
140
140
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
// console.log(`chunk: ${type}`);
|
|
144
|
+
|
|
143
145
|
|
|
144
146
|
switch (type) {
|
|
145
147
|
case 'IHDR':
|
|
@@ -157,8 +159,11 @@ PNGReader.prototype.decodeChunk = function () {
|
|
|
157
159
|
case 'IEND':
|
|
158
160
|
this.decodeIEND(chunk);
|
|
159
161
|
break;
|
|
162
|
+
case 'sRGB':
|
|
163
|
+
this.decodesRGB(chunk);
|
|
164
|
+
break;
|
|
160
165
|
default:
|
|
161
|
-
|
|
166
|
+
console.warn(`Unsupported block ${type}`);
|
|
162
167
|
break;
|
|
163
168
|
}
|
|
164
169
|
|
|
@@ -166,6 +171,19 @@ PNGReader.prototype.decodeChunk = function () {
|
|
|
166
171
|
|
|
167
172
|
};
|
|
168
173
|
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* https://www.w3.org/TR/2003/REC-PNG-20031110/#11sRGB
|
|
177
|
+
* @param {Uint8Array} chunk
|
|
178
|
+
*/
|
|
179
|
+
PNGReader.prototype.decodesRGB = function (chunk) {
|
|
180
|
+
|
|
181
|
+
const rendering_intent = readUInt8(chunk, 0);
|
|
182
|
+
|
|
183
|
+
// TODO add metadata to the PNG representation
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
169
187
|
/**
|
|
170
188
|
* https://www.w3.org/TR/PNG/#11tEXt
|
|
171
189
|
* @param {Uint8Array} chunk
|
|
@@ -294,17 +312,19 @@ PNGReader.prototype.interlaceNone = function (data) {
|
|
|
294
312
|
|
|
295
313
|
const png = this.png;
|
|
296
314
|
|
|
297
|
-
const
|
|
298
|
-
const bits_per_line = png.colors *
|
|
299
|
-
const bytes_per_pixel =
|
|
315
|
+
const depth = png.bitDepth;
|
|
316
|
+
const bits_per_line = png.colors * depth;
|
|
317
|
+
const bytes_per_pixel = bits_per_line / 8;
|
|
300
318
|
|
|
301
319
|
const width = png.width;
|
|
302
320
|
const height = png.height;
|
|
303
321
|
|
|
304
322
|
// color bytes per row
|
|
305
|
-
const color_bytes_per_row = bytes_per_pixel * width;
|
|
323
|
+
const color_bytes_per_row = Math.ceil(bytes_per_pixel * width);
|
|
306
324
|
|
|
307
|
-
const
|
|
325
|
+
const output_bytes_per_row = Math.ceil(bytes_per_pixel) * width;
|
|
326
|
+
|
|
327
|
+
const pixels = new Uint8Array(output_bytes_per_row * height);
|
|
308
328
|
|
|
309
329
|
let offset = 0;
|
|
310
330
|
|
|
@@ -320,7 +340,38 @@ PNGReader.prototype.interlaceNone = function (data) {
|
|
|
320
340
|
|
|
321
341
|
switch (header) {
|
|
322
342
|
case 0:
|
|
323
|
-
|
|
343
|
+
// NONE
|
|
344
|
+
if (depth === 1) {
|
|
345
|
+
for (let x = 0; x < output_bytes_per_row; x++) {
|
|
346
|
+
const q = x >>> 4;
|
|
347
|
+
const datum = data[q + scanline_address];
|
|
348
|
+
const shift = ((x) & 0x7);
|
|
349
|
+
const out_value = (datum >>> shift) & 0x1;
|
|
350
|
+
pixels[offset + x] = out_value;
|
|
351
|
+
}
|
|
352
|
+
} else if (depth === 2) {
|
|
353
|
+
for (let x = 0; x < output_bytes_per_row; x++) {
|
|
354
|
+
const q = x >>> 2;
|
|
355
|
+
const datum = data[q + scanline_address];
|
|
356
|
+
const shift = ((~x) & 0x3) << 1;
|
|
357
|
+
const out_value = (datum >>> shift) & 0x3;
|
|
358
|
+
pixels[offset + x] = out_value;
|
|
359
|
+
}
|
|
360
|
+
} else if (depth === 4) {
|
|
361
|
+
for (let x = 0; x < output_bytes_per_row; x++) {
|
|
362
|
+
const q = x >>> 1;
|
|
363
|
+
const datum = data[q + scanline_address];
|
|
364
|
+
const shift = ((~x) & 0x1) << 2;
|
|
365
|
+
const out_value = (datum >>> shift) & 0xF;
|
|
366
|
+
pixels[offset + x] = out_value;
|
|
367
|
+
}
|
|
368
|
+
} else if (depth === 8) {
|
|
369
|
+
for (let x = 0; x < output_bytes_per_row; x++) {
|
|
370
|
+
pixels[offset + x] = data[x + scanline_address];
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
throw new Error(`unsupported bit depth ${depth}`)
|
|
374
|
+
}
|
|
324
375
|
break;
|
|
325
376
|
case 1:
|
|
326
377
|
this.unFilterSub(data, scanline_address, pixels, bytes_per_pixel, offset, color_bytes_per_row);
|
|
@@ -338,7 +389,7 @@ PNGReader.prototype.interlaceNone = function (data) {
|
|
|
338
389
|
throw new Error(`unknown filtered scanline type '${header}'`);
|
|
339
390
|
}
|
|
340
391
|
|
|
341
|
-
offset +=
|
|
392
|
+
offset += output_bytes_per_row;
|
|
342
393
|
|
|
343
394
|
}
|
|
344
395
|
|
|
@@ -356,14 +407,6 @@ PNGReader.prototype.interlaceAdam7 = function (data) {
|
|
|
356
407
|
|
|
357
408
|
// Unfiltering
|
|
358
409
|
|
|
359
|
-
/**
|
|
360
|
-
* No filtering, direct copy
|
|
361
|
-
*/
|
|
362
|
-
PNGReader.prototype.unFilterNone = function (scanline, scanline_offset, pixels, bpp, of, length) {
|
|
363
|
-
for (let i = 0; i < length; i++) {
|
|
364
|
-
pixels[of + i] = scanline[i + scanline_offset];
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
410
|
|
|
368
411
|
/**
|
|
369
412
|
* The Sub() filter transmits the difference between each byte and the value
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
+
import { Sampler2D } from "../../../../graphics/texture/sampler/Sampler2D.js";
|
|
1
2
|
import sampler2D2Canvas from "../../../../graphics/texture/sampler/Sampler2D2Canvas.js";
|
|
3
|
+
import { AssetRequestScope } from "../../../AssetRequestScope.js";
|
|
2
4
|
import { ArrayBufferLoader } from "../../ArrayBufferLoader.js";
|
|
3
5
|
import { PNGReader } from "./PNGReader.js";
|
|
4
|
-
import { Sampler2D } from "../../../../graphics/texture/sampler/Sampler2D.js";
|
|
5
6
|
|
|
6
7
|
const array_loader = new ArrayBufferLoader();
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
// const path = 'moicon/ISO 7010 - Safety Signs (3)/ISO 7010 - Safety Signs/Emergency/400px/E001 – Emergency exit (left hand).png';
|
|
11
|
+
// const path = 'data/textures/utility/vt/uv_map_reference/5-2-1.png';
|
|
12
|
+
// const path = 'data/textures/utility/vt/uv_map_reference/6-62-60.png';
|
|
13
|
+
// const path = 'data/textures/utility/vt/uv_map_reference/5-11-5.png';
|
|
14
|
+
// const path = 'data/textures/utility/vt/uv_map_reference/1-0-0.png';
|
|
15
|
+
// const path = 'data/textures/utility/vt/uv_map_reference/5-3-0.png';
|
|
16
|
+
// const path = 'data/textures/utility/vt/uv_map_reference/5-21-14.png';
|
|
17
|
+
const path = 'data/textures/utility/vt/uv_map_reference/6-39-33.png';
|
|
9
18
|
|
|
10
|
-
array_loader.load(
|
|
19
|
+
array_loader.load(new AssetRequestScope(), path, (asset) => {
|
|
11
20
|
|
|
12
21
|
const array = asset.create();
|
|
13
22
|
|
|
@@ -19,9 +28,9 @@ array_loader.load('moicon/ISO 7010 - Safety Signs (3)/ISO 7010 - Safety Signs/Em
|
|
|
19
28
|
|
|
20
29
|
const uint8Data = png.getUint8Data();
|
|
21
30
|
|
|
22
|
-
const sampler = new Sampler2D(uint8Data.data,uint8Data.itemSize,png.getWidth(), png.getHeight());
|
|
31
|
+
const sampler = new Sampler2D(uint8Data.data, uint8Data.itemSize, png.getWidth(), png.getHeight());
|
|
23
32
|
|
|
24
|
-
const canvas = sampler2D2Canvas(sampler,1,0);
|
|
33
|
+
const canvas = sampler2D2Canvas(sampler, 1, 0);
|
|
25
34
|
|
|
26
35
|
document.body.appendChild(canvas);
|
|
27
36
|
|
|
@@ -2,11 +2,12 @@ import { WebGLRenderTarget } from "three";
|
|
|
2
2
|
import { BitSet } from "../../../../../core/binary/BitSet.js";
|
|
3
3
|
import { Cache } from "../../../../../core/cache/Cache.js";
|
|
4
4
|
import { array_copy } from "../../../../../core/collection/array/array_copy.js";
|
|
5
|
+
import { HashMap } from "../../../../../core/collection/map/HashMap.js";
|
|
5
6
|
import { passThrough, strictEquals } from "../../../../../core/function/Functions.js";
|
|
6
7
|
import { max2 } from "../../../../../core/math/max2.js";
|
|
7
8
|
import { min2 } from "../../../../../core/math/min2.js";
|
|
8
9
|
import { tile_address_to_finger_print } from "./tile/tile_address_to_finger_print.js";
|
|
9
|
-
import {
|
|
10
|
+
import { VirtualTextureTileLoader } from "./VirtualTextureTileLoader.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* How much extra data to store in cache (in bytes)
|
|
@@ -14,12 +15,22 @@ import { TileLoader } from "./TileLoader.js";
|
|
|
14
15
|
*/
|
|
15
16
|
const DEFAULT_CACHE_SIZE = 16 * 1024 * 1024;
|
|
16
17
|
|
|
17
|
-
export class
|
|
18
|
+
export class PageTexture {
|
|
18
19
|
#page_texture = new WebGLRenderTarget(1, 1);
|
|
19
20
|
|
|
20
21
|
#page_texture_size = [1, 1];
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Used internally to track number of times `update` method was called
|
|
25
|
+
* @type {number}
|
|
26
|
+
*/
|
|
27
|
+
update_count = 0;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Track updates to page content, whenever a tile is made resident or is removed - this number goes up by 1
|
|
31
|
+
* @type {number}
|
|
32
|
+
*/
|
|
33
|
+
version = 0;
|
|
23
34
|
|
|
24
35
|
/**
|
|
25
36
|
* Maximum number of new page assignments per single update cycle
|
|
@@ -35,7 +46,7 @@ export class SparseTexture {
|
|
|
35
46
|
|
|
36
47
|
/**
|
|
37
48
|
*
|
|
38
|
-
* @type {
|
|
49
|
+
* @type {VirtualTextureTile[]}
|
|
39
50
|
*/
|
|
40
51
|
#resident_tiles = [];
|
|
41
52
|
|
|
@@ -43,6 +54,15 @@ export class SparseTexture {
|
|
|
43
54
|
return this.#resident_tiles;
|
|
44
55
|
}
|
|
45
56
|
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @type {HashMap<number, VirtualTextureTile>}
|
|
60
|
+
*/
|
|
61
|
+
#resident_tile_lookup = new HashMap({
|
|
62
|
+
keyHashFunction: passThrough,
|
|
63
|
+
keyEqualityFunction: strictEquals,
|
|
64
|
+
});
|
|
65
|
+
|
|
46
66
|
#page_slot_occupancy = new BitSet();
|
|
47
67
|
|
|
48
68
|
#tile_resolution = 128;
|
|
@@ -61,7 +81,7 @@ export class SparseTexture {
|
|
|
61
81
|
*/
|
|
62
82
|
#prefetch_factor = 0.33;
|
|
63
83
|
|
|
64
|
-
#loader = new
|
|
84
|
+
#loader = new VirtualTextureTileLoader();
|
|
65
85
|
|
|
66
86
|
/**
|
|
67
87
|
*
|
|
@@ -75,7 +95,7 @@ export class SparseTexture {
|
|
|
75
95
|
|
|
76
96
|
/**
|
|
77
97
|
*
|
|
78
|
-
* @param {
|
|
98
|
+
* @param {VirtualTextureTile} tile
|
|
79
99
|
*/
|
|
80
100
|
#handle_tile_loaded(tile) {
|
|
81
101
|
const finderPrint = tile.finder_print;
|
|
@@ -112,7 +132,8 @@ export class SparseTexture {
|
|
|
112
132
|
|
|
113
133
|
this.#residency_tile_capacity = x * y;
|
|
114
134
|
|
|
115
|
-
|
|
135
|
+
// Limit the queue to be able to load no more than an entire page, trying to load more would be wasteful as we wouldn't be able to use that data immediately anyway
|
|
136
|
+
this.#loader.queue_limit = max2(1, this.#residency_tile_capacity);
|
|
116
137
|
}
|
|
117
138
|
|
|
118
139
|
|
|
@@ -129,7 +150,7 @@ export class SparseTexture {
|
|
|
129
150
|
/**
|
|
130
151
|
* Tiles that are not currently resident live here
|
|
131
152
|
* key is the tile's "fingerprint"
|
|
132
|
-
* @type {Cache<number,
|
|
153
|
+
* @type {Cache<number,VirtualTextureTile>}
|
|
133
154
|
*/
|
|
134
155
|
#tile_cache = new Cache({
|
|
135
156
|
keyHashFunction: passThrough,
|
|
@@ -183,15 +204,21 @@ export class SparseTexture {
|
|
|
183
204
|
|
|
184
205
|
removed.page_slot = -1;
|
|
185
206
|
|
|
207
|
+
const fingerprint = removed.finder_print;
|
|
208
|
+
|
|
209
|
+
this.#resident_tile_lookup.delete(fingerprint);
|
|
210
|
+
|
|
186
211
|
// push into cache
|
|
187
|
-
this.#tile_cache.put(
|
|
212
|
+
this.#tile_cache.put(fingerprint, removed);
|
|
213
|
+
|
|
214
|
+
this.version++;
|
|
188
215
|
|
|
189
216
|
return true;
|
|
190
217
|
}
|
|
191
218
|
|
|
192
219
|
/**
|
|
193
220
|
*
|
|
194
|
-
* @param {
|
|
221
|
+
* @param {VirtualTextureTile} tile
|
|
195
222
|
*/
|
|
196
223
|
#make_resident(tile) {
|
|
197
224
|
|
|
@@ -208,9 +235,13 @@ export class SparseTexture {
|
|
|
208
235
|
}
|
|
209
236
|
|
|
210
237
|
tile.page_slot = slot;
|
|
238
|
+
tile.last_used_time = this.update_count;
|
|
211
239
|
|
|
212
240
|
this.#page_slot_occupancy.set(slot, true);
|
|
213
241
|
this.#resident_tiles.push(tile);
|
|
242
|
+
this.#resident_tile_lookup.set(tile.finder_print, tile);
|
|
243
|
+
|
|
244
|
+
this.version++;
|
|
214
245
|
|
|
215
246
|
return true;
|
|
216
247
|
}
|
|
@@ -234,7 +265,7 @@ export class SparseTexture {
|
|
|
234
265
|
|
|
235
266
|
/**
|
|
236
267
|
*
|
|
237
|
-
* @param {
|
|
268
|
+
* @param {VirtualTextureUsage} usage
|
|
238
269
|
*/
|
|
239
270
|
update_usage(usage) {
|
|
240
271
|
const usage_occupancy = usage.occupancy;
|
|
@@ -256,17 +287,27 @@ export class SparseTexture {
|
|
|
256
287
|
|
|
257
288
|
const fingerPrint = tile_address_to_finger_print(tile_address);
|
|
258
289
|
|
|
259
|
-
|
|
290
|
+
let tile = this.#resident_tile_lookup.get(fingerPrint);
|
|
291
|
+
|
|
292
|
+
if (tile !== undefined) {
|
|
293
|
+
// already resident
|
|
294
|
+
|
|
295
|
+
// touch to prevent eviction
|
|
296
|
+
tile.last_used_time = this.update_count;
|
|
297
|
+
remaining_slots--;
|
|
298
|
+
fetch_limit--;
|
|
299
|
+
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
tile = this.#tile_cache.get(fingerPrint);
|
|
304
|
+
|
|
260
305
|
if (tile === null) {
|
|
261
306
|
this.#loader.enqueue(fingerPrint);
|
|
262
307
|
} else if (remaining_slots > 0) {
|
|
263
308
|
// found in cache, and we have some slots remaining to write into
|
|
264
309
|
|
|
265
|
-
|
|
266
|
-
// touch to prevent eviction
|
|
267
|
-
tile.last_used_time = this.#version;
|
|
268
|
-
|
|
269
|
-
if (tile.page_slot === -1 && writes_remaining > 0) {
|
|
310
|
+
if (writes_remaining > 0) {
|
|
270
311
|
// tile is not active, and we can write it
|
|
271
312
|
writes_remaining--;
|
|
272
313
|
this.#make_resident(tile);
|
|
@@ -280,12 +321,15 @@ export class SparseTexture {
|
|
|
280
321
|
|
|
281
322
|
this.#loader.update_usage(usage);
|
|
282
323
|
|
|
283
|
-
this
|
|
324
|
+
this.update_count++;
|
|
284
325
|
}
|
|
285
326
|
|
|
286
327
|
dispose() {
|
|
287
328
|
this.#page_texture.dispose();
|
|
288
329
|
this.#tile_cache.clear();
|
|
289
330
|
this.#page_slot_occupancy.reset();
|
|
331
|
+
|
|
332
|
+
this.#resident_tiles.splice(0, this.#resident_tiles.length);
|
|
333
|
+
this.#resident_tile_lookup.clear();
|
|
290
334
|
}
|
|
291
335
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { compose_tile_address } from "./tile/compose_tile_address.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents entire mip pyramid of tiles, where each tile slot points to an actual resident tile
|
|
5
|
+
*/
|
|
6
|
+
export class ResidentTileTexture {
|
|
7
|
+
#resolution = 0;
|
|
8
|
+
#pyramid = new Uint32Array(0);
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {number} resolution
|
|
14
|
+
*/
|
|
15
|
+
set resolution(resolution) {
|
|
16
|
+
this.#resolution = resolution;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
//max mip
|
|
20
|
+
const mip_level = Math.log2(resolution);
|
|
21
|
+
|
|
22
|
+
compose_tile_address(mip_level, 0, 0);
|
|
23
|
+
|
|
24
|
+
this.#pyramid = new Uint32Array(mip_level);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get resolution() {
|
|
28
|
+
return this.#resolution;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @param {PageTexture} page
|
|
34
|
+
*/
|
|
35
|
+
set residency(page) {
|
|
36
|
+
|
|
37
|
+
const tiles = page.resident_tiles;
|
|
38
|
+
const tile_count = tiles.length;
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < tile_count; i++) {
|
|
41
|
+
const tile = tiles[i];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
}
|
package/src/engine/graphics/texture/virtual/v2/{TileLoader.js → VirtualTextureTileLoader.js}
RENAMED
|
@@ -5,9 +5,12 @@ import { AssetManager } from "../../../../asset/AssetManager.js";
|
|
|
5
5
|
import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
6
6
|
import { compose_finger_print } from "./tile/compose_finger_print.js";
|
|
7
7
|
import { decompose_finger_print } from "./tile/decompose_finger_print.js";
|
|
8
|
-
import {
|
|
8
|
+
import { VirtualTextureTile } from "./tile/VirtualTextureTile.js";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Facilitates prioritized queueing and loading of individual texture tiles
|
|
12
|
+
*/
|
|
13
|
+
export class VirtualTextureTileLoader {
|
|
11
14
|
/**
|
|
12
15
|
* Where the tiles are stored
|
|
13
16
|
* @type {string}
|
|
@@ -38,7 +41,7 @@ export class TileLoader {
|
|
|
38
41
|
* How many tiles can be loaded at the same time
|
|
39
42
|
* @type {number}
|
|
40
43
|
*/
|
|
41
|
-
#concurrency =
|
|
44
|
+
#concurrency = 4;
|
|
42
45
|
|
|
43
46
|
/**
|
|
44
47
|
* Tiles that are currently being loaded
|
|
@@ -59,7 +62,7 @@ export class TileLoader {
|
|
|
59
62
|
*/
|
|
60
63
|
on = {
|
|
61
64
|
/**
|
|
62
|
-
* @type {Signal<
|
|
65
|
+
* @type {Signal<VirtualTextureTile>}
|
|
63
66
|
*/
|
|
64
67
|
loaded: new Signal()
|
|
65
68
|
};
|
|
@@ -127,7 +130,7 @@ export class TileLoader {
|
|
|
127
130
|
|
|
128
131
|
/**
|
|
129
132
|
*
|
|
130
|
-
* @param {
|
|
133
|
+
* @param {VirtualTextureUsage} usage
|
|
131
134
|
*/
|
|
132
135
|
#sort_queue_by_usage(usage) {
|
|
133
136
|
|
|
@@ -147,7 +150,7 @@ export class TileLoader {
|
|
|
147
150
|
|
|
148
151
|
/**
|
|
149
152
|
*
|
|
150
|
-
* @param {
|
|
153
|
+
* @param {VirtualTextureUsage} usage
|
|
151
154
|
*/
|
|
152
155
|
update_usage(usage) {
|
|
153
156
|
this.#sort_queue_by_usage(usage);
|
|
@@ -192,7 +195,7 @@ export class TileLoader {
|
|
|
192
195
|
* @param {number} mip
|
|
193
196
|
* @param {number} x
|
|
194
197
|
* @param {number} y
|
|
195
|
-
* @returns {Promise<
|
|
198
|
+
* @returns {Promise<VirtualTextureTile>}
|
|
196
199
|
*/
|
|
197
200
|
#load(mip, x, y) {
|
|
198
201
|
const file_name = this.#build_file_name(mip, x, y);
|
|
@@ -206,7 +209,7 @@ export class TileLoader {
|
|
|
206
209
|
|
|
207
210
|
const sampler = asset.create();
|
|
208
211
|
|
|
209
|
-
const tile = new
|
|
212
|
+
const tile = new VirtualTextureTile();
|
|
210
213
|
|
|
211
214
|
|
|
212
215
|
tile.data = sampler;
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { arrayQuickSort } from "../../../../../core/collection/array/arrayQuickSort.js";
|
|
2
|
-
import {
|
|
2
|
+
import { compose_tile_address } from "./tile/compose_tile_address.js";
|
|
3
3
|
import { finger_print_to_tile_address } from "./tile/finger_print_to_tile_address.js";
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
const finger_print = compose_finger_print(mip, x, y);
|
|
8
|
-
|
|
9
|
-
return finger_print_to_tile_address(finger_print);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class UsageMetadata {
|
|
6
|
+
export class VirtualTextureUsage {
|
|
13
7
|
|
|
14
8
|
#counts_intrinsic = new Uint32Array(0);
|
|
15
9
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ClampToEdgeWrapping,
|
|
3
|
+
DoubleSide,
|
|
3
4
|
GLSL3,
|
|
4
5
|
Matrix4,
|
|
5
6
|
NearestFilter,
|
|
@@ -18,8 +19,8 @@ import { max2 } from "../../../../../core/math/max2.js";
|
|
|
18
19
|
import { generate_halton_jitter } from "../../../generate_halton_jitter.js";
|
|
19
20
|
import { renderScreenSpace } from "../../../render/utils/renderScreenSpace.js";
|
|
20
21
|
import { Sampler2D } from "../../sampler/Sampler2D.js";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
22
|
+
import { VirtualTextureUsage } from "./VirtualTextureUsage.js";
|
|
23
|
+
import { fragment, vertex } from "./VirtualTextureUsageShader.js";
|
|
23
24
|
|
|
24
25
|
const usage_material_uniforms = {
|
|
25
26
|
"u_mt_params": { value: new Vector2(0.1, 1) },
|
|
@@ -40,6 +41,7 @@ const usage_material = new RawShaderMaterial({
|
|
|
40
41
|
uniforms: usage_material_uniforms,
|
|
41
42
|
vertexShader: vertex(),
|
|
42
43
|
fragmentShader: fragment(),
|
|
44
|
+
side: DoubleSide,
|
|
43
45
|
glslVersion: GLSL3
|
|
44
46
|
|
|
45
47
|
});
|
|
@@ -69,7 +71,7 @@ const clear_usage_material = new RawShaderMaterial({
|
|
|
69
71
|
|
|
70
72
|
const scratch_matrix = new Float32Array(16);
|
|
71
73
|
|
|
72
|
-
export class
|
|
74
|
+
export class VirtualTextureUsageUpdater {
|
|
73
75
|
|
|
74
76
|
#frame_index = 0;
|
|
75
77
|
|
|
@@ -79,7 +81,7 @@ export class VirtualTextureManager {
|
|
|
79
81
|
*/
|
|
80
82
|
#frame_jitter_offsets = new Float32Array([0, 0]);
|
|
81
83
|
#frame_jitter_samples = 1;
|
|
82
|
-
#frame_jitter_enabled =
|
|
84
|
+
#frame_jitter_enabled = false;
|
|
83
85
|
|
|
84
86
|
#initialize_frame_jitter() {
|
|
85
87
|
this.#frame_jitter_samples = this.#usage_resolution_scale;
|
|
@@ -109,7 +111,7 @@ export class VirtualTextureManager {
|
|
|
109
111
|
*/
|
|
110
112
|
#usage_resolution_scale = 32;
|
|
111
113
|
|
|
112
|
-
#usage_metadata = new
|
|
114
|
+
#usage_metadata = new VirtualTextureUsage();
|
|
113
115
|
|
|
114
116
|
#texture_id = 3;
|
|
115
117
|
#texture_resolution = 65536;
|
|
@@ -6,22 +6,28 @@ import { sampler2d_write_to_canvas_raw } from "../../../sampler/sampler2d_write_
|
|
|
6
6
|
export class ResidencyDebugView extends EmptyView {
|
|
7
7
|
/**
|
|
8
8
|
*
|
|
9
|
-
* @type {
|
|
9
|
+
* @type {PageTexture|null}
|
|
10
10
|
*/
|
|
11
11
|
texture = null;
|
|
12
12
|
|
|
13
13
|
#canvas = new CanvasView();
|
|
14
14
|
|
|
15
|
+
#previous_residency = new Uint32Array(1024);
|
|
16
|
+
|
|
15
17
|
constructor() {
|
|
16
18
|
super({
|
|
17
19
|
css: {
|
|
18
|
-
position: "absolute"
|
|
20
|
+
position: "absolute",
|
|
21
|
+
boxShadow: "0 0 8px black",
|
|
22
|
+
background: "black"
|
|
19
23
|
}
|
|
20
24
|
});
|
|
21
25
|
|
|
22
26
|
this.#canvas.css(CSS_ABSOLUTE_POSITIONING);
|
|
23
27
|
|
|
24
28
|
this.addChild(this.#canvas);
|
|
29
|
+
|
|
30
|
+
this.#previous_residency.fill(-1);
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
update() {
|
|
@@ -47,12 +53,18 @@ export class ResidencyDebugView extends EmptyView {
|
|
|
47
53
|
for (let i = 0; i < residentTiles.length; i++) {
|
|
48
54
|
const tile = residentTiles[i];
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
const page_slot = tile.page_slot;
|
|
57
|
+
if (this.#previous_residency[page_slot] === tile.finder_print) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
const
|
|
61
|
+
sampler2d_write_to_canvas_raw(tile.data, temp.el);
|
|
62
|
+
const column = page_slot % tile_columns;
|
|
63
|
+
const row = (page_slot / tile_columns) | 0;
|
|
54
64
|
|
|
55
65
|
canvas.context2d.drawImage(temp.el, 0, 0, tile_resolution, tile_resolution, tile_resolution * column, tile_resolution * row, tile_resolution, tile_resolution);
|
|
66
|
+
|
|
67
|
+
this.#previous_residency[page_slot] = tile.finder_print;
|
|
56
68
|
}
|
|
57
69
|
}
|
|
58
70
|
}
|