@woosh/meep-engine 2.34.32 → 2.34.36

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 (56) hide show
  1. package/core/assert.js +11 -0
  2. package/core/binary/BitSet.js +5 -0
  3. package/core/bvh2/BinaryNode.js +210 -74
  4. package/core/bvh2/Node.d.ts +3 -0
  5. package/core/bvh2/aabb3/AABB3.js +50 -4
  6. package/core/bvh2/aabb3/AABB3Math.js +1 -1
  7. package/core/bvh2/aabb3/aabb3_from_v3_array.js +34 -0
  8. package/core/bvh2/aabb3/aabb3_from_v3_array_transformed.js +39 -0
  9. package/core/bvh2/aabb3/aabb3_intersects_frustum_degree.js +46 -0
  10. package/core/bvh2/transform/RotationOptimizer.js +2 -262
  11. package/core/bvh2/transform/tryRotateSingleNode.js +259 -0
  12. package/core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js +16 -35
  13. package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +52 -0
  14. package/core/collection/list/List.js +0 -34
  15. package/core/events/signal/Signal.js +1 -1
  16. package/core/geom/3d/aabb/aabb3_matrix4_project.js +2 -3
  17. package/core/geom/Quaternion.d.ts +2 -0
  18. package/engine/Engine.js +5 -0
  19. package/engine/asset/loaders/ArrayBufferLoader.js +7 -0
  20. package/engine/asset/loaders/image/ImageRGBADataLoader.js +11 -6
  21. package/engine/development/performance/AbstractMetric.js +4 -0
  22. package/engine/development/performance/RingBufferMetric.js +4 -0
  23. package/engine/ecs/EntityBuilder.js +12 -5
  24. package/engine/ecs/EntityComponentDataset.js +26 -6
  25. package/engine/ecs/attachment/AttachmentSystem.js +1 -1
  26. package/engine/ecs/attachment/TransformAttachmentBinding.js +0 -1
  27. package/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +1 -31
  28. package/engine/ecs/foliage/InstancedFoliage.js +81 -152
  29. package/engine/ecs/foliage/ViewState.js +190 -0
  30. package/engine/ecs/foliage/ecs/Foliage2System.js +80 -12
  31. package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +30 -0
  32. package/engine/ecs/foliage/ecs/InstancedMeshLayer.js +16 -0
  33. package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +2 -2
  34. package/engine/ecs/parent/EntityNode.js +31 -49
  35. package/engine/ecs/sockets/AttachmentSockets.js +11 -1
  36. package/engine/ecs/transform-attachment/TransformAttachment.js +88 -0
  37. package/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -0
  38. package/engine/graphics/GraphicsEngine.js +23 -2
  39. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +2 -19
  40. package/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +21 -21
  41. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +9 -1
  42. package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +4 -1
  43. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +3 -0
  44. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +40 -8
  45. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +3 -3
  46. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +17 -11
  47. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +1 -34
  48. package/engine/graphics/micron/build/fill_patch_geometry_data.js +19 -6
  49. package/engine/graphics/micron/format/MicronGeometry.js +21 -0
  50. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -3
  51. package/engine/graphics/micron/prototypeVirtualGeometry.js +69 -1
  52. package/engine/graphics/render/layers/RenderLayer.js +22 -85
  53. package/engine/graphics/render/visibility/VisibilityComputer.js +23 -103
  54. package/engine/sound/ecs/emitter/SoundEmitterSystem.js +1 -1
  55. package/package.json +1 -1
  56. package/samples/terrain/editor.js +0 -1
@@ -12,6 +12,36 @@ export class InstancedMeshComponent {
12
12
  this.layers = new List();
13
13
  }
14
14
 
15
+ /**
16
+ *
17
+ * @param {CameraView} view
18
+ */
19
+ add_view(view) {
20
+ const layers = this.layers;
21
+ const layer_count = layers.length;
22
+
23
+ for (let i = 0; i < layer_count; i++) {
24
+ const layer = layers.get(i);
25
+
26
+ layer.add_view(view);
27
+ }
28
+ }
29
+
30
+ /**
31
+ *
32
+ * @param {CameraView} view
33
+ */
34
+ remove_view(view) {
35
+ const layers = this.layers;
36
+ const layer_count = layers.length;
37
+
38
+ for (let i = 0; i < layer_count; i++) {
39
+ const layer = layers.get(i);
40
+
41
+ layer.remove_view(view);
42
+ }
43
+ }
44
+
15
45
  toJSON() {
16
46
  return this.layers.toJSON();
17
47
  }
@@ -36,6 +36,22 @@ export class InstancedMeshLayer {
36
36
  this.receiveShadow = new ObservedBoolean(false);
37
37
  }
38
38
 
39
+ /**
40
+ *
41
+ * @param {CameraView} view
42
+ */
43
+ add_view(view) {
44
+ this.data.add_view(view);
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @param {CameraView} view
50
+ */
51
+ remove_view(view) {
52
+ this.data.remove_view(view);
53
+ }
54
+
39
55
  dispose() {
40
56
  this.data.dispose();
41
57
  }
@@ -223,8 +223,8 @@ export function optimizeIndividualMeshesEntitiesToInstances(dataset, threshold =
223
223
  layer.castShadow.set(true);
224
224
  layer.receiveShadow.set(true);
225
225
 
226
- instancedFoliage.instances.mesh.castShadow = layer.castShadow.getValue();
227
- instancedFoliage.instances.mesh.receiveShadow = layer.receiveShadow.getValue();
226
+ instancedFoliage.castShadow = layer.castShadow.getValue();
227
+ instancedFoliage.receiveShadow = layer.receiveShadow.getValue();
228
228
 
229
229
  foliage2.layers.add(layer);
230
230
 
@@ -3,10 +3,8 @@ import EntityBuilder from "../EntityBuilder.js";
3
3
  import { array_remove_first } from "../../../core/collection/array/array_remove_first.js";
4
4
  import { assert } from "../../../core/assert.js";
5
5
  import { array_push_if_unique } from "../../../core/collection/array/array_push_if_unique.js";
6
- import { Attachment } from "../attachment/Attachment.js";
7
- import { AttachmentSockets } from "../sockets/AttachmentSockets.js";
8
- import { AttachmentSocket } from "../sockets/AttachmentSocket.js";
9
6
  import { Transform } from "../transform/Transform.js";
7
+ import { TransformAttachment } from "../transform-attachment/TransformAttachment.js";
10
8
 
11
9
  export class EntityNode {
12
10
  /**
@@ -81,14 +79,15 @@ export class EntityNode {
81
79
  * @private
82
80
  */
83
81
  __safe_get_attachment() {
84
- let attachment = this.__entity.getComponent(Attachment);
82
+ const entity = this.__entity;
83
+
84
+ let attachment = entity.getComponent(TransformAttachment);
85
85
 
86
86
  if (attachment === null) {
87
- attachment = new Attachment();
88
- attachment.socket = "root";
87
+ attachment = new TransformAttachment();
89
88
  attachment.immediate = true;
90
89
 
91
- this.__entity.add(attachment);
90
+ entity.add(attachment);
92
91
  }
93
92
 
94
93
  return attachment;
@@ -114,43 +113,44 @@ export class EntityNode {
114
113
  * @param {EntityNode|null} node
115
114
  */
116
115
  set parent(node) {
116
+ this.__parent = node;
117
+
117
118
  // check if entity is built
118
- if (this.__entity.isBuilt) {
119
- // live re-wiring
120
- let parent_entity = this.__entity.removeComponent(ParentEntity);
121
- let attachment = this.__entity.removeComponent(Attachment);
119
+ if (!this.__entity.isBuilt) {
120
+ return;
121
+ }
122
122
 
123
- if (node !== null) {
123
+ let parent_entity = this.__entity.removeComponent(ParentEntity);
124
+ let attachment = this.__entity.removeComponent(TransformAttachment);
124
125
 
125
- // handle component ParentEntity
126
+ if (node !== null) {
126
127
 
127
- if (parent_entity === null) {
128
- parent_entity = new ParentEntity();
129
- }
128
+ // handle component ParentEntity
130
129
 
131
- const parent_entity_builder = node.entity;
130
+ if (parent_entity === null) {
131
+ parent_entity = new ParentEntity();
132
+ }
132
133
 
133
- if (!parent_entity_builder.isBuilt) {
134
- throw new Error('Parent entity is not built');
135
- }
134
+ const parent_entity_builder = node.entity;
136
135
 
137
- const parent_entity_id = parent_entity_builder.entity;
138
- parent_entity.entity = parent_entity_id;
136
+ if (!parent_entity_builder.isBuilt) {
137
+ throw new Error('Parent entity is not built');
138
+ }
139
139
 
140
- // add component back
141
- this.__entity.add(parent_entity);
140
+ const parent_entity_id = parent_entity_builder.entity;
141
+ parent_entity.entity = parent_entity_id;
142
142
 
143
+ // add component back
144
+ this.__entity.add(parent_entity);
143
145
 
144
- // handle component Attachment
145
- if (attachment === null) {
146
- attachment = this.__safe_get_attachment();
147
- }
148
146
 
149
- attachment.parent = parent_entity_id;
147
+ // handle component Attachment
148
+ if (attachment === null) {
149
+ attachment = this.__safe_get_attachment();
150
150
  }
151
- }
152
151
 
153
- this.__parent = node;
152
+ attachment.parent = parent_entity_id;
153
+ }
154
154
  }
155
155
 
156
156
  get entity() {
@@ -229,24 +229,6 @@ export class EntityNode {
229
229
  attachment.parent = parent_entity_id;
230
230
  }
231
231
 
232
- // ensure "root" socket exists for transform parenting
233
- /**
234
- *
235
- * @type {AttachmentSockets}
236
- */
237
- let sockets = this.__entity.getComponent(AttachmentSockets);
238
- if (sockets === null) {
239
- sockets = new AttachmentSockets();
240
- this.__entity.add(sockets);
241
- }
242
-
243
- if (sockets.get("root") === undefined) {
244
- const socket = new AttachmentSocket();
245
- socket.id = "root";
246
-
247
- sockets.add(socket);
248
- }
249
-
250
232
  this.__transform_sync_down();
251
233
  this.__transform.position.onChanged.add(this.__transform_sync_down, this);
252
234
  this.__transform.scale.onChanged.add(this.__transform_sync_down, this);
@@ -18,7 +18,17 @@ export class AttachmentSockets {
18
18
  * @returns {AttachmentSocket|undefined}
19
19
  */
20
20
  get(id) {
21
- return this.elements.find(s => s.id === id);
21
+ const elements = this.elements;
22
+ const n = elements.length;
23
+
24
+ for (let i = 0; i < n; i++) {
25
+ const socket = elements.get(i);
26
+
27
+ if (socket.id === id) {
28
+ return socket;
29
+ }
30
+ }
31
+
22
32
  }
23
33
 
24
34
  /**
@@ -0,0 +1,88 @@
1
+ import { Transform } from "../transform/Transform.js";
2
+
3
+ export const TransformAttachmentFlags = {
4
+ /**
5
+ * Update will be performed when component is attached.
6
+ * It's used to turn this flag off when you know that the child's transform is already correct to save some computations
7
+ */
8
+ Immediate: 1
9
+ };
10
+
11
+ const DEFAULT_FLAGS = TransformAttachmentFlags.Immediate;
12
+
13
+ export class TransformAttachment {
14
+ constructor() {
15
+ /**
16
+ * transform relative to the attachment target
17
+ * @type {Transform}
18
+ */
19
+ this.transform = new Transform();
20
+
21
+ /**
22
+ * Which entity to attach to
23
+ * @type {number}
24
+ */
25
+ this.parent = -1;
26
+
27
+ /**
28
+ *
29
+ * @type {number}
30
+ */
31
+ this.flags = DEFAULT_FLAGS;
32
+ }
33
+
34
+ get immediate() {
35
+ return this.getFlag(TransformAttachmentFlags.Immediate);
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @param {boolean} v
41
+ */
42
+ set immediate(v) {
43
+ this.writeFlag(TransformAttachmentFlags.Immediate, v);
44
+ }
45
+
46
+ /**
47
+ *
48
+ * @param {number|TransformAttachmentFlags} flag
49
+ * @returns {void}
50
+ */
51
+ setFlag(flag) {
52
+ this.flags |= flag;
53
+ }
54
+
55
+ /**
56
+ *
57
+ * @param {number|TransformAttachmentFlags} flag
58
+ * @returns {void}
59
+ */
60
+ clearFlag(flag) {
61
+ this.flags &= ~flag;
62
+ }
63
+
64
+ /**
65
+ *
66
+ * @param {number|TransformAttachmentFlags} flag
67
+ * @param {boolean} value
68
+ */
69
+ writeFlag(flag, value) {
70
+ if (value) {
71
+ this.setFlag(flag);
72
+ } else {
73
+ this.clearFlag(flag);
74
+ }
75
+ }
76
+
77
+ /**
78
+ *
79
+ * @param {number|TransformAttachmentFlags} flag
80
+ * @returns {boolean}
81
+ */
82
+ getFlag(flag) {
83
+ return (this.flags & flag) === flag;
84
+ }
85
+
86
+ }
87
+
88
+ TransformAttachment.typeName = "TransformAttachment"
@@ -0,0 +1,59 @@
1
+ import { System } from "../System.js";
2
+ import { TransformAttachment, TransformAttachmentFlags } from "./TransformAttachment.js";
3
+ import { Transform } from "../transform/Transform.js";
4
+
5
+ /**
6
+ *
7
+ * @param {Transform} parent_transform
8
+ * @param {Transform} attachment_transform
9
+ * @param {Transform} child_transform
10
+ */
11
+ function update(parent_transform, attachment_transform, child_transform) {
12
+ child_transform.multiplyTransforms(parent_transform, attachment_transform);
13
+ }
14
+
15
+ export class TransformAttachmentSystem extends System {
16
+ constructor() {
17
+ super();
18
+
19
+ this.dependencies = [TransformAttachment, Transform];
20
+ }
21
+
22
+ /**
23
+ *
24
+ * @param {TransformAttachment} attachment
25
+ * @param {Transform} transform
26
+ * @param {number} entity
27
+ */
28
+ __update_one(attachment, transform, entity) {
29
+
30
+ const em = this.entityManager;
31
+ const ecd = em.dataset;
32
+
33
+ const parent_transform = ecd.getComponent(attachment.parent, Transform);
34
+
35
+ update(parent_transform, attachment.transform, transform);
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @param {TransformAttachment} attachment
41
+ * @param {Transform} transform
42
+ * @param {number} entity
43
+ */
44
+ link(attachment, transform, entity) {
45
+ if ((attachment.flags & TransformAttachmentFlags.Immediate) !== 0) {
46
+ this.__update_one(attachment, transform, entity);
47
+ }
48
+ }
49
+
50
+ /**
51
+ *
52
+ * @param {TransformAttachment} attachment
53
+ * @param {Transform} transform
54
+ * @param {number} entity
55
+ */
56
+ unlink(attachment, transform, entity) {
57
+
58
+ }
59
+ }
@@ -26,7 +26,6 @@ import EmptyView from "../../view/elements/EmptyView.js";
26
26
  import { assert } from "../../core/assert.js";
27
27
  import { RenderLayerManager } from "./render/layers/RenderLayerManager.js";
28
28
  import { FrameBufferManager } from "./render/buffer/FrameBufferManager.js";
29
- import { SOURCE_RENDER_LAYER_PROPERTY } from "./render/visibility/VisibilityComputer.js";
30
29
  import { ColorAndDepthFrameBuffer } from "./render/buffer/buffers/ColorAndDepthFrameBuffer.js";
31
30
  import { RenderPassType } from "./render/RenderPassType.js";
32
31
  import { renderTextureToScreenQuad } from "./render/utils/renderTextureToScreenQuad.js";
@@ -527,6 +526,26 @@ GraphicsEngine.prototype.clearVisibleGroup = function () {
527
526
  this.visibleGroup.children.length = 0;
528
527
  };
529
528
 
529
+ /**
530
+ *
531
+ * @param {THREE.Object3D} object
532
+ * @returns {RenderPassType}
533
+ */
534
+ function classifyPassTypeFromObject(object) {
535
+ if (object.isMesh || object.isPoints) {
536
+
537
+ /**
538
+ * @type {THREE.Material}
539
+ */
540
+ const material = object.material;
541
+ if (material.transparent) {
542
+ return RenderPassType.Transparent;
543
+ }
544
+ }
545
+
546
+ return RenderPassType.Opaque;
547
+ }
548
+
530
549
  /**
531
550
  *
532
551
  * @param {RenderPassType} passType
@@ -545,7 +564,9 @@ GraphicsEngine.prototype.prepareRenderPass = function (passType) {
545
564
  for (let i = 0; i < element_count; i++) {
546
565
  const object3D = visible_objects.elements[i];
547
566
 
548
- if (object3D[SOURCE_RENDER_LAYER_PROPERTY].renderPass === passType) {
567
+ const object_pass = classifyPassTypeFromObject(object3D);
568
+
569
+ if (object_pass === passType) {
549
570
 
550
571
  //insert object, bypassing Object#add for speed
551
572
  //visibleGroup.add(object3D);
@@ -6,8 +6,6 @@ import { threeUpdateTransform } from "../../../../util/threeUpdateTransform.js";
6
6
  import { ShadowMap } from "../../shadow/ShadowMap.js";
7
7
  import { CameraView } from "../../../../render/view/CameraView.js";
8
8
  import { DoubleSide, Mesh, MeshDepthMaterial, RGBADepthPacking, Scene } from "three";
9
- import { SOURCE_RENDER_LAYER_PROPERTY } from "../../../../render/visibility/VisibilityComputer.js";
10
- import { RenderPassType } from "../../../../render/RenderPassType.js";
11
9
  import { ThreeBypassRenderer } from "../../../../render/utils/ThreeBypassRenderer.js";
12
10
 
13
11
  const shadow_scene = new Scene();
@@ -27,7 +25,8 @@ const __depth_material = new MeshDepthMaterial({
27
25
  * @private
28
26
  */
29
27
  function __getDepthMaterial(object) {
30
- let result = null;
28
+ let result;
29
+
31
30
  const customDepthMaterial = object.customDepthMaterial;
32
31
 
33
32
  if (customDepthMaterial !== undefined) {
@@ -39,21 +38,6 @@ function __getDepthMaterial(object) {
39
38
  return result;
40
39
  }
41
40
 
42
- /**
43
- *
44
- * @param {THREE.Object3D} object3D
45
- * @return {boolean}
46
- */
47
- function scene_input_filter(object3D) {
48
- const layer = object3D[SOURCE_RENDER_LAYER_PROPERTY];
49
-
50
- if (layer === undefined) {
51
- return false;
52
- }
53
-
54
- return layer.renderPass === RenderPassType.Opaque
55
- }
56
-
57
41
  /**
58
42
  *
59
43
  * @param {THREE.Object3D} object3D
@@ -261,7 +245,6 @@ export class ThreeLightBinding extends LightBinding {
261
245
  input: visible_objects.elements,
262
246
  input_size: visible_object_count,
263
247
  material_extractor: __getDepthMaterial,
264
- input_filter: scene_input_filter,
265
248
  object_filter: scene_object_filter
266
249
  })
267
250
 
@@ -1,21 +1,28 @@
1
- import { Matrix4 as ThreeMatrix4 } from "three";
2
- import { aabb3_matrix4_project_by_corners } from "../../../../core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js";
1
+ import { aabb3_matrix4_project } from "../../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
3
2
 
3
+ /**
4
+ * Common buffer for scratch objects for better cache locality
5
+ * @type {ArrayBuffer}
6
+ */
7
+ const scratch_buffer = new ArrayBuffer(28 * 4);
4
8
 
5
- const matrix4 = new ThreeMatrix4();
9
+ /**
10
+ *
11
+ * @type {Float32Array}
12
+ */
13
+ const scratch_matrix4 = new Float32Array(scratch_buffer, 0, 16);
6
14
 
7
15
  /**
8
- * Used to store AABB3 corners during bounding box calculation
9
- * @readonly
10
- * @type {Float64Array}
16
+ *
17
+ * @type {Float32Array}
11
18
  */
12
- const corners = new Float64Array(24);
19
+ const scratch_aabb_0 = new Float32Array(scratch_buffer, 64, 6);
13
20
 
14
21
  /**
15
22
  *
16
23
  * @type {Float32Array}
17
24
  */
18
- const scratch_aabb = new Float32Array(6);
25
+ const scratch_aabb_1 = new Float32Array(scratch_buffer, 88, 6);
19
26
 
20
27
  /**
21
28
  *
@@ -24,30 +31,23 @@ const scratch_aabb = new Float32Array(6);
24
31
  * @param {Transform} transform
25
32
  */
26
33
  export function updateNodeByTransformAndBBB(bvh, boundingBox, transform) {
27
- transform.toThreeMatrix(matrix4);
34
+ transform.toMatrix4(scratch_matrix4);
28
35
 
29
- /**
30
- * Shortcut elements for faster access
31
- * @type {number[]}
32
- */
33
- const e = matrix4.elements;
34
-
35
- updateNodeByMatrix4AndBBB(bvh, boundingBox, e);
36
+ updateNodeByMatrix4AndBBB(bvh, boundingBox, scratch_matrix4);
36
37
  }
37
38
 
38
39
  /**
39
40
  *
40
41
  * @param {LeafNode} bvh
41
42
  * @param {AABB3} boundingBox
42
- * @param {number[]} matrix4
43
+ * @param {ArrayLike<number>|number[]|Float32Array} matrix4
43
44
  */
44
45
  export function updateNodeByMatrix4AndBBB(bvh, boundingBox, matrix4) {
45
- boundingBox.getCorners(corners);
46
-
46
+ boundingBox.writeToArray(scratch_aabb_1, 0);
47
47
 
48
- aabb3_matrix4_project_by_corners(scratch_aabb, corners, matrix4);
48
+ aabb3_matrix4_project(scratch_aabb_0, scratch_aabb_1, matrix4);
49
49
 
50
- bvh.readFromArray(scratch_aabb, 0);
50
+ bvh.readFromArray(scratch_aabb_0, 0);
51
51
 
52
52
  bvh.bubbleRefit();
53
53
  }
@@ -4,9 +4,14 @@ import { LeafNode } from "../../../../core/bvh2/LeafNode.js";
4
4
  import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
5
5
  import { DrawMode } from "./DrawMode.js";
6
6
  import { applyTransformToThreeObject } from "../mesh/applyTransformToThreeObject.js";
7
+ import { ShadedGeometryFlags } from "./ShadedGeometryFlags.js";
7
8
 
8
9
  const _aabb3 = new AABB3();
9
10
 
11
+ const DEFAULT_FLAGS = ShadedGeometryFlags.CastShadow
12
+ | ShadedGeometryFlags.ReceiveShadow
13
+ ;
14
+
10
15
  export class ShadedGeometry {
11
16
  constructor() {
12
17
  /**
@@ -58,7 +63,7 @@ export class ShadedGeometry {
58
63
  *
59
64
  * @type {number}
60
65
  */
61
- this.flags = 0;
66
+ this.flags = DEFAULT_FLAGS;
62
67
  }
63
68
 
64
69
  /**
@@ -147,6 +152,9 @@ export class ShadedGeometry {
147
152
  object.matrixAutoUpdate = false;
148
153
  object.frustumCulled = false;
149
154
 
155
+ object.castShadow = this.getFlag(ShadedGeometryFlags.CastShadow);
156
+ object.receiveShadow = this.getFlag(ShadedGeometryFlags.ReceiveShadow);
157
+
150
158
  this.__cached_object = object;
151
159
  }
152
160
 
@@ -3,5 +3,8 @@
3
3
  * @enum {number}
4
4
  */
5
5
  export const ShadedGeometryFlags = {
6
- InView: 1
6
+ InView: 1,
7
+
8
+ CastShadow: 2,
9
+ ReceiveShadow: 4,
7
10
  };
@@ -81,6 +81,9 @@ export class ShadedGeometrySystem extends System {
81
81
 
82
82
  const leaf_node = sg.bvh;
83
83
 
84
+ // record entity on the BVH leaf
85
+ leaf_node.entity = entity;
86
+
84
87
  // remember entity for lookups
85
88
  sg.__entity = entity;
86
89
 
@@ -4,6 +4,8 @@ import { GameAssetType } from "../../../../asset/GameAssetType.js";
4
4
  import { EngineConfiguration } from "../../../../EngineConfiguration.js";
5
5
  import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
6
6
  import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
7
+ import { AttachmentSystem } from "../../../../ecs/attachment/AttachmentSystem.js";
8
+ import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
7
9
 
8
10
  const eh = new EngineHarness();
9
11
 
@@ -18,6 +20,8 @@ async function init(harness) {
18
20
  const config = new EngineConfiguration();
19
21
 
20
22
  config.addSystem(new ShadedGeometrySystem(engine));
23
+ config.addSystem(new AttachmentSystem());
24
+ config.addSystem(new TransformAttachmentSystem());
21
25
  config.addLoader(GameAssetType.ModelGLTF_JSON, new GLTFAssetLoader());
22
26
 
23
27
  await config.apply(engine);
@@ -27,26 +31,54 @@ async function init(harness) {
27
31
 
28
32
  /**
29
33
  *
34
+ * @param {string} path
30
35
  * @param {Engine} engine
31
36
  */
32
- async function main(engine) {
33
-
37
+ async function load_gltf(path, engine) {
34
38
  const em = engine.entityManager;
35
39
 
36
- EngineHarness.buildBasics({
37
- engine,
38
- enableWater: false
39
- })
40
-
41
40
  const ecd = em.dataset;
42
41
 
43
- const asset = await engine.assetManager.promise('moicon/06_04_hapro/08-clickable-assets-new/model.gltf', GameAssetType.ModelGLTF_JSON);
42
+ const asset = await engine.assetManager.promise(path, GameAssetType.ModelGLTF_JSON);
44
43
 
45
44
  const three_object = asset.create();
46
45
 
46
+ console.time('composition conversion');
47
47
  const composition = three_object_to_entity_composition(three_object);
48
+ console.timeEnd('composition conversion');
48
49
 
50
+ console.time('composition build');
51
+ // console.profile('composition build');
49
52
  composition.build(ecd);
53
+ // console.profileEnd('composition build');
54
+ console.timeEnd('composition build');
55
+ }
56
+
57
+ async function timeout(t = 1) {
58
+ await new Promise((resolve, reject) => setTimeout(resolve, t));
59
+ }
60
+
61
+ /**
62
+ *
63
+ * @param {Engine} engine
64
+ */
65
+ async function main(engine) {
66
+
67
+ EngineHarness.buildBasics({
68
+ engine,
69
+ enableWater: false,
70
+ enableTerrain: false
71
+ });
72
+
73
+ // a small delay to let background tasks finish, so we can get better performance reading later on
74
+ timeout(20);
75
+
76
+ load_gltf('moicon/06_04_hapro/08-clickable-assets-new/model.gltf', engine);
77
+ // load_gltf('moicon/06_04_hapro/07-1st-basement/model.gltf', engine);
78
+ // load_gltf('moicon/06_04_hapro/06-lower-ground/model.gltf', engine);
79
+ // load_gltf('moicon/06_04_hapro/05-ground-floor/model.gltf', engine);
80
+ // load_gltf('moicon/06_04_hapro/04-1st-floor/model.gltf', engine);
81
+ // load_gltf('moicon/06_04_hapro/03-2nd-floor/model.gltf', engine);
50
82
  }
51
83
 
52
84
  init(eh);