@woosh/meep-engine 2.48.1 → 2.48.5

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 (75) hide show
  1. package/package.json +1 -1
  2. package/src/core/binary/32BitEncoder.js +11 -3
  3. package/src/core/binary/BinaryBuffer.js +80 -59
  4. package/src/core/binary/int32_to_binary_string.js +32 -7
  5. package/src/core/binary/to_half_float_uint16.js +6 -4
  6. package/src/core/bvh2/visual/convert_bvh_to_dot_format_string.js +1 -1
  7. package/src/core/collection/list/List.js +3 -0
  8. package/src/core/geom/3d/CircleMath.js +13 -2
  9. package/src/core/geom/3d/matrix/m4_make_translation.js +15 -0
  10. package/src/core/geom/3d/triangle/computeTrianglePlaneSide.js +4 -13
  11. package/src/core/geom/Vector3.spec.js +10 -0
  12. package/src/core/graph/convertGraphToDotString.js +13 -3
  13. package/src/core/graph/v2/Graph.js +17 -1
  14. package/src/core/graph/v2/NodeContainer.js +58 -0
  15. package/src/core/model/ModuleRegistry.js +44 -10
  16. package/src/core/model/ResourceAccessKind.js +11 -0
  17. package/src/core/model/ResourceAccessSpecification.js +41 -0
  18. package/src/engine/Engine.js +1 -1
  19. package/src/engine/ecs/EntityEventBinding.js +74 -0
  20. package/src/engine/ecs/EntityManager.js +143 -0
  21. package/src/engine/ecs/System.js +53 -5
  22. package/src/engine/ecs/animation/InverseKinematicsSystem.js +6 -0
  23. package/src/engine/ecs/attachment/AttachmentSystem.js +8 -0
  24. package/src/engine/ecs/dynamic_actions/DynamicActorSystem.js +5 -0
  25. package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +7 -3
  26. package/src/engine/ecs/fow/FogOfWarSystem.js +6 -0
  27. package/src/engine/ecs/gui/GUIElementSystem.js +1 -1
  28. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +8 -0
  29. package/src/engine/ecs/gui/position/ViewportPositionSystem.js +6 -0
  30. package/src/engine/ecs/speaker/VoiceSystem.js +13 -0
  31. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +451 -12
  32. package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.spec.js +123 -0
  33. package/src/engine/ecs/system/computeSystemComponentDependencyGraph.js +71 -0
  34. package/src/engine/ecs/systems/RenderSystem.js +6 -0
  35. package/src/engine/ecs/terrain/ecs/Terrain.js +26 -44
  36. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +9 -0
  37. package/src/engine/ecs/terrain/tiles/TerrainTile.js +5 -0
  38. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +26 -6
  39. package/src/engine/ecs/tooltip/TooltipComponentSystem.js +7 -0
  40. package/src/engine/graphics/ecs/animation/animator/AnimationGraphSystem.js +6 -0
  41. package/src/engine/graphics/ecs/camera/CameraSystem.js +6 -0
  42. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +4 -0
  43. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +5 -0
  44. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraLanderSystem.js +6 -0
  45. package/src/engine/graphics/ecs/light/LightSystem.js +8 -0
  46. package/src/engine/graphics/ecs/mesh/MeshSystem.js +8 -1
  47. package/src/engine/graphics/ecs/path/PathDisplaySystem.js +7 -1
  48. package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +7 -0
  49. package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +34 -7
  50. package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +6 -0
  51. package/src/engine/grid/systems/GridPosition2TransformSystem.js +6 -0
  52. package/src/engine/grid/transform2grid/Transform2GridPositionSystem.js +6 -0
  53. package/src/engine/intelligence/behavior/Behavior.js +11 -0
  54. package/src/engine/intelligence/behavior/composite/CompositeBehavior.js +10 -4
  55. package/src/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +1 -0
  56. package/src/engine/intelligence/behavior/util/behavior_traverse_tree.js +8 -0
  57. package/src/engine/navigation/ecs/path_following/PathFollowingSystem.js +8 -0
  58. package/src/engine/network/RemoteController.js +60 -84
  59. package/src/engine/network/remoteEditor.js +108 -2
  60. package/src/engine/sound/SoundEngine.js +81 -79
  61. package/src/engine/sound/ecs/SoundControllerSystem.js +8 -0
  62. package/src/engine/sound/ecs/SoundListenerSystem.js +7 -0
  63. package/src/engine/sound/ecs/emitter/SoundEmitterComponentContext.js +42 -46
  64. package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +15 -2
  65. package/src/engine/sound/ecs/emitter/SoundTrack.js +137 -35
  66. package/src/engine/sound/ecs/emitter/SoundTrackFlags.js +17 -1
  67. package/src/engine/sound/ecs/emitter/SoundTrackNodes.js +2 -4
  68. package/src/engine/sound/ecs/emitter/loadSoundTrackAsset.js +1 -2
  69. package/src/generation/theme/ThemeEngine.js +20 -3
  70. package/src/view/{elements/image → common}/HTMLElementCacheKey.js +5 -5
  71. package/src/view/elements/button/ButtonView.js +10 -2
  72. package/src/view/elements/image/ImageView.js +1 -1
  73. package/src/view/elements/video/VideoView.js +1 -1
  74. package/src/view/interaction/CommandButtonView.js +16 -153
  75. package/src/view/interaction/createInterfaceCommandButton.js +124 -0
@@ -30,12 +30,9 @@ import { SplatMapping } from "./splat/SplatMapping.js";
30
30
  import { OffsetScaleTransform2D } from "./OffsetScaleTransform2D.js";
31
31
  import { GridTransformKind } from "./GridTransformKind.js";
32
32
  import { makeTerrainWorkerProxy } from "./makeTerrainWorkerProxy.js";
33
- import { loadLegacyTerrainLayers } from "./layers/loadLegacyTerrainLayers.js";
34
33
  import { TerrainFlags } from "./TerrainFlags.js";
35
34
  import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalStateException.js";
36
35
  import { buildLightTexture } from "./BuildLightTexture.js";
37
- import { promiseSamplerHeight } from "./PromiseSamplerHeight.js";
38
- import { loadLegacyTerrainSplats } from "./splat/loadLegacyTerrainSplats.js";
39
36
  import { WHITE_PIXEL_DATA_URL } from "../../../graphics/WHITE_PIXEL_DATA_URL.js";
40
37
  import { mat4 } from "gl-matrix";
41
38
  import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
@@ -470,7 +467,7 @@ class Terrain {
470
467
  * @return {boolean}
471
468
  */
472
469
  raycastVerticalFirstSync(contact, x, y) {
473
- return this.__tiles.raycastVerticalFirstSync(contact, x, y);
470
+ return this.__tiles.raycastVerticalFirstSync(contact, x, y);
474
471
  }
475
472
 
476
473
  /**
@@ -727,25 +724,7 @@ class Terrain {
727
724
  * @param {AssetManager} assetManager
728
725
  */
729
726
  buildFromLegacy(assetManager) {
730
- const pSamplerHeight = promiseSamplerHeight(this.heightRange, this.__legacyHeightSamplerURL, assetManager);
731
-
732
- const material = this.__legacyMaterialSpec;
733
-
734
- const pLayers = loadLegacyTerrainLayers(material, this.layers, assetManager, this.size, this.gridScale);
735
- const pSplats = loadLegacyTerrainSplats(material, this.splat, assetManager);
736
-
737
- Promise.all([pLayers, pSplats])
738
- .then(() => {
739
- this.updateMaterial();
740
- });
741
-
742
- pSamplerHeight.then((sampler) => {
743
- this.samplerHeight = sampler;
744
- this.updateHeightTexture();
745
-
746
- this.updateWorkerHeights();
747
- });
748
-
727
+ throw new Error('Deprecated, no longer supported');
749
728
  }
750
729
 
751
730
  startBuildService() {
@@ -786,6 +765,27 @@ class Terrain {
786
765
  }
787
766
  }
788
767
 
768
+ buildNonVisual() {
769
+
770
+ this.buildGridTransform();
771
+
772
+ this.bvh.reset();
773
+ this.bvh.setNegativelyInfiniteBounds();
774
+
775
+ //
776
+ this.overlay.size.copy(this.size);
777
+
778
+ this.__tiles.totalSize.copy(this.size);
779
+ this.__tiles.scale.set(this.gridScale, this.gridScale);
780
+ this.__tiles.resolution.set(this.resolution);
781
+
782
+
783
+ this.updateHeightTexture();
784
+
785
+ this.updateWorkerHeights();
786
+
787
+ }
788
+
789
789
  /**
790
790
  *
791
791
  * @param {AssetManager} assetManager
@@ -803,29 +803,11 @@ class Terrain {
803
803
 
804
804
  this.__assetManager = assetManager;
805
805
 
806
- this.buildGridTransform();
806
+ this.buildNonVisual();
807
807
 
808
- this.bvh.reset();
809
- this.bvh.setNegativelyInfiniteBounds();
810
- //
811
- this.overlay.size.copy(this.size);
812
-
813
- this.__tiles.totalSize.copy(this.size);
814
- this.__tiles.scale.set(this.gridScale, this.gridScale);
815
- this.__tiles.resolution.set(this.resolution);
808
+ this.layers.buildTexture();
816
809
 
817
- if (this.__legacyMaterialSpec !== null) {
818
- this.buildFromLegacy(assetManager);
819
- } else {
820
- //modern build path
821
- this.updateHeightTexture();
822
-
823
- this.updateWorkerHeights();
824
-
825
- this.layers.buildTexture();
826
-
827
- this.layers.loadTextureData(assetManager);
828
- }
810
+ this.layers.loadTextureData(assetManager);
829
811
 
830
812
  if (this.lightMapURL !== null) {
831
813
  this.material.aoMap = true;
@@ -16,6 +16,9 @@ import { Deque } from "../../../../../core/collection/queue/Deque.js";
16
16
  import { obtainTerrain } from "../../util/obtainTerrain.js";
17
17
  import { clamp01 } from "../../../../../core/math/clamp01.js";
18
18
  import { EPSILON } from "../../../../../core/math/EPSILON.js";
19
+ import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
20
+ import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
21
+ import Terrain from "../Terrain.js";
19
22
 
20
23
 
21
24
  /**
@@ -55,6 +58,12 @@ class ClingToTerrainSystem extends System {
55
58
 
56
59
  this.dependencies = [ClingToTerrain, Transform];
57
60
 
61
+
62
+ this.components_used = [
63
+ ResourceAccessSpecification.from(Transform, ResourceAccessKind.Read | ResourceAccessKind.Write),
64
+ ResourceAccessSpecification.from(Terrain, ResourceAccessKind.Read)
65
+ ];
66
+
58
67
  /**
59
68
  *
60
69
  * @type {EntityManager|null}
@@ -515,12 +515,17 @@ class TerrainTile {
515
515
  }
516
516
 
517
517
  dispose() {
518
+ if (!this.isBuilt) {
519
+ return;
520
+ }
521
+
518
522
  if (this.geometry !== null) {
519
523
  this.geometry.dispose();
520
524
  this.geometry = null;
521
525
  }
522
526
 
523
527
  this.isBuilt = false;
528
+ this.onDestroyed.send1(this);
524
529
  }
525
530
 
526
531
  build(tileData) {
@@ -218,9 +218,17 @@ class TerrainTileManager {
218
218
  destroyTiles() {
219
219
 
220
220
  //destroy all existing tiles
221
- this.tiles.forEach(this.release, this);
221
+ const tiles = this.tiles;
222
+ const tile_count = tiles.length;
223
+
224
+ for (let i = 0; i < tile_count; i++) {
225
+ const tile = tiles[i];
226
+
227
+ tile.dispose();
228
+
229
+ }
222
230
 
223
- this.tiles.splice(0, this.tiles.length);
231
+ tiles.splice(0, tile_count);
224
232
 
225
233
  //clear out BVH
226
234
  this.bvh.right = null;
@@ -302,7 +310,9 @@ class TerrainTileManager {
302
310
 
303
311
  initializeTiles() {
304
312
 
305
- const gridSize = this.totalSize.clone().divide(this.tileSize).ceil();
313
+ const gridSize = this.totalSize.clone();
314
+ gridSize.divide(this.tileSize);
315
+ gridSize.ceil();
306
316
 
307
317
  const tileCount = gridSize.x * gridSize.y;
308
318
 
@@ -397,6 +407,12 @@ class TerrainTileManager {
397
407
  * @returns {TerrainTile}
398
408
  */
399
409
  getRawTileByPosition(x, y) {
410
+ assert.isNumber(x, 'x');
411
+ assert.notNaN(x, 'x');
412
+
413
+ assert.isNumber(y, 'y');
414
+ assert.notNaN(y, 'y');
415
+
400
416
  const tileX = Math.floor(x / this.tileSize.x);
401
417
  const tileY = Math.floor(y / this.tileSize.y);
402
418
 
@@ -419,7 +435,7 @@ class TerrainTileManager {
419
435
 
420
436
  vec3.transformMat4(v3, v3, world_inverse);
421
437
 
422
- return this.getRawTileByPosition(v3.x, v3.z);
438
+ return this.getRawTileByPosition(v3[0], v3[1]);
423
439
  }
424
440
 
425
441
  /**
@@ -429,6 +445,12 @@ class TerrainTileManager {
429
445
  * @returns {Promise<TerrainTile>}
430
446
  */
431
447
  obtainTileAtWorldPosition2D(x, y) {
448
+ assert.isNumber(x, 'x')
449
+ assert.notNaN(x, 'x')
450
+
451
+ assert.isNumber(y, 'y')
452
+ assert.notNaN(y, 'y')
453
+
432
454
  const tile = this.getTileByWorldPosition2D(x, y);
433
455
 
434
456
  return this.obtain(tile.gridPosition.x, tile.gridPosition.y);
@@ -500,8 +522,6 @@ class TerrainTileManager {
500
522
  tile.dispose();
501
523
  }
502
524
 
503
- // TODO check tile.isBuilt flag
504
- tile.onDestroyed.send1(tile);
505
525
  }
506
526
 
507
527
  dispose() {
@@ -6,6 +6,9 @@ import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js";
6
6
  import { VisualTip } from "../../../view/tooltip/VisualTip.js";
7
7
  import Rectangle from "../../../core/geom/Rectangle.js";
8
8
  import { modelHitTest } from "../../graphics/util/modelHitTest.js";
9
+ import { ResourceAccessSpecification } from "../../../core/model/ResourceAccessSpecification.js";
10
+ import { ResourceAccessKind } from "../../../core/model/ResourceAccessKind.js";
11
+ import Mesh from "../../graphics/ecs/mesh/Mesh.js";
9
12
 
10
13
  const ray_source = new Vector3();
11
14
  const ray_direction = new Vector3();
@@ -25,6 +28,10 @@ export class TooltipComponentSystem extends System {
25
28
 
26
29
  this.dependencies = [TooltipComponent];
27
30
 
31
+ this.components_used = [
32
+ ResourceAccessSpecification.from(Mesh, ResourceAccessKind.Read)
33
+ ];
34
+
28
35
  /**
29
36
  *
30
37
  * @type {GraphicsEngine}
@@ -10,6 +10,8 @@ import { CameraSystem } from "../../camera/CameraSystem.js";
10
10
  import { AnimationGraphFlag } from "./graph/AnimationGraphFlag.js";
11
11
  import { projectSphere } from "../../../util/projectSphere.js";
12
12
  import { MeshEvents } from "../../mesh/MeshEvents.js";
13
+ import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
14
+ import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
13
15
 
14
16
  /**
15
17
  *
@@ -40,6 +42,10 @@ export class AnimationGraphSystem extends System {
40
42
 
41
43
  this.dependencies = [AnimationGraph, Mesh];
42
44
 
45
+ this.components_used = [
46
+ ResourceAccessSpecification.from(Mesh, ResourceAccessKind.Write)
47
+ ];
48
+
43
49
  /**
44
50
  *
45
51
  * @type {number}
@@ -15,6 +15,8 @@ import { update_camera_transform } from "./update_camera_transform.js";
15
15
  import { auto_set_camera_clipping_planes } from "./auto_set_camera_clipping_planes.js";
16
16
  import { frustum_from_camera } from "./frustum_from_camera.js";
17
17
  import { invertQuaternionOrientation } from "./InvertQuaternionOrientation.js";
18
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
19
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
18
20
 
19
21
  export class CameraSystem extends System {
20
22
  /**
@@ -30,6 +32,10 @@ export class CameraSystem extends System {
30
32
 
31
33
  this.dependencies = [Camera, Transform];
32
34
 
35
+ this.components_used = [
36
+ ResourceAccessSpecification.from(Camera,ResourceAccessKind.Write)
37
+ ];
38
+
33
39
  /**
34
40
  *
35
41
  * @type {EntityManager}
@@ -93,6 +93,7 @@ export class PerfectPanner {
93
93
  * @param {Vector2} screen_position
94
94
  */
95
95
  update(screen_position) {
96
+ //console.log(`PerfectPanner/update: ${screen_position}`)
96
97
 
97
98
  const C = this.#grab_world_reference;
98
99
  const A = this.#grab_eye_position;
@@ -115,9 +116,12 @@ export class PerfectPanner {
115
116
  translation.multiplyScalar(AC.length() / EC.length());
116
117
 
117
118
  this.#translation.copy(translation);
119
+
120
+ // console.log(`translation: ${translation}`);
118
121
  }
119
122
 
120
123
  start(screen_position) {
124
+ //console.log(`PerfectPanner/start: ${screen_position}`)
121
125
 
122
126
  // obtain reference point
123
127
 
@@ -11,6 +11,8 @@ import { System } from '../../../../ecs/System.js';
11
11
 
12
12
 
13
13
  import TopDownCameraController from './TopDownCameraController.js';
14
+ import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
15
+ import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
14
16
 
15
17
 
16
18
  const v3_scratch = new Vector3();
@@ -22,6 +24,9 @@ class TopDownCameraControllerSystem extends System {
22
24
  this.enabled = new ObservedValue(true);
23
25
  this.dependencies = [TopDownCameraController];
24
26
 
27
+ this.components_used = [
28
+ ResourceAccessSpecification.from(Transform,ResourceAccessKind.Write)
29
+ ];
25
30
  }
26
31
 
27
32
  /**
@@ -7,6 +7,8 @@ import TopDownCameraController from "./TopDownCameraController.js";
7
7
  import Vector2 from "../../../../../core/geom/Vector2.js";
8
8
  import { SignalBinding } from "../../../../../core/events/signal/SignalBinding.js";
9
9
  import { obtainTerrain } from "../../../../ecs/terrain/util/obtainTerrain.js";
10
+ import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
11
+ import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
10
12
 
11
13
 
12
14
  /**
@@ -83,6 +85,10 @@ export class TopDownCameraLanderSystem extends System {
83
85
 
84
86
  this.dependencies = [TopDownCameraLander, TopDownCameraController];
85
87
 
88
+ this.components_used = [
89
+ ResourceAccessSpecification.from(TopDownCameraController,ResourceAccessKind.Read|ResourceAccessKind.Write)
90
+ ];
91
+
86
92
  /**
87
93
  * @private
88
94
  * @type {Array}
@@ -18,6 +18,8 @@ import { ShadowManager } from "./shadow/ShadowManager.js";
18
18
  import { AbstractContextSystem } from "../../../ecs/system/AbstractContextSystem.js";
19
19
  import { LightContext } from "./LightContext.js";
20
20
  import { setShadowCameraDimensionsDiscrete } from "./shadow/setShadowCameraDimensionsDiscrete.js";
21
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
22
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
21
23
 
22
24
  class LightSystem extends AbstractContextSystem {
23
25
  /**
@@ -40,6 +42,12 @@ class LightSystem extends AbstractContextSystem {
40
42
 
41
43
  this.dependencies = [Light, Transform];
42
44
 
45
+
46
+ this.components_used = [
47
+ ResourceAccessSpecification.from(Light, ResourceAccessKind.Write)
48
+ ];
49
+
50
+
43
51
  this.engine = engine;
44
52
  this.scene = graphics.scene;
45
53
  this.settings = settings;
@@ -19,6 +19,8 @@ import { applyComponentPropertiesToThreeObject, setMesh } from "./setMesh.js";
19
19
  import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
20
20
  import { MeshEvents } from "./MeshEvents.js";
21
21
  import { assert } from "../../../../core/assert.js";
22
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
23
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
22
24
 
23
25
  const placeholderGeometry = new BoxBufferGeometry(1, 1, 1);
24
26
 
@@ -51,6 +53,11 @@ export class MeshSystem extends System {
51
53
 
52
54
  this.dependencies = [Mesh, Transform];
53
55
 
56
+ this.components_used = [
57
+ ResourceAccessSpecification.from(Mesh, ResourceAccessKind.Write)
58
+ ];
59
+
60
+
54
61
  /**
55
62
  *
56
63
  * @type {AssetManager}
@@ -119,7 +126,7 @@ export class MeshSystem extends System {
119
126
  component.setFlag(MeshFlags.Loaded);
120
127
 
121
128
  // override
122
- if (asset.override_mesh !== undefined ) {
129
+ if (asset.override_mesh !== undefined) {
123
130
  component.override_mesh = asset.override_mesh.clone();
124
131
 
125
132
  applyComponentPropertiesToThreeObject(component, component.override_mesh, entity);
@@ -13,6 +13,10 @@ import { assert } from "../../../../core/assert.js";
13
13
  import { TubePathBuilder } from "./tube/build/TubePathBuilder.js";
14
14
  import { Deque } from "../../../../core/collection/queue/Deque.js";
15
15
  import Signal from "../../../../core/events/signal/Signal.js";
16
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
17
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
18
+ import { ShadedGeometry } from "../mesh-v2/ShadedGeometry.js";
19
+ import { Transform } from "../../../ecs/transform/Transform.js";
16
20
 
17
21
  const builders = {
18
22
  [PathDisplayType.None]: function (style, path, result) {
@@ -254,7 +258,9 @@ export class PathDisplaySystem extends AbstractContextSystem {
254
258
  ];
255
259
 
256
260
  this.components_used = [
257
- ParentEntity
261
+ ResourceAccessSpecification.from(ParentEntity, ResourceAccessKind.Create),
262
+ ResourceAccessSpecification.from(ShadedGeometry, ResourceAccessKind.Create),
263
+ ResourceAccessSpecification.from(Transform, ResourceAccessKind.Create),
258
264
  ];
259
265
 
260
266
  /**
@@ -20,6 +20,8 @@ import {
20
20
  import { Reference } from "../../../reference/v2/Reference.js";
21
21
  import { RibbonXPlugin } from "../../trail/x/RibbonXPlugin.js";
22
22
  import { assert } from "../../../../core/assert.js";
23
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
24
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
23
25
 
24
26
  const v3Temp1 = new Vector3();
25
27
 
@@ -39,6 +41,11 @@ class Trail2DSystem extends System {
39
41
 
40
42
  this.dependencies = [Trail2D, Transform];
41
43
 
44
+ this.components_used = [
45
+ ResourceAccessSpecification.from(Trail2D, ResourceAccessKind.Write)
46
+ ];
47
+
48
+
42
49
  /**
43
50
  *
44
51
  * @type {Engine}
@@ -18,6 +18,17 @@ import { max3 } from "../../../../core/math/max3.js";
18
18
  import { min2 } from "../../../../core/math/min2.js";
19
19
  import { DrawMode } from "../../ecs/mesh-v2/DrawMode.js";
20
20
  import { array_copy } from "../../../../core/collection/array/copyArray.js";
21
+ import { Cache } from "../../../../core/cache/Cache.js";
22
+ import { computeMaterialHash } from "../../../asset/loaders/material/computeMaterialHash.js";
23
+
24
+ /**
25
+ * @readonly
26
+ * @type {Cache<Material, {color:Material, depth:Material}>}
27
+ */
28
+ const material_cache = new Cache({
29
+ maxWeight: 1024,
30
+ keyHashFunction: computeMaterialHash
31
+ });
21
32
 
22
33
  export class InstancedMeshGroup {
23
34
  /**
@@ -227,8 +238,11 @@ export class InstancedMeshGroup {
227
238
  /**
228
239
  *
229
240
  * @param {THREE.Material|THREE.ShaderMaterial} sourceMaterial
241
+ * @returns {{depth: Material, color: Material}}
230
242
  */
231
- setMaterial(sourceMaterial) {
243
+ #buildMaterial(sourceMaterial) {
244
+ //console.warn(`building material : {id:${sourceMaterial.id}, name: ${sourceMaterial.name}, type: ${sourceMaterial.type}`)
245
+
232
246
  const material = sourceMaterial.clone();
233
247
 
234
248
  if (material.isShaderMaterial) {
@@ -254,13 +268,26 @@ export class InstancedMeshGroup {
254
268
 
255
269
  depthMaterial.onBeforeCompile = rewriteMaterial;
256
270
 
257
-
258
271
  const cachedMaterial = StaticMaterialCache.Global.acquire(material);
259
272
 
260
- this.__material = cachedMaterial;
273
+ return {
274
+ color: cachedMaterial,
275
+ depth: StaticMaterialCache.Global.acquire(depthMaterial)
276
+ };
277
+
278
+ }
279
+
280
+ /**
281
+ *
282
+ * @param {THREE.Material|THREE.ShaderMaterial} sourceMaterial
283
+ */
284
+ setMaterial(sourceMaterial) {
285
+ const m = material_cache.getOrCompute(sourceMaterial, this.#buildMaterial, this);
286
+
287
+ this.__material = m.color;
261
288
 
262
- this.mesh.material = cachedMaterial;
263
- this.mesh.customDepthMaterial = StaticMaterialCache.Global.acquire(depthMaterial);
289
+ this.mesh.material = m.color;
290
+ this.mesh.customDepthMaterial = m.depth;
264
291
  }
265
292
 
266
293
  /**
@@ -317,7 +344,7 @@ export class InstancedMeshGroup {
317
344
  * @param {number[]|ArrayLike<number>|Float32Array} transform 4x4 transform matrix of the instance
318
345
  */
319
346
  setTransformAt(index, transform) {
320
- array_copy(transform,0,this.__attributeTransformArray,index*16,16);
347
+ array_copy(transform, 0, this.__attributeTransformArray, index * 16, 16);
321
348
  }
322
349
 
323
350
  /**
@@ -326,7 +353,7 @@ export class InstancedMeshGroup {
326
353
  * @param {number[]|ArrayLike<number>|Float32Array} color RGBA color in uint8 format (0...255), LDR
327
354
  */
328
355
  setColorAt(index, color) {
329
- array_copy(color,0,this.__attributeColorArray,index*4,4);
356
+ array_copy(color, 0, this.__attributeColorArray, index * 4, 4);
330
357
  }
331
358
 
332
359
  /**
@@ -7,6 +7,8 @@ import { RenderPassType } from "../../render/RenderPassType.js";
7
7
  import { ImageRGBADataLoader } from "../../../asset/loaders/image/ImageRGBADataLoader.js";
8
8
  import { StandardFrameBuffers } from "../../StandardFrameBuffers.js";
9
9
  import { assert } from "../../../../core/assert.js";
10
+ import { ResourceAccessSpecification } from "../../../../core/model/ResourceAccessSpecification.js";
11
+ import { ResourceAccessKind } from "../../../../core/model/ResourceAccessKind.js";
10
12
 
11
13
  /**
12
14
  *
@@ -33,6 +35,10 @@ export class ParticleEmitterSystem extends System {
33
35
 
34
36
  this.dependencies = [ParticleEmitter, Transform];
35
37
 
38
+ this.components_used = [
39
+ ResourceAccessSpecification.from(ParticleEmitter, ResourceAccessKind.Read | ResourceAccessKind.Write)
40
+ ];
41
+
36
42
  /**
37
43
  *
38
44
  * @type {GraphicsEngine}
@@ -8,6 +8,8 @@ import { GridPosition2Transform } from '../components/GridPosition2Transform.js'
8
8
  import Vector3 from "../../../core/geom/Vector3.js";
9
9
  import { GridPosition2TransformFlags } from "../components/GridPosition2TransformFlags.js";
10
10
  import { obtainTerrain } from "../../ecs/terrain/util/obtainTerrain.js";
11
+ import { ResourceAccessSpecification } from "../../../core/model/ResourceAccessSpecification.js";
12
+ import { ResourceAccessKind } from "../../../core/model/ResourceAccessKind.js";
11
13
 
12
14
 
13
15
  export class GridPosition2TransformSystem extends System {
@@ -16,6 +18,10 @@ export class GridPosition2TransformSystem extends System {
16
18
 
17
19
  this.dependencies = [GridPosition2Transform, GridPosition, Transform];
18
20
 
21
+ this.components_used = [
22
+ ResourceAccessSpecification.from(Transform, ResourceAccessKind.Write)
23
+ ];
24
+
19
25
 
20
26
  this.mapPoint = (x, y, v3) => {
21
27
  const terrain = obtainTerrain(this.entityManager.dataset);
@@ -5,6 +5,8 @@ import { Transform } from "../../ecs/transform/Transform.js";
5
5
  import Vector2 from "../../../core/geom/Vector2.js";
6
6
  import { Transform2GridPositionMode } from "./Transform2GridPositionMode.js";
7
7
  import { obtainTerrain } from "../../ecs/terrain/util/obtainTerrain.js";
8
+ import { ResourceAccessSpecification } from "../../../core/model/ResourceAccessSpecification.js";
9
+ import { ResourceAccessKind } from "../../../core/model/ResourceAccessKind.js";
8
10
 
9
11
  const v2 = new Vector2();
10
12
 
@@ -84,6 +86,10 @@ export class Transform2GridPositionSystem extends System {
84
86
 
85
87
  this.dependencies = [Transform2GridPosition, Transform, GridPosition];
86
88
 
89
+ this.components_used = [
90
+ ResourceAccessSpecification.from(GridPosition, ResourceAccessKind.Write)
91
+ ];
92
+
87
93
  /**
88
94
  *
89
95
  * @type {Synchronizer[]}
@@ -3,12 +3,14 @@ import { BehaviorStatus } from "./BehaviorStatus.js";
3
3
  /**
4
4
  * Base class of behavior tree implementation
5
5
  * @see "The Behavior Tree Starter Kit" by Alex J. Champandard and Philip Dunstan
6
+ * @see https://en.wikipedia.org/wiki/Behavior_tree_(artificial_intelligence,_robotics_and_control)
6
7
  * @template CTX
7
8
  */
8
9
  export class Behavior {
9
10
 
10
11
  /**
11
12
  * Any internal state used by the behavior
13
+ * This provides a way to interact with the outside as well as to pass data between themselves
12
14
  * @type {CTX|null}
13
15
  */
14
16
  context = null;
@@ -36,11 +38,20 @@ export class Behavior {
36
38
  * Used to clean up any resources
37
39
  */
38
40
  finalize() {
41
+ // extend in subclasses as necessary
39
42
  }
40
43
  }
41
44
 
42
45
  /**
46
+ * Useful for type checking
43
47
  * @readonly
44
48
  * @type {boolean}
45
49
  */
46
50
  Behavior.prototype.isBehavior = true;
51
+
52
+ /**
53
+ * Useful for type checking
54
+ * @readonly
55
+ * @type {string}
56
+ */
57
+ Behavior.typeName = "Behavior";
@@ -30,14 +30,20 @@ export class CompositeBehavior extends Behavior {
30
30
 
31
31
  /**
32
32
  *
33
- * @param {Behavior[]} many
33
+ * @param {Behavior[]} children
34
34
  */
35
- addChildren(many) {
36
- const n = many.length;
35
+ addChildren(children) {
36
+ assert.isArray(children, 'children');
37
+
38
+ const n = children.length;
39
+
37
40
  for (let i = 0; i < n; i++) {
38
- const e = many[i];
41
+
42
+ const e = children[i];
39
43
  this.addChild(e);
44
+
40
45
  }
46
+
41
47
  }
42
48
 
43
49
  /**
@@ -27,6 +27,7 @@ export class AbstractDecoratorBehavior extends Behavior {
27
27
  */
28
28
  setSource(source) {
29
29
  assert.defined(source, 'source');
30
+ assert.notNull(source, 'source');
30
31
 
31
32
  assert.equal(source.isBehavior, true, 'source.isBehavior');
32
33