@woosh/meep-engine 2.34.44 → 2.34.48
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/binary/BitSet.js +4 -2
- package/core/bvh2/BinaryNode.js +53 -25
- package/core/bvh2/traversal/bvh_traverse_pre_order_using_stack.js +43 -0
- package/core/bvh2/visual/convert_bvh_to_dot_format_string.js +50 -0
- package/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +1 -1
- package/core/geom/3d/topology/TopoMesh.js +0 -8
- package/core/geom/3d/topology/TopoVertex.js +7 -6
- package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +93 -5
- package/core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js +7 -4
- package/core/geom/3d/topology/simplify/quadratic/compute_edge_collapse_cost_quadratic.js +7 -1
- package/core/geom/3d/topology/simplify/simplifyTopoMesh.js +1 -14
- package/core/graph/convertGraphToDotString.js +4 -4
- package/core/graph/v2/Graph.js +4 -0
- package/engine/ecs/foliage/ecs/Foliage2System.js +22 -5
- package/engine/graphics/compute_geometry_polycount.js +21 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +64 -9
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +4 -0
- package/engine/graphics/micron/build/hierarchy/merge_patches.js +1 -1
- package/engine/graphics/micron/convert_three_object_to_micron.js +2 -0
- package/engine/graphics/micron/format/MicronGeometry.js +1 -3
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +176 -0
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +1 -135
- package/engine/graphics/micron/prototypeVirtualGeometry.js +13 -8
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +10 -43
- package/engine/graphics/micron/render/refinement/ActivePatchList.js +2 -8
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +123 -0
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +316 -11
- package/engine/graphics/render/layers/RenderLayer.js +22 -14
- package/engine/graphics/render/visibility/IncrementalDeltaSet.js +18 -5
- package/engine/graphics/render/visibility/VisibilityComputer.js +11 -15
- package/package.json +1 -1
|
@@ -4,6 +4,15 @@ import EntityBuilder from "../../../../ecs/EntityBuilder.js";
|
|
|
4
4
|
import { Transform } from "../../../../ecs/transform/Transform.js";
|
|
5
5
|
import { ShadedGeometry } from "../ShadedGeometry.js";
|
|
6
6
|
import { BoxBufferGeometry, MeshBasicMaterial } from "three";
|
|
7
|
+
import { randomFloatBetween } from "../../../../../core/math/random/randomFloatBetween.js";
|
|
8
|
+
import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
|
|
9
|
+
import ViewportPosition from "../../../../ecs/gui/position/ViewportPosition.js";
|
|
10
|
+
import GUIElement from "../../../../ecs/gui/GUIElement.js";
|
|
11
|
+
import ButtonView from "../../../../../view/elements/button/ButtonView.js";
|
|
12
|
+
import { downloadAsFile } from "../../../../../core/binary/ByteArrayTools.js";
|
|
13
|
+
import { convert_bvh_to_dot_format_string } from "../../../../../core/bvh2/visual/convert_bvh_to_dot_format_string.js";
|
|
14
|
+
import ViewportPositionSystem from "../../../../ecs/gui/position/ViewportPositionSystem.js";
|
|
15
|
+
import GUIElementSystem from "../../../../ecs/gui/GUIElementSystem.js";
|
|
7
16
|
|
|
8
17
|
const eh = new EngineHarness();
|
|
9
18
|
|
|
@@ -26,22 +35,68 @@ async function main(engine) {
|
|
|
26
35
|
color: 0xFFFFFF
|
|
27
36
|
});
|
|
28
37
|
|
|
29
|
-
material.visible = false;
|
|
38
|
+
// material.visible = false;
|
|
30
39
|
|
|
31
40
|
window.material = material;
|
|
32
41
|
|
|
33
|
-
const
|
|
42
|
+
const geometry = new BoxBufferGeometry();
|
|
34
43
|
|
|
44
|
+
const random = seededRandom(0);
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < 100000; i++) {
|
|
47
|
+
|
|
48
|
+
new EntityBuilder()
|
|
49
|
+
.add(Transform.fromJSON({
|
|
50
|
+
position: {
|
|
51
|
+
x: randomFloatBetween(random, -50, 50),
|
|
52
|
+
y: randomFloatBetween(random, 0, 10),
|
|
53
|
+
z: randomFloatBetween(random, -50, 50)
|
|
54
|
+
},
|
|
55
|
+
scale: 0.01
|
|
56
|
+
}))
|
|
57
|
+
.add(ShadedGeometry.from(geometry, material))
|
|
58
|
+
.build(ecd);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
debug_button(engine, () => {
|
|
62
|
+
const dot = convert_bvh_to_dot_format_string(engine.graphics.layers.getLayerByName('shaded-geometry').bvh);
|
|
63
|
+
downloadAsFile(dot, 'bvh.dot', 'text');
|
|
64
|
+
|
|
65
|
+
}, 'save dot file');
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
const entityManager = engine.entityManager;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
* @param {Engine} engine
|
|
75
|
+
* @param {function} action
|
|
76
|
+
* @param {string} [name]
|
|
77
|
+
* @param {EntityComponentDataset} ecd
|
|
78
|
+
*/
|
|
79
|
+
function debug_button(engine, action, name = "Button", ecd = entityManager.dataset) {
|
|
80
|
+
if (entityManager.getSystem(ViewportPositionSystem) === null) {
|
|
81
|
+
entityManager.addSystem(new ViewportPositionSystem(engine.graphics.viewport.size));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (entityManager.getSystem(GUIElementSystem) === null) {
|
|
85
|
+
entityManager.addSystem(new GUIElementSystem(engine.gui.view, engine));
|
|
86
|
+
}
|
|
35
87
|
|
|
36
88
|
new EntityBuilder()
|
|
37
|
-
.add(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
89
|
+
.add(ViewportPosition.fromJSON({}))
|
|
90
|
+
.add(GUIElement.fromView(new ButtonView({
|
|
91
|
+
action,
|
|
92
|
+
name,
|
|
93
|
+
css: {
|
|
94
|
+
background: 'rgba(255,255,255,0.8)',
|
|
95
|
+
border: '1px solid black',
|
|
96
|
+
borderRadius: '4px',
|
|
97
|
+
padding: '2px',
|
|
42
98
|
}
|
|
43
|
-
}))
|
|
44
|
-
.add(g)
|
|
99
|
+
})))
|
|
45
100
|
.build(ecd);
|
|
46
101
|
}
|
|
47
102
|
|
|
@@ -15,6 +15,7 @@ import { compute_buffer_geometry_byte_size } from "../../geometry/buffered/compu
|
|
|
15
15
|
import { deinterleaveBufferGeometry } from "../../geometry/buffered/deinterleaveBufferGeometry.js";
|
|
16
16
|
import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
|
|
17
17
|
import { aabb3_from_v3_array } from "../../../../core/bvh2/aabb3/aabb3_from_v3_array.js";
|
|
18
|
+
import { update_topo_face_normals } from "../../../../core/geom/3d/topology/update_topo_face_normals.js";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Returns current time in milliseconds
|
|
@@ -142,6 +143,9 @@ export async function buildMicronGeometryFromBufferGeometry(input) {
|
|
|
142
143
|
|
|
143
144
|
expandConnectivityByLocality(topoMesh, geometry_aabb);
|
|
144
145
|
|
|
146
|
+
// ensure faces have normals for mesh simplification
|
|
147
|
+
update_topo_face_normals(Array.from(topoMesh.getFaces()), topoMesh.getFaces().size);
|
|
148
|
+
|
|
145
149
|
/**
|
|
146
150
|
* Used to generate neighbourhood assignment
|
|
147
151
|
* @type {Map<number, PatchRepresentation>}
|
|
@@ -399,7 +399,6 @@ async function many_to_many_merge(
|
|
|
399
399
|
collapse_edges(
|
|
400
400
|
num_desired_faces_to_remove,
|
|
401
401
|
open_set,
|
|
402
|
-
[],
|
|
403
402
|
merged_mesh,
|
|
404
403
|
edge_to_collapse_map,
|
|
405
404
|
vertex_quadratics,
|
|
@@ -462,6 +461,7 @@ async function many_to_many_merge(
|
|
|
462
461
|
// );
|
|
463
462
|
|
|
464
463
|
const group_per_pixel_error = group_inverse_polycount;
|
|
464
|
+
// const group_per_pixel_error = Math.sqrt(largest_squared_error);
|
|
465
465
|
|
|
466
466
|
// split topology into desired number of pieces
|
|
467
467
|
const pieces = recursive_split_mesh_partition(merged_mesh, actual_up_count, MICRON_PATCH_SIZE_MAX);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { AssetTransformer } from "../../../asset/AssetTransformer.js";
|
|
2
|
+
import { MicronGeometryBinarySerializationAdapter } from "../format/serialization/MicronGeometryBinarySerializationAdapter.js";
|
|
3
|
+
import { MICRON_URI_FIELD } from "../MICRON_URI_FIELD.js";
|
|
4
|
+
import { computePathDirectory } from "../../../../core/FilePath.js";
|
|
5
|
+
import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
|
|
6
|
+
import { MicronGeometry } from "../format/MicronGeometry.js";
|
|
7
|
+
import { MICRON_GEOMETRY_FIELD } from "../MICRON_GEOMETRY_FIELD.js";
|
|
8
|
+
import { async_traverse_three_object } from "../../../asset/loaders/async_traverse_three_object.js";
|
|
9
|
+
import { convert_three_object_to_micron } from "../convert_three_object_to_micron.js";
|
|
10
|
+
import { compute_geometry_polycount } from "../../compute_geometry_polycount.js";
|
|
11
|
+
import { traverseThreeObject } from "../../ecs/highlight/renderer/traverseThreeObject.js";
|
|
12
|
+
import { max2 } from "../../../../core/math/max2.js";
|
|
13
|
+
|
|
14
|
+
export const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
|
|
15
|
+
|
|
16
|
+
const DEFAULT_THRESHOLD_POLYCOUNT = 1024;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {THREE.Object3D} object
|
|
21
|
+
* @return {number}
|
|
22
|
+
*/
|
|
23
|
+
function max_polycount(object) {
|
|
24
|
+
let r = 0;
|
|
25
|
+
|
|
26
|
+
traverseThreeObject(object, (m) => {
|
|
27
|
+
if (m.isMesh) {
|
|
28
|
+
const geo = m.geometry;
|
|
29
|
+
if (geo !== null) {
|
|
30
|
+
r = max2(r, compute_geometry_polycount(geo))
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return r;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class GLTFAssetTransformer extends AssetTransformer {
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} cache
|
|
42
|
+
*/
|
|
43
|
+
constructor(cache) {
|
|
44
|
+
super();
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
this.__cache = cache;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @type {AssetManager|null}
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
this.__am = null;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Minimum number of polygons required for micron to be used
|
|
62
|
+
* @type {number}
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
this.__threshold_polycount = DEFAULT_THRESHOLD_POLYCOUNT;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @type {MicronGeometryBinarySerializationAdapter}
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
this.__serde = new MicronGeometryBinarySerializationAdapter();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param {AssetManager|null} am
|
|
78
|
+
*/
|
|
79
|
+
set assetManager(am) {
|
|
80
|
+
this.__am = am;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {THREE.Object3D} object
|
|
86
|
+
* @param {{asset:AssetDescription}} ctx
|
|
87
|
+
* @return {Promise<void>}
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
async __visitObjectToLoadMicron(object, ctx) {
|
|
91
|
+
if (!object.isMesh) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @type {THREE.BufferGeometry}
|
|
97
|
+
*/
|
|
98
|
+
const geometry = object.geometry;
|
|
99
|
+
|
|
100
|
+
const micron_uri = geometry.userData[MICRON_URI_FIELD];
|
|
101
|
+
|
|
102
|
+
if (typeof micron_uri !== "string") {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @type {AssetDescription}
|
|
109
|
+
*/
|
|
110
|
+
const ad = ctx.asset;
|
|
111
|
+
|
|
112
|
+
const base = computePathDirectory(ad.path);
|
|
113
|
+
|
|
114
|
+
let micron_data;
|
|
115
|
+
|
|
116
|
+
const micron_path = `${base}/${micron_uri}`;
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
micron_data = await this.__am.promise(micron_path, ASSET_TYPE_ARRAY_BUFFER);
|
|
120
|
+
} catch (e) {
|
|
121
|
+
console.error(`Failed to load micron geometry '${micron_path}' referenced in GLTF (will skip): ${e}`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// deserialize micron data
|
|
126
|
+
const buffer = BinaryBuffer.fromArrayBuffer(micron_data.create());
|
|
127
|
+
const micron_geometry = new MicronGeometry();
|
|
128
|
+
|
|
129
|
+
this.__serde.deserialize(buffer, micron_geometry);
|
|
130
|
+
|
|
131
|
+
// set proxy for raycasting
|
|
132
|
+
micron_geometry.proxy = geometry;
|
|
133
|
+
|
|
134
|
+
geometry[MICRON_GEOMETRY_FIELD] = micron_geometry;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
*
|
|
140
|
+
* @param {Asset} source
|
|
141
|
+
* @param {AssetDescription} asset_description
|
|
142
|
+
* @return {Promise<Asset>}
|
|
143
|
+
*/
|
|
144
|
+
async transform(source, asset_description) {
|
|
145
|
+
const animationClips = source.animations;
|
|
146
|
+
|
|
147
|
+
if (animationClips !== undefined && animationClips.length > 0) {
|
|
148
|
+
// animations might cause trouble
|
|
149
|
+
console.warn(`model '${asset_description.path}' contains animations, these animations might not works as intended with micron.`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @type {THREE.Object3D}
|
|
154
|
+
*/
|
|
155
|
+
const root = source.create();
|
|
156
|
+
|
|
157
|
+
const gltf_max_polycount = max_polycount(root);
|
|
158
|
+
|
|
159
|
+
if (gltf_max_polycount < this.__threshold_polycount) {
|
|
160
|
+
// no change, geometries are too small
|
|
161
|
+
return source;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// attempt to load existing micron geometries
|
|
165
|
+
await async_traverse_three_object(root, this.__visitObjectToLoadMicron, this, {
|
|
166
|
+
asset: asset_description
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const micron_root = await convert_three_object_to_micron(root.clone(), this.__cache);
|
|
170
|
+
micron_root.boundingSphere = root.boundingSphere;
|
|
171
|
+
|
|
172
|
+
source.override_mesh = micron_root;
|
|
173
|
+
|
|
174
|
+
return source;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -2,8 +2,6 @@ import { EnginePlugin } from "../../../plugin/EnginePlugin.js";
|
|
|
2
2
|
import { VGThreeRenderer } from "../render/v1/VGThreeRenderer.js";
|
|
3
3
|
import { RenderLayer } from "../../render/layers/RenderLayer.js";
|
|
4
4
|
import { RenderPassType } from "../../render/RenderPassType.js";
|
|
5
|
-
import { AssetTransformer } from "../../../asset/AssetTransformer.js";
|
|
6
|
-
import { convert_three_object_to_micron } from "../convert_three_object_to_micron.js";
|
|
7
5
|
import { Cache } from "../../../../core/cache/Cache.js";
|
|
8
6
|
import { computeGeometryHash } from "../../../asset/loaders/geometry/geometry/computeGeometryHash.js";
|
|
9
7
|
import { computeGeometryEquality } from "../../../asset/loaders/geometry/geometry/computeGeometryEquality.js";
|
|
@@ -12,13 +10,9 @@ import { AsyncRemoteHashMap } from "../../../../core/collection/map/AsyncRemoteH
|
|
|
12
10
|
import { BufferGeometrySerializationAdapter } from "./serialization/BufferGeometrySerializationAdapter.js";
|
|
13
11
|
import { MicronGeometryBinarySerializationAdapter } from "../format/serialization/MicronGeometryBinarySerializationAdapter.js";
|
|
14
12
|
import { AsyncMapWrapper } from "../../../../core/collection/map/AsyncMapWrapper.js";
|
|
15
|
-
import { async_traverse_three_object } from "../../../asset/loaders/async_traverse_three_object.js";
|
|
16
|
-
import { computePathDirectory } from "../../../../core/FilePath.js";
|
|
17
|
-
import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
|
|
18
13
|
import { MicronGeometry } from "../format/MicronGeometry.js";
|
|
19
14
|
import { ArrayBufferLoader } from "../../../asset/loaders/ArrayBufferLoader.js";
|
|
20
|
-
import {
|
|
21
|
-
import { MICRON_GEOMETRY_FIELD } from "../MICRON_GEOMETRY_FIELD.js";
|
|
15
|
+
import { ASSET_TYPE_ARRAY_BUFFER, GLTFAssetTransformer } from "./GLTFAssetTransformer.js";
|
|
22
16
|
|
|
23
17
|
/**
|
|
24
18
|
*
|
|
@@ -26,134 +20,6 @@ import { MICRON_GEOMETRY_FIELD } from "../MICRON_GEOMETRY_FIELD.js";
|
|
|
26
20
|
*/
|
|
27
21
|
const STORAGE_KEY = '@plugin/virtual-geometry-micron/geometry-cache';
|
|
28
22
|
|
|
29
|
-
const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
|
|
30
|
-
|
|
31
|
-
class GLTFAssetTransformer extends AssetTransformer {
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} cache
|
|
35
|
-
*/
|
|
36
|
-
constructor(cache) {
|
|
37
|
-
super();
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>}
|
|
42
|
-
* @private
|
|
43
|
-
*/
|
|
44
|
-
this.__cache = cache;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @type {AssetManager|null}
|
|
49
|
-
* @private
|
|
50
|
-
*/
|
|
51
|
-
this.__am = null;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @type {MicronGeometryBinarySerializationAdapter}
|
|
56
|
-
* @private
|
|
57
|
-
*/
|
|
58
|
-
this.__serde = new MicronGeometryBinarySerializationAdapter();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
* @param {AssetManager|null} am
|
|
64
|
-
*/
|
|
65
|
-
set assetManager(am) {
|
|
66
|
-
this.__am = am;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @param {THREE.Object3D} object
|
|
72
|
-
* @param {{asset:AssetDescription}} ctx
|
|
73
|
-
* @return {Promise<void>}
|
|
74
|
-
* @private
|
|
75
|
-
*/
|
|
76
|
-
async __visitObjectToLoadMicron(object, ctx) {
|
|
77
|
-
if (!object.isMesh) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @type {THREE.BufferGeometry}
|
|
83
|
-
*/
|
|
84
|
-
const geometry = object.geometry;
|
|
85
|
-
|
|
86
|
-
const micron_uri = geometry.userData[MICRON_URI_FIELD];
|
|
87
|
-
|
|
88
|
-
if (typeof micron_uri !== "string") {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* @type {AssetDescription}
|
|
95
|
-
*/
|
|
96
|
-
const ad = ctx.asset;
|
|
97
|
-
|
|
98
|
-
const base = computePathDirectory(ad.path);
|
|
99
|
-
|
|
100
|
-
let micron_data;
|
|
101
|
-
|
|
102
|
-
const micron_path = `${base}/${micron_uri}`;
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
micron_data = await this.__am.promise(micron_path, ASSET_TYPE_ARRAY_BUFFER);
|
|
106
|
-
} catch (e) {
|
|
107
|
-
console.error(`Failed to load micron geometry '${micron_path}' referenced in GLTF (will skip): ${e}`);
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// deserialize micron data
|
|
112
|
-
const buffer = BinaryBuffer.fromArrayBuffer(micron_data.create());
|
|
113
|
-
const micron_geometry = new MicronGeometry();
|
|
114
|
-
|
|
115
|
-
this.__serde.deserialize(buffer, micron_geometry);
|
|
116
|
-
|
|
117
|
-
// set proxy for raycasting
|
|
118
|
-
micron_geometry.proxy = geometry;
|
|
119
|
-
|
|
120
|
-
geometry[MICRON_GEOMETRY_FIELD] = micron_geometry;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
* @param {Asset} source
|
|
127
|
-
* @param {AssetDescription} asset_description
|
|
128
|
-
* @return {Promise<Asset>}
|
|
129
|
-
*/
|
|
130
|
-
async transform(source, asset_description) {
|
|
131
|
-
const animationClips = source.animations;
|
|
132
|
-
|
|
133
|
-
if (animationClips !== undefined && animationClips.length > 0) {
|
|
134
|
-
// animations might cause trouble
|
|
135
|
-
console.warn(`model '${asset_description.path}' contains animations, these animations might not works as intended with micron.`);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* @type {THREE.Object3D}
|
|
140
|
-
*/
|
|
141
|
-
const root = source.create();
|
|
142
|
-
|
|
143
|
-
// attempt to load existing micron geometries
|
|
144
|
-
await async_traverse_three_object(root, this.__visitObjectToLoadMicron, this, {
|
|
145
|
-
asset: asset_description
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
const micron_root = await convert_three_object_to_micron(root.clone(), this.__cache);
|
|
149
|
-
micron_root.boundingSphere = root.boundingSphere;
|
|
150
|
-
|
|
151
|
-
source.override_mesh = micron_root;
|
|
152
|
-
|
|
153
|
-
return source;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
23
|
export class MicronRenderPlugin extends EnginePlugin {
|
|
158
24
|
constructor() {
|
|
159
25
|
super();
|
|
@@ -48,7 +48,6 @@ import { CanvasView } from "../../../view/elements/CanvasView.js";
|
|
|
48
48
|
import { Sampler2D } from "../texture/sampler/Sampler2D.js";
|
|
49
49
|
import { downsampleSampler2D } from "../texture/sampler/downsampleSampler2D.js";
|
|
50
50
|
import { ShadowMapRenderer } from "../shadows/ShadowMapRenderer.js";
|
|
51
|
-
import { MouseEvents } from "../../input/devices/events/MouseEvents.js";
|
|
52
51
|
import { mat4 } from "gl-matrix";
|
|
53
52
|
|
|
54
53
|
const background = new TextureLoader().load('data/textures/utility/checkers_white_grey_256x256.png');
|
|
@@ -262,8 +261,8 @@ function init() {
|
|
|
262
261
|
|
|
263
262
|
// shadow_camera.onBeforeRender = do_vgrt_update;
|
|
264
263
|
|
|
265
|
-
scene.add(new CameraHelper(shadow_camera));
|
|
266
|
-
scene.add(new DirectionalLightHelper(directionalLight));
|
|
264
|
+
// scene.add(new CameraHelper(shadow_camera));
|
|
265
|
+
// scene.add(new DirectionalLightHelper(directionalLight));
|
|
267
266
|
|
|
268
267
|
shadow_camera.updateProjectionMatrix();
|
|
269
268
|
|
|
@@ -460,14 +459,15 @@ function init() {
|
|
|
460
459
|
|
|
461
460
|
// sample_gltf_sponza();
|
|
462
461
|
// gltf_sample('data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf');
|
|
463
|
-
sample_lucy();
|
|
462
|
+
// sample_lucy();
|
|
463
|
+
// sample_dragon();
|
|
464
464
|
// sample_gltf_hapro_2();
|
|
465
465
|
// sample_gltf_hapro_1();
|
|
466
466
|
// sample_gltf_broken_isiflow();
|
|
467
467
|
// gltf_grid('data/models/moicon/Kople/EVCharger1.gltf');
|
|
468
468
|
// gltf_grid('data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf');
|
|
469
|
-
// gltf_sample('
|
|
470
|
-
// gltf_sample('
|
|
469
|
+
// gltf_sample('moicon/08-clickable-assets/model.gltf');
|
|
470
|
+
// gltf_sample('moicon/05-ground-floor/model.gltf');
|
|
471
471
|
// gltf_sample('data/models/moicon/isiflow_Oct_15_21/0/model.gltf');
|
|
472
472
|
// gltf_sample('moicon/29_Dec_2021_Nammo/1/model.gltf');
|
|
473
473
|
// gltf_sample('moicon/29_Dec_2021_Nammo/1-onematerial/model.gltf');
|
|
@@ -479,6 +479,8 @@ function init() {
|
|
|
479
479
|
// gltf_sample('moicon/03_Jan_22_Demo/8-assets/model.gltf');
|
|
480
480
|
// gltf_sample('moicon/03_Jan_22_Demo/worker_test/model.gltf');
|
|
481
481
|
// gltf_sample('moicon/A4/A4/model.gltf');
|
|
482
|
+
gltf_sample('moicon/ztest_object_many_pieces/model.gltf');
|
|
483
|
+
// gltf_grid('moicon/ztest_object_many_pieces/model.gltf', 3, 3);
|
|
482
484
|
|
|
483
485
|
document.addEventListener("mousemove", onDocumentMouseMove);
|
|
484
486
|
|
|
@@ -546,6 +548,7 @@ function onWindowResize() {
|
|
|
546
548
|
* @param {number} scale
|
|
547
549
|
*/
|
|
548
550
|
function createScene(geometry, m1, scale) {
|
|
551
|
+
|
|
549
552
|
geometry.computeVertexNormals();
|
|
550
553
|
|
|
551
554
|
|
|
@@ -798,7 +801,7 @@ function render() {
|
|
|
798
801
|
// console.log(`patches:${active_patches.length}, polycount:${polycount}`);
|
|
799
802
|
}
|
|
800
803
|
|
|
801
|
-
|
|
804
|
+
const raycast_handler = ({ clientX, clientY }) => {
|
|
802
805
|
const direction = new Vector3();
|
|
803
806
|
|
|
804
807
|
const viewport_size = new Vector2();
|
|
@@ -858,5 +861,7 @@ window.document.body.addEventListener(MouseEvents.Move, ({ clientX, clientY }) =
|
|
|
858
861
|
if (hits.length > 0) {
|
|
859
862
|
console.log(`HITS: ${hits.map(JSON.stringify).join(',')}`);
|
|
860
863
|
}
|
|
861
|
-
}
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
// window.document.body.addEventListener(MouseEvents.Move, raycast_handler);
|
|
862
867
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { array_copy } from "../../../../core/collection/array/copyArray.js";
|
|
2
2
|
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
3
|
-
import { MicronGeometryPatchOccurrence } from "../format/MicronGeometryPatchOccurance.js";
|
|
4
3
|
import { RefinementSpec } from "./refinement/RefinementSpec.js";
|
|
5
4
|
import { ActivePatchList } from "./refinement/ActivePatchList.js";
|
|
6
|
-
import { ActivePatchFlags } from "./refinement/ActivePatchFlags.js";
|
|
7
5
|
import { mat4 } from "gl-matrix";
|
|
6
|
+
import { get_geometry_patch_cut } from "./refinement/get_geometry_patch_cut.js";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* @readonly
|
|
@@ -125,7 +124,6 @@ export class VirtualGeometryBuilder {
|
|
|
125
124
|
// get acl
|
|
126
125
|
const acl = this.__acl;
|
|
127
126
|
|
|
128
|
-
acl.initializeFromGeometry(micron_geometry);
|
|
129
127
|
|
|
130
128
|
this.buildForMesh(
|
|
131
129
|
object.instance_id,
|
|
@@ -159,7 +157,6 @@ export class VirtualGeometryBuilder {
|
|
|
159
157
|
transform,
|
|
160
158
|
apl
|
|
161
159
|
) {
|
|
162
|
-
|
|
163
160
|
refinement_spec.build(transform, this.view_projection_matrix);
|
|
164
161
|
|
|
165
162
|
const output = this.output;
|
|
@@ -168,48 +165,19 @@ export class VirtualGeometryBuilder {
|
|
|
168
165
|
output.stats_source_triangle_count += geometry.source_triangle_count;
|
|
169
166
|
output.stats_source_vertex_count += geometry.source_vertex_count;
|
|
170
167
|
|
|
171
|
-
// apl.build_from_lod(geometry, 0);
|
|
172
|
-
apl.refine(refinement_spec);
|
|
173
|
-
|
|
174
168
|
// build up occurances
|
|
175
169
|
const output_patches = output.patches;
|
|
176
|
-
let output_patch_cursor = output.patch_count;
|
|
177
|
-
let patch_instance;
|
|
178
|
-
|
|
179
|
-
const geometry_id = geometry.id;
|
|
180
|
-
|
|
181
|
-
for (
|
|
182
|
-
let record = apl.records;
|
|
183
|
-
record !== null;
|
|
184
|
-
record = record.link_next
|
|
185
|
-
) {
|
|
186
|
-
|
|
187
|
-
if (!record.getFlag(ActivePatchFlags.Visible)) {
|
|
188
|
-
// patch is not visible, skip
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const patch = record.patch;
|
|
193
|
-
patch_instance = output_patches[output_patch_cursor];
|
|
194
|
-
|
|
195
|
-
if (patch_instance === undefined) {
|
|
196
|
-
// no instance available for reuse - create a new one
|
|
197
|
-
patch_instance = new MicronGeometryPatchOccurrence();
|
|
198
|
-
output_patches[output_patch_cursor] = patch_instance;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
patch_instance.instance_id = instance_id;
|
|
202
|
-
patch_instance.geometry_id = geometry_id;
|
|
203
|
-
patch_instance.patch = patch;
|
|
204
|
-
patch_instance.transform = transform;
|
|
205
|
-
|
|
206
|
-
output_patch_cursor++;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
output.patch_count = output_patch_cursor;
|
|
210
170
|
|
|
171
|
+
const added_patch_count = get_geometry_patch_cut(
|
|
172
|
+
output_patches,
|
|
173
|
+
output.patch_count,
|
|
174
|
+
refinement_spec,
|
|
175
|
+
geometry,
|
|
176
|
+
instance_id,
|
|
177
|
+
transform
|
|
178
|
+
);
|
|
211
179
|
|
|
212
|
-
|
|
180
|
+
output.patch_count += added_patch_count;
|
|
213
181
|
}
|
|
214
182
|
|
|
215
183
|
clearScene() {
|
|
@@ -239,7 +207,6 @@ export class VirtualGeometryBuilder {
|
|
|
239
207
|
// clear output
|
|
240
208
|
this.output.clear();
|
|
241
209
|
|
|
242
|
-
this.__info_enforced_node_splits = 0;
|
|
243
210
|
|
|
244
211
|
const n = this.input_scene_length;
|
|
245
212
|
const input_objects = this.input_scene;
|
|
@@ -194,8 +194,6 @@ export class ActivePatchList {
|
|
|
194
194
|
|
|
195
195
|
const node = record.patch;
|
|
196
196
|
|
|
197
|
-
// check if record needs to be split
|
|
198
|
-
const prev_is_visible = record.getFlag(ActivePatchFlags.Visible);
|
|
199
197
|
|
|
200
198
|
/*
|
|
201
199
|
check if node is in view frustum
|
|
@@ -205,16 +203,11 @@ export class ActivePatchList {
|
|
|
205
203
|
|
|
206
204
|
if (!in_view_frustum) {
|
|
207
205
|
// outside of view frustum, cull
|
|
208
|
-
if (prev_is_visible) {
|
|
209
|
-
record.clearFlag(ActivePatchFlags.Visible);
|
|
210
|
-
}
|
|
211
206
|
record = record.link_next;
|
|
212
207
|
continue;
|
|
213
208
|
}
|
|
214
209
|
|
|
215
|
-
|
|
216
|
-
record.setFlag(ActivePatchFlags.Visible);
|
|
217
|
-
}
|
|
210
|
+
record.setFlag(ActivePatchFlags.Visible);
|
|
218
211
|
|
|
219
212
|
/*
|
|
220
213
|
scale error to projection space:
|
|
@@ -224,6 +217,7 @@ export class ActivePatchList {
|
|
|
224
217
|
*/
|
|
225
218
|
|
|
226
219
|
|
|
220
|
+
// check if record needs to be split
|
|
227
221
|
if (node.lod > 0) {
|
|
228
222
|
|
|
229
223
|
// not the lowest level of LOD, see if subdivision might be necessary
|