@woosh/meep-engine 2.34.49 → 2.35.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/core/bvh2/BinaryNode.js +19 -35
- package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +5 -5
- package/core/bvh2/aabb3_combined_surface_area.js +21 -0
- package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +24 -12
- package/core/cache/Cache.d.ts +2 -0
- package/core/cache/Cache.js +27 -23
- package/core/geom/3d/frustum/frustum_from_projection_matrix_array.js +2 -0
- package/core/math/max2.js +2 -6
- package/core/math/min2.js +2 -6
- package/engine/asset/loaders/geometry/geometry/computeGeometryEquality.js +1 -1
- package/engine/asset/loaders/geometry/geometry/computeGeometryHash.js +9 -1
- package/engine/ecs/EntityComponentDataset.js +7 -2
- package/engine/ecs/foliage/ViewState.js +13 -3
- package/engine/ecs/parent/EntityNode.js +23 -11
- package/engine/ecs/transform/Transform.js +15 -13
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +63 -26
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +63 -3
- package/engine/graphics/ecs/mesh-v2/render/AbstractRenderAdapter.js +67 -0
- package/engine/graphics/ecs/mesh-v2/render/GenericRendererAdapter.js +48 -0
- package/engine/graphics/ecs/mesh-v2/render/InstancedRendererAdapter.js +110 -0
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +98 -0
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +5 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -5
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +8 -3
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +23 -85
- package/engine/graphics/geometry/instancing/rewriteMaterial.js +9 -45
- package/engine/graphics/material/optimization/BUFFER_GEOMETRY_UVS.js +10 -0
- package/engine/graphics/material/optimization/MaterialDescriptor.js +46 -0
- package/engine/graphics/material/optimization/MaterialOptimizationContext.js +470 -201
- package/engine/graphics/material/optimization/UvContext.js +18 -0
- package/engine/graphics/material/optimization/is_compliant_mesh.js +71 -0
- package/engine/graphics/material/optimization/prepare_atlas_texture.js +23 -0
- package/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +127 -0
- package/engine/graphics/micron/format/MicronGeometryPatch.js +1 -1
- package/engine/graphics/micron/format/VirtualGeometry.js +47 -11
- package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +16 -0
- package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -2
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +5 -7
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +1 -45
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +18 -7
- package/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -1
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +17 -24
- package/engine/graphics/micron/render/v1/MaterialContext.js +3 -2
- package/engine/graphics/micron/render/v1/VGThreeRenderer.js +19 -4
- package/engine/graphics/render/utils/ThreeBypassRenderer.js +3 -2
- package/engine/graphics/texture/normalized_internal_format.js +48 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +6 -0
- package/engine/graphics/texture/sampler/sampler2d_copy_channel_data.js +25 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -0
- package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +14 -1
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
2
|
+
import AABB2 from "../../../../core/geom/AABB2.js";
|
|
3
|
+
|
|
4
|
+
export class UvContext {
|
|
5
|
+
constructor() {
|
|
6
|
+
/**
|
|
7
|
+
* Resolution of texture
|
|
8
|
+
* @type {Vector2}
|
|
9
|
+
*/
|
|
10
|
+
this.resolution = new Vector2(1, 1);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @type {AABB2}
|
|
15
|
+
*/
|
|
16
|
+
this.atlas_patch = new AABB2();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { TextureAttachmentsByMaterialType } from "../../../asset/loaders/material/TextureAttachmensByMaterialType.js";
|
|
2
|
+
import { max2 } from "../../../../core/math/max2.js";
|
|
3
|
+
import { BUFFER_GEOMETRY_UVS } from "./BUFFER_GEOMETRY_UVS.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Is this mesh qualified to be optimized?
|
|
7
|
+
* @param {THREE.Mesh} mesh
|
|
8
|
+
* @returns {boolean}
|
|
9
|
+
*/
|
|
10
|
+
export function is_compliant_mesh(mesh) {
|
|
11
|
+
const material = mesh.material;
|
|
12
|
+
|
|
13
|
+
const attachments = TextureAttachmentsByMaterialType[material.type];
|
|
14
|
+
|
|
15
|
+
const uv_scales = [1, 1, 1, 1];
|
|
16
|
+
|
|
17
|
+
const texture_attachment_count = attachments.length;
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < texture_attachment_count; i++) {
|
|
20
|
+
const attachment = attachments[i];
|
|
21
|
+
|
|
22
|
+
const texture = attachment.read(material);
|
|
23
|
+
if (texture === undefined || texture === null) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const uv_index = attachment.uv_index;
|
|
28
|
+
|
|
29
|
+
uv_scales[uv_index * 2] = max2(uv_scales[uv_index * 2], texture.repeat.x)
|
|
30
|
+
uv_scales[uv_index * 2 + 1] = max2(uv_scales[uv_index * 2 + 1], texture.repeat.y)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const geometry = mesh.geometry;
|
|
34
|
+
|
|
35
|
+
for (let i = 0; i < BUFFER_GEOMETRY_UVS.length; i++) {
|
|
36
|
+
const uv_metadata = BUFFER_GEOMETRY_UVS[i];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @type {THREE.BufferAttribute }
|
|
41
|
+
*/
|
|
42
|
+
const attribute = geometry.attributes[uv_metadata.name];
|
|
43
|
+
|
|
44
|
+
if (attribute === undefined) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const attribute_data = attribute.array;
|
|
49
|
+
const n = attribute_data.length;
|
|
50
|
+
|
|
51
|
+
const uv_index = uv_metadata.index;
|
|
52
|
+
const uv_index_2 = uv_index * 2;
|
|
53
|
+
|
|
54
|
+
for (let j = 0; j < n; j += 2) {
|
|
55
|
+
const x = attribute_data[j];
|
|
56
|
+
const y = attribute_data[j + 1];
|
|
57
|
+
|
|
58
|
+
const scaled_u = x * uv_scales[uv_index_2];
|
|
59
|
+
const scaled_v = y * uv_scales[uv_index_2 + 1];
|
|
60
|
+
|
|
61
|
+
if (scaled_u > 1 || scaled_u < 0 || scaled_v > 1 || scaled_v < 0) {
|
|
62
|
+
// repeating/negative UV value
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { LinearEncoding, LinearFilter, LinearMipmapLinearFilter, sRGBEncoding } from "three";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Texture} texture
|
|
6
|
+
* @param {string} attachment_name
|
|
7
|
+
*/
|
|
8
|
+
export function prepare_atlas_texture(texture, attachment_name) {
|
|
9
|
+
|
|
10
|
+
switch (attachment_name) {
|
|
11
|
+
case 'diffuse':
|
|
12
|
+
texture.encoding = sRGBEncoding;
|
|
13
|
+
break;
|
|
14
|
+
default:
|
|
15
|
+
texture.encoding = LinearEncoding;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
texture.anisotropy = 4;
|
|
19
|
+
texture.minFilter = LinearMipmapLinearFilter;
|
|
20
|
+
texture.magFilter = LinearFilter;
|
|
21
|
+
|
|
22
|
+
texture.generateMipmaps = true;
|
|
23
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { EngineHarness } from "../../../EngineHarness.js";
|
|
2
|
+
import { EngineConfiguration } from "../../../EngineConfiguration.js";
|
|
3
|
+
import { ShadedGeometrySystem } from "../../ecs/mesh-v2/ShadedGeometrySystem.js";
|
|
4
|
+
import { AttachmentSystem } from "../../../ecs/attachment/AttachmentSystem.js";
|
|
5
|
+
import { TransformAttachmentSystem } from "../../../ecs/transform-attachment/TransformAttachmentSystem.js";
|
|
6
|
+
import { GameAssetType } from "../../../asset/GameAssetType.js";
|
|
7
|
+
import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
|
|
8
|
+
import { three_object_to_entity_composition } from "../../ecs/mesh-v2/three_object_to_entity_composition.js";
|
|
9
|
+
import { MaterialOptimizationContext } from "./MaterialOptimizationContext.js";
|
|
10
|
+
import { bvh_traverse_pre_order_using_stack } from "../../../../core/bvh2/traversal/bvh_traverse_pre_order_using_stack.js";
|
|
11
|
+
|
|
12
|
+
const eh = new EngineHarness();
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param {Engine} engine
|
|
18
|
+
*/
|
|
19
|
+
function optimize(engine) {
|
|
20
|
+
MaterialOptimizationContext.MAX_TEXTURE_SIZE = engine.graphics.renderer.capabilities.maxTextureSize;
|
|
21
|
+
|
|
22
|
+
const optimizer = new MaterialOptimizationContext();
|
|
23
|
+
|
|
24
|
+
engine.graphics.layers.layers.forEach(l => {
|
|
25
|
+
bvh_traverse_pre_order_using_stack(l.bvh, node => {
|
|
26
|
+
if (node.isLeafNode) {
|
|
27
|
+
const object = l.extractRenderable(node.object);
|
|
28
|
+
|
|
29
|
+
if (object) {
|
|
30
|
+
optimizer.addObject(object);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
optimizer.update();
|
|
37
|
+
|
|
38
|
+
console.log(optimizer);
|
|
39
|
+
|
|
40
|
+
// drawSamplerHTML(document.body, optimizer.atlases.get('roughness'), 20, 20, 1, 0, 512);
|
|
41
|
+
// drawSamplerHTML(document.body, optimizer.atlases.get('metalness'), 532, 20, 1, 0, 512);
|
|
42
|
+
// drawSamplerHTML(document.body, optimizer.atlases.get('ao'), 20, 532, 1, 0, 512);
|
|
43
|
+
// drawSamplerHTML(document.body, optimizer.atlases.get('normal'), 532, 20, 1, 0, 512);
|
|
44
|
+
// drawSamplerHTML(document.body, optimizer.atlases.get('diffuse'), 20, 20, 1, 0, 1024);
|
|
45
|
+
// drawSamplerHTML(document.body, optimizer.atlases.get('normal'), 552, 20, 1, 0, 512);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param {EngineHarness} harness
|
|
51
|
+
* @return {Promise<void>}
|
|
52
|
+
*/
|
|
53
|
+
async function init(harness) {
|
|
54
|
+
const engine = harness.engine;
|
|
55
|
+
|
|
56
|
+
const config = new EngineConfiguration();
|
|
57
|
+
|
|
58
|
+
config.addSystem(new ShadedGeometrySystem(engine));
|
|
59
|
+
config.addSystem(new AttachmentSystem());
|
|
60
|
+
config.addSystem(new TransformAttachmentSystem());
|
|
61
|
+
|
|
62
|
+
const gltf_loader = new GLTFAssetLoader();
|
|
63
|
+
|
|
64
|
+
config.addLoader(GameAssetType.ModelGLTF_JSON, gltf_loader);
|
|
65
|
+
|
|
66
|
+
await config.apply(engine);
|
|
67
|
+
|
|
68
|
+
eh.initialize().then(main);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param {string} path
|
|
74
|
+
* @param {Engine} engine
|
|
75
|
+
*/
|
|
76
|
+
async function load_gltf(path, engine) {
|
|
77
|
+
const em = engine.entityManager;
|
|
78
|
+
|
|
79
|
+
const ecd = em.dataset;
|
|
80
|
+
|
|
81
|
+
const asset = await engine.assetManager.promise(path, GameAssetType.ModelGLTF_JSON);
|
|
82
|
+
|
|
83
|
+
const three_object = asset.create();
|
|
84
|
+
|
|
85
|
+
console.time('composition conversion');
|
|
86
|
+
const composition = three_object_to_entity_composition(three_object);
|
|
87
|
+
console.timeEnd('composition conversion');
|
|
88
|
+
|
|
89
|
+
console.time('composition build');
|
|
90
|
+
// console.profile('composition build');
|
|
91
|
+
composition.build(ecd);
|
|
92
|
+
// console.profileEnd('composition build');
|
|
93
|
+
console.timeEnd('composition build');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function timeout(t = 1) {
|
|
97
|
+
await new Promise((resolve, reject) => setTimeout(resolve, t));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
*
|
|
102
|
+
* @param {Engine} engine
|
|
103
|
+
*/
|
|
104
|
+
async function main(engine) {
|
|
105
|
+
|
|
106
|
+
EngineHarness.buildBasics({
|
|
107
|
+
engine,
|
|
108
|
+
enableWater: false,
|
|
109
|
+
enableTerrain: true
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// a small delay to let background tasks finish, so we can get better performance reading later on
|
|
113
|
+
timeout(2000);
|
|
114
|
+
|
|
115
|
+
await load_gltf('moicon/06_04_hapro/08-clickable-assets-new/model.gltf', engine);
|
|
116
|
+
// await load_gltf('moicon/06_04_hapro/05-ground-floor/model.gltf', engine);
|
|
117
|
+
|
|
118
|
+
optimize(engine);
|
|
119
|
+
|
|
120
|
+
// load_gltf('moicon/06_04_hapro/07-1st-basement/model.gltf', engine);
|
|
121
|
+
// load_gltf('moicon/06_04_hapro/06-lower-ground/model.gltf', engine);
|
|
122
|
+
// load_gltf('moicon/06_04_hapro/05-ground-floor/model.gltf', engine);
|
|
123
|
+
// load_gltf('moicon/06_04_hapro/04-1st-floor/model.gltf', engine);
|
|
124
|
+
// load_gltf('moicon/06_04_hapro/03-2nd-floor/model.gltf', engine);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
init(eh);
|
|
@@ -1,12 +1,31 @@
|
|
|
1
|
+
import { MicronGeometryPatchOccurrence } from "./MicronGeometryPatchOccurance.js";
|
|
2
|
+
|
|
1
3
|
export class VirtualGeometry {
|
|
2
4
|
constructor() {
|
|
5
|
+
/**
|
|
6
|
+
* pack patch instance as [INSTANCE_ID, GEOMETRY_ID, PATCH_ID]
|
|
7
|
+
* @type {number[]}
|
|
8
|
+
*/
|
|
9
|
+
this.patches = new Uint32Array(300000);
|
|
10
|
+
|
|
3
11
|
/**
|
|
4
12
|
*
|
|
5
|
-
* @type {
|
|
13
|
+
* @type {number}
|
|
6
14
|
*/
|
|
7
|
-
this.patches = [];
|
|
8
15
|
this.patch_count = 0;
|
|
9
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Lookup table of matrix transforms
|
|
19
|
+
* @type {number[][]}
|
|
20
|
+
*/
|
|
21
|
+
this.lookup_instance_transforms = [];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Lookup table of geometries
|
|
25
|
+
* @type {MicronGeometry[]}
|
|
26
|
+
*/
|
|
27
|
+
this.loolup_geometries = [];
|
|
28
|
+
|
|
10
29
|
/**
|
|
11
30
|
*
|
|
12
31
|
* @type {number}
|
|
@@ -30,11 +49,20 @@ export class VirtualGeometry {
|
|
|
30
49
|
*/
|
|
31
50
|
computeFaceCount() {
|
|
32
51
|
let r = 0;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
const patch_count = this.patch_count;
|
|
53
|
+
const patches = this.patches;
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < patch_count; i++) {
|
|
56
|
+
const i3 = i * 3;
|
|
57
|
+
|
|
58
|
+
const geometry_id = patches[i3 + 1];
|
|
59
|
+
const patch_id = patches[i3 + 2];
|
|
60
|
+
|
|
61
|
+
const geometry = this.loolup_geometries[geometry_id];
|
|
36
62
|
|
|
37
|
-
|
|
63
|
+
const patch = geometry.patches[patch_id];
|
|
64
|
+
|
|
65
|
+
r += patch.polygon_count;
|
|
38
66
|
}
|
|
39
67
|
|
|
40
68
|
return r;
|
|
@@ -46,11 +74,19 @@ export class VirtualGeometry {
|
|
|
46
74
|
*/
|
|
47
75
|
computeVertexCount() {
|
|
48
76
|
let r = 0;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
77
|
+
const patch_count = this.patch_count;
|
|
78
|
+
const patches = this.patches;
|
|
79
|
+
for (let i = 0; i < patch_count; i++) {
|
|
80
|
+
const i3 = i * 3;
|
|
81
|
+
|
|
82
|
+
const geometry_id = patches[i3 + 1];
|
|
83
|
+
const patch_id = patches[i3 + 2];
|
|
84
|
+
|
|
85
|
+
const geometry = this.loolup_geometries[geometry_id];
|
|
86
|
+
|
|
87
|
+
const patch = geometry.patches[patch_id];
|
|
52
88
|
|
|
53
|
-
r +=
|
|
89
|
+
r += patch.vertex_count;
|
|
54
90
|
}
|
|
55
91
|
|
|
56
92
|
return r;
|
|
@@ -61,7 +97,7 @@ export class VirtualGeometry {
|
|
|
61
97
|
* @param {MicronGeometryPatchOccurrence} patch
|
|
62
98
|
*/
|
|
63
99
|
add(patch) {
|
|
64
|
-
|
|
100
|
+
throw new Error('Deprecated');
|
|
65
101
|
}
|
|
66
102
|
|
|
67
103
|
clear() {
|
package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js
CHANGED
|
@@ -77,6 +77,10 @@ export class MicronGeometryBinarySerializationAdapter extends BinaryClassSeriali
|
|
|
77
77
|
|
|
78
78
|
const patch_count = buffer.readUintVar();
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* @type {MicronGeometryPatch[]}
|
|
83
|
+
*/
|
|
80
84
|
const patches = [];
|
|
81
85
|
|
|
82
86
|
// for the sake of speed, we will allocate all metadata in the same piece of memory to make traversal of patch hierarchy faster
|
|
@@ -94,14 +98,26 @@ export class MicronGeometryBinarySerializationAdapter extends BinaryClassSeriali
|
|
|
94
98
|
patches[i] = patch;
|
|
95
99
|
}
|
|
96
100
|
|
|
101
|
+
let source_triangle_count = 0;
|
|
102
|
+
// NOTE: we can't easily find out source vertex count as vertices are duplicated across patches
|
|
103
|
+
|
|
104
|
+
|
|
97
105
|
//read patches
|
|
98
106
|
for (let i = 0; i < patch_count; i++) {
|
|
99
107
|
const patch = patches[i];
|
|
100
108
|
|
|
101
109
|
deserialize_patch(buffer, patch, vertex_spec, patches);
|
|
110
|
+
|
|
111
|
+
// collect source metadata
|
|
112
|
+
if (patch.lod === 0) {
|
|
113
|
+
source_triangle_count += patch.polygon_count;
|
|
114
|
+
}
|
|
102
115
|
}
|
|
103
116
|
|
|
104
117
|
value.patches = patches;
|
|
105
118
|
value.root = patches[root_patch_index];
|
|
119
|
+
|
|
120
|
+
// write source metadata
|
|
121
|
+
value.source_triangle_count = source_triangle_count;
|
|
106
122
|
}
|
|
107
123
|
}
|
|
@@ -481,8 +481,9 @@ function init() {
|
|
|
481
481
|
// gltf_sample('moicon/03_Jan_22_Demo/8-assets/model.gltf');
|
|
482
482
|
// gltf_sample('moicon/03_Jan_22_Demo/worker_test/model.gltf');
|
|
483
483
|
// gltf_sample('moicon/A4/A4/model.gltf');
|
|
484
|
-
gltf_sample('moicon/
|
|
485
|
-
//
|
|
484
|
+
gltf_sample('moicon/06_04_hapro/08-clickable-assets-new/model.gltf');
|
|
485
|
+
// gltf_sample('moicon/ztest_object_many_pieces/model.gltf');
|
|
486
|
+
// gltf_grid('moicon/ztest_object_many_pieces/model.gltf', 3, 3);
|
|
486
487
|
|
|
487
488
|
document.addEventListener("mousemove", onDocumentMouseMove);
|
|
488
489
|
|
|
@@ -157,19 +157,17 @@ export class VirtualGeometryBuilder {
|
|
|
157
157
|
output.stats_source_triangle_count += geometry.source_triangle_count;
|
|
158
158
|
output.stats_source_vertex_count += geometry.source_vertex_count;
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
output.loolup_geometries[geometry.id] = geometry;
|
|
161
|
+
output.lookup_instance_transforms[instance_id] = transform;
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
output
|
|
163
|
+
// build up occurances
|
|
164
|
+
get_geometry_patch_cut(
|
|
165
|
+
output,
|
|
166
166
|
refinement_spec,
|
|
167
167
|
geometry,
|
|
168
168
|
instance_id,
|
|
169
169
|
transform
|
|
170
170
|
);
|
|
171
|
-
|
|
172
|
-
output.patch_count += added_patch_count;
|
|
173
171
|
}
|
|
174
172
|
|
|
175
173
|
clearScene() {
|
|
@@ -3,55 +3,11 @@ import { MICRON_PATCH_SIZE_MAX } from "../../build/MICRON_PATCH_SIZE_MAX.js";
|
|
|
3
3
|
import { typed_array_copy } from "../../../../../core/collection/array/typed/typed_array_copy.js";
|
|
4
4
|
import { channelCountToThreeTextureFormat } from "../../../texture/channelCountToThreeTextureFormat.js";
|
|
5
5
|
import { DataTexture, NearestFilter } from "three";
|
|
6
|
-
import { DataType } from "../../../../../core/collection/table/DataType.js";
|
|
7
6
|
import { compute_micron_buffer_array_constructor } from "../../build/compute_micron_buffer_array_constructor.js";
|
|
8
7
|
import { computeThreeTextureTypeFromDataType } from "../../../render/forward_plus/data/computeThreeTextureTypeFromDataType.js";
|
|
9
8
|
import { computeThreeTextureInternalFormatFromDataType } from "../../../render/forward_plus/data/computeThreeTextureInternalFormatFromDataType.js";
|
|
10
9
|
import { DataTypeByteSizes } from "../../../../../core/collection/table/DataTypeByteSizes.js";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @returns {string}
|
|
15
|
-
* @param {DataType} dt
|
|
16
|
-
* @param {number} channel_count
|
|
17
|
-
*/
|
|
18
|
-
function normalized_internal_format(dt, channel_count) {
|
|
19
|
-
let suffix = '';
|
|
20
|
-
switch (dt) {
|
|
21
|
-
case DataType.Uint8:
|
|
22
|
-
suffix = '8';
|
|
23
|
-
break;
|
|
24
|
-
case DataType.Int8:
|
|
25
|
-
suffix = '8_SNORM';
|
|
26
|
-
break;
|
|
27
|
-
case DataType.Uint16:
|
|
28
|
-
suffix = '16UI';
|
|
29
|
-
break;
|
|
30
|
-
default:
|
|
31
|
-
throw new Error(`Unsupported data type '${dt}'`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let prefix = '';
|
|
35
|
-
|
|
36
|
-
switch (channel_count) {
|
|
37
|
-
case 1:
|
|
38
|
-
prefix = 'R';
|
|
39
|
-
break;
|
|
40
|
-
case 2:
|
|
41
|
-
prefix = 'RG';
|
|
42
|
-
break;
|
|
43
|
-
case 3:
|
|
44
|
-
prefix = 'RGB';
|
|
45
|
-
break;
|
|
46
|
-
case 4:
|
|
47
|
-
prefix = 'RGBA';
|
|
48
|
-
break;
|
|
49
|
-
default:
|
|
50
|
-
throw new Error(`Unsupported channel count '${channel_count}'`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return prefix + suffix;
|
|
54
|
-
}
|
|
10
|
+
import { normalized_internal_format } from "../../../texture/normalized_internal_format.js";
|
|
55
11
|
|
|
56
12
|
export class AttributeDataTexture {
|
|
57
13
|
/**
|
|
@@ -132,15 +132,16 @@ export class ThreeInstancedAdapter {
|
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
134
|
*
|
|
135
|
-
* @param {
|
|
135
|
+
* @param {Uint32Array[]} patches
|
|
136
136
|
* @param {number} patch_count
|
|
137
|
+
* @param {VirtualGeometry} virtual_geometry
|
|
137
138
|
*/
|
|
138
|
-
build(patches, patch_count) {
|
|
139
|
+
build(patches, patch_count, virtual_geometry) {
|
|
139
140
|
this.__prepare_capacity(patch_count);
|
|
140
141
|
|
|
141
142
|
const geo = this.__buffer_geometry;
|
|
142
143
|
|
|
143
|
-
const patch_transform_attribute = geo.
|
|
144
|
+
const patch_transform_attribute = geo.attributes[ATTRIBUTE_NAME_TRANSFORM];
|
|
144
145
|
/**
|
|
145
146
|
*
|
|
146
147
|
* @type {Float32Array}
|
|
@@ -149,21 +150,31 @@ export class ThreeInstancedAdapter {
|
|
|
149
150
|
|
|
150
151
|
patch_transform_attribute.needsUpdate = true;
|
|
151
152
|
|
|
152
|
-
const patch_address_attribute = geo.
|
|
153
|
+
const patch_address_attribute = geo.attributes[ATTRIBUTE_NAME_ADDRESS];
|
|
153
154
|
const patch_address_array = patch_address_attribute.array;
|
|
154
155
|
|
|
155
156
|
patch_address_attribute.needsUpdate = true;
|
|
156
157
|
|
|
157
158
|
const patch_data = this.__patch_data;
|
|
159
|
+
const transforms = virtual_geometry.lookup_instance_transforms;
|
|
160
|
+
const geometries = virtual_geometry.loolup_geometries;
|
|
158
161
|
|
|
159
162
|
for (let i = 0; i < patch_count; i++) {
|
|
160
|
-
const
|
|
163
|
+
const i3 = i * 3;
|
|
164
|
+
|
|
165
|
+
const instance_id = patches[i3];
|
|
166
|
+
const geometry_id = patches[i3 + 1];
|
|
167
|
+
const patch_id = patches[i3 + 2];
|
|
168
|
+
|
|
169
|
+
const transform = transforms[instance_id];
|
|
170
|
+
const micron_geometry = geometries[geometry_id];
|
|
171
|
+
const patch = micron_geometry.patches[patch_id];
|
|
161
172
|
|
|
162
173
|
const i16 = i * 16;
|
|
163
174
|
|
|
164
|
-
patch_transform_array.set(
|
|
175
|
+
patch_transform_array.set(transform, i16);
|
|
165
176
|
|
|
166
|
-
const patch_slot_id = patch_data.ensure(
|
|
177
|
+
const patch_slot_id = patch_data.ensure(patch);
|
|
167
178
|
|
|
168
179
|
patch_address_array[i] = patch_slot_id;
|
|
169
180
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { BitSet } from "../../../../../core/binary/BitSet.js";
|
|
2
2
|
import { aabb3_intersects_frustum_array } from "../../../../../core/bvh2/aabb3/aabb3_intersects_frustum_array.js";
|
|
3
|
-
import { MicronGeometryPatchOccurrence } from "../../format/MicronGeometryPatchOccurance.js";
|
|
4
3
|
import { aabb3_estimate_projected_area2 } from "../../../../../core/geom/3d/aabb/aabb3_estimate_projected_area2.js";
|
|
5
4
|
|
|
6
5
|
|
|
@@ -12,24 +11,22 @@ const scratch_traversal_bitset = new BitSet();
|
|
|
12
11
|
scratch_traversal_bitset.preventShrink();
|
|
13
12
|
|
|
14
13
|
/**
|
|
14
|
+
* Using a pre-allocated continuous chunk of memory gets us better cache coherence
|
|
15
15
|
* @readonly
|
|
16
|
-
* @type {
|
|
16
|
+
* @type {number[]}
|
|
17
17
|
*/
|
|
18
|
-
const scratch_traversal_stack =
|
|
18
|
+
const scratch_traversal_stack = new Uint32Array(781250);
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
*
|
|
22
|
-
* @param {
|
|
23
|
-
* @param {number} destination_offset
|
|
22
|
+
* @param {VirtualGeometry} destination
|
|
24
23
|
* @param {RefinementSpec} spec
|
|
25
24
|
* @param {MicronGeometry} geometry
|
|
26
25
|
* @param instance_id
|
|
27
26
|
* @param transform
|
|
28
|
-
* @returns {number}
|
|
29
27
|
*/
|
|
30
28
|
export function get_geometry_patch_cut(
|
|
31
29
|
destination,
|
|
32
|
-
destination_offset,
|
|
33
30
|
spec,
|
|
34
31
|
geometry,
|
|
35
32
|
instance_id,
|
|
@@ -42,26 +39,29 @@ export function get_geometry_patch_cut(
|
|
|
42
39
|
|
|
43
40
|
const geometry_id = geometry.id;
|
|
44
41
|
|
|
45
|
-
let output_patch_cursor =
|
|
42
|
+
let output_patch_cursor = destination.patch_count;
|
|
46
43
|
|
|
47
44
|
let i;
|
|
48
45
|
let stack_cursor = 1;
|
|
49
|
-
let patch_instance;
|
|
50
46
|
|
|
51
47
|
// initialize stack
|
|
52
48
|
const stack = scratch_traversal_stack;
|
|
53
49
|
const root = geometry.root;
|
|
54
|
-
stack[0] = root;
|
|
50
|
+
stack[0] = root.id;
|
|
55
51
|
|
|
56
52
|
const included_set = scratch_traversal_bitset;
|
|
57
53
|
included_set.reset();
|
|
58
54
|
|
|
59
55
|
included_set.set(root.id, true);
|
|
60
56
|
|
|
57
|
+
const patches = geometry.patches;
|
|
58
|
+
const destination_patches = destination.patches;
|
|
59
|
+
|
|
61
60
|
while (stack_cursor > 0) {
|
|
62
61
|
stack_cursor--;
|
|
63
62
|
|
|
64
|
-
const
|
|
63
|
+
const patch_id = stack[stack_cursor];
|
|
64
|
+
const patch = patches[patch_id];
|
|
65
65
|
|
|
66
66
|
/*
|
|
67
67
|
check if node is in view frustum
|
|
@@ -96,7 +96,7 @@ export function get_geometry_patch_cut(
|
|
|
96
96
|
continue;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
stack[stack_cursor++] = child;
|
|
99
|
+
stack[stack_cursor++] = child.id;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
continue;
|
|
@@ -104,22 +104,15 @@ export function get_geometry_patch_cut(
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (patch_instance === undefined) {
|
|
110
|
-
// no instance available for reuse - create a new one
|
|
111
|
-
patch_instance = new MicronGeometryPatchOccurrence();
|
|
112
|
-
destination[output_patch_cursor] = patch_instance;
|
|
113
|
-
}
|
|
107
|
+
const target_address = output_patch_cursor * 3;
|
|
114
108
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
patch_instance.transform = transform;
|
|
109
|
+
destination_patches[target_address] = instance_id;
|
|
110
|
+
destination_patches[target_address + 1] = geometry_id;
|
|
111
|
+
destination_patches[target_address + 2] = patch_id;
|
|
119
112
|
|
|
120
113
|
output_patch_cursor++;
|
|
121
114
|
|
|
122
115
|
}
|
|
123
116
|
|
|
124
|
-
|
|
117
|
+
destination.patch_count = output_patch_cursor;
|
|
125
118
|
}
|
|
@@ -144,8 +144,9 @@ export class MaterialContext {
|
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
146
|
*
|
|
147
|
+
* @param {VirtualGeometry} virtual_geometry
|
|
147
148
|
*/
|
|
148
|
-
build() {
|
|
149
|
+
build(virtual_geometry) {
|
|
149
150
|
|
|
150
151
|
if (this.__patch_count === 0) {
|
|
151
152
|
this.mesh.visible = false;
|
|
@@ -154,7 +155,7 @@ export class MaterialContext {
|
|
|
154
155
|
this.mesh.visible = true;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
this.adapter.build(this.__patches, this.__patch_count);
|
|
158
|
+
this.adapter.build(this.__patches, this.__patch_count, virtual_geometry);
|
|
158
159
|
|
|
159
160
|
}
|
|
160
161
|
}
|