@woosh/meep-engine 2.33.57 → 2.33.61

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 (95) hide show
  1. package/core/bvh2/aabb3/AABB3.js +4 -1
  2. package/core/bvh2/traversal/traverseBinaryNodeUsingVisitor.js +6 -6
  3. package/core/cache/Cache.js +7 -0
  4. package/core/collection/array/fastArrayEquals.js +17 -0
  5. package/core/collection/array/typed/is_typed_array_equals.js +58 -0
  6. package/core/collection/map/AbstractAsyncMap.js +30 -0
  7. package/core/collection/map/AsyncMapWrapper.js +16 -0
  8. package/core/collection/map/AsyncRemoteHashMap.js +358 -0
  9. package/core/collection/map/CachedAsyncMap.js +34 -0
  10. package/core/geom/3d/SurfacePoint3.js +44 -5
  11. package/core/geom/Vector2.d.ts +2 -0
  12. package/core/geom/Vector4.js +5 -5
  13. package/core/geom/packing/MaxRectangles.js +13 -4
  14. package/core/math/hash/murmur3_32.js +3 -3
  15. package/engine/animation/removeEntityGenericEffect.js +22 -31
  16. package/engine/asset/Asset.js +0 -45
  17. package/engine/asset/AssetDescription.js +51 -0
  18. package/engine/asset/AssetManager.d.ts +7 -0
  19. package/engine/asset/AssetManager.js +98 -2
  20. package/engine/asset/AssetTransformer.d.ts +5 -0
  21. package/engine/asset/AssetTransformer.js +15 -0
  22. package/engine/asset/loaders/GLTFAssetLoader.js +27 -25
  23. package/engine/asset/loaders/material/computeImageBitmapEquality.js +2 -2
  24. package/engine/asset/loaders/material/computeTextureEquality.js +2 -2
  25. package/engine/asset/loaders/material/computeTextureHash.js +7 -13
  26. package/engine/ecs/attachment/AttachmentSystem.js +18 -17
  27. package/engine/ecs/grid/HeightMap2NormalMap.js +1 -1
  28. package/engine/ecs/grid/NormalMap2AOMap.js +1 -1
  29. package/engine/ecs/gui/GUIElement.js +0 -106
  30. package/engine/ecs/gui/GUIElementSerializationAdapter.js +108 -0
  31. package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +60 -45
  32. package/engine/ecs/gui/position/ViewportPositionSystem.js +5 -5
  33. package/engine/ecs/parent/EntityNode.d.ts +20 -0
  34. package/engine/ecs/parent/EntityNode.js +284 -0
  35. package/engine/ecs/parent/FaceEditor.js +137 -0
  36. package/engine/ecs/parent/testCompositionEntityNode.js +153 -0
  37. package/engine/ecs/parent/testHuDPerf.js +123 -0
  38. package/engine/ecs/storage/binary/BinaryClassUpgrader.js +1 -0
  39. package/engine/ecs/terrain/ecs/Terrain.js +14 -5
  40. package/engine/ecs/util/removeComponentsExcept.js +3 -3
  41. package/engine/graphics/GraphicsEngine.js +4 -5
  42. package/engine/graphics/camera/testClippingPlaneComputation.js +0 -4
  43. package/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +0 -1
  44. package/engine/graphics/ecs/camera/topdown/TopDownCameraController.spec.js +8 -0
  45. package/engine/graphics/ecs/light/LightSystem.js +1 -1
  46. package/engine/graphics/ecs/mesh/Mesh.js +5 -5
  47. package/engine/graphics/ecs/mesh/MeshSystem.js +12 -20
  48. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +29 -0
  49. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +158 -1
  50. package/engine/graphics/ecs/path/PathDisplaySystem.d.ts +3 -1
  51. package/engine/graphics/ecs/path/testPathDisplaySystem.js +0 -2
  52. package/engine/graphics/ecs/trail2d/Trail2D.js +35 -1
  53. package/engine/graphics/ecs/trail2d/Trail2DSystem.js +26 -19
  54. package/engine/graphics/ecs/trail2d/makeGradientTrail.js +68 -0
  55. package/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +55 -11
  56. package/engine/graphics/micron/convert_three_object_to_micron.js +24 -7
  57. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +107 -4
  58. package/engine/graphics/micron/plugin/serialization/BufferGeometrySerializationAdapter.js +176 -0
  59. package/engine/graphics/micron/render/v1/MaterialContext.js +1 -0
  60. package/engine/graphics/particles/particular/engine/simulator/SimulationStepFixedPhysics.js +19 -3
  61. package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.d.ts +2 -0
  62. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -4
  63. package/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -2
  64. package/engine/graphics/render/buffer/simple-fx/DepthLimitedBlur.js +2 -2
  65. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -2
  66. package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +3 -1
  67. package/engine/graphics/render/frame_graph/FrameGraphBuilder.js +36 -0
  68. package/engine/graphics/render/frame_graph/IRenderContext.js +8 -0
  69. package/engine/graphics/render/frame_graph/RenderPass.js +32 -0
  70. package/engine/graphics/render/frame_graph/RenderPassFlags.js +6 -0
  71. package/engine/graphics/render/frame_graph/RenderPassResources.js +15 -0
  72. package/engine/graphics/render/frame_graph/Resource.js +21 -0
  73. package/engine/graphics/render/frame_graph/ResourceReference.js +14 -0
  74. package/engine/graphics/render/frame_graph/TextureDescriptor.js +30 -0
  75. package/engine/graphics/render/frame_graph/UsageModeType.js +5 -0
  76. package/engine/graphics/render/frame_graph/sample/deferred/GBufferDrawPass.js +27 -0
  77. package/engine/graphics/render/frame_graph/sample/deferred/PresentPass.js +17 -0
  78. package/engine/graphics/render/visibility/hiz/prototypeHiZ.js +0 -2
  79. package/engine/graphics/render/webgpu/sample/_main.ts +650 -0
  80. package/engine/graphics/render/webgpu/sample/fragmentDeferredRendering.wgsl +67 -0
  81. package/engine/graphics/render/webgpu/sample/fragmentGBuffersDebugView.wgsl +38 -0
  82. package/engine/graphics/render/webgpu/sample/fragmentWriteGBuffers.wgsl +21 -0
  83. package/engine/graphics/render/webgpu/sample/lightUpdate.wgsl +34 -0
  84. package/engine/graphics/render/webgpu/sample/main.js +566 -0
  85. package/engine/graphics/render/webgpu/sample/vertexTextureQuad.wgsl +9 -0
  86. package/engine/graphics/render/webgpu/sample/vertexWriteGBuffers.wgsl +28 -0
  87. package/engine/graphics/shadows/ShadowMapRenderer.js +10 -4
  88. package/engine/graphics/shadows/testShadowMapRendering.js +0 -2
  89. package/engine/graphics/texture/sampler/Sampler2D.js +24 -45
  90. package/engine/{ecs/grid → graphics/texture/sampler}/sampler2DToFloat32Texture.js +1 -1
  91. package/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +3 -0
  92. package/engine/save/storage/IndexedDBStorage.js +8 -1
  93. package/package.json +1 -1
  94. package/samples/terrain/main.js +117 -0
  95. package/engine/ecs/sockets/AttachmentSocketsSystem.js +0 -10
@@ -909,7 +909,7 @@ class Terrain {
909
909
 
910
910
  worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
911
911
 
912
- worker.computeHeightRange()
912
+ return worker.computeHeightRange()
913
913
  .then(({ min, max }) => {
914
914
  this.tiles.setHeightRange(min, max);
915
915
  });
@@ -1038,13 +1038,22 @@ class Terrain {
1038
1038
  heightSampler: this.samplerHeight
1039
1039
  });
1040
1040
 
1041
+
1041
1042
  const result = promise.then(() => {
1042
1043
 
1043
- this.material.aoMap = true;
1044
- this.material.needsUpdate = true;
1044
+ const ref = this.__material_reference;
1045
+
1046
+ let mat = this.material;
1047
+
1048
+ if (ref !== null && ref.getValue() !== null) {
1049
+ mat = ref.getValue();
1050
+ }
1051
+
1052
+ mat.aoMap = true;
1053
+ mat.needsUpdate = true;
1045
1054
 
1046
- this.material.uniforms.aoMap.value = texture;
1047
- this.material.uniforms.aoMapIntensity.value = 0.7;
1055
+ mat.uniforms.aoMap.value = texture;
1056
+ mat.uniforms.aoMapIntensity.value = 0.7;
1048
1057
 
1049
1058
  return texture;
1050
1059
  });
@@ -10,7 +10,7 @@ export function removeComponentsExcept(ecd, entity, whitelist) {
10
10
  const components = ecd.getAllComponents(entity);
11
11
  const component_count = components.length;
12
12
 
13
- for (let i = 0; i < component_count; i++) {
13
+ l0:for (let i = 0; i < component_count; i++) {
14
14
  const component = components[i];
15
15
 
16
16
  if (component === undefined) {
@@ -21,7 +21,7 @@ export function removeComponentsExcept(ecd, entity, whitelist) {
21
21
  for (let i = 0; i < exception_count; i++) {
22
22
  if (component instanceof whitelist[i]) {
23
23
  //keep
24
- continue;
24
+ continue l0;
25
25
  }
26
26
  }
27
27
 
@@ -29,4 +29,4 @@ export function removeComponentsExcept(ecd, entity, whitelist) {
29
29
  ecd.removeComponentFromEntityByIndex(entity, i);
30
30
  }
31
31
 
32
- }
32
+ }
@@ -35,7 +35,6 @@ import { MetricsCategory } from "../metrics/MetricsCategory.js";
35
35
  import Vector1 from "../../core/geom/Vector1.js";
36
36
  import { NormalFrameBuffer } from "./render/buffer/buffers/NormalFrameBuffer.js";
37
37
  import { MaterialManager } from "./material/manager/MaterialManager.js";
38
- import { CoalesceTextures } from "./material/manager/compilers/CoalesceTextures.js";
39
38
  import { ShadowMapRenderer } from "./shadows/ShadowMapRenderer.js";
40
39
  import { CameraViewManager } from "./render/view/CameraViewManager.js";
41
40
  import { StandardFrameBuffers } from "./StandardFrameBuffers.js";
@@ -91,14 +90,15 @@ function GraphicsEngine(camera, entityManger) {
91
90
  */
92
91
  this.__material_manager = new MaterialManager();
93
92
 
94
- this.__material_manager.addCompileStep(new CoalesceTextures());
93
+ // The line below would de-dupe textures, it is a rather slow process however
94
+ // this.__material_manager.addCompileStep(new CoalesceTextures());
95
95
 
96
96
  this.on = {
97
97
  preRender: new Signal(),
98
98
  postRender: new Signal(),
99
99
 
100
100
  preOpaquePass: new Signal(),
101
- postOpaquePass : new Signal(),
101
+ postOpaquePass: new Signal(),
102
102
 
103
103
  /**
104
104
  * @deprecated
@@ -585,6 +585,7 @@ GraphicsEngine.prototype.renderOpaque = function () {
585
585
  GraphicsEngine.prototype.renderTransparent = function () {
586
586
  const scene = this.scene;
587
587
 
588
+ // clear background, as transparent pass is drawn on top, the background should already be composited
588
589
  const _background = scene.background;
589
590
  scene.background = null;
590
591
 
@@ -596,8 +597,6 @@ GraphicsEngine.prototype.renderTransparent = function () {
596
597
 
597
598
  // restore background
598
599
  scene.background = _background;
599
-
600
- // TODO render transparent objects into a buffer, to be able to apply post-fx
601
600
  };
602
601
 
603
602
  /**
@@ -8,8 +8,6 @@ import PathFollowingSystem from "../../navigation/ecs/path_following/PathFollowi
8
8
  import SteeringSystem from "../../ecs/systems/SteeringSystem.js";
9
9
  import MotionSystem from "../../ecs/systems/MotionSystem.js";
10
10
  import TagSystem from "../../ecs/systems/TagSystem.js";
11
- import { AttachmentSocketsSystem } from "../../ecs/sockets/AttachmentSocketsSystem.js";
12
- import { AttachmentSystem } from "../../ecs/attachment/AttachmentSystem.js";
13
11
  import { SoundEmitterSystem } from "../../sound/ecs/emitter/SoundEmitterSystem.js";
14
12
  import SoundControllerSystem from "../../sound/ecs/SoundControllerSystem.js";
15
13
  import SoundListenerSystem from "../../sound/ecs/SoundListenerSystem.js";
@@ -84,8 +82,6 @@ function makeConfig(engine) {
84
82
  new SteeringSystem(),
85
83
  new MotionSystem(),
86
84
  new TagSystem(),
87
- new AttachmentSocketsSystem(),
88
- new AttachmentSystem(),
89
85
  new SoundEmitterSystem(assetManager, sound.destination, sound.context),
90
86
  new SoundControllerSystem(),
91
87
  new SoundListenerSystem(sound.context),
@@ -11,7 +11,6 @@ import { PI2 } from "../../../../../core/math/MathUtils.js";
11
11
 
12
12
  const m4 = new Matrix4();
13
13
  const euler = new Euler();
14
- const scratch_vector3 = new Vector3();
15
14
 
16
15
  const panOffset = new Vector3();
17
16
 
@@ -3,6 +3,14 @@ import Vector3 from "../../../../../core/geom/Vector3.js";
3
3
  import { computeTopDownTransform } from "./TopDownCameraControllerSystem.js";
4
4
  import { Transform } from "../../../../ecs/transform/Transform.js";
5
5
 
6
+ test('setFromEyeAndTarget does not introduce roll when UP is aligned with +Y', () => {
7
+ const ut = new TopDownCameraController();
8
+
9
+ ut.setFromEyeAndTarget(new Vector3(0, 1, -1), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
10
+
11
+ expect(ut.roll).toBe(0);
12
+ });
13
+
6
14
  test('setFromEyeAndTarget results in roll respecting UP vector', () => {
7
15
  const eye = new Vector3();
8
16
  const target = new Vector3();
@@ -26,7 +26,7 @@ class LightSystem extends AbstractContextSystem {
26
26
  * @param settings
27
27
  * @constructor
28
28
  */
29
- constructor(engine, settings) {
29
+ constructor(engine, settings = {}) {
30
30
  super(LightContext);
31
31
 
32
32
  /**
@@ -52,10 +52,10 @@ class Mesh {
52
52
  this.mesh = null;
53
53
 
54
54
  /**
55
- * Mesh with micron data, if available
55
+ * Override Mesh data, if available. Typically set via plugins
56
56
  * @type {Object3D|null}
57
57
  */
58
- this.micron_mesh = null;
58
+ this.override_mesh = null;
59
59
 
60
60
  /**
61
61
  * @transient
@@ -128,9 +128,9 @@ class Mesh {
128
128
  //set bvh
129
129
  updateNodeByTransformAndBBB(this.bvh, this.boundingBox, _t);
130
130
 
131
- // micron
132
- if (this.micron_mesh !== null) {
133
- applyTransformToThreeObject(this.micron_mesh, _t);
131
+ // override
132
+ if (this.override_mesh !== null) {
133
+ applyTransformToThreeObject(this.override_mesh, _t);
134
134
  }
135
135
  }
136
136
 
@@ -18,7 +18,6 @@ import Mesh, { MeshFlags } from "./Mesh.js";
18
18
  import { applyComponentPropertiesToThreeObject, setMesh } from "./setMesh.js";
19
19
  import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
20
20
  import { MeshEvents } from "./MeshEvents.js";
21
- import { MicronRenderPlugin } from "../../micron/plugin/MicronRenderPlugin.js";
22
21
  import { assert } from "../../../../core/assert.js";
23
22
 
24
23
  const placeholderGeometry = new BoxBufferGeometry(1, 1, 1);
@@ -86,13 +85,6 @@ export class MeshSystem extends System {
86
85
  * @type {BinaryNode}
87
86
  */
88
87
  this.bvh = null;
89
-
90
- /**
91
- *
92
- * @type {boolean}
93
- * @private
94
- */
95
- this.__use_micron = false;
96
88
  }
97
89
 
98
90
  /**
@@ -126,11 +118,11 @@ export class MeshSystem extends System {
126
118
 
127
119
  component.setFlag(MeshFlags.Loaded);
128
120
 
129
- // micron
130
- if (asset.micron !== undefined && this.__use_micron) {
131
- component.micron_mesh = asset.micron.clone();
121
+ // override
122
+ if (asset.override_mesh !== undefined ) {
123
+ component.override_mesh = asset.override_mesh.clone();
132
124
 
133
- applyComponentPropertiesToThreeObject(component, component.micron_mesh, entity);
125
+ applyComponentPropertiesToThreeObject(component, component.override_mesh, entity);
134
126
  }
135
127
 
136
128
  setMesh(dataset, entity, component, mesh);
@@ -141,11 +133,6 @@ export class MeshSystem extends System {
141
133
  }
142
134
 
143
135
  async startup(entityManager, readyCallback, errorCallback) {
144
- const engine = this.__engine;
145
-
146
- // is micron supported here?
147
- this.__use_micron = engine.plugins.getPlugin(MicronRenderPlugin) !== undefined;
148
-
149
136
  const am = this.assetManager;
150
137
 
151
138
  this.entityManager = entityManager;
@@ -158,10 +145,15 @@ export class MeshSystem extends System {
158
145
  const graphics = this.graphics;
159
146
  this.renderLayer = graphics.layers.create("mesh-system");
160
147
 
148
+ /**
149
+ *
150
+ * @param {Mesh} component
151
+ * @return {Object3D}
152
+ */
161
153
  const extractRenderable = (component) => {
162
- if (this.__use_micron && component.micron_mesh !== null) {
163
- // use micron mesh
164
- return component.micron_mesh;
154
+ if (component.override_mesh !== null) {
155
+ // use override mesh
156
+ return component.override_mesh;
165
157
  } else {
166
158
  // use standard mesh
167
159
  return component.mesh;
@@ -39,6 +39,35 @@ export class ShadedGeometry {
39
39
  * @private
40
40
  */
41
41
  this.__bvh_leaf = new LeafNode(this, 0, 0, 0, 0, 0, 0);
42
+
43
+ /**
44
+ * Transient, assigned in the system
45
+ * @type {number}
46
+ * @private
47
+ */
48
+ this.__entity = -1;
49
+ /**
50
+ * Transform matrix
51
+ * Transient, assigned in the system
52
+ * @type {number[]|null}
53
+ * @private
54
+ */
55
+ this.__transform = null;
56
+ }
57
+
58
+ /**
59
+ * Global transform matrix
60
+ * 4x4 matrix
61
+ * @return {null|number[]}
62
+ */
63
+ get transform() {
64
+ if (this.__transform !== null) {
65
+ return this.__transform;
66
+ } else if (this.__cached_object !== null) {
67
+ return this.__cached_object.matrix.elements;
68
+ } else {
69
+ return null;
70
+ }
42
71
  }
43
72
 
44
73
  __build_object() {
@@ -1,6 +1,27 @@
1
1
  import { ShadedGeometry } from "./ShadedGeometry.js";
2
2
  import { Transform } from "../../../ecs/transform/Transform.js";
3
3
  import { System } from "../../../ecs/System.js";
4
+ import { intersectRay } from "../../../../core/bvh2/aabb3/AABB3Math.js";
5
+ import { GeometrySpatialQueryAccelerator } from "../../geometry/buffered/query/GeometrySpatialQueryAccelerator.js";
6
+ import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
7
+ import { v3_distance_sqr } from "../../../../core/geom/v3_distance_sqr.js";
8
+ import { mat4 } from "gl-matrix";
9
+ import { returnTrue } from "../../../../core/function/Functions.js";
10
+
11
+ const traversal_stack = [];
12
+ let traversal_cursor = 0;
13
+
14
+ /**
15
+ *
16
+ * @type {SurfacePoint3}
17
+ */
18
+ const scratch_point = new SurfacePoint3();
19
+
20
+ /**
21
+ *
22
+ * @type {Float32Array|mat4}
23
+ */
24
+ const scratch_m4 = new Float32Array(16);
4
25
 
5
26
  export class ShadedGeometrySystem extends System {
6
27
  /**
@@ -49,7 +70,12 @@ export class ShadedGeometrySystem extends System {
49
70
 
50
71
  sg.applyTransform(t);
51
72
 
52
- this.__render_layer.bvh.insertNode(sg.bvh);
73
+ const leaf_node = sg.bvh;
74
+
75
+ // remember entity for lookups
76
+ sg.__entity = entity;
77
+
78
+ this.__render_layer.bvh.insertNode(leaf_node);
53
79
  }
54
80
 
55
81
  /**
@@ -65,4 +91,135 @@ export class ShadedGeometrySystem extends System {
65
91
 
66
92
  sg.bvh.disconnect();
67
93
  }
94
+
95
+ /**
96
+ *
97
+ * @param {SurfacePoint3} contact
98
+ * @param {number} origin_x
99
+ * @param {number} origin_y
100
+ * @param {number} origin_z
101
+ * @param {number} direction_x
102
+ * @param {number} direction_y
103
+ * @param {number} direction_z
104
+ * @param {function(entity:number, mesh:ShadedGeometry)} [filter_function]
105
+ * @param {*} [filter_function_context]
106
+ * @returns {{entity:number, mesh:ShadedGeometry}|undefined}
107
+ */
108
+ raycastNearest(
109
+ contact,
110
+ origin_x, origin_y, origin_z,
111
+ direction_x, direction_y, direction_z,
112
+ filter_function = returnTrue, filter_function_context
113
+ ) {
114
+ const root_bvh = this.__render_layer.bvh;
115
+ const stack_frame_address = traversal_cursor;
116
+
117
+ traversal_stack[traversal_cursor++] = root_bvh;
118
+
119
+ let best_distance = Infinity;
120
+ let found_hit = false;
121
+ let best_result = null;
122
+
123
+ while (traversal_cursor > stack_frame_address) {
124
+ traversal_cursor--;
125
+
126
+ /**
127
+ *
128
+ * @type {BinaryNode|LeafNode<ShadedGeometry>}
129
+ */
130
+ const node = traversal_stack[traversal_cursor];
131
+
132
+ // test node against the ray
133
+ const intersects = intersectRay(
134
+ node.x0, node.y0, node.z0,
135
+ node.x1, node.y1, node.z1,
136
+ origin_x, origin_y, origin_z,
137
+ direction_x, direction_y, direction_z
138
+ );
139
+
140
+ if (!intersects) {
141
+ continue;
142
+ }
143
+
144
+ if (node.isBinaryNode) {
145
+ if (node.right !== null) {
146
+ traversal_stack[traversal_cursor++] = node.right;
147
+ }
148
+ if (node.left !== null) {
149
+ traversal_stack[traversal_cursor++] = node.left;
150
+ }
151
+ } else {
152
+ // leaf node
153
+
154
+ /**
155
+ *
156
+ * @type {ShadedGeometry}
157
+ */
158
+ const sg = node.object;
159
+
160
+ const entity = sg.__entity;
161
+
162
+ if (!filter_function.call(filter_function_context, entity, sg)) {
163
+ // filtered out
164
+ continue;
165
+ }
166
+
167
+ const m4 = sg.transform;
168
+
169
+ // get transform in local space
170
+ mat4.invert(scratch_m4, m4);
171
+
172
+ // transform ray to local space
173
+ const local_origin_x = scratch_m4[0] * origin_x + scratch_m4[4] * origin_y + scratch_m4[8] * origin_z + scratch_m4[12];
174
+ const local_origin_y = scratch_m4[1] * origin_x + scratch_m4[5] * origin_y + scratch_m4[9] * origin_z + scratch_m4[13];
175
+ const local_origin_z = scratch_m4[2] * origin_x + scratch_m4[6] * origin_y + scratch_m4[10] * origin_z + scratch_m4[14];
176
+
177
+ const local_direction_x = scratch_m4[0] * direction_x + scratch_m4[4] * direction_y + scratch_m4[8] * direction_z;
178
+ const local_direction_y = scratch_m4[1] * direction_x + scratch_m4[5] * direction_y + scratch_m4[9] * direction_z;
179
+ const local_direction_z = scratch_m4[2] * direction_x + scratch_m4[6] * direction_y + scratch_m4[10] * direction_z;
180
+ // NOTE: direction is not normalized
181
+
182
+ const geometry_hit_found = GeometrySpatialQueryAccelerator.INSTANCE.queryRaycastNearest_primitive(
183
+ scratch_point,
184
+ sg.geometry,
185
+ local_origin_x, local_origin_y, local_origin_z,
186
+ local_direction_x, local_direction_y, local_direction_z
187
+ );
188
+
189
+ if (!geometry_hit_found) {
190
+ continue;
191
+ }
192
+
193
+ // transform hit contact into global space
194
+ scratch_point.applyMatrix4(m4);
195
+
196
+ found_hit = true;
197
+
198
+ const hit_position = scratch_point.position;
199
+
200
+ const distance_sqr = v3_distance_sqr(
201
+ hit_position.x, hit_position.y, hit_position.z,
202
+ origin_x, origin_y, origin_z
203
+ );
204
+
205
+ if (distance_sqr >= best_distance) {
206
+ // further than best found
207
+ continue;
208
+ }
209
+
210
+ contact.copy(scratch_point);
211
+ best_result = sg;
212
+ }
213
+ }
214
+
215
+ // drop stack frame
216
+ traversal_cursor = stack_frame_address;
217
+
218
+ if (found_hit) {
219
+ return {
220
+ entity: best_result.__entity,
221
+ mesh: best_result
222
+ };
223
+ }
224
+ }
68
225
  }
@@ -1,5 +1,7 @@
1
1
  import Engine from "../../../Engine";
2
+ import {System} from "../../../ecs/System";
3
+ import {PathDisplay} from "./PathDisplay";
2
4
 
3
- export class PathDisplaySystem {
5
+ export class PathDisplaySystem extends System<PathDisplay> {
4
6
  constructor(engine: Engine)
5
7
  }
@@ -19,7 +19,6 @@ import PathFollowingSystem from "../../../navigation/ecs/path_following/PathFoll
19
19
  import SteeringSystem from "../../../ecs/systems/SteeringSystem.js";
20
20
  import MotionSystem from "../../../ecs/systems/MotionSystem.js";
21
21
  import TagSystem from "../../../ecs/systems/TagSystem.js";
22
- import { AttachmentSocketsSystem } from "../../../ecs/sockets/AttachmentSocketsSystem.js";
23
22
  import { AttachmentSystem } from "../../../ecs/attachment/AttachmentSystem.js";
24
23
  import { SoundEmitterSystem } from "../../../sound/ecs/emitter/SoundEmitterSystem.js";
25
24
  import SoundControllerSystem from "../../../sound/ecs/SoundControllerSystem.js";
@@ -95,7 +94,6 @@ function makeConfig(engine) {
95
94
  new SteeringSystem(),
96
95
  new MotionSystem(),
97
96
  new TagSystem(),
98
- new AttachmentSocketsSystem(),
99
97
  new AttachmentSystem(),
100
98
  new SoundEmitterSystem(assetManager, sound.destination, sound.context),
101
99
  new SoundControllerSystem(),
@@ -6,6 +6,10 @@
6
6
  import Vector3 from "../../../../core/geom/Vector3.js";
7
7
  import Vector4 from "../../../../core/geom/Vector4.js";
8
8
  import { RibbonXMaterialSpec } from "../../trail/x/RibbonXMaterialSpec.js";
9
+ import { LeafNode } from "../../../../core/bvh2/LeafNode.js";
10
+ import { makeGradientTrail } from "./makeGradientTrail.js";
11
+ import { RibbonX } from "../../trail/x/RibbonX.js";
12
+ import ThreeFactory from "../../three/ThreeFactory.js";
9
13
 
10
14
  /**
11
15
  * @readonly
@@ -14,6 +18,7 @@ import { RibbonXMaterialSpec } from "../../trail/x/RibbonXMaterialSpec.js";
14
18
  export const Trail2DFlags = {
15
19
  Spawning: 1,
16
20
  Aging: 2,
21
+ Built: 4,
17
22
  };
18
23
 
19
24
  class Trail2D {
@@ -37,6 +42,12 @@ class Trail2D {
37
42
  */
38
43
  this.time = 0;
39
44
 
45
+ /**
46
+ *
47
+ * @type {number}
48
+ */
49
+ this.trailingIndex = 0;
50
+
40
51
  /**
41
52
  * Time elapsed since last update
42
53
  * @type {number}
@@ -72,7 +83,11 @@ class Trail2D {
72
83
  * transient
73
84
  * @type {LeafNode|null}
74
85
  */
75
- this.bvhLeaf = null;
86
+ this.bvhLeaf = new LeafNode(
87
+ this,
88
+ 0, 0, 0,
89
+ 0, 0, 0
90
+ );
76
91
 
77
92
  /**
78
93
  * @private
@@ -165,6 +180,21 @@ class Trail2D {
165
180
  }
166
181
  }
167
182
 
183
+ build(segment_count) {
184
+
185
+ const ribbon = new RibbonX();
186
+
187
+ ribbon.buildGeometry();
188
+ ribbon.setCount(segment_count);
189
+
190
+ const geometry = ribbon.getGeometry();
191
+
192
+ const mesh = ThreeFactory.createMesh(geometry, null);
193
+
194
+ this.ribbon = ribbon;
195
+ this.mesh = mesh;
196
+ }
197
+
168
198
  toJSON() {
169
199
  return {
170
200
  maxAge: this.maxAge,
@@ -187,10 +217,14 @@ class Trail2D {
187
217
  && this.offset.equals(other.offset)
188
218
  ;
189
219
  }
220
+
221
+
190
222
  }
191
223
 
192
224
  Trail2D.typeName = "Trail2D";
193
225
 
194
226
  Trail2D.serializable = false;
195
227
 
228
+ Trail2D.makeGradientTrail = makeGradientTrail;
229
+
196
230
  export default Trail2D;
@@ -10,9 +10,6 @@ import { Transform } from '../../../ecs/transform/Transform.js';
10
10
  import Vector3 from '../../../../core/geom/Vector3.js';
11
11
 
12
12
  import Trail2D, { Trail2DFlags } from './Trail2D.js';
13
-
14
- import { LeafNode } from '../../../../core/bvh2/LeafNode.js';
15
- import ThreeFactory from '../../three/ThreeFactory.js';
16
13
  import { GraphicsEngine } from "../../GraphicsEngine.js";
17
14
  import { RibbonXFixedPhysicsSimulator } from "../../trail/x/simulator/RibbonXFixedPhysicsSimulator.js";
18
15
  import { RibbonX } from "../../trail/x/RibbonX.js";
@@ -118,11 +115,11 @@ class Trail2DSystem extends System {
118
115
 
119
116
  /**
120
117
  *
121
- * @param {Transform} transform
122
118
  * @param {Trail2D} trail
123
- * @param {number} entityId
119
+ * @param {Transform} transform
120
+ * @private
124
121
  */
125
- link(trail, transform, entityId) {
122
+ __build_trail(trail, transform) {
126
123
  const segmentsPerSecond = 60;
127
124
  const maxSegments = 1000;
128
125
  //instantiation
@@ -130,24 +127,19 @@ class Trail2DSystem extends System {
130
127
  //make a mesh
131
128
  const segment_count = Math.ceil(clamp(trail.maxAge * segmentsPerSecond, 2, maxSegments));
132
129
 
133
- const ribbon = new RibbonX();
134
-
135
- ribbon.buildGeometry();
136
- ribbon.setCount(segment_count);
130
+ trail.build(segment_count);
137
131
 
138
-
139
- const geometry = ribbon.getGeometry();
132
+ const ribbon = trail.ribbon;
140
133
 
141
134
  const ribbons = this.__ribbon_plugin.getValue();
142
135
 
143
136
  const material = ribbons.obtain_material_x(trail.material);
144
137
 
145
- const mesh = ThreeFactory.createMesh(geometry, material);
138
+ trail.mesh.material = material;
146
139
 
147
140
  trail.time = 0;
148
141
  trail.trailingIndex = 0;
149
142
  trail.ribbon = ribbon;
150
- trail.mesh = mesh;
151
143
  trail.timeSinceLastUpdate = 0;
152
144
 
153
145
 
@@ -173,16 +165,31 @@ class Trail2DSystem extends System {
173
165
 
174
166
  }
175
167
 
176
- const leafNode = new LeafNode(
177
- trail,
178
-
168
+ trail.bvhLeaf.resize(
179
169
  position_x, position_y, position_z,
180
170
  position_x, position_y, position_z
181
171
  );
182
172
 
183
- trail.bvhLeaf = leafNode;
173
+ trail.setFlag(Trail2DFlags.Built);
174
+ }
175
+
176
+ /**
177
+ *
178
+ * @param {Transform} transform
179
+ * @param {Trail2D} trail
180
+ * @param {number} entityId
181
+ */
182
+ link(trail, transform, entityId) {
183
+ if (!trail.getFlag(Trail2DFlags.Built)) {
184
+ this.__build_trail(trail, transform);
185
+ } else {
186
+
187
+ const material = this.__ribbon_plugin.getValue().obtain_material_x(trail.material);
188
+ trail.mesh.material = material;
189
+ }
190
+
184
191
 
185
- this.bvh.insertNode(leafNode);
192
+ this.bvh.insertNode(trail.bvhLeaf);
186
193
  }
187
194
 
188
195
  /**