@woosh/meep-engine 2.39.18 → 2.39.19

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.
@@ -12,6 +12,8 @@ import { clamp01 } from "../math/clamp01.js";
12
12
  import { rgb2hex } from "./rgb2hex.js";
13
13
  import { linear_to_sRGB } from "./linear_to_sRGB.js";
14
14
  import { sRGB_to_linear } from "./sRGB_to_linear.js";
15
+ import { lerp } from "../math/lerp.js";
16
+ import { float2uint8 } from "../binary/float2uint8.js";
15
17
 
16
18
  /**
17
19
  * @class
@@ -22,8 +24,9 @@ export class Color {
22
24
  * @param {number} r value from 0 to 1
23
25
  * @param {number} g value from 0 to 1
24
26
  * @param {number} b value from 0 to 1
27
+ * @param {number} [a] value from 0 to 1
25
28
  */
26
- constructor(r = 0, g = 0, b = 0) {
29
+ constructor(r = 0, g = 0, b = 0, a = 1) {
27
30
  /**
28
31
  * Red channel
29
32
  * Value from 0 to 1
@@ -43,6 +46,13 @@ export class Color {
43
46
  */
44
47
  this.b = b;
45
48
 
49
+ /**
50
+ * Alpha channel
51
+ * Value from 0 to 1
52
+ * @type {number}
53
+ */
54
+ this.a = a;
55
+
46
56
  /**
47
57
  * @readonly
48
58
  * @type {Signal<number,number,number,number,number,number>}
@@ -98,6 +108,22 @@ export class Color {
98
108
  this.b = v;
99
109
  }
100
110
 
111
+ /**
112
+ *
113
+ * @returns {number}
114
+ */
115
+ get 3() {
116
+ return this.a;
117
+ }
118
+
119
+ /**
120
+ *
121
+ * @param {number} v
122
+ */
123
+ set 3(v) {
124
+ this.a = v;
125
+ }
126
+
101
127
  /**
102
128
  *
103
129
  * @param {number} r
@@ -356,12 +382,20 @@ export class Color {
356
382
  */
357
383
  toHex() {
358
384
  return '#' + rgb2hex(
359
- Math.round(this.r),
360
- Math.round(this.g),
361
- Math.round(this.b)
385
+ float2uint8(this.r),
386
+ float2uint8(this.g),
387
+ float2uint8(this.b)
362
388
  );
363
389
  }
364
390
 
391
+ /**
392
+ *
393
+ * @returns {string}
394
+ */
395
+ toCssRGBAString() {
396
+ return `rgba(${float2uint8(this.r)},${float2uint8(this.g)},${float2uint8(this.b)},${this.a})`;
397
+ }
398
+
365
399
  /**
366
400
  *
367
401
  * @param {Color} other
@@ -463,9 +497,28 @@ export class Color {
463
497
  parse(str) {
464
498
  const c = parseColor(str);
465
499
 
500
+ if (typeof c[3] === "number") {
501
+ this.a = c[3];
502
+ } else {
503
+ this.a = 1;
504
+ }
505
+
466
506
  this.setRGB(c[0] / 255, c[1] / 255, c[2] / 255);
467
507
  }
468
508
 
509
+ /**
510
+ *
511
+ * @param {Color} a
512
+ * @param {Color} b
513
+ * @param {number} f
514
+ */
515
+ lerpColors(a, b, f) {
516
+ this.r = lerp(a.r, b.r, f);
517
+ this.g = lerp(a.g, b.g, f);
518
+ this.b = lerp(a.b, b.b, f);
519
+ this.a = lerp(a.a, b.a, f);
520
+ }
521
+
469
522
  /**
470
523
  *
471
524
  * @param {number} r
@@ -557,3 +610,9 @@ Color.white = Object.freeze(new Color(1, 1, 1));
557
610
  * @type {Readonly<Color>}
558
611
  */
559
612
  Color.black = Object.freeze(new Color(0, 0, 0));
613
+
614
+ /**
615
+ * @readonly
616
+ * @type {Readonly<Color>}
617
+ */
618
+ Color.transparent = Object.freeze(new Color(0, 0, 0, 0));
@@ -6,7 +6,8 @@ import { hsv2rgb } from "./hsv2rgb.js";
6
6
  import { parseHex } from "./parseHex.js";
7
7
 
8
8
 
9
- const rgbRegEx = /rgb\(([0-9]+),\s*([0-9]+),\s*([0-9]+)\)/;
9
+ const rgbRegEx = /rgb\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+)\s*\)/;
10
+ const rgbaRegEx = /rgba\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+),\s*([0-9]+(?:\.[0-9]*)?)\s*\)/;
10
11
  const hsvRegEx = /hsv\(([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?),\s*([0-9]+(?:\.[0-9]*)?)\)/;
11
12
 
12
13
  /**
@@ -20,6 +21,8 @@ export function parseColor(c) {
20
21
 
21
22
  const type_of_code = typeof c;
22
23
 
24
+ let r, g, b, a = 1;
25
+
23
26
  if (type_of_code === "string") {
24
27
  const cL = c.toLowerCase();
25
28
 
@@ -27,9 +30,16 @@ export function parseColor(c) {
27
30
 
28
31
  if ((match = cL.match(rgbRegEx)) !== null) {
29
32
 
30
- result[0] = parseInt(match[1]);
31
- result[1] = parseInt(match[2]);
32
- result[2] = parseInt(match[3]);
33
+ r = parseInt(match[1]);
34
+ g = parseInt(match[2]);
35
+ b = parseInt(match[3]);
36
+
37
+ } else if ((match = cL.match(rgbaRegEx)) !== null) {
38
+
39
+ r = parseInt(match[1]);
40
+ g = parseInt(match[2]);
41
+ b = parseInt(match[3]);
42
+ a = parseInt(match[4]);
33
43
 
34
44
  } else if ((match = cL.match(hsvRegEx)) !== null) {
35
45
 
@@ -39,31 +49,37 @@ export function parseColor(c) {
39
49
  parseFloat(match[3])
40
50
  );
41
51
 
42
- result[0] = rgb.r;
43
- result[1] = rgb.g;
44
- result[2] = rgb.b;
52
+ r = rgb.r;
53
+ g = rgb.g;
54
+ b = rgb.b;
45
55
 
46
56
  } else if (cL.startsWith('#')) {
47
57
 
48
58
  const rgb = parseHex(cL);
49
59
 
50
- result[0] = rgb.r;
51
- result[1] = rgb.g;
52
- result[2] = rgb.b;
60
+ r = rgb.r;
61
+ g = rgb.g;
62
+ b = rgb.b;
53
63
 
54
64
  } else {
55
65
  throw new Error(`Failed to decode color string '${c}' `);
56
66
  }
57
67
  } else if (type_of_code === 'number') {
58
68
 
59
- result[0] = c >> 16;
60
- result[1] = (c >> 8) & 0xFF;
61
- result[2] = (c) & 0xFF;
69
+ r = c >> 16;
70
+ g = (c >> 8) & 0xFF;
71
+ b = (c) & 0xFF;
62
72
 
63
73
  } else {
64
74
  throw new Error(`Failed to decode color '${c}'`);
65
75
  }
66
76
 
77
+ result[0] = r;
78
+ result[1] = g;
79
+ result[2] = b;
80
+ result[3] = a;
81
+
82
+
67
83
  return result;
68
84
  }
69
85
 
@@ -52,6 +52,15 @@ export function returnEmptyArray() {
52
52
  return [];
53
53
  }
54
54
 
55
+ /**
56
+ * @template T
57
+ * @param {T} v
58
+ * @returns {function():T}
59
+ */
60
+ export function makeReturnValue(v) {
61
+ return () => v;
62
+ }
63
+
55
64
  /**
56
65
  * @template A
57
66
  * @param {A} a
@@ -1000,6 +1000,13 @@ Vector3.zero = Object.freeze(new Vector3(0, 0, 0));
1000
1000
  */
1001
1001
  Vector3.one = Object.freeze(new Vector3(1, 1, 1));
1002
1002
 
1003
+ /**
1004
+ * Useful for setting scale
1005
+ * @readonly
1006
+ * @type {Vector3}
1007
+ */
1008
+ Vector3.minus_one = Object.freeze(new Vector3(-1, -1, -1));
1009
+
1003
1010
  /**
1004
1011
  * @readonly
1005
1012
  * @type {Vector3}
@@ -12,6 +12,10 @@ import '../../../../../../css/editor/EditorView.scss';
12
12
  import { TerrainLayer } from "../../../engine/ecs/terrain/ecs/layers/TerrainLayer.js";
13
13
  import Terrain from "../../../engine/ecs/terrain/ecs/Terrain.js";
14
14
  import Vector3 from "../../../core/geom/Vector3.js";
15
+ import { BlenderCameraOrientationGizmo } from "../v2/BlenderCameraOrientationGizmo.js";
16
+ import Quaternion from "../../../core/geom/Quaternion.js";
17
+ import { Transform } from "../../../engine/ecs/transform/Transform.js";
18
+ import TopDownCameraController from "../../../engine/graphics/ecs/camera/topdown/TopDownCameraController.js";
15
19
 
16
20
  new EngineHarness()
17
21
  .initialize({
@@ -23,17 +27,23 @@ new EngineHarness()
23
27
  }
24
28
  }).then(main);
25
29
 
30
+ /**
31
+ *
32
+ * @param {Engine} engine
33
+ * @returns {Promise<void>}
34
+ */
26
35
  async function main(engine) {
27
36
  await EngineHarness.buildBasics({
28
37
  engine,
29
- focus:new Vector3(128,0,128),
30
- distance:30,
38
+ focus: new Vector3(128, 0, 128),
39
+ distance: 30,
31
40
  terrainResolution: 1,
32
41
  terrainSize: new Vector2(128, 128),
33
42
  enableWater: false
34
43
  });
35
44
 
36
- const terrain_entity = engine.entityManager.dataset.getAnyComponent(Terrain);
45
+ const ecd = engine.entityManager.dataset;
46
+ const terrain_entity = ecd.getAnyComponent(Terrain);
37
47
  const terrain = terrain_entity.component;
38
48
 
39
49
  terrain.samplerHeight.resize(256, 256);
@@ -59,8 +69,67 @@ async function main(engine) {
59
69
 
60
70
  editor_controls.enable();
61
71
 
72
+ const camera_orientation_gizmo = new BlenderCameraOrientationGizmo(new Quaternion());
73
+
74
+ camera_orientation_gizmo.css({
75
+ position: 'absolute',
76
+ top: 0,
77
+ right: 0,
78
+ pointerEvents: 'auto'
79
+ });
80
+
81
+
82
+ camera_orientation_gizmo.on.axisSelected.add((axis) => {
83
+ /**
84
+ *
85
+ * @type {TopDownCameraController}
86
+ */
87
+ const tdcc = editor_controls.editor.cameraEntity.getComponent(TopDownCameraController);
88
+
89
+ tdcc.pitch = 0;
90
+ tdcc.yaw = 0;
91
+ tdcc.roll = 0;
92
+
93
+ switch (axis) {
94
+ case 'x':
95
+ tdcc.yaw = Math.PI / 2;
96
+ break;
97
+ case '-x':
98
+ tdcc.yaw = -Math.PI / 2;
99
+ break;
100
+ case 'z':
101
+ tdcc.yaw = 0;
102
+ break;
103
+ case '-z':
104
+ tdcc.yaw = Math.PI;
105
+ break;
106
+ case 'y':
107
+ tdcc.pitch = Math.PI / 2;
108
+ break;
109
+ case '-y':
110
+ tdcc.pitch = -Math.PI / 2;
111
+ break;
112
+ }
113
+ });
114
+
115
+ engine.gameView.addChild(camera_orientation_gizmo);
116
+
117
+ engine.graphics.on.preRender.add(() => {
118
+ const camera_transform = editor_controls.editor.cameraEntity.getComponent(Transform);
119
+
120
+ if (camera_transform === null) {
121
+ return;
122
+ }
123
+
124
+ camera_orientation_gizmo.orientation = camera_transform.rotation;
125
+
126
+ camera_orientation_gizmo.update();
127
+ });
128
+
62
129
  setTimeout(() => {
63
130
  editor_controls.editor.selection.add(terrain_entity.entity);
131
+
132
+ // camera_orientation_gizmo.orientation =;
64
133
  }, 100);
65
134
 
66
135
  console.warn(terrain);
@@ -0,0 +1,17 @@
1
+ import View, {IViewSignals} from "../../../view/View";
2
+ import Quaternion from "../../../core/geom/Quaternion";
3
+ import Signal from "../../../core/events/signal/Signal";
4
+
5
+ interface ISignals extends IViewSignals {
6
+ readonly axisSelected: Signal
7
+ }
8
+
9
+ export class BlenderCameraOrientationGizmo extends View {
10
+ constructor(orientation?: Quaternion)
11
+
12
+ on: ISignals
13
+
14
+ orientation: Quaternion | null
15
+
16
+ update(): void
17
+ }