@woosh/meep-engine 2.75.4 → 2.75.6

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 (49) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/meep.cjs +91 -74
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +91 -74
  5. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +35 -21
  6. package/package.json +2 -2
  7. package/src/core/collection/array/array_compute_min_max.js +20 -0
  8. package/src/core/collection/map/HashMap.js +16 -14
  9. package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +23 -13
  10. package/src/core/geom/2d/intersect_ray_2d.js +7 -14
  11. package/src/core/geom/3d/aabb/AABB3.js +13 -0
  12. package/src/core/geom/3d/topology/samples/sampleFloodFill.js +21 -21
  13. package/src/core/geom/3d/topology/tm_face_area.js +1 -1
  14. package/src/core/geom/3d/triangle/computeTriangleSurfaceArea.js +39 -0
  15. package/src/core/process/task/util/countTask.js +1 -2
  16. package/src/engine/EngineBootstrapper.js +15 -7
  17. package/src/engine/animation/curve/AnimationCurve.js +50 -31
  18. package/src/engine/animation/curve/AnimationCurve.spec.js +9 -1
  19. package/src/engine/animation/curve/compression/prototypeCurveCompression.js +20 -11
  20. package/src/engine/animation/curve/compute_curve_aabb.js +26 -0
  21. package/src/engine/animation/curve/draw/build_curve_editor.js +82 -42
  22. package/src/engine/animation/curve/draw/build_plot_entity_from_array.js +5 -5
  23. package/src/engine/animation/curve/preset/CURVE_EASE_IN.js +8 -0
  24. package/src/engine/animation/curve/preset/CURVE_EASE_IN_OUT.js +7 -0
  25. package/src/engine/animation/curve/preset/CURVE_EASE_OUT.js +7 -0
  26. package/src/engine/asset/loaders/image/png/PNGReader.js +119 -1
  27. package/src/engine/graphics/GraphicsEngine.d.ts +6 -3
  28. package/src/engine/graphics/canvas/canvas2d_draw_grid.js +42 -0
  29. package/src/engine/{animation/curve/draw/draw_label.js → graphics/canvas/canvas2d_draw_label.js} +6 -1
  30. package/src/engine/graphics/canvas/canvas2d_draw_linear_scale.js +64 -0
  31. package/src/engine/graphics/canvas/canvas2d_draw_path.js +60 -0
  32. package/src/engine/graphics/canvas/canvas2d_plot_data_line.js +84 -0
  33. package/src/engine/{animation/curve/draw/plot_array.js → graphics/canvas/canvas2d_plot_line_array.js} +8 -25
  34. package/src/engine/graphics/geometry/computeMeshSurfaceArea.js +2 -37
  35. package/src/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +8 -26
  36. package/src/engine/graphics/material/manager/MaterialManager.d.ts +6 -0
  37. package/src/engine/graphics/sh3/LightProbeVolume.js +38 -17
  38. package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +26 -35
  39. package/src/engine/graphics/sh3/prototypeSH3Probe.js +166 -100
  40. package/src/engine/graphics/texture/makeOnePixelTexture.js +19 -0
  41. package/src/engine/graphics/texture/sprite/prototypeSpriteCutoutGeometry.js +5 -68
  42. package/src/engine/input/devices/PointerDevice.js +6 -3
  43. package/src/engine/makeSimpleTaskProgressView.js +33 -0
  44. package/src/engine/scene/transitionToScene.js +9 -10
  45. package/src/view/task/TaskLoadingScreen.js +5 -12
  46. package/src/view/task/TaskProgressView.js +9 -9
  47. package/src/engine/animation/curve/draw/draw_grid.js +0 -27
  48. package/src/engine/animation/curve/draw/plot_data.js +0 -49
  49. package/src/engine/graphics/geometry/QuadGeometry.js +0 -13
@@ -58131,6 +58131,19 @@ class AABB3 {
58131
58131
  this.setBounds(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
58132
58132
  }
58133
58133
 
58134
+ /**
58135
+ *
58136
+ * @param {number} x
58137
+ * @param {number} y
58138
+ * @param {number} z
58139
+ */
58140
+ _translate(x,y,z){
58141
+ this.setBounds(
58142
+ this.x0 + x, this.y0 + y, this.z0 + z,
58143
+ this.x1 + x, this.y1 + y, this.z1 + z
58144
+ );
58145
+ }
58146
+
58134
58147
  /**
58135
58148
  *
58136
58149
  * @param {number} x
@@ -61433,41 +61446,6 @@ const GridTransformKind = {
61433
61446
  Direct: 1
61434
61447
  };
61435
61448
 
61436
- /**
61437
- * Performs equality check via {@link #equals} method on first object
61438
- * @template T
61439
- * @param {T} a
61440
- * @param {T} b
61441
- * @return {boolean}
61442
- */
61443
- function invokeObjectEquals(a, b) {
61444
- return a.equals(b);
61445
- }
61446
-
61447
- /**
61448
- * @template T
61449
- * @param {T} object
61450
- * @return {number}
61451
- */
61452
- function invokeObjectHash(object) {
61453
- return object.hash();
61454
- }
61455
-
61456
- /**
61457
- * Is the number a power of two?
61458
- * e.g. 2,4,8,16 etc.
61459
- * NOTE: only valid for non-negative integers
61460
- * @param {number} value
61461
- * @returns {boolean}
61462
- */
61463
- function isPowerOfTwo(value) {
61464
- assert.isNonNegativeInteger(value, 'value');
61465
-
61466
-
61467
- return (value & (value - 1)) === 0 && value !== 0;
61468
-
61469
- }
61470
-
61471
61449
  /**
61472
61450
  * Count trailing zeroes
61473
61451
  * adapted from https://github.com/git/git/blob/bcd6bc478adc4951d57ec597c44b12ee74bc88fb/ewah/ewok.h#L44
@@ -61510,21 +61488,38 @@ function ctz32(x) {
61510
61488
  }
61511
61489
 
61512
61490
  /**
61513
- *
61514
- * @param {number} count
61515
- * @returns {function}
61491
+ * Is the number a power of two?
61492
+ * e.g. 2,4,8,16 etc.
61493
+ * NOTE: only valid for non-negative integers
61494
+ * @param {number} value
61495
+ * @returns {boolean}
61516
61496
  */
61517
- function UintArrayForCount(count) {
61497
+ function isPowerOfTwo(value) {
61498
+ assert.isNonNegativeInteger(value, 'value');
61518
61499
 
61519
- if (count <= 256) {
61520
- return Uint8Array;
61521
- } else if (count <= 65536) {
61522
- return Uint16Array;
61523
- } else if (count <= 4294967295) {
61524
- return Uint32Array;
61525
- } else {
61526
- throw new Error(`Unsupported size ${count}`)
61527
- }
61500
+
61501
+ return (value & (value - 1)) === 0 && value !== 0;
61502
+
61503
+ }
61504
+
61505
+ /**
61506
+ * Performs equality check via {@link #equals} method on first object
61507
+ * @template T
61508
+ * @param {T} a
61509
+ * @param {T} b
61510
+ * @return {boolean}
61511
+ */
61512
+ function invokeObjectEquals(a, b) {
61513
+ return a.equals(b);
61514
+ }
61515
+
61516
+ /**
61517
+ * @template T
61518
+ * @param {T} object
61519
+ * @return {number}
61520
+ */
61521
+ function invokeObjectHash(object) {
61522
+ return object.hash();
61528
61523
  }
61529
61524
 
61530
61525
  /**
@@ -61540,6 +61535,24 @@ function arraySwapElements(array, index0, index1) {
61540
61535
  array[index1] = t;
61541
61536
  }
61542
61537
 
61538
+ /**
61539
+ *
61540
+ * @param {number} count
61541
+ * @returns {function}
61542
+ */
61543
+ function UintArrayForCount(count) {
61544
+
61545
+ if (count <= 256) {
61546
+ return Uint8Array;
61547
+ } else if (count <= 65536) {
61548
+ return Uint16Array;
61549
+ } else if (count <= 4294967295) {
61550
+ return Uint32Array;
61551
+ } else {
61552
+ throw new Error(`Unsupported size ${count}`)
61553
+ }
61554
+ }
61555
+
61543
61556
  /*
61544
61557
  * Heavily inspired by ruby's "new" (circa 2016) hash table implementation
61545
61558
  * @see https://github.com/ruby/ruby/blob/82995d4615e993f1d13f3e826b93fbd65c47e19e/st.c
@@ -61909,15 +61922,17 @@ class HashMap {
61909
61922
  }
61910
61923
 
61911
61924
  #rebuild_if_necessary() {
61912
- if (this.#entries_bound === this.#entries_allocated_count) {
61913
- if (this.#size === this.#entries_allocated_count) {
61914
- // used up all allocated entries
61915
- // bin count must always be larger than end of the entries table
61916
- this.#grow();
61917
- } else {
61918
- // exhausted entries array, perform compaction
61919
- this.rebuild();
61920
- }
61925
+ if (this.#entries_bound !== this.#entries_allocated_count) {
61926
+ return;
61927
+ }
61928
+
61929
+ if (this.#size === this.#entries_allocated_count) {
61930
+ // used up all allocated entries
61931
+ // bin count must always be larger than end of the entries table
61932
+ this.#grow();
61933
+ } else {
61934
+ // exhausted entries array, perform compaction
61935
+ this.rebuild();
61921
61936
  }
61922
61937
  }
61923
61938
 
@@ -65389,22 +65404,6 @@ class OffsetScaleTransform2D {
65389
65404
  }
65390
65405
  }
65391
65406
 
65392
- /**
65393
- * Created by Alex on 25/08/2016.
65394
- */
65395
-
65396
-
65397
- /**
65398
- * @readonly
65399
- * @enum {number}
65400
- */
65401
- const TaskSignal = {
65402
- EndSuccess: 0,
65403
- EndFailure: 1,
65404
- Continue: 2,
65405
- Yield: 3
65406
- };
65407
-
65408
65407
  /**
65409
65408
  * @template T
65410
65409
  * @param {T[]} array
@@ -65422,6 +65421,22 @@ function array_push_if_unique(array, element) {
65422
65421
  return false;
65423
65422
  }
65424
65423
 
65424
+ /**
65425
+ * Created by Alex on 25/08/2016.
65426
+ */
65427
+
65428
+
65429
+ /**
65430
+ * @readonly
65431
+ * @enum {number}
65432
+ */
65433
+ const TaskSignal = {
65434
+ EndSuccess: 0,
65435
+ EndFailure: 1,
65436
+ Continue: 2,
65437
+ Yield: 3
65438
+ };
65439
+
65425
65440
  /**
65426
65441
  * Created by Alex on 22/05/2016.
65427
65442
  */
@@ -65784,7 +65799,6 @@ function countTask(initial, limit, callback) {
65784
65799
  }
65785
65800
 
65786
65801
  i = initialValue;
65787
-
65788
65802
  },
65789
65803
  cycleFunction: cycle,
65790
65804
  computeProgress: function () {
@@ -92881,6 +92895,9 @@ class PointerDevice {
92881
92895
  down: new Signal(),
92882
92896
  up: new Signal(),
92883
92897
  move: new Signal(),
92898
+ /**
92899
+ * @type {Signal<Vector2, (MouseEvent|TouchEvent)>}
92900
+ */
92884
92901
  tap: new Signal(),
92885
92902
  drag: new Signal(),
92886
92903
  dragStart: new Signal(),
@@ -1,9 +1,9 @@
1
- import { TypeEditor } from "../../TypeEditor.js";
2
- import { CanvasView } from "../../../../../src/view/elements/CanvasView.js";
3
- import { plot_data } from "../../../../../src/engine/animation/curve/draw/plot_data.js";
4
1
  import Vector2 from "../../../../../src/core/geom/Vector2.js";
5
- import EmptyView from "../../../../../src/view/elements/EmptyView.js";
2
+ import { canvas2d_plot_data_line } from "../../../../../src/engine/graphics/canvas/canvas2d_plot_data_line.js";
6
3
  import { MouseEvents } from "../../../../../src/engine/input/devices/events/MouseEvents.js";
4
+ import { CanvasView } from "../../../../../src/view/elements/CanvasView.js";
5
+ import EmptyView from "../../../../../src/view/elements/EmptyView.js";
6
+ import { TypeEditor } from "../../TypeEditor.js";
7
7
 
8
8
  export class ParameterLookupTableEditor extends TypeEditor {
9
9
  get schema() {
@@ -16,7 +16,7 @@ export class ParameterLookupTableEditor extends TypeEditor {
16
16
  };
17
17
  }
18
18
 
19
- build(parent, field,registry) {
19
+ build(parent, field, registry) {
20
20
 
21
21
  /**
22
22
  * @type {ParameterLookupTable}
@@ -25,7 +25,7 @@ export class ParameterLookupTableEditor extends TypeEditor {
25
25
  const trackName = field.adapter.read(parent, "name");
26
26
 
27
27
  // if it is a track scale
28
- if (trackName === "scale"){
28
+ if (trackName === "scale") {
29
29
  const canvasView = new CanvasView();
30
30
  canvasView.size.set(200, 100);
31
31
  const ctx = canvasView.context2d;
@@ -41,19 +41,30 @@ export class ParameterLookupTableEditor extends TypeEditor {
41
41
  data[i] = sample[0];
42
42
  }
43
43
 
44
- plot_data({ ctx, data, width: canvasView.size.x, height: canvasView.size.y, margin: new Vector2(4, 4) });
44
+ canvas2d_plot_data_line({
45
+ ctx,
46
+ data,
47
+ width: canvasView.size.x,
48
+ height: canvasView.size.y,
49
+ margin: new Vector2(4, 4),
50
+ range_x: [lut.positions[0], lut.positions[lut.positions.length - 1]],
51
+ });
45
52
 
46
53
  return canvasView;
47
- } else if (trackName === "color"){
54
+ } else if (trackName === "color") {
48
55
  // if it is color track
49
56
  const resultView = new EmptyView();
50
57
  const canvasView = new CanvasView();
51
- canvasView.css({borderColor: 'white', borderStyle: 'solid', borderWidth: '1px',});
58
+ canvasView.css({ borderColor: 'white', borderStyle: 'solid', borderWidth: '1px', });
52
59
  canvasView.size.set(200, 70);
53
60
 
54
61
  const ctx = canvasView.context2d;
55
62
 
56
- const colorView = new EmptyView({tag: "input", attr: {type: "color"}, css: {padding: "0px", border: "0px"}});
63
+ const colorView = new EmptyView({
64
+ tag: "input",
65
+ attr: { type: "color" },
66
+ css: { padding: "0px", border: "0px" }
67
+ });
57
68
 
58
69
  resultView.addChild(canvasView);
59
70
  resultView.addChild(colorView);
@@ -76,7 +87,7 @@ export class ParameterLookupTableEditor extends TypeEditor {
76
87
  y = e.clientY - rect.top;
77
88
  for (let i = 0; i < stops.length; i++) {
78
89
  if (stops[i].x <= x && stops[i].x + stops[i].width >= x &&
79
- stops[i].y <= y && stops[i].y + stops[i].height >= y){
90
+ stops[i].y <= y && stops[i].y + stops[i].height >= y) {
80
91
  let s = [];
81
92
  lut.sample(lut.positions[i], s);
82
93
 
@@ -97,13 +108,14 @@ export class ParameterLookupTableEditor extends TypeEditor {
97
108
  return resultView;
98
109
  }
99
110
  }
111
+
100
112
  /**
101
113
  * converts rgb to hex string
102
114
  * @param {Float} r
103
115
  * @param {Float} g
104
116
  * @param {Float} b
105
117
  */
106
- RGBToHex(r,g,b) {
118
+ RGBToHex(r, g, b) {
107
119
  r = r.toString(16);
108
120
  g = g.toString(16);
109
121
  b = b.toString(16);
@@ -122,20 +134,21 @@ export class ParameterLookupTableEditor extends TypeEditor {
122
134
  * converts lut color sample to RGB
123
135
  * @param {number[]} sample
124
136
  */
125
- convertRGB(sample){
137
+ convertRGB(sample) {
126
138
  sample[0] = Math.floor(sample[0] * 255);
127
139
  sample[1] = Math.floor(sample[1] * 255);
128
140
  sample[2] = Math.floor(sample[2] * 255);
129
141
  }
142
+
130
143
  /**
131
144
  * draws tiled background
132
145
  * @param {CanvasView} canvasView
133
146
  * @param {CanvasRenderingContext2D} ctx
134
147
  * @param {{}} config
135
148
  */
136
- DrawBackground(canvasView, ctx, config){
149
+ DrawBackground(canvasView, ctx, config) {
137
150
  for (let i = 0; i < canvasView.size.x; i += config.tileSize.x) {
138
- for (let j = config.gradientBoxYRange.x; j < config.gradientBoxYRange.y; j += config.tileSize.y){
151
+ for (let j = config.gradientBoxYRange.x; j < config.gradientBoxYRange.y; j += config.tileSize.y) {
139
152
  ctx.fillStyle = (((i / config.tileSize.x) + (j / config.tileSize.y)) % 2 === 0 ? config.tileColor1 : config.tileColor2);
140
153
  ctx.fillRect(i, j, config.tileSize.x, config.tileSize.y);
141
154
  }
@@ -149,7 +162,7 @@ export class ParameterLookupTableEditor extends TypeEditor {
149
162
  * @param {CanvasRenderingContext2D} ctx
150
163
  * @param {{}} config
151
164
  */
152
- DrawGradient(canvasView, lut, ctx, config){
165
+ DrawGradient(canvasView, lut, ctx, config) {
153
166
  const sample = [];
154
167
  for (let i = 0; i < canvasView.size.x; i++) {
155
168
  const f = i / (canvasView.size.x - 1);
@@ -172,23 +185,24 @@ export class ParameterLookupTableEditor extends TypeEditor {
172
185
  * @param {Integer} selectedInd
173
186
  * @returns {*[]}
174
187
  */
175
- DrawStops(canvasView, lut, ctx, colorView, config, selectedInd){
188
+ DrawStops(canvasView, lut, ctx, colorView, config, selectedInd) {
176
189
  const sample = [];
177
190
 
178
191
  let stops = [];
179
- for (let i = 0; i < lut.positions.length; i++){
192
+ for (let i = 0; i < lut.positions.length; i++) {
180
193
  const posX = lut.positions[i] * canvasView.size.x;
181
- if (i === selectedInd){
194
+ if (i === selectedInd) {
182
195
  lut.sample(lut.positions[i], sample);
183
196
 
184
197
  this.convertRGB(sample);
185
198
 
186
199
  colorView.el.value = this.RGBToHex(sample[0], sample[1], sample[2]);
187
200
  }
188
- stops.push(this.DrawStop(ctx, config, posX, i=== selectedInd));
201
+ stops.push(this.DrawStop(ctx, config, posX, i === selectedInd));
189
202
  }
190
203
  return stops;
191
204
  }
205
+
192
206
  /**
193
207
  * draws gradient stop
194
208
  * @param {CanvasRenderingContext2D} ctx
@@ -196,7 +210,7 @@ export class ParameterLookupTableEditor extends TypeEditor {
196
210
  * @param {Integer} posX
197
211
  * @param {Boolean} isSelected
198
212
  */
199
- DrawStop(ctx, config, posX, isSelected){
213
+ DrawStop(ctx, config, posX, isSelected) {
200
214
  ctx.beginPath();
201
215
  ctx.moveTo(posX, config.gradientBoxYRange.x + 7);
202
216
  ctx.lineTo(posX - 5, config.gradientBoxYRange.x);
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.75.4",
8
+ "version": "2.75.6",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -38,7 +38,7 @@
38
38
  "fastest-levenshtein": "1.0.16",
39
39
  "gl-matrix": "3.4.3",
40
40
  "opentype.js": "1.3.3",
41
- "robust-predicates": "3.0.1",
41
+ "robust-predicates": "3.0.2",
42
42
  "simplex-noise": "2.4.0",
43
43
  "pako": "2.0.3"
44
44
  },
@@ -0,0 +1,20 @@
1
+ import { max2 } from "../../math/max2.js";
2
+ import { min2 } from "../../math/min2.js";
3
+
4
+ /**
5
+ *
6
+ * @param {number[]} data
7
+ * @return {number[]} [min, max]
8
+ */
9
+ export function array_compute_min_max(data) {
10
+ const point_count = data.length;
11
+
12
+ let min = Number.POSITIVE_INFINITY;
13
+ let max = Number.NEGATIVE_INFINITY;
14
+ for (let i = 0; i < point_count; i++) {
15
+ min = min2(data[i], min);
16
+ max = max2(data[i], max);
17
+ }
18
+
19
+ return [min, max];
20
+ }
@@ -1,13 +1,13 @@
1
1
  import { assert } from "../../assert.js";
2
- import { invokeObjectEquals } from "../../model/object/invokeObjectEquals.js";
3
- import { invokeObjectHash } from "../../model/object/invokeObjectHash.js";
4
- import { isPowerOfTwo } from "../../math/isPowerOrTwo.js";
5
2
  import { ctz32 } from "../../binary/ctz32.js";
6
3
  import { ceilPowerOfTwo } from "../../binary/operations/ceilPowerOfTwo.js";
7
- import { UintArrayForCount } from "../array/typed/uint_array_for_count.js";
8
- import { array_copy } from "../array/array_copy.js";
4
+ import { isPowerOfTwo } from "../../math/isPowerOrTwo.js";
9
5
  import { min2 } from "../../math/min2.js";
6
+ import { invokeObjectEquals } from "../../model/object/invokeObjectEquals.js";
7
+ import { invokeObjectHash } from "../../model/object/invokeObjectHash.js";
8
+ import { array_copy } from "../array/array_copy.js";
10
9
  import { arraySwapElements } from "../array/arraySwapElements.js";
10
+ import { UintArrayForCount } from "../array/typed/uint_array_for_count.js";
11
11
 
12
12
  /*
13
13
  * Heavily inspired by ruby's "new" (circa 2016) hash table implementation
@@ -378,15 +378,17 @@ export class HashMap {
378
378
  }
379
379
 
380
380
  #rebuild_if_necessary() {
381
- if (this.#entries_bound === this.#entries_allocated_count) {
382
- if (this.#size === this.#entries_allocated_count) {
383
- // used up all allocated entries
384
- // bin count must always be larger than end of the entries table
385
- this.#grow();
386
- } else {
387
- // exhausted entries array, perform compaction
388
- this.rebuild();
389
- }
381
+ if (this.#entries_bound !== this.#entries_allocated_count) {
382
+ return;
383
+ }
384
+
385
+ if (this.#size === this.#entries_allocated_count) {
386
+ // used up all allocated entries
387
+ // bin count must always be larger than end of the entries table
388
+ this.#grow();
389
+ } else {
390
+ // exhausted entries array, perform compaction
391
+ this.rebuild();
390
392
  }
391
393
  }
392
394
 
@@ -1,9 +1,9 @@
1
1
  //
2
2
 
3
3
  import { array_copy } from "../../../collection/array/array_copy.js";
4
+ import { UintArrayForCount } from "../../../collection/array/typed/uint_array_for_count.js";
4
5
  import { compute_polygon_area_2d } from "../compute_polygon_area_2d.js";
5
6
  import { intersect_ray_2d } from "../intersect_ray_2d.js";
6
- import { UintArrayForCount } from "../../../collection/array/typed/uint_array_for_count.js";
7
7
 
8
8
  /**
9
9
  * Compute a bounding polygon with a fixed given number of vertices such that the area would be minimal
@@ -15,7 +15,7 @@ import { UintArrayForCount } from "../../../collection/array/typed/uint_array_fo
15
15
  * @param {number} output_point_count number of points to comprise bounding polygon
16
16
  * @param {number[]} input_points Points to be bounded, must be an ordered loop
17
17
  * @param {number} input_point_count number of points in the input to consider
18
- * @returns {number} actual number of points, this can be lower because input polygon has too few points
18
+ * @returns {boolean} whether or not a valid result could be found
19
19
  *
20
20
  * @see 2014 "Implementation of linear minimum area enclosing triangle algorithm" Ovidiu Pârvu & David Gilbert
21
21
  * @see https://github.com/MagnusTiberius/humus3/blob/9d43412d6e6be869e224817f0a966fe48a1af40f/Util/ConvexHull.cpp#L281
@@ -64,19 +64,29 @@ export function fixed_convex_hull_humus(
64
64
  const i0 = subset[i];
65
65
  const i1 = subset[(i + 1) % k];
66
66
 
67
- const a0x = input_points[i0 * 2];
68
- const a0y = input_points[i0 * 2 + 1];
67
+ const i0_2 = i0 << 1;
68
+
69
+ const a0x = input_points[i0_2];
70
+ const a0y = input_points[i0_2 + 1];
69
71
 
70
72
  const a1 = (i0 + 1) % input_point_count;
71
73
 
72
- const a1x = input_points[a1 * 2];
73
- const a1y = input_points[a1 * 2 + 1];
74
+ const a1_2 = a1 << 1;
75
+
76
+ const a1x = input_points[a1_2];
77
+ const a1y = input_points[a1_2 + 1];
78
+
79
+ const i1_2 = i1 << 1;
80
+
81
+ const b0x = input_points[i1_2];
82
+ const b0y = input_points[i1_2 + 1];
74
83
 
75
- const b0x = input_points[i1 * 2];
76
- const b0y = input_points[i1 * 2 + 1];
77
84
  const b1 = (i1 + 1) % input_point_count;
78
- const b1x = input_points[b1 * 2];
79
- const b1y = input_points[b1 * 2 + 1];
85
+
86
+ const b1_2 = b1 << 1;
87
+
88
+ const b1x = input_points[b1_2];
89
+ const b1y = input_points[b1_2 + 1];
80
90
 
81
91
  const a_dir_x = a1x - a0x;
82
92
  const a_dir_y = a1y - a0y;
@@ -85,7 +95,7 @@ export function fixed_convex_hull_humus(
85
95
  const b_dir_y = b1y - b0y;
86
96
 
87
97
  if (!intersect_ray_2d(
88
- intersections, i * 2,
98
+ intersections, i << 1,
89
99
  a0x, a0y, a_dir_x, a_dir_y,
90
100
  b0x, b0y, b_dir_x, b_dir_y
91
101
  )) {
@@ -98,7 +108,7 @@ export function fixed_convex_hull_humus(
98
108
  const area = compute_polygon_area_2d(intersections, k);
99
109
 
100
110
  if (area < best_area) {
101
- array_copy(intersections, 0, output, output_offset, k * 2);
111
+ array_copy(intersections, 0, output, output_offset, k << 1);
102
112
  best_area = area;
103
113
  }
104
114
 
@@ -135,5 +145,5 @@ export function fixed_convex_hull_humus(
135
145
 
136
146
  console.log(`combinations: ${combos}, valid: ${combos_valid} (${(combos_valid * 100 / combos).toFixed(2)}%)`);
137
147
 
138
- return output_point_count;
148
+ return combos_valid > 0;
139
149
  }
@@ -1,17 +1,5 @@
1
1
  import { fabsf } from "../../math/fabsf.js";
2
2
 
3
- /**
4
- *
5
- * @param {number} ux
6
- * @param {number} uy
7
- * @param {number} vx
8
- * @param {number} vy
9
- * @returns {number}
10
- */
11
- function perp(ux, uy, vx, vy) {
12
- return (ux * vy - uy * vx);
13
- }
14
-
15
3
  /**
16
4
  * NOTE: that direction must not be normalized for correct results and instead derived from line length
17
5
  * @param {number[]|Float32Array|Float64Array} out
@@ -31,11 +19,16 @@ export function intersect_ray_2d(
31
19
  origin_a_x, origin_a_y, direction_a_x, direction_a_y,
32
20
  origin_b_x, origin_b_y, direction_b_x, direction_b_y
33
21
  ) {
34
- const d = perp(direction_a_x, direction_a_y, direction_b_x, direction_b_y);
22
+
23
+ const d = (direction_a_x * direction_b_y - direction_a_y * direction_b_x);
24
+
35
25
  if (fabsf(d) < 0.000000000001) // Parallel lines
36
26
  return false;
37
27
 
38
- const t = perp(direction_b_x, direction_b_y, origin_a_x - origin_b_x, origin_a_y - origin_b_y) / d;
28
+ const oab_y = origin_a_y - origin_b_y;
29
+ const oab_x = origin_a_x - origin_b_x;
30
+
31
+ const t = (direction_b_x * oab_y - direction_b_y * oab_x) / d;
39
32
 
40
33
  if (t < 0.5) // Intersects on the wrong side
41
34
  return false;
@@ -296,6 +296,19 @@ export class AABB3 {
296
296
  this.setBounds(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
297
297
  }
298
298
 
299
+ /**
300
+ *
301
+ * @param {number} x
302
+ * @param {number} y
303
+ * @param {number} z
304
+ */
305
+ _translate(x,y,z){
306
+ this.setBounds(
307
+ this.x0 + x, this.y0 + y, this.z0 + z,
308
+ this.x1 + x, this.y1 + y, this.z1 + z
309
+ )
310
+ }
311
+
299
312
  /**
300
313
  *
301
314
  * @param {number} x
@@ -1,32 +1,32 @@
1
- import { EngineHarness } from "../../../../../engine/EngineHarness.js";
2
1
  import { MeshBasicMaterial, MeshStandardMaterial, OctahedronBufferGeometry } from "three";
3
- import Entity from "../../../../../engine/ecs/Entity.js";
4
- import { ShadedGeometry } from "../../../../../engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
5
- import { Transform } from "../../../../../engine/ecs/transform/Transform.js";
6
- import { ShadedGeometrySystem } from "../../../../../engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
7
- import { SurfacePoint3 } from "../../SurfacePoint3.js";
8
- import { topo_mesh_to_three_buffer_geometry } from "../topo_mesh_to_three_buffer_geometry.js";
9
- import { three_buffer_geometry_to_topo_mesh } from "../three_buffer_geometry_to_topo_mesh.js";
10
- import { mesh_flood_fill } from "../util/mesh_flood_fill.js";
11
- import { compute_aabb_from_points } from "../../aabb/compute_aabb_from_points.js";
12
- import { AABB3 } from "../../../../geom/3d/aabb/AABB3.js";
13
2
  import { mergeVertices } from "three/examples/jsm/utils/BufferGeometryUtils.js";
14
- import { makeGeometryIndexed } from "../../../../../engine/graphics/geometry/buffered/makeGeometryIndexed.js";
15
- import { v3_dot } from "../../../vec3/v3_dot.js";
16
- import { TopoMesh } from "../struct/TopoMesh.js";
17
- import { SGMeshSystem } from "../../../../../engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js";
18
- import { SGMesh } from "../../../../../engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js";
19
3
  import { GameAssetType } from "../../../../../engine/asset/GameAssetType.js";
20
4
  import { GLTFAssetLoader } from "../../../../../engine/asset/loaders/GLTFAssetLoader.js";
21
- import { computeTriangleSurfaceArea } from "../../../../../engine/graphics/geometry/computeMeshSurfaceArea.js";
5
+ import Entity from "../../../../../engine/ecs/Entity.js";
6
+ import { EntityNode } from "../../../../../engine/ecs/parent/EntityNode.js";
7
+ import { TransformAttachmentSystem } from "../../../../../engine/ecs/transform-attachment/TransformAttachmentSystem.js";
8
+ import { Transform } from "../../../../../engine/ecs/transform/Transform.js";
9
+ import { EngineHarness } from "../../../../../engine/EngineHarness.js";
10
+ import { SGMesh } from "../../../../../engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js";
22
11
  import { SGMeshEvents } from "../../../../../engine/graphics/ecs/mesh-v2/aggregate/SGMeshEvents.js";
12
+ import { SGMeshSystem } from "../../../../../engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js";
13
+ import { ShadedGeometry } from "../../../../../engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
14
+ import { ShadedGeometrySystem } from "../../../../../engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
15
+ import { makeGeometryIndexed } from "../../../../../engine/graphics/geometry/buffered/makeGeometryIndexed.js";
16
+ import { load_and_set_cubemap_v0 } from "../../../../../engine/graphics/load_and_set_cubemap_v0.js";
17
+ import { make_ray_from_viewport_position } from "../../../../../engine/graphics/make_ray_from_viewport_position.js";
23
18
  import { Color } from "../../../../color/Color.js";
19
+ import { AABB3 } from "../../../../geom/3d/aabb/AABB3.js";
24
20
  import { seededRandom } from "../../../../math/random/seededRandom.js";
21
+ import { v3_dot } from "../../../vec3/v3_dot.js";
22
+ import { compute_aabb_from_points } from "../../aabb/compute_aabb_from_points.js";
23
+ import { SurfacePoint3 } from "../../SurfacePoint3.js";
24
+ import { computeTriangleSurfaceArea } from "../../triangle/computeTriangleSurfaceArea.js";
25
25
  import { expandConnectivityByLocality } from "../expandConnectivityByLocality.js";
26
- import { EntityNode } from "../../../../../engine/ecs/parent/EntityNode.js";
27
- import { TransformAttachmentSystem } from "../../../../../engine/ecs/transform-attachment/TransformAttachmentSystem.js";
28
- import { make_ray_from_viewport_position } from "../../../../../engine/graphics/make_ray_from_viewport_position.js";
29
- import { load_and_set_cubemap_v0 } from "../../../../../engine/graphics/load_and_set_cubemap_v0.js";
26
+ import { TopoMesh } from "../struct/TopoMesh.js";
27
+ import { three_buffer_geometry_to_topo_mesh } from "../three_buffer_geometry_to_topo_mesh.js";
28
+ import { topo_mesh_to_three_buffer_geometry } from "../topo_mesh_to_three_buffer_geometry.js";
29
+ import { mesh_flood_fill } from "../util/mesh_flood_fill.js";
30
30
 
31
31
  const harness = new EngineHarness();
32
32