@woosh/meep-engine 2.73.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 +185 -189
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +185 -189
- 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/NativeImageDecoder.js +2 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +5 -6
- package/src/engine/asset/loaders/image/png/PNG.js +339 -332
- package/src/engine/asset/loaders/image/png/PNGReader.js +77 -30
- package/src/engine/asset/loaders/image/png/prototypePNG.js +13 -4
- package/src/engine/graphics/generate_halton_jitter.js +21 -0
- package/src/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +3 -20
- package/src/engine/graphics/texture/virtual/v2/PageTexture.js +335 -0
- package/src/engine/graphics/texture/virtual/v2/ResidentTileTexture.js +46 -0
- package/src/engine/graphics/texture/virtual/v2/{TileLoader.js → VirtualTextureTileLoader.js} +33 -13
- package/src/engine/graphics/texture/virtual/v2/{UsageMetadata.js → VirtualTextureUsage.js} +68 -22
- package/src/engine/graphics/texture/virtual/v2/{VirtualTextureManager.js → VirtualTextureUsageUpdater.js} +66 -9
- package/src/engine/graphics/texture/virtual/v2/debug/ResidencyDebugView.js +70 -0
- package/src/engine/graphics/texture/virtual/v2/debug/UsageDebugView.js +63 -0
- package/src/engine/graphics/texture/virtual/v2/{UsagePyramidDebugView.js → debug/UsagePyramidDebugView.js} +31 -40
- package/src/engine/graphics/texture/virtual/v2/prototype.js +98 -54
- package/src/engine/graphics/texture/virtual/v2/{TextureTile.js → tile/VirtualTextureTile.js} +3 -3
- package/src/engine/graphics/texture/virtual/v2/tile/compose_finger_print.js +23 -0
- package/src/engine/graphics/texture/virtual/v2/tile/compose_tile_address.js +26 -0
- package/src/engine/graphics/texture/virtual/v2/tile/decompose_finger_print.js +12 -0
- package/src/engine/graphics/texture/virtual/v2/tile/finger_print_to_tile_address.js +16 -0
- package/src/engine/graphics/texture/virtual/v2/{tile_index_to_finger_print.js → tile/tile_address_to_finger_print.js} +7 -3
- package/src/view/CSS_ABSOLUTE_POSITIONING.js +5 -0
- package/src/engine/graphics/texture/virtual/v2/SparseTexture.js +0 -182
- package/src/engine/graphics/texture/virtual/v2/UsageDebugView.js +0 -64
- package/src/engine/graphics/texture/virtual/v2/compose_finger_print.js +0 -13
- package/src/engine/graphics/texture/virtual/v2/finger_print_to_tile_index.js +0 -37
- /package/src/engine/graphics/texture/virtual/v2/{ShaderUsage.js → VirtualTextureUsageShader.js} +0 -0
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { assert } from "
|
|
2
|
-
import LabelView from "
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
top: 0,
|
|
8
|
-
left: 0
|
|
9
|
-
};
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import LabelView from "../../../../../../view/common/LabelView.js";
|
|
3
|
+
import { CSS_ABSOLUTE_POSITIONING } from "../../../../../../view/CSS_ABSOLUTE_POSITIONING.js";
|
|
4
|
+
import EmptyView from "../../../../../../view/elements/EmptyView.js";
|
|
5
|
+
import { decompose_finger_print } from "../tile/decompose_finger_print.js";
|
|
6
|
+
import { tile_address_to_finger_print } from "../tile/tile_address_to_finger_print.js";
|
|
10
7
|
|
|
11
8
|
class TextureLODView extends EmptyView {
|
|
12
9
|
|
|
@@ -22,7 +19,7 @@ class TextureLODView extends EmptyView {
|
|
|
22
19
|
resolution = [1, 1],
|
|
23
20
|
tile_size = 8
|
|
24
21
|
}) {
|
|
25
|
-
super({ css:
|
|
22
|
+
super({ css: CSS_ABSOLUTE_POSITIONING });
|
|
26
23
|
|
|
27
24
|
this.css({
|
|
28
25
|
background: "rgba(255,255,255,0.05)"
|
|
@@ -38,10 +35,11 @@ class TextureLODView extends EmptyView {
|
|
|
38
35
|
|
|
39
36
|
for (let j = 0; j < height; j++) {
|
|
40
37
|
for (let i = 0; i < width; i++) {
|
|
41
|
-
const tileView = new EmptyView({ css:
|
|
38
|
+
const tileView = new EmptyView({ css: CSS_ABSOLUTE_POSITIONING });
|
|
42
39
|
|
|
43
40
|
// const flipped_y = height - j - 1;
|
|
44
41
|
tileView.position.set(i * tile_size, j * tile_size);
|
|
42
|
+
// tileView.position.set(i * tile_size, flipped_y * tile_size);
|
|
45
43
|
tileView.size.set(tile_size, tile_size);
|
|
46
44
|
|
|
47
45
|
this.clearTile(tileView);
|
|
@@ -57,7 +55,7 @@ class TextureLODView extends EmptyView {
|
|
|
57
55
|
|
|
58
56
|
const label = new LabelView(`${width} x ${height}`, {
|
|
59
57
|
css: {
|
|
60
|
-
...
|
|
58
|
+
...CSS_ABSOLUTE_POSITIONING,
|
|
61
59
|
color: '#FFFFFF',
|
|
62
60
|
textShadow: '0 0 2px black',
|
|
63
61
|
whiteSpace: "pre"
|
|
@@ -193,17 +191,14 @@ export class UsagePyramidDebugView extends EmptyView {
|
|
|
193
191
|
|
|
194
192
|
/**
|
|
195
193
|
*
|
|
196
|
-
* @param {
|
|
194
|
+
* @param {VirtualTextureUsage} usage
|
|
197
195
|
*/
|
|
198
196
|
set usage(usage) {
|
|
199
197
|
|
|
200
198
|
for (let i = 0; i < this.#used_set_size; i++) {
|
|
201
199
|
const finger_print = this.#used_set[i];
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
const mip = (finger_print >> 24) & 0xFF;
|
|
205
|
-
const x = (finger_print >> 16) & 0xFF;
|
|
206
|
-
const y = (finger_print >> 8) & 0xFF;
|
|
201
|
+
const { mip, x, y } = decompose_finger_print(finger_print);
|
|
207
202
|
|
|
208
203
|
const mipView = this.#levels[mip];
|
|
209
204
|
|
|
@@ -214,38 +209,34 @@ export class UsagePyramidDebugView extends EmptyView {
|
|
|
214
209
|
this.#used_set_size = 0;
|
|
215
210
|
|
|
216
211
|
|
|
217
|
-
const
|
|
212
|
+
const occupancy = usage.occupancy;
|
|
213
|
+
const occupancyCount = usage.occupancy_count;
|
|
218
214
|
|
|
219
|
-
for (let
|
|
220
|
-
const
|
|
215
|
+
for (let i = 0; i < occupancyCount; i++) {
|
|
216
|
+
const occupancy_index = occupancy[i];
|
|
217
|
+
const fingerPrint = tile_address_to_finger_print(occupancy_index);
|
|
221
218
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
219
|
+
const count = usage.getCountByFingerprint(fingerPrint);
|
|
220
|
+
|
|
221
|
+
if (count <= 0) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
225
224
|
|
|
226
|
-
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
225
|
+
const { mip, x, y } = decompose_finger_print(fingerPrint);
|
|
229
226
|
|
|
230
|
-
const mipView = this.#levels[mip];
|
|
231
227
|
|
|
232
|
-
|
|
228
|
+
const mipView = this.#levels[mip];
|
|
233
229
|
|
|
234
|
-
|
|
235
|
-
background: "rgba(255,0,0,0.8)"
|
|
236
|
-
});
|
|
230
|
+
const tile = mipView.getTile(x, y);
|
|
237
231
|
|
|
238
|
-
|
|
232
|
+
tile.css({
|
|
233
|
+
background: "rgba(255,0,0,0.8)"
|
|
234
|
+
});
|
|
239
235
|
|
|
240
|
-
|
|
241
|
-
| (x << 16)
|
|
242
|
-
| (y << 8)
|
|
243
|
-
;
|
|
236
|
+
tile.visible = true;
|
|
244
237
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
}
|
|
238
|
+
this.#used_set[this.#used_set_size] = fingerPrint;
|
|
239
|
+
this.#used_set_size++;
|
|
249
240
|
}
|
|
250
241
|
|
|
251
242
|
}
|
|
@@ -3,12 +3,14 @@ import {
|
|
|
3
3
|
AmbientLight,
|
|
4
4
|
Clock,
|
|
5
5
|
DirectionalLight,
|
|
6
|
+
DoubleSide,
|
|
7
|
+
Matrix4,
|
|
6
8
|
Mesh,
|
|
7
|
-
|
|
9
|
+
MeshBasicMaterial,
|
|
8
10
|
PerspectiveCamera,
|
|
11
|
+
PlaneBufferGeometry,
|
|
9
12
|
Scene,
|
|
10
13
|
TextureLoader,
|
|
11
|
-
TorusGeometry,
|
|
12
14
|
Vector2,
|
|
13
15
|
WebGLRenderer
|
|
14
16
|
} from "three";
|
|
@@ -18,9 +20,11 @@ import EmptyView from "../../../../../view/elements/EmptyView.js";
|
|
|
18
20
|
import { AssetManager } from "../../../../asset/AssetManager.js";
|
|
19
21
|
import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
20
22
|
import { ImageRGBADataLoader } from "../../../../asset/loaders/image/ImageRGBADataLoader.js";
|
|
21
|
-
import {
|
|
22
|
-
import { UsageDebugView } from "./UsageDebugView.js";
|
|
23
|
-
import {
|
|
23
|
+
import { ResidencyDebugView } from "./debug/ResidencyDebugView.js";
|
|
24
|
+
import { UsageDebugView } from "./debug/UsageDebugView.js";
|
|
25
|
+
import { UsagePyramidDebugView } from "./debug/UsagePyramidDebugView.js";
|
|
26
|
+
import { PageTexture } from "./PageTexture.js";
|
|
27
|
+
import { VirtualTextureUsageUpdater } from "./VirtualTextureUsageUpdater.js";
|
|
24
28
|
|
|
25
29
|
let camera,
|
|
26
30
|
/**
|
|
@@ -35,61 +39,102 @@ let camera,
|
|
|
35
39
|
|
|
36
40
|
let mesh;
|
|
37
41
|
|
|
38
|
-
const
|
|
39
|
-
am.registerLoader(GameAssetType.Image, new ImageRGBADataLoader());
|
|
40
|
-
am.startup();
|
|
41
|
-
|
|
42
|
-
const virtualTextureManager = new VirtualTextureManager();
|
|
43
|
-
virtualTextureManager.setTextureParameters(
|
|
44
|
-
// 2048,
|
|
45
|
-
16384,
|
|
46
|
-
128,
|
|
47
|
-
3
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const sparseTexture = new SparseTexture();
|
|
51
|
-
sparseTexture.page_texture_size = [1024, 1024];
|
|
52
|
-
sparseTexture.tile_resolution = virtualTextureManager.tile_resolution;
|
|
53
|
-
sparseTexture.asset_manager = am;
|
|
54
|
-
|
|
55
|
-
console.log(sparseTexture);
|
|
56
|
-
|
|
57
|
-
// const TEXTURE_URL = "data/textures/utility/uv_map_reference.png";
|
|
42
|
+
const TEXTURE_URL = "data/textures/utility/uv_map_reference.png";
|
|
58
43
|
// const TEXTURE_URL = "data/textures/utility/4096x4096TexelDensityTexture1.png";
|
|
59
44
|
// const TEXTURE_URL = "data/textures/utility/Lenna.png";
|
|
60
45
|
// const TEXTURE_URL = "data/textures/utility/TESTIMAGES/SAMPLING/8BIT/RGB/2448x2448/SRC/img_2448x2448_3x8bit_SRC_RGB_cards_a.png";
|
|
61
|
-
const TEXTURE_URL = "data/models/LowPolyTownshipSet/Town_Hall//diffuse_2048.png";
|
|
62
|
-
|
|
63
|
-
const container_view = new EmptyView();
|
|
64
|
-
//
|
|
65
|
-
const usageDebugView = new UsageDebugView();
|
|
66
|
-
usageDebugView.mip_levels = virtualTextureManager.max_mip_level;
|
|
67
|
-
container_view.addChild(usageDebugView);
|
|
46
|
+
// const TEXTURE_URL = "data/models/LowPolyTownshipSet/Town_Hall//diffuse_2048.png";
|
|
68
47
|
|
|
48
|
+
const virtualTextureManager = new VirtualTextureUsageUpdater();
|
|
49
|
+
const sparseTexture = new PageTexture();
|
|
50
|
+
const residencyDebugView = new ResidencyDebugView();
|
|
69
51
|
|
|
70
|
-
|
|
71
|
-
// usagePyramidDebugView.setImageURL(TEXTURE_URL);
|
|
72
|
-
//
|
|
73
|
-
// container_view.addChild(usagePyramidDebugView);
|
|
52
|
+
const container_view = new EmptyView();
|
|
74
53
|
|
|
75
54
|
const options = {
|
|
76
|
-
spin:
|
|
55
|
+
spin: false
|
|
77
56
|
};
|
|
78
57
|
|
|
79
58
|
init();
|
|
80
|
-
animate();
|
|
81
59
|
|
|
82
|
-
|
|
83
|
-
function makeTorus() {
|
|
60
|
+
function makeMesh() {
|
|
84
61
|
const size = 0.65;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
62
|
+
|
|
63
|
+
const map = new TextureLoader().load(TEXTURE_URL);
|
|
64
|
+
map.flipY = false;
|
|
65
|
+
|
|
66
|
+
// const geo = new TetrahedronBufferGeometry(size,30);
|
|
67
|
+
// const geo = new TorusGeometry(size, 0.3, 30, 30);
|
|
68
|
+
const geo = new PlaneBufferGeometry(size, size);
|
|
69
|
+
|
|
70
|
+
mesh = new Mesh(geo, new MeshBasicMaterial({
|
|
71
|
+
map,
|
|
72
|
+
side: DoubleSide
|
|
88
73
|
}));
|
|
89
|
-
|
|
74
|
+
const m4 = new Matrix4();
|
|
75
|
+
|
|
76
|
+
// m4.makeRotationZ(-Math.PI/2);
|
|
77
|
+
m4.makeScale(1, -1, -1);
|
|
78
|
+
|
|
79
|
+
geo.applyMatrix4(m4);
|
|
80
|
+
|
|
81
|
+
// mesh.rotation.x = 0.3;
|
|
82
|
+
|
|
83
|
+
scene.add(mesh);
|
|
90
84
|
}
|
|
91
85
|
|
|
92
|
-
function
|
|
86
|
+
function makeGLTF(path) {
|
|
87
|
+
|
|
88
|
+
new GLTFLoader().load(path, (gltf) => {
|
|
89
|
+
|
|
90
|
+
mesh = gltf.scene;
|
|
91
|
+
scene.add(mesh);
|
|
92
|
+
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function init() {
|
|
97
|
+
|
|
98
|
+
const am = new AssetManager();
|
|
99
|
+
await am.registerLoader(GameAssetType.Image, new ImageRGBADataLoader());
|
|
100
|
+
am.startup();
|
|
101
|
+
|
|
102
|
+
virtualTextureManager.setTextureParameters(
|
|
103
|
+
2048,
|
|
104
|
+
// 16384,
|
|
105
|
+
32,
|
|
106
|
+
3
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
sparseTexture.path = "data/textures/utility/vt/uv_map_reference";
|
|
110
|
+
// sparseTexture.path = "data/textures/utility/vt/Lenna";
|
|
111
|
+
// sparseTexture.path = "data/textures/utility/vt/TexelDensity1";
|
|
112
|
+
sparseTexture.page_texture_size = [128, 768];
|
|
113
|
+
sparseTexture.tile_resolution = virtualTextureManager.tile_resolution;
|
|
114
|
+
sparseTexture.asset_manager = am;
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
console.log(sparseTexture);
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
//
|
|
121
|
+
const usageDebugView = new UsageDebugView();
|
|
122
|
+
usageDebugView.mip_levels = virtualTextureManager.max_mip_level;
|
|
123
|
+
// container_view.addChild(usageDebugView);
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
const usagePyramidDebugView = new UsagePyramidDebugView();
|
|
127
|
+
usagePyramidDebugView.setImageURL(TEXTURE_URL);
|
|
128
|
+
container_view.addChild(usagePyramidDebugView);
|
|
129
|
+
|
|
130
|
+
residencyDebugView.texture = sparseTexture;
|
|
131
|
+
residencyDebugView.css({
|
|
132
|
+
bottom: 0,
|
|
133
|
+
right: 0
|
|
134
|
+
});
|
|
135
|
+
container_view.addChild(residencyDebugView);
|
|
136
|
+
|
|
137
|
+
// ===================
|
|
93
138
|
|
|
94
139
|
const container = document.body;
|
|
95
140
|
|
|
@@ -98,20 +143,17 @@ function init() {
|
|
|
98
143
|
container.appendChild(container_view.el);
|
|
99
144
|
container_view.link();
|
|
100
145
|
|
|
101
|
-
camera = new PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1,
|
|
146
|
+
camera = new PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100);
|
|
102
147
|
camera.position.z = 4;
|
|
103
148
|
|
|
104
149
|
scene = new Scene();
|
|
105
150
|
|
|
106
151
|
clock = new Clock();
|
|
107
152
|
|
|
153
|
+
// makeTorus();
|
|
154
|
+
makeMesh();
|
|
108
155
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
mesh = gltf.scene;
|
|
112
|
-
scene.add(mesh);
|
|
113
|
-
|
|
114
|
-
});
|
|
156
|
+
// makeGLTF("data/models/LowPolyTownshipSet/Town_Hall/model.gltf");
|
|
115
157
|
|
|
116
158
|
scene.add(new DirectionalLight(0xFFFFFF, 0.7));
|
|
117
159
|
scene.add(new AmbientLight(0xFFFFFF, 0.2));
|
|
@@ -143,7 +185,7 @@ function init() {
|
|
|
143
185
|
gui.add(options, key);
|
|
144
186
|
});
|
|
145
187
|
|
|
146
|
-
|
|
188
|
+
animate();
|
|
147
189
|
}
|
|
148
190
|
|
|
149
191
|
function onWindowResize() {
|
|
@@ -185,8 +227,10 @@ function render() {
|
|
|
185
227
|
renderer.clear();
|
|
186
228
|
renderer.render(scene, camera)
|
|
187
229
|
|
|
188
|
-
usageDebugView.usage = virtualTextureManager.usage_metadata;
|
|
230
|
+
// usageDebugView.usage = virtualTextureManager.usage_metadata;
|
|
189
231
|
|
|
190
232
|
// usagePyramidDebugView.setTextureParameters(virtualTextureManager.texture_resolution, virtualTextureManager.tile_resolution);
|
|
191
233
|
// usagePyramidDebugView.usage = virtualTextureManager.usage_metadata;
|
|
234
|
+
|
|
235
|
+
residencyDebugView.update();
|
|
192
236
|
}
|
package/src/engine/graphics/texture/virtual/v2/{TextureTile.js → tile/VirtualTextureTile.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export class
|
|
1
|
+
export class VirtualTextureTile {
|
|
2
2
|
|
|
3
3
|
finder_print = 0;
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ export class TextureTile {
|
|
|
8
8
|
* Currently occupied page slot, only valid when page is resident
|
|
9
9
|
* @type {number}
|
|
10
10
|
*/
|
|
11
|
-
page_slot =
|
|
11
|
+
page_slot = -1;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
@@ -18,7 +18,7 @@ export class TextureTile {
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
*
|
|
21
|
-
* @param {
|
|
21
|
+
* @param {VirtualTextureTile} other
|
|
22
22
|
* @returns {boolean}
|
|
23
23
|
*/
|
|
24
24
|
equals(other) {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} mip
|
|
6
|
+
* @param {number} x
|
|
7
|
+
* @param {number} y
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
export function compose_finger_print(mip, x, y) {
|
|
11
|
+
// validate
|
|
12
|
+
assert.isNonNegativeInteger(x, 'x');
|
|
13
|
+
assert.isNonNegativeInteger(y, 'y');
|
|
14
|
+
assert.isNonNegativeInteger(mip, 'mip');
|
|
15
|
+
|
|
16
|
+
assert.lessThan(x, (1 << mip), 'x');
|
|
17
|
+
assert.lessThan(y, (1 << mip), 'y');
|
|
18
|
+
|
|
19
|
+
return (mip << 24)
|
|
20
|
+
| (x << 16)
|
|
21
|
+
| (y << 8)
|
|
22
|
+
;
|
|
23
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
2
|
+
import { split_by_2 } from "../../../../../../core/geom/3d/morton/split_by_2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {number} mip
|
|
7
|
+
* @param {number} x
|
|
8
|
+
* @param {number} y
|
|
9
|
+
* @returns {number}
|
|
10
|
+
*/
|
|
11
|
+
export function compose_tile_address(mip, x, y) {
|
|
12
|
+
|
|
13
|
+
// figure out resolution of this mip level
|
|
14
|
+
const mip_resolution = 1 << mip;
|
|
15
|
+
|
|
16
|
+
assert.lessThan(x, mip_resolution);
|
|
17
|
+
assert.lessThan(y, mip_resolution);
|
|
18
|
+
|
|
19
|
+
// this is basically converting something like 0100 to 0011;
|
|
20
|
+
const mip_mask = mip_resolution - 1;
|
|
21
|
+
|
|
22
|
+
// where data for this mip starts
|
|
23
|
+
const index_offset = split_by_2(mip_mask);
|
|
24
|
+
|
|
25
|
+
return index_offset + x + y * mip_resolution;
|
|
26
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} finger_print
|
|
4
|
+
* @returns {{mip: number, x: number, y: number}}
|
|
5
|
+
*/
|
|
6
|
+
export function decompose_finger_print(finger_print) {
|
|
7
|
+
const mip = (finger_print >> 24) & 0xFF;
|
|
8
|
+
const x = (finger_print >> 16) & 0xFF;
|
|
9
|
+
const y = (finger_print >> 8) & 0xFF;
|
|
10
|
+
|
|
11
|
+
return { mip, x, y };
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { compose_tile_address } from "./compose_tile_address.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} finger_print
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function finger_print_to_tile_address(finger_print) {
|
|
9
|
+
// decode fingerprint
|
|
10
|
+
const mip = (finger_print >> 24) & 0xFF;
|
|
11
|
+
const x = (finger_print >> 16) & 0xFF;
|
|
12
|
+
const y = (finger_print >> 8) & 0xFF;
|
|
13
|
+
|
|
14
|
+
return compose_tile_address(mip, x, y);
|
|
15
|
+
}
|
|
16
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { split_by_2 } from "
|
|
1
|
+
import { split_by_2 } from "../../../../../../core/geom/3d/morton/split_by_2.js";
|
|
2
2
|
import { compose_finger_print } from "./compose_finger_print.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -6,7 +6,7 @@ import { compose_finger_print } from "./compose_finger_print.js";
|
|
|
6
6
|
* @param {number} index
|
|
7
7
|
* @returns {number}
|
|
8
8
|
*/
|
|
9
|
-
export function
|
|
9
|
+
export function tile_address_to_finger_print(index) {
|
|
10
10
|
for (let mip = 0; mip < 99; mip++) {
|
|
11
11
|
const resolution = 1 << mip;
|
|
12
12
|
|
|
@@ -14,7 +14,11 @@ export function tile_index_to_finger_print(index) {
|
|
|
14
14
|
|
|
15
15
|
const index_offset = split_by_2(mip_mask);
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const next_mip_mask = mip_mask << 1 | 0x1;
|
|
18
|
+
|
|
19
|
+
const index_offset_next = split_by_2(next_mip_mask);
|
|
20
|
+
|
|
21
|
+
if (index >= index_offset_next) {
|
|
18
22
|
continue;
|
|
19
23
|
}
|
|
20
24
|
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { WebGLRenderTarget } from "three";
|
|
2
|
-
import { BitSet } from "../../../../../core/binary/BitSet.js";
|
|
3
|
-
import { Cache } from "../../../../../core/cache/Cache.js";
|
|
4
|
-
import { array_copy } from "../../../../../core/collection/array/array_copy.js";
|
|
5
|
-
import { passThrough, strictEquals } from "../../../../../core/function/Functions.js";
|
|
6
|
-
import { compose_finger_print } from "./compose_finger_print.js";
|
|
7
|
-
import { TileLoader } from "./TileLoader.js";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* How much extra data to store in cache (in bytes)
|
|
11
|
-
* @type {number}
|
|
12
|
-
*/
|
|
13
|
-
const DEFAULT_CACHE_SIZE = 16 * 1024 * 1024;
|
|
14
|
-
|
|
15
|
-
export class SparseTexture {
|
|
16
|
-
#page_texture = new WebGLRenderTarget(1, 1);
|
|
17
|
-
|
|
18
|
-
#page_texture_size = [1, 1];
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
* @type {TextureTile[]}
|
|
23
|
-
*/
|
|
24
|
-
#resident_tiles = [];
|
|
25
|
-
|
|
26
|
-
#page_slot_occupancy = new BitSet();
|
|
27
|
-
|
|
28
|
-
#tile_resolution = 128;
|
|
29
|
-
|
|
30
|
-
#residency_tile_capacity = 0;
|
|
31
|
-
|
|
32
|
-
#loader = new TileLoader();
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
* @type {AssetManager|null}
|
|
37
|
-
*/
|
|
38
|
-
#asset_manager = null;
|
|
39
|
-
|
|
40
|
-
set asset_manager(v) {
|
|
41
|
-
this.#asset_manager = v
|
|
42
|
-
|
|
43
|
-
this.#loader.asset_manager = v;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
#update_residency_capacity() {
|
|
47
|
-
const tile_resolution = this.#tile_resolution;
|
|
48
|
-
const size = this.#page_texture_size;
|
|
49
|
-
|
|
50
|
-
const x = size[0] / tile_resolution;
|
|
51
|
-
const y = size[1] / tile_resolution;
|
|
52
|
-
|
|
53
|
-
this.#residency_tile_capacity = x * y;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
* @param {number} v
|
|
60
|
-
*/
|
|
61
|
-
set tile_resolution(v) {
|
|
62
|
-
this.#tile_resolution = v;
|
|
63
|
-
|
|
64
|
-
this.#update_residency_capacity();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Tiles that are not currently resident live here
|
|
69
|
-
* key is the tile's "fingerprint"
|
|
70
|
-
* @type {Cache<number,TextureTile>}
|
|
71
|
-
*/
|
|
72
|
-
#tile_cache = new Cache({
|
|
73
|
-
keyHashFunction: passThrough,
|
|
74
|
-
keyEqualityFunction: strictEquals,
|
|
75
|
-
maxWeight: DEFAULT_CACHE_SIZE,
|
|
76
|
-
valueWeigher: () => this.#tile_resolution * this.#tile_resolution * 4
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
#find_eviction_target_index() {
|
|
80
|
-
// find least-recently used
|
|
81
|
-
const tiles = this.#resident_tiles;
|
|
82
|
-
const count = tiles.length;
|
|
83
|
-
|
|
84
|
-
let max = -1;
|
|
85
|
-
let max_index = -1;
|
|
86
|
-
|
|
87
|
-
for (let i = 0; i < count; i++) {
|
|
88
|
-
const tile = tiles[i];
|
|
89
|
-
|
|
90
|
-
if (tile.last_used_time > max) {
|
|
91
|
-
max = tile.last_used_time;
|
|
92
|
-
max_index = i;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return max_index;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
#evict_one() {
|
|
100
|
-
const index = this.#find_eviction_target_index();
|
|
101
|
-
|
|
102
|
-
if (index === -1) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return this.#remove_resident_tile(index);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
*
|
|
111
|
-
* @param {number} index
|
|
112
|
-
* @returns {boolean}
|
|
113
|
-
*/
|
|
114
|
-
#remove_resident_tile(index) {
|
|
115
|
-
const [removed] = this.#resident_tiles.splice(index, 1);
|
|
116
|
-
|
|
117
|
-
const pageSlot = removed.page_slot;
|
|
118
|
-
|
|
119
|
-
// mark slot as empty for next tile
|
|
120
|
-
this.#page_slot_occupancy.clear(pageSlot);
|
|
121
|
-
|
|
122
|
-
// push into cache
|
|
123
|
-
this.#tile_cache.put(removed.finder_print, removed);
|
|
124
|
-
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
*
|
|
130
|
-
* @param {number[]} v
|
|
131
|
-
*/
|
|
132
|
-
set page_texture_size(v) {
|
|
133
|
-
array_copy(
|
|
134
|
-
v, 0,
|
|
135
|
-
this.#page_texture_size, 0,
|
|
136
|
-
2
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
this.#page_texture.dispose();
|
|
140
|
-
this.#page_texture.setSize(this.#page_texture[0], this.#page_texture[1]);
|
|
141
|
-
|
|
142
|
-
this.#update_residency_capacity();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
*
|
|
147
|
-
* @param {UsageMetadata} usage
|
|
148
|
-
*/
|
|
149
|
-
update_usage(usage) {
|
|
150
|
-
const max_mip = usage.max_mip_level;
|
|
151
|
-
|
|
152
|
-
for (let mip = 0; mip < max_mip; mip++) {
|
|
153
|
-
|
|
154
|
-
const resolution = 1 << mip;
|
|
155
|
-
|
|
156
|
-
for (let y = 0; y < resolution; y++) {
|
|
157
|
-
for (let x = 0; x < resolution; x++) {
|
|
158
|
-
|
|
159
|
-
const count = usage.getCountBy(mip, x, y);
|
|
160
|
-
|
|
161
|
-
if (count === 0) {
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const fingerprint = compose_finger_print(mip, x, y);
|
|
166
|
-
|
|
167
|
-
this.#loader.enqueue(fingerprint);
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
this.#loader.update_usage(usage);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
dispose() {
|
|
178
|
-
this.#page_texture.dispose();
|
|
179
|
-
this.#tile_cache.clear();
|
|
180
|
-
this.#page_slot_occupancy.reset();
|
|
181
|
-
}
|
|
182
|
-
}
|