@woosh/meep-engine 2.35.1 → 2.35.4

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.
Files changed (25) hide show
  1. package/core/bvh2/aabb3/aabb3_intersects_frustum_degree.js +6 -6
  2. package/core/bvh2/traversal/queryBinaryNode_CollectData.js +1 -2
  3. package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +30 -17
  4. package/core/collection/HashMap.js +1 -1
  5. package/core/geom/3d/SurfacePoint3.js +6 -6
  6. package/engine/ecs/EntityManager.d.ts +7 -0
  7. package/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +13 -4
  8. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +20 -119
  9. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts +11 -1
  10. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +77 -13
  11. package/engine/graphics/ecs/mesh-v2/build_three_object.js +39 -0
  12. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +37 -5
  13. package/engine/graphics/ecs/mesh-v2/render/{AbstractRenderAdapter.js → adapters/AbstractRenderAdapter.js} +13 -1
  14. package/engine/graphics/ecs/mesh-v2/render/{GenericRendererAdapter.js → adapters/GenericRendererAdapter.js} +8 -3
  15. package/engine/graphics/ecs/mesh-v2/render/{InstancedRendererAdapter.js → adapters/InstancedRendererAdapter.js} +63 -10
  16. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +14 -5
  17. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +0 -1
  18. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +11 -2
  19. package/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +150 -0
  20. package/engine/graphics/micron/render/VirtualGeometryBuilder.js +1 -3
  21. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -7
  22. package/engine/graphics/micron/render/v1/MaterialContext.js +1 -2
  23. package/engine/graphics/micron/render/v1/VGThreeRenderer.js +6 -12
  24. package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +0 -50
  25. package/package.json +1 -1
@@ -19,18 +19,18 @@ export function aabb3_intersects_frustum_degree(
19
19
  frustum
20
20
  ) {
21
21
 
22
- let i = 0;
23
22
  let result = 2;
23
+ let i = 0;
24
24
 
25
25
  for (; i < 24; i += 4) {
26
26
 
27
- const p_nx = frustum[i];
28
- const p_ny = frustum[i + 1];
29
- const p_nz = frustum[i + 2];
30
- const p_c = frustum[i + 3];
27
+ const p_x = frustum[i];
28
+ const p_y = frustum[i + 1];
29
+ const p_z = frustum[i + 2];
30
+ const p_w = frustum[i + 3];
31
31
 
32
32
  const plane_side = computeAABB3PlaneSide(
33
- p_nx, p_ny, p_nz, p_c,
33
+ p_x, p_y, p_z, p_w,
34
34
  x0, y0, z0, x1, y1, z1
35
35
  );
36
36
 
@@ -13,13 +13,12 @@ let stackPointer = 0;
13
13
  */
14
14
  export function queryBinaryNode_CollectData(destination, destinationOffset, root) {
15
15
  let n;
16
+ let i = 0;
16
17
 
17
18
  const stackOffset = stackPointer;
18
19
 
19
20
  stack[stackPointer++] = root;
20
21
 
21
- let i = 0;
22
-
23
22
  while (stackPointer-- > stackOffset) {
24
23
 
25
24
  n = stack[stackPointer];
@@ -1,3 +1,6 @@
1
+ import { aabb3_intersects_frustum_degree } from "../aabb3/aabb3_intersects_frustum_degree.js";
2
+ import { queryBinaryNode_CollectData } from "./queryBinaryNode_CollectData.js";
3
+
1
4
  /**
2
5
  *
3
6
  * @type {(BinaryNode|LeafNode)[]}
@@ -30,32 +33,42 @@ export function queryBinaryNode_FrustumIntersections_Data(destination, destinati
30
33
 
31
34
  n = stack[stackPointer];
32
35
 
33
- const node_intersects_frustum = n.intersectFrustum_array(frustum);
36
+ const intersection_degree = aabb3_intersects_frustum_degree(
37
+ n.x0, n.y0, n.z0,
38
+ n.x1, n.y1, n.z1,
39
+ frustum
40
+ );
34
41
 
35
- if (!node_intersects_frustum) {
36
- continue;
37
- }
42
+ if (intersection_degree === 2) {
43
+ // fully inside
38
44
 
39
- if (n.isBinaryNode === true) {
45
+ offset += queryBinaryNode_CollectData(destination, offset, n);
40
46
 
41
- const right = n.right;
47
+ } else if (intersection_degree === 1) {
48
+ // partly inside
42
49
 
43
- if (right !== null) {
44
- stack[stackPointer++] = right;
45
- }
50
+ if (n.isBinaryNode === true) {
46
51
 
47
- const left = n.left;
52
+ const right = n.right;
48
53
 
49
- if (left !== null) {
50
- stack[stackPointer++] = left;
51
- }
54
+ if (right !== null) {
55
+ stack[stackPointer++] = right;
56
+ }
52
57
 
53
- } else {
54
- // leaf node
58
+ const left = n.left;
55
59
 
56
- destination[offset] = n.object;
60
+ if (left !== null) {
61
+ stack[stackPointer++] = left;
62
+ }
63
+
64
+ } else {
65
+ // leaf node
66
+
67
+ destination[offset] = n.object;
68
+
69
+ offset++;
70
+ }
57
71
 
58
- offset++;
59
72
  }
60
73
 
61
74
  }
@@ -176,7 +176,7 @@ export class HashMap {
176
176
  const mixed_hash = (hash >>> 16) ^ hash;
177
177
 
178
178
  // ensure index is non-negative
179
- const index = (2147483647) & mixed_hash;
179
+ const index = mixed_hash >>> 0;
180
180
 
181
181
  return index % this.__bucket_count;
182
182
  }
@@ -1,9 +1,6 @@
1
- import Quaternion from "../Quaternion.js";
2
1
  import Vector3 from "../Vector3.js";
3
2
  import { v3_length } from "../v3_length.js";
4
3
 
5
- const q = new Quaternion();
6
-
7
4
  /**
8
5
  * Used for representing points on a 3D surface. Used for raycasting contacts
9
6
  */
@@ -25,9 +22,12 @@ export class SurfacePoint3 {
25
22
  const p_y = p.y;
26
23
  const p_z = p.z;
27
24
 
28
- const result_p_x = m4[0] * p_x + m4[4] * p_y + m4[8] * p_z + m4[12];
29
- const result_p_y = m4[1] * p_x + m4[5] * p_y + m4[9] * p_z + m4[13];
30
- const result_p_z = m4[2] * p_x + m4[6] * p_y + m4[10] * p_z + m4[14];
25
+ // compute perspective projection
26
+ const w = 1 / (m4[3] * p_x + m4[7] * p_y + m4[11] * p_z + m4[15]);
27
+
28
+ const result_p_x = (m4[0] * p_x + m4[4] * p_y + m4[8] * p_z + m4[12]) * w;
29
+ const result_p_y = (m4[1] * p_x + m4[5] * p_y + m4[9] * p_z + m4[13]) * w;
30
+ const result_p_z = (m4[2] * p_x + m4[6] * p_y + m4[10] * p_z + m4[14]) * w;
31
31
 
32
32
  this.position.set(
33
33
  result_p_x,
@@ -1,6 +1,11 @@
1
1
  import {EntityComponentDataset} from "./EntityComponentDataset";
2
2
  import {System} from "./System";
3
3
 
4
+ interface Type<T> extends Function {
5
+ new(...args: any[]): T;
6
+ }
7
+
8
+
4
9
  export class EntityManager {
5
10
  dataset: EntityComponentDataset
6
11
 
@@ -10,6 +15,8 @@ export class EntityManager {
10
15
 
11
16
  removeSystem<T>(system: System<T>): Promise<void>
12
17
 
18
+ getSystem<T>(systemClass: Type<T>): T | null
19
+
13
20
  attachDataSet(dataset: EntityComponentDataset): void
14
21
 
15
22
  detachDataSet(): void
@@ -3,6 +3,7 @@ import { HighlightRenderElementSource } from "../plugin/HighlightRenderElementSo
3
3
  import Highlight from "../Highlight.js";
4
4
  import { OutlineRenderPlugin } from "../plugin/OutlineRenderPlugin.js";
5
5
  import { ShadedGeometry } from "../../mesh-v2/ShadedGeometry.js";
6
+ import { build_three_object } from "../../mesh-v2/build_three_object.js";
6
7
 
7
8
  class Supplier extends HighlightRenderElementSource {
8
9
  /**
@@ -31,6 +32,13 @@ class Supplier extends HighlightRenderElementSource {
31
32
  * @private
32
33
  */
33
34
  this.__group = null;
35
+
36
+ /**
37
+ *
38
+ * @type {WeakMap<ShadedGeometry, THREE.Object3D>}
39
+ * @private
40
+ */
41
+ this.__object_cache = new WeakMap();
34
42
  }
35
43
 
36
44
  collect(pool, group) {
@@ -77,13 +85,14 @@ class Supplier extends HighlightRenderElementSource {
77
85
  return;
78
86
  }
79
87
 
80
- const object = sg.__cached_object;
88
+ let object = this.__object_cache.get(sg);
81
89
 
82
- if (object === null) {
83
- // no renderable primitive
84
- return;
90
+ if(object === undefined){
91
+ object = build_three_object(sg);
85
92
  }
86
93
 
94
+ object.matrixWorld.elements = sg.transform;
95
+
87
96
  const renderElement = this.__pool.create();
88
97
 
89
98
  renderElement.definitions = elements.asArray();
@@ -1,9 +1,7 @@
1
- import { Line, LineSegments, Mesh } from "three";
2
1
  import { updateNodeByMatrix4AndBBB } from "../mesh/updateNodeByTransformAndBBB.js";
3
2
  import { LeafNode } from "../../../../core/bvh2/LeafNode.js";
4
3
  import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
5
4
  import { DrawMode } from "./DrawMode.js";
6
- import { applyTransformToThreeObject } from "../mesh/applyTransformToThreeObject.js";
7
5
  import { ShadedGeometryFlags } from "./ShadedGeometryFlags.js";
8
6
 
9
7
  const _aabb3 = new AABB3();
@@ -12,42 +10,6 @@ const DEFAULT_FLAGS = ShadedGeometryFlags.CastShadow
12
10
  | ShadedGeometryFlags.ReceiveShadow
13
11
  ;
14
12
 
15
- /**
16
- *
17
- * @param {ShadedGeometry} sg
18
- * @returns {THREE.Object3D}
19
- */
20
- export function build_three_object(sg) {
21
-
22
- /**
23
- * @type {THREE.Object3D}
24
- */
25
- let object;
26
-
27
- const mode = sg.mode;
28
- const shader = sg.material;
29
- const geo = sg.geometry;
30
-
31
- if (mode === DrawMode.Triangles) {
32
- object = new Mesh(geo, shader);
33
- } else if (mode === DrawMode.Lines) {
34
- object = new Line(geo, shader);
35
- } else if (mode === DrawMode.LineSegments) {
36
- object = new LineSegments(geo, shader);
37
- } else {
38
- throw new Error(`Unsupported draw mode '${mode}'`);
39
- }
40
-
41
- object.matrixAutoUpdate = false;
42
- object.frustumCulled = false;
43
- object.matrixWorldNeedsUpdate = false;
44
-
45
- object.castShadow = sg.getFlag(ShadedGeometryFlags.CastShadow);
46
- object.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
47
-
48
- return object;
49
- }
50
-
51
13
  export class ShadedGeometry {
52
14
  constructor() {
53
15
  /**
@@ -67,13 +29,6 @@ export class ShadedGeometry {
67
29
  */
68
30
  this.mode = DrawMode.Triangles;
69
31
 
70
- /**
71
- *
72
- * @type {THREE.Object3D|null}
73
- * @private
74
- */
75
- this.__cached_object = null;
76
-
77
32
  /**
78
33
  *
79
34
  * @type {LeafNode<ShadedGeometry>}
@@ -88,13 +43,20 @@ export class ShadedGeometry {
88
43
  */
89
44
  this.__entity = -1;
90
45
 
46
+ /**
47
+ *
48
+ * @type {Transform|null}
49
+ * @private
50
+ */
51
+ this.__c_transform = null;
52
+
91
53
  /**
92
54
  * Transform matrix
93
55
  * Transient, assigned in the system
94
56
  * @type {number[]|null}
95
57
  * @private
96
58
  */
97
- this.__transform = null;
59
+ this.__transform = new Float32Array(16);
98
60
 
99
61
  /**
100
62
  * Transient property signifying how to render object
@@ -109,6 +71,14 @@ export class ShadedGeometry {
109
71
  this.flags = DEFAULT_FLAGS;
110
72
  }
111
73
 
74
+ /**
75
+ * @deprecated
76
+ * @private
77
+ */
78
+ get __cached_object(){
79
+ throw new Error('Deprecated');
80
+ }
81
+
112
82
  /**
113
83
  *
114
84
  * @param {number|ShadedGeometryFlags} flag
@@ -182,17 +152,7 @@ export class ShadedGeometry {
182
152
  * @return {null|number[]}
183
153
  */
184
154
  get transform() {
185
- if (this.__transform !== null) {
186
- return this.__transform;
187
- } else if (this.__cached_object !== null) {
188
- return this.__cached_object.matrix.elements;
189
- } else {
190
- return null;
191
- }
192
- }
193
-
194
- __build_object() {
195
- this.__cached_object = build_three_object(this);
155
+ return this.__transform;
196
156
  }
197
157
 
198
158
  get bvh() {
@@ -214,13 +174,6 @@ export class ShadedGeometry {
214
174
  if (geometry.boundingBox === null) {
215
175
  geometry.computeBoundingBox();
216
176
  }
217
-
218
- if (this.__cached_object === null) {
219
- this.__build_object();
220
- } else {
221
- this.__cached_object.material = material;
222
- this.__cached_object.geometry = geometry;
223
- }
224
177
  }
225
178
 
226
179
  /**
@@ -239,11 +192,8 @@ export class ShadedGeometry {
239
192
  }
240
193
 
241
194
  updateTransform() {
242
- const object_3d = this.__cached_object;
243
-
244
- // update matrix
245
- object_3d.updateMatrix();
246
- object_3d.updateMatrixWorld();
195
+ //
196
+ this.__c_transform.toMatrix4(this.__transform);
247
197
 
248
198
  // update bounds
249
199
  const gbb = this.geometry.boundingBox;
@@ -260,56 +210,7 @@ export class ShadedGeometry {
260
210
  max.z
261
211
  );
262
212
 
263
- updateNodeByMatrix4AndBBB(this.__bvh_leaf, _aabb3, object_3d.matrix.elements);
264
- }
265
-
266
- /**
267
- *
268
- * @param {number} x
269
- * @param {number} y
270
- * @param {number} z
271
- */
272
- setPositionByComponents(x, y, z) {
273
-
274
- this.__cached_object.position.set(x, y, z);
275
-
276
- this.updateTransform();
277
- }
278
-
279
- /**
280
- *
281
- * @param {number} x
282
- * @param {number} y
283
- * @param {number} z
284
- * @param {number} w
285
- */
286
- setRotationByComponents(x, y, z, w) {
287
-
288
- this.__cached_object.quaternion.set(x, y, z, w);
289
-
290
- this.updateTransform();
291
- }
292
-
293
- /**
294
- *
295
- * @param {number} x
296
- * @param {number} y
297
- * @param {number} z
298
- */
299
- setScaleByComponents(x, y, z) {
300
- this.__cached_object.scale.set(x, y, z);
301
-
302
- this.updateTransform();
303
- }
304
-
305
- /**
306
- *
307
- * @param {Transform} t
308
- */
309
- applyTransform(t) {
310
- applyTransformToThreeObject(this.__cached_object, t);
311
-
312
- this.updateTransform();
213
+ updateNodeByMatrix4AndBBB(this.__bvh_leaf, _aabb3, this.__transform);
313
214
  }
314
215
  }
315
216
 
@@ -1,6 +1,16 @@
1
1
  import {System} from "../../../ecs/System";
2
2
  import Engine from "../../../Engine";
3
+ import {ShadedGeometry} from "./ShadedGeometry";
4
+ import {SurfacePoint3} from "../../../../core/geom/3d/SurfacePoint3";
3
5
 
4
- export class ShadedGeometrySystem extends System {
6
+ export class ShadedGeometrySystem extends System<ShadedGeometry> {
5
7
  constructor(engine: Engine)
8
+
9
+ raycastNearest(
10
+ contact: SurfacePoint3,
11
+ origin_x: number, origin_y: number, origin_z: number,
12
+ direction_x: number, direction_y: number, direction_z: number,
13
+ filter_function?: (entity: number, mesh: ShadedGeometry) => boolean,
14
+ filter_function_context?: any
15
+ ): { entity: number, mesh: ShadedGeometry } | undefined
6
16
  }
@@ -9,6 +9,7 @@ import { returnTrue } from "../../../../core/function/Functions.js";
9
9
  import { aabb3_intersects_ray } from "../../../../core/bvh2/aabb3/aabb3_intersects_ray.js";
10
10
  import { ShadedGeometryRendererContext } from "./render/ShadedGeometryRendererContext.js";
11
11
  import { BinaryNode } from "../../../../core/bvh2/BinaryNode.js";
12
+ import { assert } from "../../../../core/assert.js";
12
13
 
13
14
  /**
14
15
  *
@@ -66,6 +67,58 @@ export class ShadedGeometrySystem extends System {
66
67
 
67
68
  this.__bvh = new BinaryNode();
68
69
  this.__bvh.setNegativelyInfiniteBounds();
70
+
71
+ /**
72
+ *
73
+ * @type {Map<number, function():AbstractRenderAdapter>}
74
+ * @private
75
+ */
76
+ this.__adapter_suppliers = new Map();
77
+ }
78
+
79
+ /**
80
+ *
81
+ * @param {number} index
82
+ * @param {function():AbstractRenderAdapter} supplier
83
+ */
84
+ register_render_adapter(index, supplier) {
85
+ assert.isNonNegativeInteger(index, 'index');
86
+
87
+ if (this.__adapter_suppliers.has(index)) {
88
+ // slot is already taken
89
+ console.warn(`Render adapter slot '${index}' is already taken, removing old adapter`);
90
+ this.unregister_render_adapter(index);
91
+ }
92
+
93
+ this.__adapter_suppliers.set(index, supplier);
94
+
95
+ this.__view_contexts.forEach((value, key) => {
96
+ value.setAdapter(index, supplier());
97
+ });
98
+ }
99
+
100
+ /**
101
+ *
102
+ * @param {number} index
103
+ * @return {boolean}
104
+ */
105
+ unregister_render_adapter(index) {
106
+ assert.isNonNegativeInteger(index, 'index');
107
+
108
+ const supplier = this.__adapter_suppliers.get(index);
109
+
110
+ if (supplier === undefined) {
111
+ // not found
112
+ return false;
113
+ }
114
+
115
+ this.__adapter_suppliers.delete(index);
116
+
117
+ this.__view_contexts.forEach((value, key) => {
118
+ value.removeAdapter(index);
119
+ });
120
+
121
+ return true;
69
122
  }
70
123
 
71
124
  /**
@@ -74,7 +127,14 @@ export class ShadedGeometrySystem extends System {
74
127
  * @private
75
128
  */
76
129
  __handle_view_added(view) {
77
- this.__view_contexts.set(view, new ShadedGeometryRendererContext());
130
+ const ctx = new ShadedGeometryRendererContext();
131
+
132
+ // attach adapters
133
+ this.__adapter_suppliers.forEach((value, key) => {
134
+ ctx.setAdapter(key, value());
135
+ });
136
+
137
+ this.__view_contexts.set(view, ctx);
78
138
  }
79
139
 
80
140
  /**
@@ -133,11 +193,13 @@ export class ShadedGeometrySystem extends System {
133
193
  * @param {number} entity
134
194
  */
135
195
  link(sg, t, entity) {
136
- t.position.onChanged.add(sg.setPositionByComponents, sg);
137
- t.rotation.onChanged.add(sg.setRotationByComponents, sg);
138
- t.scale.onChanged.add(sg.setScaleByComponents, sg);
196
+ sg.__c_transform = t;
139
197
 
140
- sg.applyTransform(t);
198
+ t.position.onChanged.add(sg.updateTransform, sg);
199
+ t.rotation.onChanged.add(sg.updateTransform, sg);
200
+ t.scale.onChanged.add(sg.updateTransform, sg);
201
+
202
+ sg.updateTransform();
141
203
 
142
204
  const leaf_node = sg.bvh;
143
205
 
@@ -157,9 +219,9 @@ export class ShadedGeometrySystem extends System {
157
219
  * @param {number} entity
158
220
  */
159
221
  unlink(sg, t, entity) {
160
- t.position.onChanged.remove(sg.setPositionByComponents, sg);
161
- t.rotation.onChanged.remove(sg.setRotationByComponents, sg);
162
- t.scale.onChanged.remove(sg.setScaleByComponents, sg);
222
+ t.position.onChanged.remove(sg.updateTransform, sg);
223
+ t.rotation.onChanged.remove(sg.updateTransform, sg);
224
+ t.scale.onChanged.remove(sg.updateTransform, sg);
163
225
 
164
226
  sg.bvh.disconnect();
165
227
  }
@@ -173,7 +235,7 @@ export class ShadedGeometrySystem extends System {
173
235
  * @param {number} direction_x
174
236
  * @param {number} direction_y
175
237
  * @param {number} direction_z
176
- * @param {function(entity:number, mesh:ShadedGeometry)} [filter_function]
238
+ * @param {function(entity:number, mesh:ShadedGeometry):boolean} [filter_function]
177
239
  * @param {*} [filter_function_context]
178
240
  * @returns {{entity:number, mesh:ShadedGeometry}|undefined}
179
241
  */
@@ -183,7 +245,7 @@ export class ShadedGeometrySystem extends System {
183
245
  direction_x, direction_y, direction_z,
184
246
  filter_function = returnTrue, filter_function_context
185
247
  ) {
186
- const root_bvh = this.__render_layer.bvh;
248
+ const root_bvh = this.__bvh;
187
249
  const stack_frame_address = traversal_cursor;
188
250
 
189
251
  traversal_stack[traversal_cursor++] = root_bvh;
@@ -242,9 +304,11 @@ export class ShadedGeometrySystem extends System {
242
304
  mat4.invert(scratch_m4, m4);
243
305
 
244
306
  // transform ray to local space
245
- const local_origin_x = scratch_m4[0] * origin_x + scratch_m4[4] * origin_y + scratch_m4[8] * origin_z + scratch_m4[12];
246
- const local_origin_y = scratch_m4[1] * origin_x + scratch_m4[5] * origin_y + scratch_m4[9] * origin_z + scratch_m4[13];
247
- const local_origin_z = scratch_m4[2] * origin_x + scratch_m4[6] * origin_y + scratch_m4[10] * origin_z + scratch_m4[14];
307
+ const inv_w = 1 / (scratch_m4[3] * origin_x + scratch_m4[7] * origin_y + scratch_m4[11] * origin_z + scratch_m4[15]);
308
+
309
+ const local_origin_x = (scratch_m4[0] * origin_x + scratch_m4[4] * origin_y + scratch_m4[8] * origin_z + scratch_m4[12]) * inv_w;
310
+ const local_origin_y = (scratch_m4[1] * origin_x + scratch_m4[5] * origin_y + scratch_m4[9] * origin_z + scratch_m4[13]) * inv_w;
311
+ const local_origin_z = (scratch_m4[2] * origin_x + scratch_m4[6] * origin_y + scratch_m4[10] * origin_z + scratch_m4[14]) * inv_w;
248
312
 
249
313
  const local_direction_x = scratch_m4[0] * direction_x + scratch_m4[4] * direction_y + scratch_m4[8] * direction_z;
250
314
  const local_direction_y = scratch_m4[1] * direction_x + scratch_m4[5] * direction_y + scratch_m4[9] * direction_z;
@@ -0,0 +1,39 @@
1
+ import { DrawMode } from "./DrawMode.js";
2
+ import { Line, LineSegments, Mesh } from "three";
3
+ import { ShadedGeometryFlags } from "./ShadedGeometryFlags.js";
4
+
5
+ /**
6
+ *
7
+ * @param {ShadedGeometry} sg
8
+ * @returns {THREE.Object3D}
9
+ */
10
+ export function build_three_object(sg) {
11
+
12
+ /**
13
+ * @type {THREE.Object3D}
14
+ */
15
+ let object;
16
+
17
+ const mode = sg.mode;
18
+ const shader = sg.material;
19
+ const geo = sg.geometry;
20
+
21
+ if (mode === DrawMode.Triangles) {
22
+ object = new Mesh(geo, shader);
23
+ } else if (mode === DrawMode.Lines) {
24
+ object = new Line(geo, shader);
25
+ } else if (mode === DrawMode.LineSegments) {
26
+ object = new LineSegments(geo, shader);
27
+ } else {
28
+ throw new Error(`Unsupported draw mode '${mode}'`);
29
+ }
30
+
31
+ object.matrixAutoUpdate = false;
32
+ object.frustumCulled = false;
33
+ object.matrixWorldNeedsUpdate = false;
34
+
35
+ object.castShadow = sg.getFlag(ShadedGeometryFlags.CastShadow);
36
+ object.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
37
+
38
+ return object;
39
+ }
@@ -1,7 +1,8 @@
1
1
  import { queryBinaryNode_FrustumIntersections_Data } from "../../../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
2
- import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
3
- import { InstancedRendererAdapter } from "./InstancedRendererAdapter.js";
4
- import { GenericRendererAdapter } from "./GenericRendererAdapter.js";
2
+ import { AbstractRenderAdapter } from "./adapters/AbstractRenderAdapter.js";
3
+ import { InstancedRendererAdapter } from "./adapters/InstancedRendererAdapter.js";
4
+ import { GenericRendererAdapter } from "./adapters/GenericRendererAdapter.js";
5
+ import { assert } from "../../../../../core/assert.js";
5
6
 
6
7
  /**
7
8
  * 1 - collect visible meshes
@@ -19,7 +20,16 @@ export class ShadedGeometryRendererContext {
19
20
  ];
20
21
  }
21
22
 
23
+ /**
24
+ *
25
+ * @param {number} index
26
+ * @param {AbstractRenderAdapter} adapter
27
+ */
22
28
  setAdapter(index, adapter) {
29
+ assert.isNonNegativeInteger(index, 'index');
30
+ assert.defined(adapter, 'adapter');
31
+ assert.equal(adapter.isShadedGeometryRenderAdapter, true, 'adapter.isShadedGeometryRenderAdapter !== true');
32
+
23
33
  const existing = this.adapters[index];
24
34
  if (existing !== undefined) {
25
35
  // dispose of existing adapter
@@ -29,14 +39,36 @@ export class ShadedGeometryRendererContext {
29
39
  this.adapters[index] = adapter;
30
40
  }
31
41
 
42
+ /**
43
+ *
44
+ * @param {number} index
45
+ * @returns {boolean}
46
+ */
47
+ removeAdapter(index) {
48
+ assert.isNonNegativeInteger(index, 'index');
49
+
50
+ const adapter = this.adapters[index];
51
+
52
+ if (adapter === undefined) {
53
+ return false;
54
+ }
55
+
56
+ delete this.adapters[index];
57
+
58
+ adapter.dispose();
59
+
60
+ return true;
61
+ }
62
+
32
63
  /**
33
64
  *
34
65
  * @param {THREE.Object3D[]} destination
35
66
  * @param {number} destination_offset
67
+ * @param {THREE.WebGLRenderer} renderer
36
68
  * @param {CameraView} view
37
69
  * @param {BinaryNode<ShadedGeometry>} bvh
38
70
  */
39
- collect(destination, destination_offset, view, bvh) {
71
+ collect(destination, destination_offset, renderer, view, bvh) {
40
72
  const adapters = this.adapters;
41
73
  const adapter_count = adapters.length;
42
74
 
@@ -44,7 +76,7 @@ export class ShadedGeometryRendererContext {
44
76
  for (; i < adapter_count; i++) {
45
77
  const adapter = adapters[i];
46
78
 
47
- adapter.build_start();
79
+ adapter.build_start(renderer);
48
80
  }
49
81
 
50
82
 
@@ -35,7 +35,13 @@ export class AbstractRenderAdapter {
35
35
  throw new Error('Not Implemented');
36
36
  }
37
37
 
38
- build_start() {
38
+
39
+ /**
40
+ *
41
+ * @param {THREE.WebGLRenderer} renderer
42
+ * @param {CameraView} view
43
+ */
44
+ build_start(renderer, view) {
39
45
 
40
46
  }
41
47
 
@@ -65,3 +71,9 @@ export class AbstractRenderAdapter {
65
71
 
66
72
  }
67
73
  }
74
+
75
+ /**
76
+ * @readonly
77
+ * @type {boolean}
78
+ */
79
+ AbstractRenderAdapter.prototype.isShadedGeometryRenderAdapter = true;
@@ -1,6 +1,6 @@
1
1
  import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
2
- import { build_three_object } from "../ShadedGeometry.js";
3
- import { array_copy } from "../../../../../core/collection/array/copyArray.js";
2
+ import { array_copy } from "../../../../../../core/collection/array/copyArray.js";
3
+ import { build_three_object } from "../../build_three_object.js";
4
4
 
5
5
  export class GenericRendererAdapter extends AbstractRenderAdapter {
6
6
  constructor() {
@@ -19,7 +19,12 @@ export class GenericRendererAdapter extends AbstractRenderAdapter {
19
19
  return 0;
20
20
  }
21
21
 
22
- build_start() {
22
+ /**
23
+ *
24
+ * @param {THREE.WebGLRenderer} renderer
25
+ * @param {CameraView} view
26
+ */
27
+ build_start(renderer, view) {
23
28
  this.clear();
24
29
  }
25
30
 
@@ -1,12 +1,43 @@
1
1
  import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
2
- import { HashMap } from "../../../../../core/collection/HashMap.js";
3
- import { InstancedMeshGroup } from "../../../geometry/instancing/InstancedMeshGroup.js";
4
- import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
2
+ import { HashMap } from "../../../../../../core/collection/HashMap.js";
3
+ import { InstancedMeshGroup } from "../../../../geometry/instancing/InstancedMeshGroup.js";
4
+ import { ShadedGeometryFlags } from "../../ShadedGeometryFlags.js";
5
+ import { DrawMode } from "../../DrawMode.js";
5
6
 
6
7
  const INSTANCED_EQUALITY_FLAGS = ShadedGeometryFlags.CastShadow
7
8
  | ShadedGeometryFlags.ReceiveShadow
8
9
  ;
9
10
 
11
+ /**
12
+ *
13
+ * @param {ShadedGeometry} a
14
+ * @param {ShadedGeometry} b
15
+ * @returns {number}
16
+ */
17
+ function compare(a, b) {
18
+ const d_geometry = a.geometry.id - b.geometry.id;
19
+ if (d_geometry !== 0) {
20
+ return d_geometry;
21
+ }
22
+
23
+ const d_material = a.material.id - b.material.id;
24
+ if (d_material !== 0) {
25
+ return d_material;
26
+ }
27
+
28
+ const d_flags = (a.flags & INSTANCED_EQUALITY_FLAGS) - (b.flags & INSTANCED_EQUALITY_FLAGS);
29
+ if (d_flags !== 0) {
30
+ return d_flags;
31
+ }
32
+
33
+ const d_mode = a.mode - b.mode;
34
+ if (d_mode !== 0) {
35
+ return d_mode;
36
+ }
37
+
38
+ return 0;
39
+ }
40
+
10
41
  export class InstancedRendererAdapter extends AbstractRenderAdapter {
11
42
  constructor() {
12
43
  super();
@@ -18,11 +49,12 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
18
49
  */
19
50
  this.__instanced_meshes = new HashMap({
20
51
  keyHashFunction(sg) {
21
- return sg.geometry.id ^ sg.material.id;
52
+ return sg.geometry.id ^ sg.material.id ^ sg.mode;
22
53
  },
23
54
  keyEqualityFunction(a, b) {
24
55
  return a.material.id === b.material.id
25
56
  && a.geometry.id === b.geometry.id
57
+ && a.mode === b.mode
26
58
  && (a.flags & INSTANCED_EQUALITY_FLAGS) === (b.flags & INSTANCED_EQUALITY_FLAGS)
27
59
  ;
28
60
  }
@@ -45,7 +77,17 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
45
77
  __get_instanced_mesh(sg) {
46
78
  let im = this.__instanced_meshes.get(sg);
47
79
 
48
- if (im === undefined) {
80
+
81
+ if (im !== undefined) {
82
+
83
+ return im;
84
+
85
+ } else {
86
+
87
+ if (sg.mode !== DrawMode.Triangles) {
88
+ throw new Error(`Unsupported draw mode ${sg.mode}`);
89
+ }
90
+
49
91
  im = new InstancedMeshGroup();
50
92
  im.shrinkFactor = 0; // prevent shrinking as we're essentially rebuilding this geometry frame
51
93
 
@@ -56,9 +98,10 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
56
98
  im.mesh.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
57
99
 
58
100
  this.__instanced_meshes.set(sg, im);
59
- }
60
101
 
61
- return im;
102
+ return im;
103
+
104
+ }
62
105
  }
63
106
 
64
107
  add(sg) {
@@ -66,7 +109,11 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
66
109
 
67
110
  const index = mesh.count;
68
111
 
69
- mesh.ensureCapacity(index + 1);
112
+ const new_size = index + 1;
113
+
114
+ if (new_size > mesh.capacity) {
115
+ mesh.ensureCapacity(new_size);
116
+ }
70
117
 
71
118
  mesh.setTransformAt(index, sg.transform);
72
119
 
@@ -75,18 +122,24 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
75
122
  this.__active_meshes.add(mesh);
76
123
  }
77
124
 
78
- build_start() {
125
+ /**
126
+ *
127
+ * @param {THREE.WebGLRenderer} renderer
128
+ * @param {CameraView} view
129
+ */
130
+ build_start(renderer, view) {
79
131
  this.clear();
80
132
  }
81
133
 
82
134
  build_end() {
135
+ const objects = this.__objects;
83
136
 
84
137
  for (const activeMesh of this.__active_meshes) {
85
138
  // force underlying geometry to update
86
139
  activeMesh.setCount(activeMesh.getCount());
87
140
  activeMesh.requestAttributeUpdate();
88
141
 
89
- this.__objects[this.__object_count++] = activeMesh.mesh;
142
+ objects[this.__object_count++] = activeMesh.mesh;
90
143
  }
91
144
 
92
145
  }
@@ -16,6 +16,7 @@ import GUIElementSystem from "../../../../ecs/gui/GUIElementSystem.js";
16
16
  import Vector3 from "../../../../../core/geom/Vector3.js";
17
17
  import Quaternion from "../../../../../core/geom/Quaternion.js";
18
18
  import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
19
+ import { randomFromArray } from "../../../../../core/math/random/randomFromArray.js";
19
20
 
20
21
  const eh = new EngineHarness();
21
22
 
@@ -51,23 +52,31 @@ async function main(engine) {
51
52
 
52
53
  window.material = material;
53
54
 
54
- const geometry = new BoxBufferGeometry();
55
-
56
55
  const random = seededRandom(0);
57
56
 
58
- for (let i = 0; i < 100000; i++) {
57
+ const INSTANCE_COUNT = 20000;
58
+
59
+ const geometries = [];
60
+
61
+ for (let i = 0; i < 1000; i++) {
62
+ geometries.push(new BoxBufferGeometry());
63
+ }
59
64
 
65
+ for (let i = 0; i < INSTANCE_COUNT; i++) {
66
+ const geometry = randomFromArray(random, geometries);
60
67
  const sg = ShadedGeometry.from(geometry, material);
61
68
 
69
+ // sg.draw_method = DRAW_METHOD_PLAIN;
62
70
  sg.draw_method = DRAW_METHOD_INSTANCED;
71
+ // sg.draw_method = random() > 0.01 ? DRAW_METHOD_INSTANCED : DRAW_METHOD_PLAIN;
63
72
  sg.clearFlag(ShadedGeometryFlags.CastShadow | ShadedGeometryFlags.ReceiveShadow);
64
73
 
65
74
  new EntityBuilder()
66
75
  .add(Transform.fromJSON({
67
76
  position: {
68
- x: randomFloatBetween(random, -50, 50),
77
+ x: randomFloatBetween(random, 0, 20),
69
78
  y: randomFloatBetween(random, 0, 10),
70
- z: randomFloatBetween(random, -50, 50)
79
+ z: randomFloatBetween(random, 0, 20)
71
80
  },
72
81
  rotation: Quaternion.random(random),
73
82
  scale: 0.05
@@ -22,7 +22,6 @@ export function three_object_to_entity_composition(root) {
22
22
  }
23
23
 
24
24
  const sg = ShadedGeometry.from(root.geometry, root.material);
25
- sg.draw_method = 1;
26
25
 
27
26
  entity.add(sg);
28
27
  }
@@ -11,6 +11,7 @@ import { StaticMaterialCache } from "../../../asset/loaders/material/StaticMater
11
11
  import { composeCompile } from "../../material/composeCompile.js";
12
12
  import { typed_array_copy } from "../../../../core/collection/array/typed/typed_array_copy.js";
13
13
  import { rewriteMaterial } from "./rewriteMaterial.js";
14
+ import { max3 } from "../../../../core/math/max3.js";
14
15
 
15
16
  export class InstancedMeshGroup {
16
17
  /**
@@ -69,6 +70,13 @@ export class InstancedMeshGroup {
69
70
  */
70
71
  this.__attributeTransform = null;
71
72
 
73
+ /**
74
+ * Shortcut to buffer attribute data
75
+ * @type {Float32Array}
76
+ * @private
77
+ */
78
+ this.__attributeTransformArray = null;
79
+
72
80
  /**
73
81
  *
74
82
  * @type {Material}
@@ -167,7 +175,7 @@ export class InstancedMeshGroup {
167
175
  if (currentCapacity < size) {
168
176
  // grow
169
177
 
170
- const newCapacityRaw = Math.max(
178
+ const newCapacityRaw = max3(
171
179
  size,
172
180
  currentCapacity * this.growFactor,
173
181
  currentCapacity + this.growConstant
@@ -193,7 +201,7 @@ export class InstancedMeshGroup {
193
201
  * @param {number[]|ArrayLike<number>|Float32Array} transform 4x4 transform matrix of the instance
194
202
  */
195
203
  setTransformAt(index, transform) {
196
- this.__attributeTransform.array.set(transform, index * 16);
204
+ this.__attributeTransformArray.set(transform, index * 16);
197
205
  }
198
206
 
199
207
  requestAttributeUpdate() {
@@ -357,6 +365,7 @@ export class InstancedMeshGroup {
357
365
  }
358
366
 
359
367
  //rewrite old attributes
368
+ this.__attributeTransformArray = newTransformArray;
360
369
  this.__attributeTransform = new InstancedBufferAttribute(newTransformArray, 16);
361
370
  this.__attributeTransform.setUsage(StreamDrawUsage);
362
371
 
@@ -0,0 +1,150 @@
1
+ import { AbstractRenderAdapter } from "../../../ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js";
2
+ import Vector2 from "../../../../../core/geom/Vector2.js";
3
+ import { MaterialVertexSpec } from "../../render/v1/MaterialVertexSpec.js";
4
+
5
+ /**
6
+ *
7
+ * @type {MaterialVertexSpec}
8
+ */
9
+ const scratch_mvc = new MaterialVertexSpec();
10
+
11
+ class MicronRenderContext {
12
+
13
+ }
14
+
15
+ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
16
+ constructor({
17
+ vgtr
18
+ }) {
19
+ super();
20
+
21
+ /**
22
+ * @type {VGThreeRenderer}
23
+ * @private
24
+ */
25
+ this.__vgtr = vgtr;
26
+
27
+ /**
28
+ *
29
+ * @type {VirtualGeometry|null}
30
+ * @private
31
+ */
32
+ this.__vg = null;
33
+
34
+ /**
35
+ *
36
+ * @type {VirtualGeometryBuilder|null}
37
+ * @private
38
+ */
39
+ this.__vgb = null;
40
+
41
+ /**
42
+ *
43
+ * @type {Map<number, MicronGeometry>}
44
+ * @private
45
+ */
46
+ this.__geometry_map = new Map();
47
+
48
+ /**
49
+ *
50
+ * @type {Set<MaterialContext>}
51
+ * @private
52
+ */
53
+ this.__active_contexts = new Set();
54
+ }
55
+
56
+ add(sg) {
57
+
58
+ const micron_geometry = this.__geometry_map.get(sg.geometry.id);
59
+
60
+ // populate virtual geometry for this instance
61
+ this.__vgb.buildForMesh(sg.entity, micron_geometry, sg.transform);
62
+
63
+ }
64
+
65
+ /**
66
+ *
67
+ * @param {THREE.WebGLRenderer} renderer
68
+ * @param {CameraView} view
69
+ */
70
+ build_start(renderer, view) {
71
+ const resolution = new Vector2();
72
+ let pixelRatio = 1;
73
+
74
+ /**
75
+ *
76
+ * @type {THREE.RenderTarget}
77
+ */
78
+ const render_target = renderer.getRenderTarget();
79
+
80
+ if (render_target !== null) {
81
+ resolution.set(render_target.width, render_target.height);
82
+ } else {
83
+ renderer.getSize(resolution);
84
+ pixelRatio = renderer.getPixelRatio();
85
+ }
86
+
87
+ const vg_builder = this.__vgb;
88
+
89
+ vg_builder.resolution.set(resolution.x * pixelRatio, resolution.y * pixelRatio);
90
+ vg_builder.setMatricesFromCamera(view.camera);
91
+ vg_builder.setOutput(this.__vg);
92
+
93
+ vg_builder.build();
94
+ }
95
+
96
+ build_end() {
97
+ const contexts = this.__contexts_array;
98
+ const context_count = contexts.length;
99
+
100
+ /**
101
+ *
102
+ * @type {Map<number, MaterialContext>}
103
+ */
104
+ const instance_to_ctx = new Map();
105
+
106
+ for (let i = 0; i < context_count; i++) {
107
+ const ctx = contexts[i];
108
+ ctx.__patch_count = 0;
109
+
110
+ for (const instance of ctx.instances) {
111
+ instance_to_ctx.set(instance, ctx);
112
+ }
113
+ }
114
+
115
+ // sort patches into relevant contexts
116
+ const geometry = this.geometry;
117
+ const patch_count = geometry.patch_count;
118
+ const patches = geometry.patches;
119
+
120
+ for (let i = 0; i < patch_count; i++) {
121
+ const i3 = i * 3;
122
+
123
+ const instance_id = patches[i3];
124
+ const geometry_id = patches[i3 + 1];
125
+ const patch_id = patches[i3 + 2];
126
+
127
+ const ctx = instance_to_ctx.get(instance_id);
128
+
129
+ const target_address = ctx.__patch_count * 3;
130
+ ctx.__patch_count++;
131
+
132
+ const ctx_patches = ctx.__patches;
133
+
134
+ ctx_patches[target_address] = instance_id;
135
+ ctx_patches[target_address + 1] = geometry_id;
136
+ ctx_patches[target_address + 2] = patch_id;
137
+ }
138
+
139
+ // build each context
140
+ for (let i = 0; i < context_count; i++) {
141
+ const ctx = contexts[i];
142
+
143
+ ctx.build(this.geometry);
144
+ }
145
+ }
146
+
147
+ dispose() {
148
+
149
+ }
150
+ }
@@ -141,13 +141,11 @@ export class VirtualGeometryBuilder {
141
141
  * @param {number} instance_id
142
142
  * @param {MicronGeometry} geometry
143
143
  * @param {number[]} transform world transform matrix of the instance
144
- * @param {ActivePatchList} apl
145
144
  */
146
145
  buildForMesh(
147
146
  instance_id,
148
147
  geometry,
149
- transform,
150
- apl
148
+ transform
151
149
  ) {
152
150
  refinement_spec.build(transform, this.view_projection_matrix);
153
151
 
@@ -42,13 +42,6 @@ export class ThreeInstancedAdapter {
42
42
 
43
43
  this.__uniforms = Object.assign({}, this.__patch_data.genUniforms());
44
44
 
45
- /**
46
- *
47
- * @type {WebGL2RenderingContext|null}
48
- * @private
49
- */
50
- this.__gl_context = null;
51
-
52
45
  /**
53
46
  *
54
47
  * @type {Signal}
@@ -73,8 +73,7 @@ export class MaterialContext {
73
73
  return this.instances.has(occurrence.instance_id);
74
74
  }
75
75
 
76
- init(gl) {
77
- this.adapter.__gl_context = gl;
76
+ init() {
78
77
 
79
78
  const material = this.material.clone();
80
79
 
@@ -19,13 +19,6 @@ export class VGThreeRenderer {
19
19
 
20
20
  this.builder = new VirtualGeometryBuilder();
21
21
 
22
- /**
23
- *
24
- * @type {WebGL2RenderingContext|null}
25
- * @private
26
- */
27
- this.__gl_context = null;
28
-
29
22
  /**
30
23
  *
31
24
  * @type {Map<MaterialVertexSpec, MaterialContext>}
@@ -89,7 +82,7 @@ export class VGThreeRenderer {
89
82
 
90
83
  const ctx = new MaterialContext(spec, m);
91
84
 
92
- ctx.init(this.__gl_context);
85
+ ctx.init();
93
86
 
94
87
  this.material_contexts.set(key, ctx);
95
88
  this.__contexts_array.push(ctx);
@@ -189,12 +182,13 @@ export class VGThreeRenderer {
189
182
  const ctx = instance_to_ctx.get(instance_id);
190
183
 
191
184
  const target_address = ctx.__patch_count * 3;
185
+ ctx.__patch_count++;
192
186
 
193
- ctx.__patches[target_address] = instance_id;
194
- ctx.__patches[target_address + 1] = geometry_id;
195
- ctx.__patches[target_address + 2] = patch_id;
187
+ const ctx_patches = ctx.__patches;
196
188
 
197
- ctx.__patch_count++;
189
+ ctx_patches[target_address] = instance_id;
190
+ ctx_patches[target_address + 1] = geometry_id;
191
+ ctx_patches[target_address + 2] = patch_id;
198
192
  }
199
193
 
200
194
  // build each context
@@ -1,6 +1,5 @@
1
1
  import { ParticleEmitterFlag } from "../../emitter/ParticleEmitterFlag.js";
2
2
  import { PARTICLE_ATTRIBUTE_DEATH_AGE, PARTICLE_ATTRIBUTE_POSITION } from "../../emitter/PARTICLE_ATTRIBUTES.js";
3
- import { EmissionShapeType } from "../../emitter/EmissionShapeType.js";
4
3
  import { Matrix4 } from "three";
5
4
  import { composeMatrix4 } from "../../../../../util/composeMatrix4.js";
6
5
  import Quaternion from "../../../../../../../core/geom/Quaternion.js";
@@ -14,55 +13,6 @@ import { SerializationMetadata } from "../../../../../../ecs/components/Serializ
14
13
  import { UnitCubeShape3D } from "../../../../../../../core/geom/3d/shape/UnitCubeShape3D.js";
15
14
  import { shape_from_json } from "../../../../../../../core/geom/3d/shape/json/shape_from_json.js";
16
15
 
17
- /**
18
- *
19
- * @param {ParticleLayer} layer
20
- * @returns {number}
21
- */
22
- function computeLayerVolume(layer) {
23
- let base_volume = 0;
24
-
25
- switch (layer.emissionShape) {
26
- case EmissionShapeType.Box:
27
- base_volume = 1;
28
- break;
29
- case EmissionShapeType.Sphere:
30
- base_volume = 0.5236;
31
- break;
32
- case EmissionShapeType.Point:
33
- base_volume = 0;
34
- break;
35
- }
36
-
37
- const scale_volume = layer.scale.x * layer.scale.y * layer.scale.z;
38
-
39
- return base_volume * scale_volume;
40
- }
41
-
42
- /**
43
- *
44
- * @param {ParticleEmitter} emitter
45
- * @param {Transform} transform
46
- * @returns {number}
47
- */
48
- function computeEmitterVolume(emitter, transform) {
49
-
50
- const layers = emitter.layers;
51
- const n = layers.length;
52
-
53
- let layer_volume_sum = 0;
54
-
55
- for (let i = 0; i < n; i++) {
56
- const particleLayer = layers.get(i);
57
-
58
- layer_volume_sum += computeLayerVolume(particleLayer);
59
- }
60
-
61
- const scale_volume = transform.scale.x * transform.scale.y * transform.scale.z;
62
-
63
- return layer_volume_sum * scale_volume;
64
- }
65
-
66
16
  const DEFAULT_ATTRIBUTE_VALUES = {
67
17
  color: [1, 1, 1, 1],
68
18
  age: [0],
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.35.1",
8
+ "version": "2.35.4",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",