@woosh/meep-engine 2.34.45 → 2.34.46

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.
@@ -211,44 +211,60 @@ export class BinaryNode extends Node {
211
211
  */
212
212
  __insertion_findSiblingFor(box) {
213
213
 
214
- const open_set = [this];
215
- let cursor = 1;
214
+ let node = this;
215
+ let cost_left = 0;
216
+ let cost_right = 0;
216
217
 
217
- let best_cost = Infinity;
218
- let best_node = this;
218
+ while (node.isBinaryNode) {
219
+ const left = node.left;
220
+ const right = node.right;
219
221
 
220
- while (cursor > 0) {
221
- const node = open_set[--cursor];
222
+ const area = aabb3_box_surface_area_2(node);
222
223
 
223
- const cost = inclusion_surface_area_heuristic(node, box);
224
+ const combined_area = combined_surface_area(node, box);
224
225
 
225
- if (cost < best_cost) {
226
- best_cost = cost;
227
- best_node = node;
228
- }
226
+ //cost of creating a new parent for this node and the new leaf
227
+ const cost = combined_area;
229
228
 
230
- if (node.isBinaryNode) {
229
+ // minimum cost of pushing the leaf further down the tree
230
+ const inheritance_cost = combined_area - area;
231
231
 
232
- // consider pushing children into the queue
232
+ // cost of descending left
233
+ if (left !== null) {
234
+ if (left.isLeafNode) {
235
+ cost_left = combined_surface_area(left, box) + inheritance_cost;
236
+ } else {
237
+ cost_left = combined_surface_area(left, box) - aabb3_box_surface_area_2(left) + inheritance_cost;
238
+ }
239
+ } else {
240
+ cost_left = Infinity;
241
+ }
233
242
 
234
- // compute lower bound for cost
235
- const c_low = inclusion_cost_lower_bound(node, box);
243
+ // cost of descending right
244
+ if (right !== null) {
236
245
 
237
- if (c_low < best_cost) {
238
- // worth-while to explore children
239
- if (node.left !== null) {
240
- open_set[cursor++] = node.left;
241
- }
242
- if (node.right !== null) {
243
- open_set[cursor++] = node.right
244
- }
246
+ if (right.isLeafNode) {
247
+ cost_right = combined_surface_area(right, box) + inheritance_cost;
248
+ } else {
249
+ cost_right = combined_surface_area(right, box) - aabb3_box_surface_area_2(right) + inheritance_cost;
245
250
  }
251
+ } else {
252
+ cost_right = Infinity;
246
253
  }
247
254
 
255
+ if (cost < cost_left && cost < cost_right) {
256
+ // descending either branch is too expensive
257
+ break;
258
+ }
248
259
 
260
+ if (cost_left < cost_right) {
261
+ node = left;
262
+ } else {
263
+ node = right;
264
+ }
249
265
  }
250
266
 
251
- return best_node;
267
+ return node;
252
268
  }
253
269
 
254
270
  /**
@@ -1134,6 +1150,16 @@ BinaryNode.prototype.isBinaryNode = true;
1134
1150
  * @returns {number}
1135
1151
  */
1136
1152
  function inclusion_surface_area_heuristic(node, addition) {
1153
+ return combined_surface_area(node, addition) - aabb3_box_surface_area_2(node);
1154
+ }
1155
+
1156
+ /**
1157
+ *
1158
+ * @param {AABB3} node
1159
+ * @param {AABB3} addition
1160
+ * @returns {number}
1161
+ */
1162
+ function combined_surface_area(node, addition) {
1137
1163
  const x0 = min2(node.x0, addition.x0);
1138
1164
  const y0 = min2(node.y0, addition.y0);
1139
1165
  const z0 = min2(node.z0, addition.z0);
@@ -1142,7 +1168,7 @@ function inclusion_surface_area_heuristic(node, addition) {
1142
1168
  const y1 = max2(node.y1, addition.y1);
1143
1169
  const z1 = max2(node.z1, addition.z1);
1144
1170
 
1145
- return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1) - aabb3_box_surface_area_2(node);
1171
+ return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
1146
1172
  }
1147
1173
 
1148
1174
  /**
@@ -0,0 +1,43 @@
1
+ const stack = [];
2
+ let stackPointer = 0;
3
+
4
+ /**
5
+ *
6
+ * @param {BinaryNode} root
7
+ * @param {function(BinaryNode|LeafNode):*} visitor
8
+ * @param {*} [thisArg]
9
+ * @return {number}
10
+ */
11
+ export function bvh_traverse_pre_order_using_stack(root, visitor, thisArg) {
12
+ let visitCount = 0;
13
+
14
+ const stackOffset = stackPointer;
15
+
16
+ stack[stackPointer++] = root;
17
+
18
+ let n;
19
+
20
+ while (stackPointer-- > stackOffset) {
21
+
22
+ visitCount++;
23
+
24
+ n = stack[stackPointer];
25
+
26
+ visitor.call(thisArg, n);
27
+
28
+ if (!n.isLeafNode) {
29
+ //a binary node
30
+ if (n.right !== null) {
31
+ stack[stackPointer++] = n.right;
32
+ }
33
+ if (n.left !== null) {
34
+ stack[stackPointer++] = n.left;
35
+ }
36
+ }
37
+ }
38
+
39
+ // drop stack frame
40
+ stackPointer = stackOffset;
41
+
42
+ return visitCount;
43
+ }
@@ -0,0 +1,50 @@
1
+ import { convertGraphToDotString } from "../../graph/convertGraphToDotString.js";
2
+ import { bvh_traverse_pre_order_using_stack } from "../traversal/bvh_traverse_pre_order_using_stack.js";
3
+ import { Graph } from "../../graph/v2/Graph.js";
4
+ import { Edge, EdgeDirectionType } from "../../graph/Edge.js";
5
+
6
+ /**
7
+ *
8
+ * @param {BinaryNode} bvh
9
+ * @returns {Graph}
10
+ */
11
+ export function bvh_to_graph(bvh) {
12
+ //traverse twice, first collect all nodes, second time introduce edges
13
+ const graph = new Graph();
14
+
15
+ bvh_traverse_pre_order_using_stack(bvh, node => {
16
+ graph.addNode(node);
17
+ });
18
+
19
+ bvh_traverse_pre_order_using_stack(bvh, node => {
20
+ if (node.isBinaryNode) {
21
+
22
+ if (node.left !== null) {
23
+ const edge = new Edge(node, node.left);
24
+
25
+ edge.direction = EdgeDirectionType.Forward;
26
+
27
+ graph.addEdge(edge);
28
+ }
29
+ if (node.right !== null) {
30
+ const edge = new Edge(node, node.right);
31
+
32
+ edge.direction = EdgeDirectionType.Forward;
33
+
34
+ graph.addEdge(edge);
35
+ }
36
+ }
37
+ });
38
+
39
+ return graph;
40
+ }
41
+
42
+ /**
43
+ * Build a Graphviz DOT representation of the graph
44
+ * @param {BinaryNode} bvh
45
+ * @returns {string}
46
+ */
47
+ export function convert_bvh_to_dot_format_string(bvh) {
48
+ const graph = bvh_to_graph(bvh);
49
+ return convertGraphToDotString(graph);
50
+ }
@@ -2,7 +2,7 @@ import LineBuilder from "../codegen/LineBuilder.js";
2
2
  import { EdgeDirectionType } from "./Edge.js";
3
3
 
4
4
  /**
5
- * Build a DOT representation of the graph
5
+ * Build a Graphviz DOT representation of the graph
6
6
  * @param {Graph} graph
7
7
  * @returns {string}
8
8
  */
@@ -13,7 +13,7 @@ export function convertGraphToDotString(graph) {
13
13
 
14
14
  lb.indent();
15
15
 
16
- const nodes = graph.nodes;
16
+ const nodes = Array.from(graph.getNodes());
17
17
  const nodeCount = nodes.length;
18
18
 
19
19
  function nodeId(index) {
@@ -33,9 +33,9 @@ export function convertGraphToDotString(graph) {
33
33
 
34
34
  const node = nodes[i];
35
35
 
36
- const attachedEdges = graph.getAttachedEdges(node);
36
+ const attachedEdges = [];
37
37
 
38
- const nAttachedEdges = attachedEdges.length;
38
+ const nAttachedEdges = graph.getAttachedEdges(attachedEdges, node);
39
39
 
40
40
  for (let j = 0; j < nAttachedEdges; j++) {
41
41
  const edge = attachedEdges[j];
@@ -335,6 +335,10 @@ export class Graph {
335
335
  * @returns {number}
336
336
  */
337
337
  getAttachedEdges(result, node) {
338
+ assert.defined(result, 'result');
339
+ assert.isArray(result, 'result');
340
+ assert.defined(node, 'node');
341
+
338
342
  const context = this.__nodes.get(node);
339
343
 
340
344
  if (context === undefined) {
@@ -116,8 +116,9 @@ export class Foliage2System extends System {
116
116
  graphics.views.elements.on.added.add(this.__handle_view_added, this);
117
117
  graphics.views.elements.on.removed.add(this.__handle_view_removed, this);
118
118
 
119
- this.renderLayer.buildVisibleSet = (view, visitObject, thisArg) => {
119
+ this.renderLayer.buildVisibleSet = (destination, destination_offset, view) => {
120
120
  const data = this.data;
121
+ let additions = 0;
121
122
 
122
123
  for (let entity in data) {
123
124
 
@@ -147,11 +148,14 @@ export class Foliage2System extends System {
147
148
  }
148
149
 
149
150
  const mesh = group.mesh;
150
- visitObject.call(thisArg, mesh);
151
+
152
+ destination[additions + destination_offset] = mesh;
151
153
  }
152
154
 
153
155
  }
154
156
  }
157
+
158
+ return additions;
155
159
  };
156
160
 
157
161
  readyCallback();
@@ -0,0 +1,21 @@
1
+ /**
2
+ *
3
+ * @param {THREE.BufferGeometry} geometry
4
+ * @returns {number}
5
+ */
6
+ export function compute_geometry_polycount(geometry) {
7
+ const index = geometry.getIndex();
8
+
9
+ if (index !== null) {
10
+ return index.count / 3;
11
+ }
12
+
13
+ const position_attribute = geometry.getAttribute('position');
14
+
15
+ if (position_attribute !== undefined) {
16
+ return position_attribute.count / 3;
17
+ }
18
+
19
+ // no valid way to discern polycount, assume 0
20
+ return 0;
21
+ }
@@ -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 g = ShadedGeometry.from(new BoxBufferGeometry(), material);
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(Transform.fromJSON({
38
- position: {
39
- x: 10,
40
- y: 1,
41
- z: 10
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
 
@@ -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 { MICRON_URI_FIELD } from "../MICRON_URI_FIELD.js";
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();
@@ -188,8 +188,8 @@ heatmap_lut_pink_to_blue.write([
188
188
  ]);
189
189
  heatmap_lut_pink_to_blue.computeUniformPositions();
190
190
 
191
- const heatmap_lut_3 = new ParameterLookupTable(4);
192
- heatmap_lut_3.write(
191
+ const heatmap_lut_discrete = new ParameterLookupTable(4);
192
+ heatmap_lut_discrete.write(
193
193
  [
194
194
  196, 196, 196, 255,
195
195
  196, 196, 196, 255,
@@ -303,8 +303,8 @@ async function sample_scene_0(engine) {
303
303
  }
304
304
 
305
305
  // load_model('moicon/06_04_hapro/00-environment/model.gltf', -0.1);
306
- // load_model_s('moicon/06_04_hapro/05-ground-floor/model.gltf');
307
- // load_model_s('C:/git/moh/app/moicon/06_04_hapro/08-clickable-assets-new/model.gltf');
306
+ load_model_s('moicon/06_04_hapro/05-ground-floor/model.gltf');
307
+ load_model_s('C:/git/moh/app/moicon/06_04_hapro/08-clickable-assets-new/model.gltf');
308
308
  // load_model('moicon/06_04_hapro/02-bearers/model.gltf');
309
309
  // load_model('moicon/06_04_hapro/04-1st-floor/model.gltf');
310
310
 
@@ -360,7 +360,7 @@ async function sample_scene_0(engine) {
360
360
  // large open room, dense particles
361
361
  await make_demo_volume({
362
362
  ecd: ecd,
363
- lut: heatmap_lut_3,
363
+ lut: heatmap_lut_discrete,
364
364
  shape: UnionShape3D.from([
365
365
  TransformedShape3D.from_m4(new UnitCubeShape3D(), [20.977896627021547, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 36.201589869571954, 0, 99.2120028317975, 1.5919924971428276, 49.21655402009093, 1]),
366
366
  TransformedShape3D.from_m4(new UnitCubeShape3D(), [24.455615450514458, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 28.081536987027807, 0, 80.11618755300161, 1.5919924971428276, 45.13808745329574, 1]),
@@ -534,7 +534,7 @@ async function sample_scene_nam(engine) {
534
534
 
535
535
  await make_demo_volume({
536
536
  ecd: ecd,
537
- lut: heatmap_lut_3,
537
+ lut: heatmap_lut_discrete,
538
538
  shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.260857135913424, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 24.82865688356064, 1.4169994923726943, 2.4066558057134095, 1]),
539
539
  particle_size: P_SIZE_SMALL,
540
540
  density: 3,
@@ -545,7 +545,7 @@ async function sample_scene_nam(engine) {
545
545
 
546
546
  await make_demo_volume({
547
547
  ecd: ecd,
548
- lut: heatmap_lut_3,
548
+ lut: heatmap_lut_discrete,
549
549
  shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.870266350649175, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 20.022408905267525, 1.4169994923726943, 2.4066558057134095, 1]),
550
550
  particle_size: P_SIZE_SMALL,
551
551
  density: 3,
@@ -585,6 +585,309 @@ async function sample_scene_nam(engine) {
585
585
  // }));
586
586
  }
587
587
 
588
+ /**
589
+ *
590
+ * @param {Engine} engine
591
+ * @returns {Promise<void>}
592
+ */
593
+ async function sample_scene_moicon_0(engine) {
594
+ const ecd = engine.entityManager.dataset;
595
+
596
+ ecd.getAnyComponent(TopDownCameraController).component.fromJSON({
597
+ "target": {
598
+ "x": 21.09522080045099,
599
+ "y": -0.6327784109623013,
600
+ "z": 6.138907038731565
601
+ },
602
+ "pitch": 1.1099999999999923,
603
+ "yaw": -3.143185307179591,
604
+ "roll": 0,
605
+ "distance": 29,
606
+ "distanceMin": 0,
607
+ "distanceMax": 1000
608
+ });
609
+
610
+ load_model('moicon/10_Feb_22_Demo/1/model.gltf', ecd);
611
+ load_model('moicon/10_Feb_22_Demo/2/model.gltf', ecd);
612
+ // load_model('moicon/10_Feb_22_Demo/3/model.gltf', ecd); // volume markers - main floor
613
+ // load_model('moicon/10_Feb_22_Demo/4/model.gltf', ecd); // volume markers - small corner room
614
+ load_model('moicon/10_Feb_22_Demo/5/model.gltf', ecd);
615
+ // load_model('moicon/10_Feb_22_Demo/6/model.gltf', ecd); // roof
616
+ load_model('moicon/10_Feb_22_Demo/7/model.gltf', ecd);
617
+ load_model('moicon/10_Feb_22_Demo/assets/model.gltf', ecd);
618
+
619
+ const P_SIZE_SMALL = 0.15;
620
+ const P_SIZE_MEDIUM = 0.6;
621
+ const P_SIZE_LARGE = 2;
622
+
623
+ const random = seededRandom(42);
624
+
625
+ const PERIOD_LONG = 13;
626
+
627
+ // await make_demo_volume({
628
+ // ecd: ecd,
629
+ // lut: heatmap_lut_pink_to_blue,
630
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.267098043281134, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 2.8037239954452864, 1.4169994923726943, 11.460158766988037, 1]),
631
+ // particle_size: P_SIZE_MEDIUM,
632
+ // density: 3,
633
+ // period: PERIOD_LONG,
634
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
635
+ // sprite: 'data/textures/particle/UETools/Hexagon_01.png'
636
+ // });
637
+ // await make_demo_volume({
638
+ // ecd: ecd,
639
+ // lut: heatmap_lut_orange_to_red,
640
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.7577406314060395, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 8.075207307031247, 1.4169994923726943, 11.460158766988037, 1]),
641
+ // particle_size: P_SIZE_MEDIUM,
642
+ // density: 3,
643
+ // period: PERIOD_LONG,
644
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
645
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
646
+ // });
647
+ //
648
+ // await make_demo_volume({
649
+ // ecd: ecd,
650
+ // lut: heatmap_lut_pink_to_blue,
651
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.956797095914032, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 14.17733466985805, 1.4169994923726943, 11.460158766988037, 1]),
652
+ // particle_size: P_SIZE_MEDIUM,
653
+ // density: 3,
654
+ // period: PERIOD_LONG,
655
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
656
+ // sprite: 'data/textures/particle/travnik/plus_2.png'
657
+ // });
658
+ //
659
+ // await make_demo_volume({
660
+ // ecd: ecd,
661
+ // lut: heatmap_lut_pink_to_blue,
662
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.733772190018377, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 20.284613387782148, 1.4169994923726943, 11.460158766988037, 1]),
663
+ // particle_size: P_SIZE_MEDIUM,
664
+ // density: 3,
665
+ // period: PERIOD_LONG,
666
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
667
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
668
+ // });
669
+ //
670
+ // await make_demo_volume({
671
+ // ecd: ecd,
672
+ // lut: heatmap_lut_pink_to_blue,
673
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.924905976332568, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 31.662442543335885, 1.4169994923726943, 11.460158766988037, 1]),
674
+ // particle_size: P_SIZE_MEDIUM,
675
+ // density: 3,
676
+ // period: PERIOD_LONG,
677
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
678
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
679
+ // });
680
+ //
681
+ // await make_demo_volume({
682
+ // ecd: ecd,
683
+ // lut: heatmap_lut_0,
684
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.7305058801925, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 37.70942297505848, 1.4169994923726943, 11.460158766988037, 1]),
685
+ // particle_size: P_SIZE_MEDIUM,
686
+ // density: 8,
687
+ // period: PERIOD_LONG,
688
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
689
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
690
+ // });
691
+ // await make_demo_volume({
692
+ // ecd: ecd,
693
+ // lut: heatmap_lut_0,
694
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.575632395877399, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 37.272800538855826, 1.4169994923726943, 2.4066558057134095, 1]),
695
+ // particle_size: P_SIZE_MEDIUM,
696
+ // density: 8,
697
+ // period: PERIOD_LONG,
698
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
699
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
700
+ // });
701
+ //
702
+ // await make_demo_volume({
703
+ // ecd: ecd,
704
+ // lut: heatmap_lut_0,
705
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.410614101275306, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 30.458756650580582, 1.4169994923726943, 2.4066558057134095, 1]),
706
+ // particle_size: P_SIZE_MEDIUM,
707
+ // density: 8,
708
+ // period: PERIOD_LONG,
709
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
710
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
711
+ // });
712
+ //
713
+ // await make_demo_volume({
714
+ // ecd: ecd,
715
+ // lut: heatmap_lut_3,
716
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.260857135913424, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 24.82865688356064, 1.4169994923726943, 2.4066558057134095, 1]),
717
+ // particle_size: P_SIZE_SMALL,
718
+ // density: 3,
719
+ // period: PERIOD_LONG,
720
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
721
+ // sprite: 'data/textures/particle/UETools/Circle_01.png'
722
+ // });
723
+ //
724
+ // await make_demo_volume({
725
+ // ecd: ecd,
726
+ // lut: heatmap_lut_3,
727
+ // shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.870266350649175, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 20.022408905267525, 1.4169994923726943, 2.4066558057134095, 1]),
728
+ // particle_size: P_SIZE_SMALL,
729
+ // density: 3,
730
+ // period: PERIOD_LONG,
731
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
732
+ // sprite: 'data/textures/particle/UETools/Cross_04.png'
733
+ // });
734
+ // await make_demo_volume({
735
+ // ecd: ecd,
736
+ // lut: heatmap_lut_pink_to_blue,
737
+ // shape: UnionShape3D.from([
738
+ // TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.985827128973811, 0, 0, 0, 0, 2.435269776236539, 0, 0, 0, 0, 4.669621139110231, 0, 11.08356834576874, 1.2643565739307023, 2.4360416869081885, 1]),
739
+ // TransformedShape3D.from_m4(new UnitCubeShape3D(), [8.413758403821523, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 7.775469675813772, 0, 4.313201108449287, 1.4169994923726943, 4.011630095541064, 1]),
740
+ // TransformedShape3D.from_m4(new UnitCubeShape3D(), [8.413758403821523, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 2.925065210015915, 0, 12.417224289491141, 1.4169994923726943, 6.432483110925785, 1])
741
+ // ]),
742
+ // particle_size: P_SIZE_LARGE,
743
+ // density: 4,
744
+ // period: PERIOD_LONG,
745
+ // period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
746
+ // sprite: 'data/textures/particle/UETools/Circle_04.png'
747
+ // });
748
+ await make_demo_volume({
749
+ ecd: ecd,
750
+ lut: heatmap_lut_pink_to_blue,
751
+ shape: UnionShape3D.from([
752
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [24.84144698268643, 0, 0, 0, 0, 5, 0, 0, 0, 0, 10.014132199037626, 0, 17.535114352814745, 2.5767637841580786, 15.087856547232908, 1]),
753
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [3.119746486000208, 0, 0, 0, 0, 5, 0, 0, 0, 0, 5.08916554361867, 0, 6.026351574317095, 2.5767637841580786, 17.554804169904074, 1])
754
+ ]),
755
+ particle_size: P_SIZE_LARGE,
756
+ density: 4,
757
+ period: PERIOD_LONG,
758
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
759
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
760
+ });
761
+
762
+ await make_demo_volume({
763
+ ecd: ecd,
764
+ lut: heatmap_lut_orange_to_red,
765
+ shape: UnionShape3D.from([
766
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.23148852648068, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 4.843722925544828, 0, 2.178004397277256, 1.4442400806689264, 17.49419453432575, 1])
767
+ ]),
768
+ particle_size: P_SIZE_MEDIUM,
769
+ density: 4,
770
+ period: PERIOD_LONG,
771
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
772
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
773
+ });
774
+ await make_demo_volume({
775
+ ecd: ecd,
776
+ lut: heatmap_lut_pink_to_blue,
777
+ shape: UnionShape3D.from([
778
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.23148852648068, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 4.843722925544828, 0, -2.3684201443478874, 1.4819864080894103, 17.435101092023466, 1])
779
+ ]),
780
+ particle_size: P_SIZE_LARGE,
781
+ density: 4,
782
+ period: PERIOD_LONG,
783
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
784
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
785
+ });
786
+ await make_demo_volume({
787
+ ecd: ecd,
788
+ lut: heatmap_lut_orange_to_red,
789
+ shape: UnionShape3D.from([
790
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.827875822302671, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 7.195620725226215, 0, -7.134776782683499, 1.4819864080894103, 16.41960212963852, 1])
791
+ ]),
792
+ particle_size: P_SIZE_MEDIUM,
793
+ density: 4,
794
+ period: PERIOD_LONG,
795
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
796
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
797
+ });
798
+ await make_demo_volume({
799
+ ecd: ecd,
800
+ lut: heatmap_lut_pink_to_blue,
801
+ shape: UnionShape3D.from([
802
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.827875822302671, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 7.142815034586885, 0, -12.122694984141244, 1.4819864080894103, 16.39260186069935, 1]),
803
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [2.0910380492069933, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 5.042906378175556, 0, -13.835348677127275, 1.4819864080894103, 17.348732325334534, 1])
804
+ ]),
805
+ particle_size: P_SIZE_LARGE,
806
+ density: 4,
807
+ period: PERIOD_LONG,
808
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
809
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
810
+ });
811
+ await make_demo_volume({
812
+ ecd: ecd,
813
+ lut: heatmap_lut_orange_to_red,
814
+ shape: UnionShape3D.from([
815
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.630054702949254, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 5.132455640292213, 0, -17.444335306984925, 1.4819864080894103, 17.416555162219638, 1])
816
+ ]),
817
+ particle_size: P_SIZE_MEDIUM,
818
+ density: 4,
819
+ period: PERIOD_LONG,
820
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
821
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
822
+ });
823
+ await make_demo_volume({
824
+ ecd: ecd,
825
+ lut: heatmap_lut_pink_to_blue,
826
+ shape: UnionShape3D.from([
827
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [3.9334060066229277, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 4.909748196656206, 0, -2.993297445749089, 1.4819864080894103, -6.9614900068054615, 1])
828
+ ]),
829
+ particle_size: P_SIZE_LARGE,
830
+ density: 4,
831
+ period: PERIOD_LONG,
832
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
833
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
834
+ });
835
+ await make_demo_volume({
836
+ ecd: ecd,
837
+ lut: heatmap_lut_orange_to_red,
838
+ shape: UnionShape3D.from([
839
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.693637284485993, 0, 0, 0, 0, 2.8688316144733066, 0, 0, 0, 0, 9.774881301181045, 0, -26.90124286380605, 4.656150234283974, 14.984350120152822, 1])
840
+ ]),
841
+ particle_size: P_SIZE_MEDIUM,
842
+ density: 4,
843
+ period: PERIOD_LONG,
844
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
845
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
846
+ });
847
+
848
+ await make_demo_volume({
849
+ ecd: ecd,
850
+ lut: heatmap_lut_discrete,
851
+ shape: UnionShape3D.from([
852
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.331512511030024, 0, 0, 0, 0, 2.329600948715924, 0, 0, 0, 0, 9.610682816430089, 0, -21.021354476323573, 1.3409243433436, -1.345765978128314, 1])]),
853
+ particle_size: P_SIZE_SMALL,
854
+ density: 4,
855
+ period: PERIOD_LONG,
856
+ period_offset: 0,
857
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
858
+ });
859
+ await make_demo_volume({
860
+ ecd: ecd,
861
+ lut: heatmap_lut_discrete,
862
+ shape: UnionShape3D.from([
863
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [13.623136537846888, 0, 0, 0, 0, 2.193382560214131, 0, 0, 0, 0, 4.880453458023407, 0, 8.339521865997591, 1.1217848106509791, -1.5586407794900627, 1]),
864
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.162666210784313, 0, 0, 0, 0, 1.7455477622575266, 0, 0, 0, 0, 4.880453458023407, 0, 2.0126515547811556, 0.9110827940157051, -1.5586407794900627, 1]),
865
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.162666210784313, 0, 0, 0, 0, 1.1232395183163202, 0, 0, 0, 0, 3.565672994277359, 0, 2.0440383546262932, 1.8620329637166853, -2.1963940023653703, 1])
866
+ ]),
867
+ particle_size: P_SIZE_SMALL,
868
+ density: 4,
869
+ period: PERIOD_LONG,
870
+ period_offset: PERIOD_LONG * 0.5,
871
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
872
+ });
873
+
874
+ make_shape_vis_toggle(engine).toggle(); // turn off shape vis initially
875
+
876
+ // editing box
877
+ // make_box_editor(engine, Transform.fromJSON({
878
+ // position: {
879
+ // x: -2,
880
+ // y: 0,
881
+ // z: 0
882
+ // },
883
+ // scale: {
884
+ // x: 5,
885
+ // y: 5,
886
+ // z: 5
887
+ // }
888
+ // }));
889
+ }
890
+
588
891
  /**
589
892
  *
590
893
  * @param {Engine} engine
@@ -608,8 +911,9 @@ async function main(engine) {
608
911
 
609
912
  engine.graphics.renderer.setClearColor('rgba(99,99,99,1)');
610
913
 
611
- await sample_scene_nam(engine);
914
+ // await sample_scene_nam(engine);
612
915
  // await sample_scene_0(engine);
916
+ await sample_scene_moicon_0(engine);
613
917
  }
614
918
 
615
919
  /**
@@ -788,7 +1092,7 @@ function make_symbol_view({
788
1092
  };
789
1093
 
790
1094
  const symbol_view = new EmptyView();
791
- symbol_view.size.set(128, 20);
1095
+ symbol_view.size.set(64, 20);
792
1096
 
793
1097
  symbol_view.css({
794
1098
  position: 'absolute',
@@ -798,7 +1102,7 @@ function make_symbol_view({
798
1102
  });
799
1103
 
800
1104
  const view_lut = new CanvasView();
801
- view_lut.size.set(128, 10);
1105
+ view_lut.size.set(64, 4);
802
1106
  view_lut.css({
803
1107
  position: 'absolute',
804
1108
  border: '1px solid white',
@@ -817,10 +1121,11 @@ function make_symbol_view({
817
1121
 
818
1122
  view_cursor.css({
819
1123
  position: 'absolute',
820
- left: 0,
821
- top: "-1px",
1124
+ left: "-6px",
1125
+ top: "-4px",
822
1126
  height: "10px",
823
- width: "4px",
1127
+ width: "10px",
1128
+ borderRadius: "10px",
824
1129
  border: '2px solid white',
825
1130
  zIndex: 2,
826
1131
  boxShadow: '0 0 4px black'
@@ -55,6 +55,7 @@ export class RenderLayer {
55
55
  this.extractRenderable = passThrough;
56
56
 
57
57
  /**
58
+ * @deprecated use CameraView's visible set instead
58
59
  * Contains visible elements across all views, if element is in at least one view - it will be here
59
60
  * @type {IncrementalDeltaSet<THREE.Object3D>}
60
61
  */
@@ -112,35 +113,42 @@ export class RenderLayer {
112
113
 
113
114
  /**
114
115
  *
116
+ * @param {THREE.Object3D[]} destination
117
+ * @param {number} destination_offset
115
118
  * @param {CameraView} view
116
- * @param {function(THREE.Object3D)} callback
117
- * @param {*} [callbackContext]
119
+ * @returns {number} Number of records added to destination
118
120
  */
119
- buildVisibleSet(view, callback, callbackContext) {
121
+ buildVisibleSet(destination, destination_offset, view) {
120
122
  const frustum = view.frustum;
121
123
 
122
124
  const reader = this.extractRenderable;
123
125
 
126
+ if (typeof reader !== "function") {
127
+ // no reader method
128
+ return 0;
129
+ }
124
130
 
125
- if (typeof reader === "function") {
126
-
127
- const hits = queryBinaryNode_FrustumIntersections_Data(scratch_array, 0, this.bvh, frustum);
131
+ const intersection_count = queryBinaryNode_FrustumIntersections_Data(scratch_array, 0, this.bvh, frustum);
128
132
 
129
- for (let i = 0; i < hits; i++) {
130
- const datum = scratch_array[i];
133
+ let additions = 0;
134
+ let i = 0;
131
135
 
132
- const object3D = reader(datum);
136
+ for (; i < intersection_count; i++) {
137
+ const datum = scratch_array[i];
133
138
 
134
- if (!object3D) {
135
- // null or undefined
136
- continue;
137
- }
139
+ const object3D = reader(datum);
138
140
 
139
- callback.call(callbackContext, object3D);
141
+ if (!object3D) {
142
+ // null or undefined
143
+ continue;
140
144
  }
141
145
 
146
+ destination[additions + destination_offset] = object3D;
147
+
148
+ additions++;
142
149
  }
143
150
 
151
+ return additions;
144
152
  }
145
153
  }
146
154
 
@@ -251,26 +251,31 @@ export class IncrementalDeltaSet {
251
251
  * @param {V} element
252
252
  */
253
253
  push(element) {
254
+ const elements = this.__elements;
255
+
254
256
  //check if element is already in the set
255
- const index = this.__indexExpected(element);
257
+ const existing_size = this.size;
258
+ const index = binarySearchHighIndex(elements, element, this.__compare, 0, existing_size - 1);
256
259
 
257
- const elements = this.__elements;
260
+
261
+ const flags = this.flags;
258
262
 
259
263
  if (elements[index] !== element) {
260
264
  // element is not in the set
261
265
 
262
266
  // shift flags to make space for it
263
- this.flags.shift(1, index, this.size);
267
+ flags.shift(1, index, existing_size);
264
268
 
265
269
  // insert
266
270
  elements.splice(index, 0, element);
267
- this.size++;
271
+
272
+ this.size = existing_size + 1;
268
273
 
269
274
  this.onAdded.send1(element);
270
275
  }
271
276
 
272
277
  // clear flag for inserted element
273
- this.flags.clear(index);
278
+ flags.clear(index);
274
279
 
275
280
  }
276
281
 
@@ -281,6 +286,7 @@ export class IncrementalDeltaSet {
281
286
  pushOther(other) {
282
287
  const elements = other.__elements;
283
288
  const n = other.size;
289
+
284
290
  for (let i = 0; i < n; i++) {
285
291
  const el = elements[i];
286
292
 
@@ -288,3 +294,10 @@ export class IncrementalDeltaSet {
288
294
  }
289
295
  }
290
296
  }
297
+
298
+
299
+ /**
300
+ * @readonly
301
+ * @type {boolean}
302
+ */
303
+ IncrementalDeltaSet.prototype.isIncrementalDeltaSet = true;
@@ -1,4 +1,4 @@
1
- import { assert } from "../../../../core/assert.js";
1
+ const scratch_array = [];
2
2
 
3
3
  export class VisibilityComputer {
4
4
  constructor() {
@@ -67,19 +67,6 @@ export class VisibilityComputer {
67
67
  this.__view = view;
68
68
  }
69
69
 
70
- /**
71
- * @private
72
- * @param {Object3D} object3d
73
- */
74
- __includeObject(object3d) {
75
- assert.equal(object3d.isObject3D, true, 'object3d.isObject3D !== true');
76
-
77
- //object passed all filters, add it to visible set
78
- this.__output.push(object3d);
79
-
80
- this.__activeLayer.visibleSet.push(object3d);
81
- }
82
-
83
70
  /**
84
71
  * @private
85
72
  * @param {RenderLayer} layer
@@ -101,7 +88,16 @@ export class VisibilityComputer {
101
88
  return;
102
89
  }
103
90
 
104
- layer.buildVisibleSet(this.__view, this.__includeObject, this);
91
+ const added_objects = layer.buildVisibleSet(scratch_array, 0, this.__view);
92
+
93
+ for (let i = 0; i < added_objects; i++) {
94
+ const object3d = scratch_array[i];
95
+
96
+ //object passed all filters, add it to visible set
97
+ this.__output.push(object3d);
98
+
99
+ this.__activeLayer.visibleSet.push(object3d);
100
+ }
105
101
  }
106
102
 
107
103
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.34.45",
8
+ "version": "2.34.46",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",