@woosh/meep-engine 2.33.19 → 2.33.23

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 (104) hide show
  1. package/core/assert.js +3 -1
  2. package/core/bvh2/traversal/__detailed_box_volume_intersection.js +11 -8
  3. package/core/collection/HashMap.js +66 -22
  4. package/core/geom/3d/CircleMath.js +4 -4
  5. package/core/geom/3d/cone/computeConeBoundingBox.js +4 -4
  6. package/core/geom/3d/{compute_bounding_cone_of_2_cones.js → cone/compute_bounding_cone_of_2_cones.js} +3 -3
  7. package/core/geom/3d/{compute_bounding_cone_of_2_cones.spec.js → cone/compute_bounding_cone_of_2_cones.spec.js} +1 -1
  8. package/core/geom/3d/frustum/array_setFromProjectionMatrix.js +1 -1
  9. package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +10 -2
  10. package/core/geom/3d/{encode_unit3_hemioct.js → normal/hemioct/encode_unit3_hemioct.js} +0 -0
  11. package/core/geom/3d/{unit_hemioct.spec.js → normal/hemioct/unit_hemioct.spec.js} +1 -1
  12. package/core/geom/3d/normal/lamber_azimuth/transform.js +61 -0
  13. package/core/geom/3d/normal/spherical/sphere_map_transform.js +77 -0
  14. package/core/geom/3d/{lerp_planes_to_array.js → plane/lerp_planes_to_array.js} +1 -3
  15. package/core/geom/3d/plane/plane3_lerp.js +3 -1
  16. package/core/geom/3d/plane/plane3_slerp.js +4 -1
  17. package/core/geom/3d/{plane_computeConvex3PlaneIntersection.js → plane/plane_computeConvex3PlaneIntersection.js} +14 -16
  18. package/core/geom/3d/topology/TopoTriangle.js +1 -1
  19. package/core/geom/3d/topology/TopoVertex.js +1 -1
  20. package/core/geom/3d/topology/bounds/computeTraingleClusterNormalBoundingCone.js +2 -2
  21. package/core/geom/3d/topology/simplify/compute_face_normal_change_dot_product.js +1 -1
  22. package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +1 -1
  23. package/core/geom/3d/triangle/computeTrianglePlaneSide.js +1 -1
  24. package/core/geom/3d/triangle/computeTriangleRayIntersection.js +1 -1
  25. package/core/geom/3d/voxel/DenseBitVolume3D.js +87 -0
  26. package/core/geom/3d/voxel/buildVolumeFromProjectedGeometry.js +23 -0
  27. package/core/geom/LineSegment.js +3 -1
  28. package/core/geom/Matrix4.js +2 -1
  29. package/core/geom/Plane.js +15 -10
  30. package/core/geom/Quaternion.js +2 -1
  31. package/core/geom/Vector3.d.ts +2 -0
  32. package/core/geom/Vector3.js +33 -158
  33. package/core/geom/Vector3.spec.js +2 -1
  34. package/core/geom/v3_angle_between.js +31 -0
  35. package/core/geom/v3_distance.js +16 -0
  36. package/core/geom/v3_distance_sqr.js +17 -0
  37. package/core/geom/v3_dot.js +13 -0
  38. package/core/geom/v3_length.js +5 -0
  39. package/core/geom/v3_length_sqr.js +10 -0
  40. package/core/geom/v3_lerp.js +21 -0
  41. package/core/geom/v3_slerp.js +48 -0
  42. package/core/primitives/array/computeIntegerArrayHash.js +6 -1
  43. package/engine/asset/loaders/material/computeImageBitmapEquality.js +11 -0
  44. package/engine/asset/loaders/material/computeImageBitmapHash.js +22 -28
  45. package/engine/asset/loaders/material/computeMaterialHash.js +1 -2
  46. package/engine/asset/loaders/material/computeTextureEquality.js +13 -5
  47. package/engine/ecs/animation/OneBoneSurfaceAlignmentSolver.js +3 -1
  48. package/engine/ecs/animation/TwoBoneInverseKinematicsSolver.js +3 -1
  49. package/engine/ecs/fow/FogOfWar.js +2 -3
  50. package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +1 -1
  51. package/engine/ecs/systems/SteeringSystem.js +2 -1
  52. package/engine/ecs/terrain/ecs/Terrain.js +6 -0
  53. package/engine/ecs/terrain/ecs/layers/TerrainLayers.js +5 -0
  54. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +5 -0
  55. package/engine/ecs/util/hideEntityGracefully.js +18 -0
  56. package/engine/graphics/GraphicsEngine.js +1 -0
  57. package/engine/graphics/camera/testClippingPlaneComputation.js +2 -2
  58. package/engine/graphics/ecs/camera/CameraClippingPlaneComputer.js +1 -1
  59. package/engine/graphics/ecs/highlight/renderer/OutlineRenderer.js +0 -53
  60. package/engine/graphics/ecs/path/testPathDisplaySystem.js +98 -98
  61. package/engine/graphics/ecs/trail2d/Trail2D.js +17 -4
  62. package/engine/graphics/ecs/trail2d/Trail2DSystem.d.ts +2 -3
  63. package/engine/graphics/ecs/trail2d/Trail2DSystem.js +34 -118
  64. package/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +2 -1
  65. package/engine/graphics/micron/build/clustering/computeFaceCurvatureScore.js +1 -1
  66. package/engine/graphics/micron/build/clustering/compute_face_connection_weight.js +1 -1
  67. package/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +1 -1
  68. package/engine/graphics/micron/build/hierarchy/patch_combine.js +1 -1
  69. package/engine/graphics/micron/render/refinement/is_patch_facing_back.js +2 -2
  70. package/engine/graphics/particles/particular/engine/ParticularEngine.js +4 -2
  71. package/engine/graphics/particles/particular/engine/emitter/PARTICULAR_PARTICLE_SPECIFICATION.js +20 -0
  72. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +40 -97
  73. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +12 -2
  74. package/engine/graphics/particles/particular/engine/emitter/computeEmissionFunction.js +37 -0
  75. package/engine/graphics/particles/particular/engine/emitter/distance_to_camera.js +25 -0
  76. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +7 -25
  77. package/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +2 -2
  78. package/engine/graphics/render/forward_plus/LightManager.js +10 -2
  79. package/engine/graphics/render/forward_plus/computeFrustumCorners.js +15 -33
  80. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +12 -2
  81. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  82. package/engine/graphics/render/forward_plus/prototypeLightManager.js +96 -95
  83. package/engine/graphics/render/forward_plus/queryBVH_Frustum.js +18 -6
  84. package/engine/graphics/render/layers/RenderLayerUtils.js +8 -5
  85. package/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  86. package/engine/graphics/texture/atlas/AtlasPatch.js +7 -2
  87. package/engine/graphics/texture/atlas/TextureAtlas.js +18 -14
  88. package/engine/graphics/texture/sampler/Sampler2D.js +8 -7
  89. package/engine/graphics/texture/sampler/scaleSampler2D.js +7 -10
  90. package/engine/graphics/trail/x/RibbonMaterialX.js +3 -3
  91. package/engine/graphics/trail/x/RibbonX.js +17 -2
  92. package/engine/graphics/trail/x/RibbonXPlugin.js +51 -1
  93. package/engine/graphics/util/projectSphere.js +1 -1
  94. package/engine/grid/components/GridObstacle.js +2 -9
  95. package/engine/navigation/ecs/components/Path.js +2 -1
  96. package/engine/network/convertPathToURL.js +2 -2
  97. package/engine/reference/v2/Reference.js +6 -0
  98. package/generation/filtering/numeric/complex/CellFilterAngleToNormal.js +3 -2
  99. package/generation/markers/GridCellActionPlaceMarker.js +13 -1
  100. package/generation/markers/MarkerNode.js +6 -0
  101. package/generation/theme/ThemeEngine.js +4 -1
  102. package/package.json +3 -3
  103. package/view/View.js +4 -2
  104. package/view/minimap/gl/MinimapMarkersGL.js +13 -1
@@ -1,7 +1,7 @@
1
- import { v3_distance_sqr } from "../../../../core/geom/Vector3.js";
2
1
  import { line3_computeSegmentPointDistance_sqr } from "../../../../core/geom/LineSegment.js";
3
2
  import { computeConePlaneSide } from "../../../../core/geom/3d/cone/computeConePlaneSide.js";
4
3
  import { aabb3_computeDistanceAbovePlane } from "../../../../core/geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
4
+ import { v3_distance_sqr } from "../../../../core/geom/v3_distance_sqr.js";
5
5
 
6
6
  /**
7
7
  *
@@ -67,7 +67,11 @@ biplanar_edge_mapping[0b100010] = 5 | (7 << 3);
67
67
  * @param {number[]} points
68
68
  * @return {boolean}
69
69
  */
70
- function detailed_sphere_frustum_intersection_test(radius, light_x, light_y, light_z, outside_plane_count, outside_plane_bitfield, points) {
70
+ function detailed_sphere_frustum_intersection_test(
71
+ radius, light_x, light_y, light_z,
72
+ outside_plane_count, outside_plane_bitfield,
73
+ points
74
+ ) {
71
75
 
72
76
  const radius_sqr = radius * radius;
73
77
 
@@ -201,7 +205,11 @@ function point_light_inside_volume(light, points, planes) {
201
205
  if (outside_plane_count < 2) {
202
206
  return true;
203
207
  } else {
204
- return detailed_sphere_frustum_intersection_test(radius, light_x, light_y, light_z, outside_plane_count, outside_plane_bitfield, points);
208
+ return detailed_sphere_frustum_intersection_test(
209
+ radius, light_x, light_y, light_z,
210
+ outside_plane_count, outside_plane_bitfield,
211
+ points
212
+ );
205
213
  }
206
214
  }
207
215
 
@@ -246,7 +254,11 @@ function spot_light_inside_volume(light, points, planes) {
246
254
  * @param {number[]|Float32Array|Float64Array} points
247
255
  * @returns {number} number of items added to the destination, non-negative integer
248
256
  */
249
- export function queryBVH_Frustum(destination, destination_offset, root, planes, points) {
257
+ export function queryBVH_Frustum(
258
+ destination,
259
+ destination_offset,
260
+ root, planes, points
261
+ ) {
250
262
  let i = 0;
251
263
  let j = 0;
252
264
  // read out points
@@ -258,7 +270,7 @@ export function queryBVH_Frustum(destination, destination_offset, root, planes,
258
270
 
259
271
  stack_loop:while (stackPointer-- > stackOffset) {
260
272
 
261
- queryBVH_Frustum.iteration_count++;
273
+ // queryBVH_Frustum.iteration_count++;
262
274
 
263
275
  const n = stack[stackPointer];
264
276
 
@@ -282,7 +294,7 @@ export function queryBVH_Frustum(destination, destination_offset, root, planes,
282
294
  if (distanceAbovePlane < 0) {
283
295
  // node is below the plane
284
296
 
285
- queryBVH_Frustum.rejection_count++;
297
+ // queryBVH_Frustum.rejection_count++;
286
298
 
287
299
  continue stack_loop;
288
300
  }
@@ -1,6 +1,5 @@
1
- import Vector3 from "../../../../core/geom/Vector3.js";
2
1
  import { computePointDistanceToPlane } from "../../../../core/geom/Plane.js";
3
- import { plane_three_computeConvex3PlaneIntersection } from "../../../../core/geom/3d/plane_computeConvex3PlaneIntersection.js";
2
+ import { plane_three_computeConvex3PlaneIntersection } from "../../../../core/geom/3d/plane/plane_computeConvex3PlaneIntersection.js";
4
3
 
5
4
  /**
6
5
  *
@@ -10,7 +9,11 @@ import { plane_three_computeConvex3PlaneIntersection } from "../../../../core/ge
10
9
  */
11
10
  export function buildPlanarRenderLayerClipPlaneComputationMethod(traversePlanes, bias = 0) {
12
11
 
13
- const p = new Vector3();
12
+ /**
13
+ *
14
+ * @type {number[]}
15
+ */
16
+ const p = [];
14
17
 
15
18
  const adjacentPlanePairs = [
16
19
  [],
@@ -38,7 +41,7 @@ export function buildPlanarRenderLayerClipPlaneComputationMethod(traversePlanes,
38
41
  const p0 = pair[0];
39
42
  const p1 = pair[1];
40
43
 
41
- const planeIntersection = plane_three_computeConvex3PlaneIntersection(p, p0, p1, objectPlane);
44
+ const planeIntersection = plane_three_computeConvex3PlaneIntersection(p, 0, p0, p1, objectPlane);
42
45
 
43
46
  if (!planeIntersection) {
44
47
  //no intersection
@@ -48,7 +51,7 @@ export function buildPlanarRenderLayerClipPlaneComputationMethod(traversePlanes,
48
51
 
49
52
  const plane_normal = nearPlane.normal;
50
53
 
51
- const distanceToNearPlane = computePointDistanceToPlane(p.x, p.y, p.z, plane_normal.x, plane_normal.y, plane_normal.z, nearPlane.constant);
54
+ const distanceToNearPlane = computePointDistanceToPlane(p[0], p[1], p[2], plane_normal.x, plane_normal.y, plane_normal.z, nearPlane.constant);
52
55
 
53
56
  //update near and far plane distances
54
57
  if (distanceToNearPlane > 0 && distanceToNearPlane < range.near) {
@@ -112,7 +112,7 @@ function makeConfig(engine) {
112
112
  new ClingToTerrainSystem(),
113
113
  new TerrainSystem(graphics, assetManager),
114
114
  new WaterSystem(graphics),
115
- new Trail2DSystem(graphics, assetManager),
115
+ new Trail2DSystem(engine),
116
116
  new Foliage2System(assetManager, graphics),
117
117
  new ViewportPositionSystem(graphics.viewport.size),
118
118
  new GridPosition2TransformSystem(),
@@ -5,12 +5,15 @@ import AABB2 from "../../../../core/geom/AABB2.js";
5
5
  export class AtlasPatch {
6
6
  constructor() {
7
7
  /**
8
- *
8
+ * Position in the atlas where the raw patch data is found, excludes padding
9
+ * @readonly
9
10
  * @type {Vector2}
10
11
  */
11
12
  this.position = new Vector2(0, 0);
13
+
12
14
  /**
13
- *
15
+ * Size in pixels of the patch, excludes padding
16
+ * @readonly
14
17
  * @type {Vector2}
15
18
  */
16
19
  this.size = new Vector2(0, 0);
@@ -34,11 +37,13 @@ export class AtlasPatch {
34
37
  this.sampler = null;
35
38
 
36
39
  /**
40
+ * @readonly
37
41
  * @type {Rectangle}
38
42
  */
39
43
  this.uv = new Rectangle(0, 0, 0, 0);
40
44
 
41
45
  /**
46
+ * Area in the atlas where patch along with the padding is packed into
42
47
  * Used for packing inside TextureAtlas. Do not modify manually
43
48
  * @readonly
44
49
  * @protected
@@ -82,8 +82,8 @@ export class TextureAtlas {
82
82
  * @returns {boolean}
83
83
  */
84
84
  contains(patch) {
85
- assert.notEqual(patch, null, 'patch is null');
86
- assert.notEqual(patch, undefined, 'patch is undefined');
85
+ assert.notNull(patch, 'patch');
86
+ assert.defined(patch, 'patch');
87
87
  assert.ok(patch.isAtlasPatch, 'patch argument is not an AtlasPatch');
88
88
 
89
89
  return this.patches.includes(patch);
@@ -116,28 +116,32 @@ export class TextureAtlas {
116
116
  *
117
117
  * @param {number} x
118
118
  * @param {number} y
119
- * @returns {boolean}
119
+ * @returns {boolean} true if resizing successful, false otherwise
120
120
  */
121
121
  resize(x, y) {
122
122
  //check if any patches would be cut
123
123
  const patches = this.patches;
124
124
  const numPatches = patches.length;
125
- const patchBoundsViolated = patches.some(patch => {
126
125
 
127
- if (!patch.getFlag(AtlasPatchFlag.Packed)) {
126
+ //update patch UVs
127
+ for (let i = 0; i < numPatches; i++) {
128
+ const patch = patches[i];
129
+
130
+ if (patch.getFlag(AtlasPatchFlag.Packed)) {
128
131
  //only care about packed patches
129
- return false;
130
- }
131
132
 
132
- const x1 = patch.position.x + patch.size.x + patch.padding;
133
- const y1 = patch.position.y + patch.size.y + patch.padding;
133
+ const pp = patch.position;
134
+ const ps = patch.size;
134
135
 
135
- return x1 >= x || y1 >= y;
136
- });
136
+ const x1 = pp.x + ps.x + patch.padding;
137
+ const y1 = pp.y + ps.y + patch.padding;
137
138
 
138
- if (patchBoundsViolated) {
139
- //Resizing atlas would result in some patches not fitting
140
- return false;
139
+ if (x1 >= x || y1 >= y) {
140
+ // patch bounds would violate the desired atlas extends
141
+ //Resizing atlas would result in some patches not fitting
142
+ return false;
143
+ }
144
+ }
141
145
  }
142
146
 
143
147
  //update patch UVs
@@ -493,7 +493,7 @@ Sampler2D.prototype.get = function (x, y, result) {
493
493
 
494
494
  const t = [];
495
495
 
496
- this.sampleBilinear(x, y, t);
496
+ this.sampleBilinear(x, y, t, 0);
497
497
 
498
498
  if (result !== undefined) {
499
499
  result.readFromArray(t, 0);
@@ -655,14 +655,15 @@ Sampler2D.prototype.sampleChannelBicubic = function (x, y, channel) {
655
655
  * @param {number} x
656
656
  * @param {number} y
657
657
  * @param {number[]} result
658
+ * @param {number} result_offset
658
659
  */
659
- Sampler2D.prototype.sampleBilinear = function (x, y, result) {
660
+ Sampler2D.prototype.sampleBilinear = function (x, y, result, result_offset) {
660
661
 
661
662
  const itemSize = this.itemSize;
662
663
 
663
664
  for (let i = 0; i < itemSize; i++) {
664
665
  //TODO this can be optimized greatly
665
- result[i] = this.sampleChannelBilinear(x, y, i);
666
+ result[i + result_offset] = this.sampleChannelBilinear(x, y, i);
666
667
 
667
668
  }
668
669
  };
@@ -809,7 +810,7 @@ Sampler2D.prototype.sample = function (u, v, result) {
809
810
 
810
811
  const temp = [];
811
812
 
812
- this.sampleBilinear(u * (this.width - 1), v * (this.height - 1), temp);
813
+ this.sampleBilinear(u * (this.width - 1), v * (this.height - 1), temp, 0);
813
814
 
814
815
  result.readFromArray(temp);
815
816
 
@@ -888,7 +889,7 @@ Sampler2D.prototype.makeArrayFiller = function (scale, offset) {
888
889
  }
889
890
 
890
891
  function fillDD2(index, array, x, y) {
891
- sampler.sampleBilinear(x, y, v4);
892
+ sampler.sampleBilinear(x, y, v4, 0);
892
893
  const val = (v4[0] + offset) * scale | 0;
893
894
  array.fill(val, index, index + 3);
894
895
  array[index + 3] = (v4[1] + offset) * scale | 0;
@@ -896,7 +897,7 @@ Sampler2D.prototype.makeArrayFiller = function (scale, offset) {
896
897
 
897
898
  function fillDD3(index, array, x, y) {
898
899
 
899
- sampler.sampleBilinear(x, y, v4);
900
+ sampler.sampleBilinear(x, y, v4, 0);
900
901
 
901
902
  array[index] = (v4[0] + offset) * scale | 0;
902
903
  array[index + 1] = (v4[1] + offset) * scale | 0;
@@ -905,7 +906,7 @@ Sampler2D.prototype.makeArrayFiller = function (scale, offset) {
905
906
  }
906
907
 
907
908
  function fillDD4(index, array, x, y) {
908
- sampler.sampleBilinear(x, y, v4);
909
+ sampler.sampleBilinear(x, y, v4, 0);
909
910
  array[index] = (v4[0] + offset) * scale | 0;
910
911
  array[index + 1] = (v4[1] + offset) * scale | 0;
911
912
  array[index + 2] = (v4[2] + offset) * scale | 0;
@@ -7,6 +7,7 @@ import { assert } from "../../../../core/assert.js";
7
7
  */
8
8
  export function scaleSampler2D(source, target) {
9
9
  const targetItemSize = target.itemSize;
10
+
10
11
  assert.equal(source.itemSize, targetItemSize, 'both source and target must have the same number of channels');
11
12
 
12
13
  const targetWidth = target.width;
@@ -18,32 +19,28 @@ export function scaleSampler2D(source, target) {
18
19
  const target_data = target.data;
19
20
 
20
21
  if (sourceWidth === targetWidth && sourceHeight === targetHeight) {
21
- // exact size match
22
+ // exact size match, nothing to do
22
23
  target_data.set(source.data);
23
24
  return;
24
25
  }
25
26
 
26
- const sample = [];
27
-
28
27
  const targetRowSize = targetItemSize * targetWidth;
29
28
 
29
+ const source_scale_x = sourceWidth / targetWidth;
30
+ const source_scale_y = sourceHeight / targetHeight;
31
+
30
32
  for (let y = 0; y < targetHeight; y++) {
31
33
 
32
- const v = y / targetHeight;
33
34
 
35
+ const sample_y = y * source_scale_y;
34
36
  const target_row_address = y * targetRowSize;
35
37
 
36
38
  for (let x = 0; x < targetWidth; x++) {
37
39
 
38
- const u = x / targetWidth;
39
-
40
- source.sampleBilinear(u * sourceWidth, v * sourceHeight, sample);
41
40
 
42
41
  const target_offset = target_row_address + x * targetItemSize;
43
42
 
44
- for (let i = 0; i < targetItemSize; i++) {
45
- target_data[target_offset + i] = sample[i];
46
- }
43
+ source.sampleBilinear(x * source_scale_x, sample_y, target_data, target_offset);
47
44
 
48
45
  }
49
46
  }
@@ -106,11 +106,11 @@ export class RibbonMaterialX extends ShaderMaterial {
106
106
  uDiffuse: {
107
107
  type: 't',
108
108
  value: null
109
- },
110
- defines: {
111
- USE_TEXTURE: false
112
109
  }
113
110
  },
111
+ defines: {
112
+ USE_TEXTURE: false
113
+ },
114
114
  blending: NormalBlending,
115
115
  transparent: true,
116
116
  depthWrite: false,
@@ -36,7 +36,6 @@ export class RibbonX {
36
36
  */
37
37
  this.__data = new RowFirstTable(ribbon_attributes_spec);
38
38
 
39
-
40
39
  /**
41
40
  * Index into current geometry segment that is at the END of the ribbon
42
41
  * @type {number}
@@ -66,6 +65,10 @@ export class RibbonX {
66
65
  this.__count = 0;
67
66
  }
68
67
 
68
+ dispose() {
69
+ this.__geometry.dispose();
70
+ }
71
+
69
72
  /**
70
73
  *
71
74
  * @returns {BufferGeometry}
@@ -350,6 +353,11 @@ export class RibbonX {
350
353
  this.setPointAttribute_Vector3(index, RIBBON_ATTRIBUTE_ADDRESS_COLOR, r, g, b);
351
354
  }
352
355
 
356
+ /**
357
+ *
358
+ * @param {number} index
359
+ * @param {number} value
360
+ */
353
361
  setPointAlpha(index, value) {
354
362
  const i2 = index * 2;
355
363
 
@@ -359,7 +367,11 @@ export class RibbonX {
359
367
  this.__ib_float32.needsUpdate = true;
360
368
  }
361
369
 
362
-
370
+ /**
371
+ *
372
+ * @param {number} index
373
+ * @param {number} value
374
+ */
363
375
  setPointThickness(index, value) {
364
376
  const i2 = index * 2;
365
377
 
@@ -377,6 +389,9 @@ export class RibbonX {
377
389
  assert.greaterThanOrEqual(count, 2, 'number of points in the ribbon must be at least 2 (to produce at least a single quad)');
378
390
  assert.isNonNegativeInteger(count, 'count');
379
391
 
392
+ // dispose of existing geometry
393
+ this.__geometry.dispose();
394
+
380
395
  const point_count = count * 2;
381
396
 
382
397
  if (this.__data.length > point_count) {
@@ -1,15 +1,18 @@
1
1
  import { EnginePlugin } from "../../../plugin/EnginePlugin.js";
2
2
  import { RibbonMaterialX } from "./RibbonMaterialX.js";
3
- import { DoubleSide } from "three";
3
+ import { DoubleSide, Vector2 } from "three";
4
4
  import { GameAssetType } from "../../../asset/GameAssetType.js";
5
5
  import { Cache } from "../../../../core/cache/Cache.js";
6
6
  import { invokeObjectEquals } from "../../../../core/model/object/invokeObjectEquals.js";
7
7
  import { invokeObjectHash } from "../../../../core/model/object/invokeObjectHash.js";
8
+ import { MaterialManager } from "../../material/manager/MaterialManager.js";
8
9
 
9
10
  export class RibbonXPlugin extends EnginePlugin {
10
11
  initialize(engine) {
11
12
  super.initialize(engine);
12
13
 
14
+ this.id = 'ribbon-x-plugin';
15
+
13
16
  /**
14
17
  * @private
15
18
  * @readonly
@@ -21,6 +24,51 @@ export class RibbonXPlugin extends EnginePlugin {
21
24
  keyHashFunction: invokeObjectHash,
22
25
  keyEqualityFunction: invokeObjectEquals
23
26
  });
27
+
28
+ this.__shared_uniforms = {
29
+ resolution: {
30
+ value: new Vector2(1, 1)
31
+ }
32
+ };
33
+
34
+ /**
35
+ *
36
+ * @type {MaterialManager}
37
+ * @private
38
+ */
39
+ this.__materials = new MaterialManager();
40
+ }
41
+
42
+ __handle_viewport_size_change() {
43
+ const s = this.engine.graphics.viewport.size;
44
+
45
+ this.__shared_uniforms.resolution.value.set(s.x, s.y);
46
+ }
47
+
48
+ async startup() {
49
+ this.__handle_viewport_size_change();
50
+
51
+ this.engine.graphics.viewport.size.onChanged.add(this.__handle_viewport_size_change, this);
52
+
53
+ return super.startup();
54
+ }
55
+
56
+ async shutdown() {
57
+
58
+ this.engine.graphics.viewport.size.onChanged.remove(this.__handle_viewport_size_change, this);
59
+
60
+ return super.shutdown();
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @param {RibbonXMaterialSpec} spec
66
+ * @return {Reference<Material>}
67
+ */
68
+ obtain_material_reference(spec) {
69
+ const mm = this.obtain_material_x(spec);
70
+
71
+ return this.__materials.obtain(mm);
24
72
  }
25
73
 
26
74
  /**
@@ -62,6 +110,8 @@ export class RibbonXPlugin extends EnginePlugin {
62
110
  }
63
111
  });
64
112
 
113
+ material.uniforms.resolution = this.__shared_uniforms.resolution;
114
+
65
115
  if (spec.diffuse !== null) {
66
116
  const am = this.engine.assetManager;
67
117
 
@@ -1,6 +1,6 @@
1
1
  import { assert } from "../../../core/assert.js";
2
2
  import { v4_applyMatrix4 } from "../../../core/geom/Vector4.js";
3
- import { v3_dot } from "../../../core/geom/Vector3.js";
3
+ import { v3_dot } from "../../../core/geom/v3_dot.js";
4
4
 
5
5
  const v4 = [];
6
6
 
@@ -8,6 +8,7 @@ import { computeHashIntegerArray } from "../../../core/math/MathUtils.js";
8
8
  import { assert } from "../../../core/assert.js";
9
9
  import { BinaryClassSerializationAdapter } from "../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
10
10
  import { computeIntegerArrayHash } from "../../../core/primitives/array/computeIntegerArrayHash.js";
11
+ import { isArrayEqualStrict } from "../../../core/collection/array/isArrayEqualStrict.js";
11
12
 
12
13
  class GridObstacle {
13
14
  constructor() {
@@ -236,15 +237,7 @@ class GridObstacle {
236
237
  return false;
237
238
  }
238
239
 
239
- const dataSize = this.size.x * this.size.y;
240
-
241
- for (let i = 0; i < dataSize; i++) {
242
- if (this.data[i] !== other.data[i]) {
243
- return false;
244
- }
245
- }
246
-
247
- return true;
240
+ return isArrayEqualStrict(this.data, other.data);
248
241
  }
249
242
  }
250
243
 
@@ -4,7 +4,7 @@
4
4
 
5
5
 
6
6
  import { line3_computeSegmentPointDistance_sqr } from "../../../../core/geom/LineSegment.js";
7
- import Vector3, { v3_distance } from "../../../../core/geom/Vector3.js";
7
+ import Vector3 from "../../../../core/geom/Vector3.js";
8
8
 
9
9
  import { CatmullRomCurve3 } from "three";
10
10
  import { clamp } from "../../../../core/math/clamp.js";
@@ -17,6 +17,7 @@ import { max2 } from "../../../../core/math/max2.js";
17
17
  import { min2 } from "../../../../core/math/min2.js";
18
18
  import { computeNonuniformCatmullRomSplineSample } from "./computeNonuniformCatmullRomSplineSample.js";
19
19
  import { InterpolationType } from "./InterpolationType.js";
20
+ import { v3_distance } from "../../../../core/geom/v3_distance.js";
20
21
 
21
22
  const v3_a = new Vector3();
22
23
  const v3_b = new Vector3();
@@ -68,8 +68,8 @@ export function convertPathToURL(path) {
68
68
  */
69
69
 
70
70
  if (pathname.endsWith('/')) {
71
- //path is to a directory
72
- directoryPath = pathname;
71
+ //path is to a directory, strip last slash
72
+ directoryPath = pathname.substring(0, pathname.length - 1);
73
73
  } else {
74
74
  //path is to a file
75
75
  const i = pathname.lastIndexOf('/');
@@ -81,3 +81,9 @@ export class Reference {
81
81
  this.__onReleased.send1(this);
82
82
  }
83
83
  }
84
+
85
+ /**
86
+ * @readonly
87
+ * @type {Readonly<Reference>}
88
+ */
89
+ Reference.NULL = Object.freeze(new Reference());
@@ -1,6 +1,7 @@
1
1
  import { CellFilter } from "../../CellFilter.js";
2
- import Vector3, { v3_angleBetween } from "../../../../core/geom/Vector3.js";
2
+ import Vector3 from "../../../../core/geom/Vector3.js";
3
3
  import { assert } from "../../../../core/assert.js";
4
+ import { v3_angle_between } from "../../../../core/geom/v3_angle_between.js";
4
5
 
5
6
  /**
6
7
  * Builds surface normal of another filter, and then computes the angle to a fixed 3d vector
@@ -70,7 +71,7 @@ export class CellFilterAngleToNormal extends CellFilter {
70
71
 
71
72
  const reference = this.reference;
72
73
 
73
- const angle = v3_angleBetween(reference.x, reference.y, reference.z, _x, _y, _z);
74
+ const angle = v3_angle_between(reference.x, reference.y, reference.z, _x, _y, _z);
74
75
 
75
76
  return angle;
76
77
  }
@@ -36,6 +36,12 @@ export class GridCellActionPlaceMarker extends GridCellAction {
36
36
  */
37
37
  this.transformers = [];
38
38
 
39
+ /**
40
+ *
41
+ * @type {number}
42
+ */
43
+ this.priority = 0;
44
+
39
45
  /**
40
46
  *
41
47
  * @type {Vector2}
@@ -91,6 +97,7 @@ export class GridCellActionPlaceMarker extends GridCellAction {
91
97
  * @param {string[]} [tags]
92
98
  * @param {Transform} [transform]
93
99
  * @param {*} [properties]
100
+ * @param priority
94
101
  * @return {GridCellActionPlaceMarker}
95
102
  */
96
103
  static from({
@@ -99,7 +106,8 @@ export class GridCellActionPlaceMarker extends GridCellAction {
99
106
  transformers = [],
100
107
  tags = [],
101
108
  transform,
102
- properties
109
+ properties,
110
+ priority = 0
103
111
  }) {
104
112
 
105
113
  assert.typeOf(type, 'string', 'type');
@@ -125,6 +133,8 @@ export class GridCellActionPlaceMarker extends GridCellAction {
125
133
  r.properties = properties;
126
134
  }
127
135
 
136
+ r.priority = priority;
137
+
128
138
  return r;
129
139
  }
130
140
 
@@ -183,6 +193,8 @@ export class GridCellActionPlaceMarker extends GridCellAction {
183
193
  //write properties
184
194
  Object.assign(node.properties, this.properties);
185
195
 
196
+ node.priority = this.priority;
197
+
186
198
  //apply transformations
187
199
  const transformers = this.transformers;
188
200
  const transformerCount = transformers.length;
@@ -5,6 +5,12 @@ import { circleIntersectsCircle } from "../../core/geom/2d/circle/circleIntersec
5
5
 
6
6
  export class MarkerNode {
7
7
  constructor() {
8
+ /**
9
+ * Processing order, higher priority nodes are processed first
10
+ * @type {number}
11
+ */
12
+ this.priority = 0;
13
+
8
14
  /**
9
15
  *
10
16
  * @type {String}
@@ -337,7 +337,7 @@ export class ThemeEngine {
337
337
  const source_x = u * weights.width;
338
338
 
339
339
 
340
- weights.sampleBilinear(source_x, source_y, weightSample);
340
+ weights.sampleBilinear(source_x, source_y, weightSample, 0);
341
341
 
342
342
  for (let i = 0; i < layer_count; i++) {
343
343
  const targetAddress = (y * splatWidth + x) + i * splatLayerSize;
@@ -451,6 +451,9 @@ export class ThemeEngine {
451
451
  return new Task({
452
452
  initializer() {
453
453
  grid.markers.getRawData(nodes);
454
+
455
+ // sort nodes by priority
456
+ nodes.sort((a, b) => b.priority - a.priority);
454
457
  },
455
458
  cycleFunction
456
459
  });
package/package.json CHANGED
@@ -4,15 +4,15 @@
4
4
  "productName": "Meep",
5
5
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
6
6
  "author": "Alexander Goldring",
7
- "version": "2.33.19",
7
+ "version": "2.33.23",
8
8
  "dependencies": {
9
9
  "fast-levenshtein": "2.0.6",
10
10
  "opentype.js": "1.3.3",
11
11
  "simplex-noise": "2.4.0",
12
- "three": "0.132.2"
12
+ "three": "^0.132.2"
13
13
  },
14
14
  "devDependencies": {
15
15
  "babel-jest": "^26.6.3",
16
- "@types/three": "0.132.2"
16
+ "@types/three": "^0.132.2"
17
17
  }
18
18
  }
package/view/View.js CHANGED
@@ -677,10 +677,12 @@ class View {
677
677
 
678
678
  const classesToRemove = [];
679
679
 
680
- for (let i = 0; i < classList.length; i++) {
680
+ const initial_class_count = classList.length;
681
+
682
+ for (let i = 0; i < initial_class_count; i++) {
681
683
  const className = classList[i];
682
684
 
683
- if (className.startsWith('locale-')) {
685
+ if (className.search(rx) !== -1) {
684
686
  classesToRemove.push(className);
685
687
  }
686
688
  }