@woosh/meep-engine 2.38.1 → 2.39.0

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 (30) hide show
  1. package/core/geom/Quaternion.js +70 -0
  2. package/core/geom/Vector2.js +17 -0
  3. package/core/geom/v3_angle_between.js +17 -3
  4. package/engine/ecs/EntityBuilder.d.ts +3 -1
  5. package/engine/ecs/EntityBuilder.js +10 -1
  6. package/engine/ecs/EntityComponentDataset.js +1 -1
  7. package/engine/ecs/parent/ChildEntities.d.ts +3 -0
  8. package/engine/ecs/parent/ChildEntities.js +41 -0
  9. package/engine/ecs/system/AbstractContextSystem.js +4 -2
  10. package/engine/graphics/ecs/mesh-v2/{sg_compute_hierarchy_bounding_box_by_parent_entity.js → sg_hierarchy_compute_bounding_box_via_parent_entity.js} +1 -1
  11. package/engine/graphics/ecs/path/PathDisplayEvents.js +3 -2
  12. package/engine/graphics/ecs/path/PathDisplaySystem.js +5 -0
  13. package/engine/graphics/ecs/path/highlight/PathDisplayHighlightSystem.d.ts +7 -0
  14. package/engine/graphics/ecs/path/highlight/PathDisplayHighlightSystem.js +141 -0
  15. package/engine/graphics/ecs/path/testPathDisplaySystem.js +78 -25
  16. package/engine/graphics/ecs/path/tube/TubePathStyle.d.ts +12 -0
  17. package/engine/graphics/ecs/path/tube/TubePathStyle.js +53 -8
  18. package/engine/graphics/ecs/path/tube/build/TubePathBuilder.js +114 -4
  19. package/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.js +12 -2
  20. package/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +13 -2
  21. package/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +33 -28
  22. package/engine/graphics/ecs/path/tube/build/makeTubeGeometry.js +123 -347
  23. package/engine/graphics/ecs/path/tube/build/make_cap.js +274 -0
  24. package/engine/graphics/ecs/path/tube/build/make_ring_faces.js +40 -0
  25. package/engine/graphics/ecs/path/tube/build/make_ring_vertices.js +152 -0
  26. package/package.json +1 -1
  27. package/view/View.js +2 -2
  28. package/view/{compose3x3transform.js → m3_cm_compose_transform.js} +11 -3
  29. package/view/m3_rm_compose_transform.js +45 -0
  30. package/view/multiplyMatrices3.js +4 -4
@@ -26,6 +26,76 @@ function normalizeAngle(v) {
26
26
  return v % PI2;
27
27
  }
28
28
 
29
+ /**
30
+ *
31
+ * @param {number[]|Float32Array} out
32
+ * @param {number} fx
33
+ * @param {number} fy
34
+ * @param {number} fz
35
+ * @param {number} ux
36
+ * @param {number} uy
37
+ * @param {number} uz
38
+ */
39
+ export function quat_array_from_look(out, fx, fy, fz, ux, uy, uz) {
40
+ forward.set(fx, fy, fz);
41
+ forward.normalize();
42
+
43
+ right._crossVectors(ux, uy, uz, forward.x, forward.y, forward.z);
44
+ right.normalize();
45
+
46
+ up.crossVectors(forward, right);
47
+
48
+ var m00 = right.x;
49
+ var m01 = right.y;
50
+ var m02 = right.z;
51
+ var m10 = up.x;
52
+ var m11 = up.y;
53
+ var m12 = up.z;
54
+ var m20 = forward.x;
55
+ var m21 = forward.y;
56
+ var m22 = forward.z;
57
+
58
+
59
+ const num8 = (m00 + m11) + m22;
60
+
61
+ let _x, _y, _z, _w;
62
+
63
+ if (num8 > 0) {
64
+ let num = Math.sqrt(num8 + 1);
65
+ _w = num * 0.5;
66
+ num = 0.5 / num;
67
+ _x = (m12 - m21) * num;
68
+ _y = (m20 - m02) * num;
69
+ _z = (m01 - m10) * num;
70
+ } else if ((m00 >= m11) && (m00 >= m22)) {
71
+ var num7 = Math.sqrt(((1 + m00) - m11) - m22);
72
+ var num4 = 0.5 / num7;
73
+ _x = 0.5 * num7;
74
+ _y = (m01 + m10) * num4;
75
+ _z = (m02 + m20) * num4;
76
+ _w = (m12 - m21) * num4;
77
+ } else if (m11 > m22) {
78
+ var num6 = Math.sqrt(((1 + m11) - m00) - m22);
79
+ var num3 = 0.5 / num6;
80
+ _x = (m10 + m01) * num3;
81
+ _y = 0.5 * num6;
82
+ _z = (m21 + m12) * num3;
83
+ _w = (m20 - m02) * num3;
84
+ } else {
85
+ var num5 = Math.sqrt(((1 + m22) - m00) - m11);
86
+ var num2 = 0.5 / num5;
87
+ _x = (m20 + m02) * num2;
88
+ _y = (m21 + m12) * num2;
89
+ _z = 0.5 * num5;
90
+ _w = (m01 - m10) * num2;
91
+ }
92
+
93
+ out[0] = _x;
94
+ out[1] = _y;
95
+ out[2] = _z;
96
+ out[3] = _w;
97
+ }
98
+
29
99
  /**
30
100
  * just in case you need that function also
31
101
  * @param {Vector3} axis
@@ -662,6 +662,23 @@ export function v2_angleBetween(x0, y0, x1, y1) {
662
662
  return Math.acos(theta);
663
663
  }
664
664
 
665
+ /**
666
+ * https://math.stackexchange.com/questions/1596513/find-the-bearing-angle-between-two-points-in-a-2d-space
667
+ * @param {number} x0
668
+ * @param {number} y0
669
+ * @param {number} x1
670
+ * @param {number} y1
671
+ * @returns {number}
672
+ */
673
+ export function v2_bearing_angle_towards(x0, y0, x1, y1) {
674
+ const TWOPI = 6.2831853071795865;
675
+ // if (a1 = b1 and a2 = b2) throw an error
676
+ let theta = Math.atan2(x1 - x0, y0 - y1);
677
+ if (theta < 0.0)
678
+ theta += TWOPI;
679
+ return theta;
680
+ }
681
+
665
682
  /**
666
683
  *
667
684
  * @param {number} x0
@@ -13,6 +13,22 @@ import { clamp } from "../math/clamp.js";
13
13
  * @returns {number}
14
14
  */
15
15
  export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
16
+ const theta = v3_angle_cos_between(x0, y0, z0, x1, y1, z1);
17
+
18
+ return Math.acos(theta);
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param {number} x0
24
+ * @param {number} y0
25
+ * @param {number} z0
26
+ * @param {number} x1
27
+ * @param {number} y1
28
+ * @param {number} z1
29
+ * @returns {number}
30
+ */
31
+ export function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
16
32
  const d = v3_dot(x0, y0, z0, x1, y1, z1);
17
33
 
18
34
  const magnitude_0 = v3_length(x0, y0, z0);
@@ -25,9 +41,7 @@ export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
25
41
  return 0;
26
42
  }
27
43
 
28
- const theta = clamp(d / l, -1, 1);
29
-
30
- return Math.acos(theta);
44
+ return clamp(d / l, -1, 1);
31
45
  }
32
46
 
33
47
  /**
@@ -6,7 +6,7 @@ interface Type<T> extends Function {
6
6
 
7
7
  export default class EntityBuilder {
8
8
  public entity: number;
9
-
9
+
10
10
  add<T>(component: T): EntityBuilder
11
11
 
12
12
  removeComponent<T>(componentType: Type<T>): T | null
@@ -15,6 +15,8 @@ export default class EntityBuilder {
15
15
 
16
16
  getComponentSafe<T>(componentType: Type<T>): T
17
17
 
18
+ hasComponent<T>(componentType: Type<T>): boolean
19
+
18
20
  build(dataset: EntityComponentDataset): number
19
21
 
20
22
  destroy(): boolean
@@ -132,7 +132,7 @@ class EntityBuilder {
132
132
  throw new Error("Can not add " + componentInstance + " to EntityBuilder");
133
133
  }
134
134
 
135
- assert.notOk(this.getComponent(Object.getPrototypeOf(componentInstance).constructor) !== null, 'Component of this type already exists');
135
+ assert.notOk(this.hasComponent(Object.getPrototypeOf(componentInstance).constructor) , 'Component of this type already exists');
136
136
 
137
137
  this.element.push(componentInstance);
138
138
 
@@ -144,6 +144,15 @@ class EntityBuilder {
144
144
  return this;
145
145
  }
146
146
 
147
+ /**
148
+ * @template T
149
+ * @param {T} klass
150
+ * @returns {boolean}
151
+ */
152
+ hasComponent(klass) {
153
+ return this.getComponent(klass) !== null;
154
+ }
155
+
147
156
  /**
148
157
  * @template T
149
158
  * @param {Class<T>} klass
@@ -1467,7 +1467,7 @@ export class EntityComponentDataset {
1467
1467
  * Registers an event listener to a specific entity and event type, specified by eventName string.
1468
1468
  * @param {number} entity
1469
1469
  * @param {string} eventName
1470
- * @param {function|Function} listener
1470
+ * @param {function()} listener
1471
1471
  * @param {*} [thisArg]
1472
1472
  */
1473
1473
  addEntityEventListener(entity, eventName, listener, thisArg) {
@@ -0,0 +1,3 @@
1
+ export class ChildEntities {
2
+ readonly entities: number[]
3
+ }
@@ -0,0 +1,41 @@
1
+ import { assert } from "../../../core/assert.js";
2
+
3
+ export class ChildEntities {
4
+ constructor() {
5
+ /**
6
+ * Directly attached children, must have to relevant {@link ParentEntity} components in children as well
7
+ * @readonly
8
+ * @type {number[]}
9
+ */
10
+ this.entities = [];
11
+ }
12
+
13
+ /**
14
+ *
15
+ * @param {number[]} elements
16
+ * @returns {ChildEntities}
17
+ */
18
+ static from(elements) {
19
+ assert.isArrayLike(elements, 'elements');
20
+
21
+ const r = new ChildEntities();
22
+
23
+ Array.prototype.push.apply(r.entities, elements);
24
+
25
+ return r;
26
+ }
27
+
28
+ toJSON() {
29
+ return {
30
+ entities: this.entities
31
+ };
32
+ }
33
+
34
+ /**
35
+ *
36
+ * @param {number[]} entities
37
+ */
38
+ fromJSON({ entities = [] }) {
39
+ this.entities = entities;
40
+ }
41
+ }
@@ -16,7 +16,7 @@ export class AbstractContextSystem extends System {
16
16
 
17
17
  assert.defined(ContextClass, 'ContextClass');
18
18
  assert.notNull(ContextClass, 'ContextClass');
19
- assert.typeOf(ContextClass, 'function', 'ContextClass');
19
+ assert.isFunction(ContextClass, 'ContextClass');
20
20
 
21
21
  /**
22
22
  *
@@ -60,10 +60,12 @@ export class AbstractContextSystem extends System {
60
60
  /**
61
61
  *
62
62
  * @param entity
63
- * @return {T}
63
+ * @return {T|undefined}
64
64
  * @protected
65
65
  */
66
66
  __getEntityContext(entity) {
67
+ assert.isNumber(entity, 'entity');
68
+
67
69
  return this.__live_contexts[entity];
68
70
  }
69
71
 
@@ -18,7 +18,7 @@ export function sg_hierarchy_compute_bounding_box_via_parent_entity(result, root
18
18
  */
19
19
  const sg = ecd.getComponent(root_entity, ShadedGeometry);
20
20
 
21
- if (sg !== null) {
21
+ if (sg !== undefined) {
22
22
  sg.getBoundingBox(scratch_aabb3);
23
23
 
24
24
  result.expandToFit(scratch_aabb3);
@@ -3,5 +3,6 @@
3
3
  * @enum {string}
4
4
  */
5
5
  export const PathDisplayEvents = {
6
- Changed: "@ecd-component-PathDisplay/changed"
7
- }
6
+ Changed: "@ecd-component-PathDisplay/changed",
7
+ BuildComplete: "@ecd-component-PathDisplay/build-complete"
8
+ }
@@ -139,6 +139,11 @@ class PathDisplayContext extends SystemEntityContext {
139
139
  }
140
140
 
141
141
  this.__build_existing_entities();
142
+
143
+ const ecd = this.getDataset();
144
+
145
+ // signal completion of build
146
+ ecd.sendEvent(this.entity, PathDisplayEvents.BuildComplete, ownedEntities);
142
147
  }
143
148
 
144
149
  __build_existing_entities() {
@@ -0,0 +1,7 @@
1
+ import {System} from "../../../../ecs/System";
2
+ import {PathDisplay} from "../PathDisplay";
3
+ import Highlight from "../../highlight/Highlight";
4
+
5
+ export class PathDisplayHighlightSystem extends System<PathDisplay, Highlight> {
6
+
7
+ }
@@ -0,0 +1,141 @@
1
+ import { System } from "../../../../ecs/System.js";
2
+ import { PathDisplay } from "../PathDisplay.js";
3
+ import Highlight from "../../highlight/Highlight.js";
4
+ import { PathDisplayEvents } from "../PathDisplayEvents.js";
5
+ import { PathDisplaySystem } from "../PathDisplaySystem.js";
6
+
7
+ export class PathDisplayHighlightSystem extends System {
8
+ constructor() {
9
+ super();
10
+
11
+ this.dependencies = [PathDisplay, Highlight];
12
+ }
13
+
14
+ /**
15
+ *
16
+ * @param {number} entity
17
+ * @returns {PathDisplayContext|undefined}
18
+ * @private
19
+ */
20
+ __getPathDisplayContext(entity) {
21
+
22
+ /**
23
+ *
24
+ * @type {PathDisplaySystem}
25
+ */
26
+ const pds = this.entityManager.getSystem(PathDisplaySystem);
27
+
28
+ if (pds === null) {
29
+ console.warn('PathDisplaySystem not registered');
30
+ return;
31
+ }
32
+ /**
33
+ *
34
+ * @type {PathDisplayContext}
35
+ */
36
+ const ctx = pds.__getEntityContext(entity);
37
+
38
+ return ctx;
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @param _
44
+ * @param {number} entity
45
+ * @private
46
+ */
47
+ __apply_to_entity(_, entity) {
48
+ const ecd = this.entityManager.dataset;
49
+
50
+ const highlight = ecd.getComponent(entity, Highlight);
51
+
52
+ if (highlight === undefined) {
53
+ console.error(`Entity ${entity} no longer has a Highlight`);
54
+ return;
55
+ }
56
+
57
+ const ctx = this.__getPathDisplayContext(entity);
58
+
59
+ if (ctx === undefined) {
60
+ // no context
61
+ return;
62
+ }
63
+
64
+ /**
65
+ *
66
+ * @type {EntityBuilder[]}
67
+ */
68
+ const ownedEntities = ctx.__owned_entities;
69
+
70
+ for (let i = 0; i < ownedEntities.length; i++) {
71
+ const eb = ownedEntities[i];
72
+
73
+ if (eb.hasComponent(Highlight)) {
74
+ //already has a highlight
75
+ console.warn(`Owned entity ${eb.entity} of PathDisplay entity ${entity} already has a Highlight component attached. Keeping existing Highlight.`);
76
+ continue;
77
+ }
78
+
79
+ eb.add(highlight);
80
+ }
81
+ }
82
+
83
+ /**
84
+ *
85
+ * @param _
86
+ * @param {number} entity
87
+ * @private
88
+ */
89
+ __remove_from_entity(_, entity) {
90
+ const ecd = this.entityManager.dataset;
91
+
92
+ const highlight = ecd.getComponent(entity, Highlight);
93
+
94
+ if (highlight === undefined) {
95
+ console.error(`Entity ${entity} no longer has a Highlight`);
96
+ return;
97
+ }
98
+
99
+ const ctx = this.__getPathDisplayContext(entity);
100
+
101
+ if (ctx === undefined) {
102
+ // no context
103
+ return;
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @type {EntityBuilder[]}
109
+ */
110
+ const ownedEntities = ctx.__owned_entities;
111
+
112
+ for (let i = 0; i < ownedEntities.length; i++) {
113
+ const eb = ownedEntities[i];
114
+
115
+ const hl = eb.getComponent(Highlight);
116
+
117
+ if (hl !== highlight) {
118
+ // has a different highlight, leave alone
119
+ continue;
120
+ }
121
+
122
+ eb.removeComponent(Highlight);
123
+ }
124
+ }
125
+
126
+ link(display, highlight, entity) {
127
+ this.__apply_to_entity(null, entity);
128
+
129
+ const ecd = this.entityManager.dataset;
130
+
131
+ ecd.addEntityEventListener(entity, PathDisplayEvents.BuildComplete, this.__apply_to_entity, this);
132
+ }
133
+
134
+ unlink(display, highlight, entity) {
135
+ const ecd = this.entityManager.dataset;
136
+
137
+ ecd.removeEntityEventListener(entity, PathDisplayEvents.BuildComplete, this.__apply_to_entity, this);
138
+
139
+ this.__remove_from_entity(null, entity);
140
+ }
141
+ }
@@ -19,9 +19,6 @@ import SteeringSystem from "../../../ecs/systems/SteeringSystem.js";
19
19
  import MotionSystem from "../../../ecs/systems/MotionSystem.js";
20
20
  import TagSystem from "../../../ecs/systems/TagSystem.js";
21
21
  import { AttachmentSystem } from "../../../ecs/attachment/AttachmentSystem.js";
22
- import { SoundEmitterSystem } from "../../../sound/ecs/emitter/SoundEmitterSystem.js";
23
- import SoundControllerSystem from "../../../sound/ecs/SoundControllerSystem.js";
24
- import SoundListenerSystem from "../../../sound/ecs/SoundListenerSystem.js";
25
22
  import TimerSystem from "../../../ecs/systems/TimerSystem.js";
26
23
  import AnimationSystem from "../../../ecs/systems/AnimationSystem.js";
27
24
  import TopDownCameraControllerSystem from "../camera/topdown/TopDownCameraControllerSystem.js";
@@ -34,11 +31,6 @@ import WaterSystem from "../water/WaterSystem.js";
34
31
  import Trail2DSystem from "../trail2d/Trail2DSystem.js";
35
32
  import { Foliage2System } from "../../../ecs/foliage/ecs/Foliage2System.js";
36
33
  import ViewportPositionSystem from "../../../ecs/gui/position/ViewportPositionSystem.js";
37
- import { GridPosition2TransformSystem } from "../../../grid/systems/GridPosition2TransformSystem.js";
38
- import { Transform2GridPositionSystem } from "../../../grid/transform2grid/Transform2GridPositionSystem.js";
39
- import SynchronizePositionSystem from "../../../ecs/systems/SynchronizePositionSystem.js";
40
- import GridObstacleSystem from "../../../grid/systems/GridObstacleSystem.js";
41
- import GridPositionSystem from "../../../grid/systems/GridPositionSystem.js";
42
34
  import InputControllerSystem from "../../../input/ecs/systems/InputControllerSystem.js";
43
35
  import { InputSystem } from "../../../input/ecs/systems/InputSystem.js";
44
36
  import MeshHighlightSystem from "../highlight/system/MeshHighlightSystem.js";
@@ -58,7 +50,9 @@ import { GameAssetType } from "../../../asset/GameAssetType.js";
58
50
  import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
59
51
  import { JsonAssetLoader } from "../../../asset/loaders/JsonAssetLoader.js";
60
52
  import { ImageRGBADataLoader } from "../../../asset/loaders/image/ImageRGBADataLoader.js";
61
- import { AmbientOcclusionPostProcessEffect } from "../../render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js";
53
+ import {
54
+ AmbientOcclusionPostProcessEffect
55
+ } from "../../render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js";
62
56
  import { CanvasView } from "../../../../view/elements/CanvasView.js";
63
57
  import { computeCatmullRomSpline } from "../../../navigation/ecs/components/computeCatmullRomSpline.js";
64
58
  import { PathDisplaySpec } from "./PathDisplaySpec.js";
@@ -68,6 +62,10 @@ import { TubeMaterialType } from "./tube/TubeMaterialType.js";
68
62
  import { MatcapMaterialDefinition } from "./tube/MatcapMaterialDefinition.js";
69
63
  import { TextureAssetLoader } from "../../../asset/loaders/texture/TextureAssetLoader.js";
70
64
  import { ShadedGeometrySystem } from "../mesh-v2/ShadedGeometrySystem.js";
65
+ import { CapType } from "./tube/CapType.js";
66
+ import { StandardMaterialDefinition } from "./tube/StandardMaterialDefinition.js";
67
+ import { PathDisplayHighlightSystem } from "./highlight/PathDisplayHighlightSystem.js";
68
+ import { ShadedGeometryHighlightSystem } from "../highlight/system/ShadedGeometryHighlightSystem.js";
71
69
 
72
70
  const engineHarness = new EngineHarness();
73
71
 
@@ -95,9 +93,6 @@ function makeConfig(engine) {
95
93
  new MotionSystem(),
96
94
  new TagSystem(),
97
95
  new AttachmentSystem(),
98
- new SoundEmitterSystem(assetManager, sound.destination, sound.context),
99
- new SoundControllerSystem(),
100
- new SoundListenerSystem(sound.context),
101
96
  new TimerSystem(),
102
97
  guiSystem,
103
98
  new AnimationSystem(graphics.viewport.size),
@@ -111,11 +106,6 @@ function makeConfig(engine) {
111
106
  new Trail2DSystem(engine),
112
107
  new Foliage2System(assetManager, graphics),
113
108
  new ViewportPositionSystem(graphics.viewport.size),
114
- new GridPosition2TransformSystem(),
115
- new Transform2GridPositionSystem(),
116
- new SynchronizePositionSystem(),
117
- new GridObstacleSystem(),
118
- new GridPositionSystem(),
119
109
  new InputControllerSystem(devices),
120
110
  new InputSystem(devices),
121
111
  new MeshHighlightSystem(engine),
@@ -128,7 +118,9 @@ function makeConfig(engine) {
128
118
  new BehaviorSystem(engine),
129
119
  new SerializationMetadataSystem(),
130
120
  new InverseKinematicsSystem(),
121
+ new ShadedGeometryHighlightSystem(engine),
131
122
  new PathDisplaySystem(engine),
123
+ new PathDisplayHighlightSystem()
132
124
  );
133
125
 
134
126
  // Plugins
@@ -309,17 +301,67 @@ function sample_style_tube() {
309
301
  const style = new TubePathStyle();
310
302
 
311
303
  style.color.setRGB(1, 1, 1);
312
- style.material_type = TubeMaterialType.Matcap;
313
- style.material = new MatcapMaterialDefinition();
314
- // style.material.texture = 'data/textures/matcap/matcap-porcelain-white.jpg';
315
- style.material.texture = "data/textures/matcap/nidorx/3E2335_D36A1B_8E4A2E_2842A5.jpg";
316
304
 
317
- style.width = 0.1;
305
+ function make_matcap(style) {
306
+
307
+ style.material_type = TubeMaterialType.Matcap;
308
+ style.material = new MatcapMaterialDefinition();
309
+ // style.material.texture = 'data/textures/matcap/matcap-porcelain-white.jpg';
310
+ style.material.texture = "data/textures/matcap/nidorx/3E2335_D36A1B_8E4A2E_2842A5.jpg";
311
+
312
+ }
313
+
314
+ function make_standard(style) {
315
+
316
+ style.material_type = TubeMaterialType.Standard;
317
+ style.material = new StandardMaterialDefinition();
318
+ // style.material.texture = 'data/textures/matcap/matcap-porcelain-white.jpg';
319
+ // style.material.texture = "data/textures/matcap/nidorx/3E2335_D36A1B_8E4A2E_2842A5.jpg";
320
+
321
+ style.color.setHSV(0, 1, 0.9);
322
+ }
323
+
324
+ make_standard(style);
325
+
326
+ style.width = 0.5;
327
+ style.cast_shadow = true;
328
+
329
+ style.cap_type = CapType.Round;
330
+ // style.cap_type = CapType.None;
331
+
332
+ // style.path_mask = [
333
+ // 0.1, 0.12,
334
+ // 0.3, 1
335
+ // ];
336
+
337
+ //
338
+ // style.shape = [
339
+ // 0.1, -0.5,
340
+ // 0.1, 0.5,
341
+ // -0.1, 0.5,
342
+ // -0.1, -0.5,
343
+ // ];
344
+
345
+ // style.shape = [
346
+ // -0.5, -0.1,
347
+ // 0.5, -0.1,
348
+ // 0.5, 0.1,
349
+ // -0.5, 0.1,
350
+ // ];
351
+ //
352
+ style.shape = [
353
+ -0.5, -0.1,
354
+ -0.45, -0.15,
355
+ 0.45, -0.15,
356
+ 0.5, -0.1,
357
+ 0.5, 0.1,
358
+ 0.45, 0.15,
359
+ -0.45, 0.15,
360
+ -0.5, 0.1
361
+ ];
318
362
 
319
363
  style.path_mask = [
320
- 0.1, 0.12,
321
- 0.3, 0.8,
322
- 0.9, 1
364
+ 0, 1
323
365
  ];
324
366
 
325
367
  return style;
@@ -352,6 +394,16 @@ function main(engine) {
352
394
  ]);
353
395
 
354
396
 
397
+ // _p.setPositionsFromVectorArray([
398
+ // new Vector3(1, 1, 3),
399
+ // new Vector3(3, 1, 3),
400
+ // new Vector3(3, 1, 7),
401
+ // new Vector3(7, 1, 7),
402
+ // new Vector3(7, 1, 3),
403
+ // new Vector3(8, 1, 3),
404
+ // ]);
405
+ // _p.reverse();
406
+
355
407
  const trailPathStyle = new RibbonPathStyle();
356
408
  trailPathStyle.material.diffuse = "data/textures/trail/Circle_04.png";
357
409
  trailPathStyle.resolution = 10;
@@ -377,6 +429,7 @@ function main(engine) {
377
429
  new EntityBuilder()
378
430
  .add(_p)
379
431
  .add(pathDisplay)
432
+ .add(Highlight.fromOne(0, 1, 1, 1))
380
433
  .build(engine.entityManager.dataset);
381
434
  }
382
435
 
@@ -11,7 +11,19 @@ export class TubePathStyle {
11
11
  public opacity: number
12
12
  public width: number
13
13
  public resolution: number
14
+ /**
15
+ * @deprecated
16
+ */
14
17
  public radial_resolution: number
18
+ /**
19
+ * Profile shape of the path, such as a circle or a square
20
+ * Defined as a sequence of 2d points: [x0,y0,x1,y1, ... xN, yN]
21
+ */
22
+ public shape: ArrayLike<number>
23
+ /**
24
+ * Optional, contains 2d normals of the profile shape, if not set - smooth normals will be automatically computed
25
+ */
26
+ public shape_normals: ArrayLike<number>
15
27
  public cast_shadow: boolean
16
28
  public receive_shadow: boolean
17
29
  public path_mask: number[]