@woosh/meep-engine 2.36.1 → 2.36.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.
@@ -194,7 +194,7 @@ export class Deque {
194
194
 
195
195
  /**
196
196
  *
197
- * @param {E} e
197
+ * @param {T} e
198
198
  * @returns {number}
199
199
  * @private
200
200
  */
@@ -7,7 +7,37 @@ export class Color {
7
7
  g: number
8
8
  b: number
9
9
 
10
- onChanged: Signal
10
+ readonly onChanged: Signal<number, number, number, number, number, number>
11
11
 
12
- setRGB(r: number, g: number, b: number)
12
+ parse(text: string): void
13
+
14
+ setRGB(r: number, g: number, b: number): void
15
+
16
+ setHSL(h: number, s: number, l: number): void
17
+
18
+ setHCL(h: number, c: number, l: number): void
19
+
20
+ setHSI(h: number, s: number, i: number): void
21
+
22
+ setHSV(h: number, s: number, v: number): void
23
+
24
+ getHSV(): { h: number, s: number, v: number }
25
+
26
+ toUint(): number
27
+
28
+ fromUint(v: number): void
29
+
30
+ equals(other: Color): boolean
31
+
32
+ hash(): number
33
+
34
+ copy(other: Color): void
35
+
36
+ clone(): Color
37
+
38
+ fromJSON(json: any): void
39
+
40
+ toJSON(): any
41
+
42
+ writeToArray(destination: ArrayLike<number>, destination_offset: number): void
13
43
  }
@@ -10,7 +10,7 @@ import { computeHashFloat } from "../math/hash/computeHashFloat.js";
10
10
  import { rgb2hsv } from "./rgb2hsv.js";
11
11
  import { rgb2uint24 } from "./rgb2uint24.js";
12
12
 
13
- class Color {
13
+ export class Color {
14
14
  /**
15
15
  *
16
16
  * @param {number} r value from 0 to 1
@@ -37,6 +37,10 @@ class Color {
37
37
  */
38
38
  this.b = b;
39
39
 
40
+ /**
41
+ * @readonly
42
+ * @type {Signal<number,number,number,number,number,number>}
43
+ */
40
44
  this.onChanged = new Signal();
41
45
  }
42
46
 
@@ -384,30 +388,39 @@ class Color {
384
388
  this.setRGB(r, g, b);
385
389
  }
386
390
 
391
+ /**
392
+ *
393
+ * @param {string} str CSS-style string
394
+ * @returns {void}
395
+ */
387
396
  parse(str) {
388
397
  const c = parseColor(str);
389
398
 
390
399
  this.setRGB(c[0] / 255, c[1] / 255, c[2] / 255);
391
400
  }
392
- }
393
401
 
394
- /**
395
- *
396
- * @param {number} r
397
- * @param {number} g
398
- * @param {number} b
399
- * @returns {Color}
400
- */
401
- Color.fromRGB = function (r, g, b) {
402
- return new Color(r, g, b);
403
- };
402
+ /**
403
+ *
404
+ * @param {number} r
405
+ * @param {number} g
406
+ * @param {number} b
407
+ * @returns {Color}
408
+ */
409
+ static fromRGB(r, g, b) {
410
+ return new Color(r, g, b);
411
+ }
404
412
 
405
- Color.parse = function (str) {
406
- const r = new Color();
407
413
 
408
- r.parse(str);
414
+ /**
415
+ *
416
+ * @param {string} str
417
+ * @return {Color}
418
+ */
419
+ static parse(str) {
420
+ const r = new Color();
409
421
 
410
- return r;
411
- };
422
+ r.parse(str);
412
423
 
413
- export { Color };
424
+ return r;
425
+ };
426
+ }
@@ -6,13 +6,15 @@ import {AssetLoader} from "./asset/loaders/AssetLoader";
6
6
  export class EngineConfiguration {
7
7
  addPlugin(plugin: EnginePlugin): boolean
8
8
 
9
- addSystem(system: System): boolean
9
+ addSystem<T>(system: System<T>): boolean
10
10
 
11
- addManySystems(...systems: System[]): void
11
+ addManySystems(...systems: System<any>[]): void
12
12
 
13
13
  addDataTable(table: StaticKnowledgeDataTableDescriptor): boolean
14
14
 
15
- addLoader<T>(type: string, loader: AssetLoader<T>): boolean;
15
+ addLoader<T>(type: string, loader: AssetLoader<T>): boolean
16
+
17
+ hasLoader(type: string): boolean
16
18
 
17
19
  apply(engine): Promise<any>
18
20
  }
@@ -28,6 +28,15 @@ export class EngineConfiguration {
28
28
  this.loaders = new Map();
29
29
  }
30
30
 
31
+ /**
32
+ *
33
+ * @param {string} type
34
+ * @returns {boolean}
35
+ */
36
+ hasLoader(type) {
37
+ return this.loaders.has(type);
38
+ }
39
+
31
40
  /**
32
41
  * @template T
33
42
  * @param {string} type
@@ -26,6 +26,7 @@ import { EngineConfiguration } from "./EngineConfiguration.js";
26
26
  import { JsonAssetLoader } from "./asset/loaders/JsonAssetLoader.js";
27
27
  import { logger } from "./logging/GlobalLogger.js";
28
28
  import { ConsoleLoggerBackend } from "./logging/ConsoleLoggerBackend.js";
29
+ import { noop } from "../core/function/Functions.js";
29
30
 
30
31
  /**
31
32
  *
@@ -85,10 +86,12 @@ export class EngineHarness {
85
86
  }
86
87
 
87
88
  /**
88
- *
89
+ * @param {(config:EngineConfiguration,engine:Engine)=>*} configuration
89
90
  * @returns {Promise<Engine>}
90
91
  */
91
- initialize() {
92
+ initialize({
93
+ configuration = noop
94
+ } = {}) {
92
95
 
93
96
  if (this.p !== null) {
94
97
  return this.p;
@@ -98,7 +101,12 @@ export class EngineHarness {
98
101
 
99
102
  const promise = new Promise(async function (resolve, reject) {
100
103
  const config = new EngineConfiguration();
101
- config.addLoader('json', new JsonAssetLoader());
104
+
105
+ configuration(config, engine);
106
+
107
+ if (!config.hasLoader('json')) {
108
+ config.addLoader('json', new JsonAssetLoader());
109
+ }
102
110
 
103
111
  await config.apply(engine);
104
112
 
@@ -16,7 +16,7 @@ export class EntityNode {
16
16
 
17
17
  removeChild(node: EntityNode): boolean
18
18
 
19
- traverseChildren(visitor: (EntityNode) => void, thisArg?: any): void
19
+ traverse(visitor: (node: EntityNode) => any, thisArg?: any): void
20
20
 
21
21
  build(ecd: EntityComponentDataset): void
22
22
 
@@ -5,6 +5,7 @@ import { assert } from "../../../core/assert.js";
5
5
  import { array_push_if_unique } from "../../../core/collection/array/array_push_if_unique.js";
6
6
  import { Transform } from "../transform/Transform.js";
7
7
  import { TransformAttachment, TransformAttachmentFlags } from "../transform-attachment/TransformAttachment.js";
8
+ import Signal from "../../../core/events/signal/Signal.js";
8
9
 
9
10
  export class EntityNode {
10
11
  /**
@@ -39,6 +40,29 @@ export class EntityNode {
39
40
  * @private
40
41
  */
41
42
  this.__transform = new Transform();
43
+
44
+ this.on = {
45
+ built: new Signal(),
46
+ destroyed: new Signal()
47
+ };
48
+ }
49
+
50
+ /**
51
+ *
52
+ * @param {(node:EntityNode)=>*} visitor
53
+ * @param {*} [thisArg]
54
+ */
55
+ traverse(visitor, thisArg) {
56
+ visitor.call(thisArg, this);
57
+
58
+ const children = this.__children;
59
+ const n = children.length;
60
+
61
+ for (let i = 0; i < n; i++) {
62
+ const child = children[i];
63
+
64
+ child.traverse(visitor, thisArg);
65
+ }
42
66
  }
43
67
 
44
68
  /**
@@ -276,6 +300,8 @@ export class EntityNode {
276
300
 
277
301
  child.build(ecd);
278
302
  }
303
+
304
+ this.on.built.send0();
279
305
  }
280
306
 
281
307
  destroy() {
@@ -295,5 +321,7 @@ export class EntityNode {
295
321
 
296
322
  // then main entity
297
323
  this.__entity.destroy();
324
+
325
+ this.on.destroyed.send0();
298
326
  }
299
327
  }
@@ -12,11 +12,62 @@ function update(parent_transform, attachment_transform, child_transform) {
12
12
  child_transform.multiplyTransforms(parent_transform, attachment_transform);
13
13
  }
14
14
 
15
+ class UpdateContext {
16
+ constructor() {
17
+ /**
18
+ *
19
+ * @type {TransformAttachment|null}
20
+ */
21
+ this.attachment = null;
22
+
23
+ /**
24
+ *
25
+ * @type {Transform|null}
26
+ */
27
+ this.transform = null;
28
+
29
+ /**
30
+ *
31
+ * @type {number}
32
+ */
33
+ this.entity = -1;
34
+
35
+ /**
36
+ *
37
+ * @type {Transform|null}
38
+ */
39
+ this.parent_transform = null;
40
+ }
41
+
42
+ update() {
43
+ update(this.parent_transform, this.attachment.transform, this.transform);
44
+ }
45
+
46
+ link() {
47
+ this.parent_transform.position.onChanged.add(this.update, this);
48
+ this.parent_transform.rotation.onChanged.add(this.update, this);
49
+ this.parent_transform.scale.onChanged.add(this.update, this);
50
+ }
51
+
52
+ unlink() {
53
+ this.parent_transform.position.onChanged.remove(this.update, this);
54
+ this.parent_transform.rotation.onChanged.remove(this.update, this);
55
+ this.parent_transform.scale.onChanged.remove(this.update, this);
56
+ }
57
+ }
58
+
15
59
  export class TransformAttachmentSystem extends System {
16
60
  constructor() {
17
61
  super();
18
62
 
19
63
  this.dependencies = [TransformAttachment, Transform];
64
+
65
+ /**
66
+ *
67
+ * @type {UpdateContext[]}
68
+ * @private
69
+ */
70
+ this.__contexts = [];
20
71
  }
21
72
 
22
73
  /**
@@ -25,25 +76,23 @@ export class TransformAttachmentSystem extends System {
25
76
  * @param {Transform} transform
26
77
  * @param {number} entity
27
78
  */
28
- __update_one(attachment, transform, entity) {
79
+ link(attachment, transform, entity) {
80
+ const ctx = new UpdateContext();
81
+ ctx.system = this;
29
82
 
30
- const em = this.entityManager;
31
- const ecd = em.dataset;
83
+ ctx.attachment = attachment;
84
+ ctx.transform = transform;
85
+ ctx.entity = entity;
32
86
 
33
- const parent_transform = ecd.getComponent(attachment.parent, Transform);
34
87
 
35
- update(parent_transform, attachment.transform, transform);
36
- }
88
+ ctx.parent_transform = this.entityManager.dataset.getComponent(attachment.parent, Transform);
89
+
90
+ ctx.link();
91
+
92
+ this.__contexts[entity] = ctx;
37
93
 
38
- /**
39
- *
40
- * @param {TransformAttachment} attachment
41
- * @param {Transform} transform
42
- * @param {number} entity
43
- */
44
- link(attachment, transform, entity) {
45
94
  if ((attachment.flags & TransformAttachmentFlags.Immediate) !== 0) {
46
- this.__update_one(attachment, transform, entity);
95
+ ctx.update();
47
96
  }
48
97
  }
49
98
 
@@ -55,5 +104,11 @@ export class TransformAttachmentSystem extends System {
55
104
  */
56
105
  unlink(attachment, transform, entity) {
57
106
 
107
+
108
+ const ctx = this.__contexts[entity];
109
+
110
+ delete this.__contexts[entity];
111
+
112
+ ctx.unlink();
58
113
  }
59
114
  }
@@ -1,6 +1,16 @@
1
1
  import {Color} from "../../../../core/color/Color";
2
2
 
3
3
  export class HighlightDefinition {
4
- color: Color
4
+ readonly color: Color
5
5
  opacity: number
6
+
7
+ static rgba(r: number, g: number, b: number, a?: number): HighlightDefinition
8
+
9
+ equals(other: HighlightDefinition): boolean
10
+
11
+ hash(): number
12
+
13
+ fromJSON(json: any): void
14
+
15
+ toJSON(): any
6
16
  }
@@ -1,6 +1,5 @@
1
1
  import { Color } from "../../../../core/color/Color.js";
2
2
  import { assert } from "../../../../core/assert.js";
3
- import { COMPONENT_SERIALIZATION_TRANSIENT_FIELD } from "../../../ecs/storage/COMPONENT_SERIALIZATION_TRANSIENT_FIELD.js";
4
3
  import { computeHashIntegerArray } from "../../../../core/collection/array/computeHashIntegerArray.js";
5
4
  import { computeHashFloat } from "../../../../core/math/hash/computeHashFloat.js";
6
5
 
@@ -8,7 +7,7 @@ export class HighlightDefinition {
8
7
  constructor() {
9
8
 
10
9
  /**
11
- *
10
+ * @readonly
12
11
  * @type {Color}
13
12
  */
14
13
  this.color = new Color();
@@ -18,12 +17,6 @@ export class HighlightDefinition {
18
17
  * @type {number}
19
18
  */
20
19
  this.opacity = 1;
21
-
22
- /**
23
- *
24
- * @type {boolean}
25
- */
26
- this[COMPONENT_SERIALIZATION_TRANSIENT_FIELD] = false;
27
20
  }
28
21
 
29
22
  /**
@@ -73,4 +66,21 @@ export class HighlightDefinition {
73
66
 
74
67
  return r;
75
68
  }
69
+
70
+ /**
71
+ *
72
+ * @param {number} r
73
+ * @param {number} g
74
+ * @param {number} b
75
+ * @param {number} [a]
76
+ * @return {HighlightDefinition}
77
+ */
78
+ static rgba(r, g, b, a = 1) {
79
+ const result = new HighlightDefinition();
80
+
81
+ result.color.setRGB(r, g, b);
82
+ result.opacity = a;
83
+
84
+ return result;
85
+ }
76
86
  }
@@ -10,7 +10,9 @@ import { ShadedGeometryRendererContext } from "./render/ShadedGeometryRendererCo
10
10
  import { assert } from "../../../../core/assert.js";
11
11
  import { ray3_array_compose } from "../../../../core/geom/3d/ray/ray3_array_compose.js";
12
12
  import { ray3_array_apply_matrix4 } from "../../../../core/geom/3d/ray/ray3_array_apply_matrix4.js";
13
- import { ExplicitBinaryBoundingVolumeHierarchy } from "../../../../core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js";
13
+ import {
14
+ ExplicitBinaryBoundingVolumeHierarchy
15
+ } from "../../../../core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js";
14
16
  import { bvh_query_leaves_generic } from "../../../../core/bvh2/bvh3/bvh_query_leaves_generic.js";
15
17
  import { BVHQueryIntersectsRay } from "../../../../core/bvh2/bvh3/query/BVHQueryIntersectsRay.js";
16
18
 
@@ -157,6 +159,8 @@ export class ShadedGeometrySystem extends System {
157
159
 
158
160
  async startup(entityManager, readyCallback, errorCallback) {
159
161
 
162
+ this.entityManager = entityManager;
163
+
160
164
  const engine = this.__engine;
161
165
  const graphics = engine.graphics;
162
166
 
@@ -0,0 +1,8 @@
1
+ export class SGMesh {
2
+ url: string
3
+
4
+ castShadow: boolean
5
+ receiveShadow: boolean
6
+
7
+ static fromURL(url: string): SGMesh
8
+ }
@@ -0,0 +1,137 @@
1
+ export const SGMeshFlags = {
2
+ CastShadow: 1,
3
+ ReceiveShadow: 2
4
+ };
5
+
6
+ export class SGMesh {
7
+ constructor() {
8
+ /**
9
+ *
10
+ * @type {string|null}
11
+ */
12
+ this.__url = null;
13
+
14
+ /**
15
+ *
16
+ * @type {EntityNode|null}
17
+ * @private
18
+ */
19
+ this.__node = null;
20
+
21
+ /**
22
+ *
23
+ * @type {number}
24
+ */
25
+ this.flags = 0;
26
+ }
27
+
28
+ /**
29
+ *
30
+ * @returns {string|null}
31
+ */
32
+ get url() {
33
+ return this.__url;
34
+ }
35
+
36
+ /**
37
+ *
38
+ * @param {string|null} v
39
+ */
40
+ set url(v) {
41
+ if (v === this.__url) {
42
+ // no change
43
+ return;
44
+ }
45
+
46
+ this.__url = v;
47
+ }
48
+
49
+ /**
50
+ *
51
+ * @param {number|SGMeshFlags} flag
52
+ * @returns {void}
53
+ */
54
+ setFlag(flag) {
55
+ this.flags |= flag;
56
+ }
57
+
58
+ /**
59
+ *
60
+ * @param {number|SGMeshFlags} flag
61
+ * @returns {void}
62
+ */
63
+ clearFlag(flag) {
64
+ this.flags &= ~flag;
65
+ }
66
+
67
+ /**
68
+ *
69
+ * @param {number|SGMeshFlags} flag
70
+ * @param {boolean} value
71
+ */
72
+ writeFlag(flag, value) {
73
+ if (value) {
74
+ this.setFlag(flag);
75
+ } else {
76
+ this.clearFlag(flag);
77
+ }
78
+ }
79
+
80
+ /**
81
+ *
82
+ * @param {number|SGMeshFlags} flag
83
+ * @returns {boolean}
84
+ */
85
+ getFlag(flag) {
86
+ return (this.flags & flag) === flag;
87
+ }
88
+
89
+ /**
90
+ *
91
+ * @return {boolean}
92
+ */
93
+ get castShadow() {
94
+ return this.getFlag(SGMeshFlags.CastShadow);
95
+ }
96
+
97
+ /**
98
+ *
99
+ * @param {boolean} v
100
+ */
101
+ set castShadow(v) {
102
+ this.writeFlag(SGMeshFlags.CastShadow, v);
103
+ }
104
+
105
+ /**
106
+ *
107
+ * @return {boolean}
108
+ */
109
+ get receiveShadow() {
110
+ return this.getFlag(SGMeshFlags.ReceiveShadow);
111
+ }
112
+
113
+ /**
114
+ *
115
+ * @param {boolean} v
116
+ */
117
+ set receiveShadow(v) {
118
+ this.writeFlag(SGMeshFlags.ReceiveShadow, v);
119
+ }
120
+
121
+ /**
122
+ *
123
+ * @param {string} url
124
+ * @returns {SGMesh}
125
+ */
126
+ static fromURL(url) {
127
+ const r = new SGMesh();
128
+
129
+ r.url = url;
130
+ r.castShadow = true;
131
+ r.receiveShadow = true;
132
+
133
+ return r;
134
+ }
135
+ }
136
+
137
+ SGMesh.typeName = "SGMesh";
@@ -0,0 +1,12 @@
1
+ export enum SGMeshEvents {
2
+
3
+ /**
4
+ * When asset is attached/loaded onto the Mesh component.
5
+ * This is the time when the 3d data becomes renderable
6
+ */
7
+ AssetLoaded= '@ecd-component-SGMesh/asset-attached',
8
+ /**
9
+ * Required asset failed to load for whatever reason
10
+ */
11
+ AssetLoadFailed= '@ecd-component-SGMesh/asset-failed',
12
+ }
@@ -0,0 +1,12 @@
1
+ export const SGMeshEvents = {
2
+
3
+ /**
4
+ * When asset is attached/loaded onto the Mesh component.
5
+ * This is the time when the 3d data becomes renderable
6
+ */
7
+ AssetLoaded: '@ecd-component-SGMesh/asset-attached',
8
+ /**
9
+ * Required asset failed to load for whatever reason
10
+ */
11
+ AssetLoadFailed: '@ecd-component-SGMesh/asset-failed',
12
+ };
@@ -0,0 +1,7 @@
1
+ import {System} from "../../../../ecs/System";
2
+ import {SGMesh} from "./SGMesh";
3
+ import {Transform} from "../../../../ecs/transform/Transform";
4
+
5
+ export class SGMeshSystem extends System<SGMesh, Transform> {
6
+
7
+ }
@@ -0,0 +1,203 @@
1
+ import { System } from "../../../../ecs/System.js";
2
+ import { SGMesh } from "./SGMesh.js";
3
+ import { Transform } from "../../../../ecs/transform/Transform.js";
4
+ import { assetTypeByPath } from "../../mesh/assetTypeByPath.js";
5
+ import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
6
+ import { ShadedGeometry } from "../ShadedGeometry.js";
7
+ import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
8
+ import { SGMeshEvents } from "./SGMeshEvents.js";
9
+
10
+
11
+ /**
12
+ * @readonly
13
+ * @type {number}
14
+ */
15
+ const CYCLE_COUNT = 128;
16
+
17
+ export class SGMeshSystem extends System {
18
+ /**
19
+ *
20
+ * @param {Engine} engine
21
+ */
22
+ constructor(engine) {
23
+ super();
24
+
25
+ /**
26
+ *
27
+ * @type {Engine}
28
+ * @private
29
+ */
30
+ this.__engine = engine;
31
+
32
+ /**
33
+ *
34
+ * @type {AssetManager}
35
+ * @private
36
+ */
37
+ this.__assetManager = engine.assetManager;
38
+
39
+ this.dependencies = [SGMesh, Transform];
40
+
41
+ /**
42
+ *
43
+ * @type {number[]}
44
+ * @private
45
+ */
46
+ this.__wait_queue = [];
47
+ /**
48
+ *
49
+ * @type {number}
50
+ * @private
51
+ */
52
+ this.__wait_queue_process_index = 0;
53
+ }
54
+
55
+ /**
56
+ *
57
+ * @param {number} entity
58
+ * @param {SGMesh} mesh
59
+ * @param {Transform} transform
60
+ */
61
+ async process(entity, mesh, transform) {
62
+ const am = this.__assetManager;
63
+ const ecd = this.entityManager.dataset;
64
+
65
+ const assetType = assetTypeByPath(mesh.url);
66
+
67
+ let asset;
68
+
69
+ try {
70
+ asset = await am.promise(mesh.url, assetType);
71
+ } catch (e) {
72
+ ecd.sendEvent(entity, SGMeshEvents.AssetLoadFailed);
73
+ return;
74
+ }
75
+
76
+ // TODO check that entity still exists, as we get to this point asynchronously
77
+
78
+ const entity_node = three_object_to_entity_composition(asset.create());
79
+
80
+ mesh.__node = entity_node;
81
+
82
+ entity_node.transform.copy(transform);
83
+
84
+ entity_node.build(ecd);
85
+
86
+ function update_position() {
87
+ entity_node.transform.position.copy(transform.position);
88
+ }
89
+
90
+ function update_rotation() {
91
+ entity_node.transform.rotation.copy(transform.rotation);
92
+ }
93
+
94
+ function update_scale() {
95
+ entity_node.transform.scale.copy(transform.scale);
96
+ }
97
+
98
+ transform.position.onChanged.add(update_position);
99
+ transform.rotation.onChanged.add(update_rotation);
100
+ transform.scale.onChanged.add(update_scale);
101
+
102
+ entity_node.on.destroyed.addOne(() => {
103
+
104
+ transform.position.onChanged.remove(update_position);
105
+ transform.rotation.onChanged.remove(update_rotation);
106
+ transform.scale.onChanged.remove(update_scale);
107
+
108
+ });
109
+
110
+ // apply flags to the hierarchy
111
+ entity_node.traverse(node => {
112
+ /**
113
+ *
114
+ * @type {ShadedGeometry|null}
115
+ */
116
+ const sg = node.entity.getComponent(ShadedGeometry);
117
+ if (sg === null) {
118
+ return;
119
+ }
120
+
121
+ sg.writeFlag(ShadedGeometryFlags.CastShadow, mesh.castShadow);
122
+ sg.writeFlag(ShadedGeometryFlags.ReceiveShadow, mesh.receiveShadow);
123
+ });
124
+
125
+
126
+ ecd.sendEvent(entity, SGMeshEvents.AssetLoaded);
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @param {SGMesh} mesh
132
+ * @param {Transform} transform
133
+ * @param {number} entity
134
+ */
135
+ link(mesh, transform, entity) {
136
+ if (mesh.url === null) {
137
+ this.__wait_queue.push(entity);
138
+ return;
139
+ }
140
+
141
+ this.process(entity, mesh, transform);
142
+ }
143
+
144
+ /**
145
+ *
146
+ * @param {SGMesh} mesh
147
+ * @param {Transform} transform
148
+ * @param {number} entity
149
+ */
150
+ unlink(mesh, transform, entity) {
151
+ if (mesh.__node !== null) {
152
+ mesh.__node.destroy();
153
+
154
+ mesh.__node = null;
155
+ }
156
+
157
+ // check the queue
158
+ const i = this.__wait_queue.indexOf(entity);
159
+
160
+ if (i !== -1) {
161
+ this.__wait_queue.splice(i, 1);
162
+ }
163
+ }
164
+
165
+ update(time_delta) {
166
+
167
+ const waiting = this.__wait_queue;
168
+
169
+ let l = waiting.length;
170
+
171
+ if (l > 0) {
172
+
173
+ let pointer = this.__wait_queue_process_index;
174
+
175
+ const dataset = this.entityManager.dataset;
176
+
177
+ for (let i = 0; i < CYCLE_COUNT; i++) {
178
+
179
+ const index = pointer % l;
180
+
181
+ const entity = waiting[index];
182
+
183
+ const mesh = dataset.getComponent(entity, SGMesh);
184
+
185
+ if (mesh.url === null) {
186
+ continue;
187
+ }
188
+
189
+ const transform = dataset.getComponent(entity, Transform);
190
+
191
+ this.process(entity, mesh, transform);
192
+
193
+ waiting.splice(i, 1);
194
+
195
+ i--;
196
+ l--;
197
+ }
198
+
199
+ this.__wait_queue_process_index = pointer;
200
+
201
+ }
202
+ }
203
+ }
@@ -0,0 +1,53 @@
1
+ import { EngineHarness } from "../../../../EngineHarness.js";
2
+ import { ShadedGeometrySystem } from "../ShadedGeometrySystem.js";
3
+ import { SGMeshSystem } from "./SGMeshSystem.js";
4
+ import EntityBuilder from "../../../../ecs/EntityBuilder.js";
5
+ import { Transform } from "../../../../ecs/transform/Transform.js";
6
+ import { SGMesh } from "./SGMesh.js";
7
+ import { GameAssetType } from "../../../../asset/GameAssetType.js";
8
+ import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
9
+ import Vector3 from "../../../../../core/geom/Vector3.js";
10
+ import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
11
+ import { BehaviorComponent } from "../../../../intelligence/behavior/ecs/BehaviorComponent.js";
12
+ import { OrbitingBehavior } from "../../../../../../model/game/util/behavior/OrbitingBehavior.js";
13
+ import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
14
+
15
+ new EngineHarness().initialize({
16
+ configuration(config, engine) {
17
+ config.addManySystems(
18
+ new ShadedGeometrySystem(engine),
19
+ new SGMeshSystem(engine),
20
+ new BehaviorSystem(engine),
21
+ new TransformAttachmentSystem()
22
+ );
23
+
24
+ config.addLoader(GameAssetType.ModelGLTF_JSON, new GLTFAssetLoader());
25
+ }
26
+ }).then(main);
27
+
28
+ /**
29
+ *
30
+ * @param {Engine} engine
31
+ */
32
+ function main(engine) {
33
+ EngineHarness.buildBasics({
34
+ engine
35
+ });
36
+
37
+ const ecd = engine.entityManager.dataset;
38
+
39
+ const mesh = SGMesh.fromURL("data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf");
40
+
41
+ new EntityBuilder()
42
+ .add(Transform.fromJSON({
43
+ position: new Vector3(10, 0, 10)
44
+ }))
45
+ // .add(SGMesh.fromURL("data/models/snaps/cube_blue.gltf"))
46
+ .add(mesh)
47
+ .add(BehaviorComponent.fromOne(OrbitingBehavior.from({
48
+ center: new Vector3(10, 0, 10),
49
+ radius: 5,
50
+ rate: 2
51
+ })))
52
+ .build(ecd);
53
+ }
@@ -0,0 +1,4 @@
1
+ import {Object3D} from "three";
2
+ import {EntityNode} from "../../../ecs/parent/EntityNode";
3
+
4
+ export function three_object_to_entity_composition(object: Object3D): EntityNode
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.36.1",
8
+ "version": "2.36.5",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",