@woosh/meep-engine 2.33.22 → 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 (42) hide show
  1. package/core/bvh2/traversal/__detailed_box_volume_intersection.js +10 -7
  2. package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +9 -1
  3. package/core/geom/3d/plane/plane_computeConvex3PlaneIntersection.js +13 -14
  4. package/core/geom/3d/voxel/DenseBitVolume3D.js +87 -0
  5. package/core/geom/3d/voxel/buildVolumeFromProjectedGeometry.js +23 -0
  6. package/core/geom/Plane.js +14 -9
  7. package/core/primitives/array/computeIntegerArrayHash.js +1 -1
  8. package/engine/asset/loaders/material/computeImageBitmapEquality.js +11 -0
  9. package/engine/asset/loaders/material/computeImageBitmapHash.js +22 -28
  10. package/engine/ecs/util/hideEntityGracefully.js +18 -0
  11. package/engine/graphics/GraphicsEngine.js +0 -17
  12. package/engine/graphics/camera/testClippingPlaneComputation.js +2 -2
  13. package/engine/graphics/ecs/path/testPathDisplaySystem.js +98 -98
  14. package/engine/graphics/ecs/trail2d/Trail2D.js +17 -4
  15. package/engine/graphics/ecs/trail2d/Trail2DSystem.d.ts +2 -3
  16. package/engine/graphics/ecs/trail2d/Trail2DSystem.js +34 -118
  17. package/engine/graphics/particles/particular/engine/ParticularEngine.js +4 -2
  18. package/engine/graphics/particles/particular/engine/emitter/PARTICULAR_PARTICLE_SPECIFICATION.js +20 -0
  19. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +40 -97
  20. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +12 -2
  21. package/engine/graphics/particles/particular/engine/emitter/computeEmissionFunction.js +37 -0
  22. package/engine/graphics/particles/particular/engine/emitter/distance_to_camera.js +25 -0
  23. package/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +2 -2
  24. package/engine/graphics/render/forward_plus/LightManager.js +10 -2
  25. package/engine/graphics/render/forward_plus/computeFrustumCorners.js +14 -32
  26. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  27. package/engine/graphics/render/forward_plus/prototypeLightManager.js +96 -95
  28. package/engine/graphics/render/forward_plus/queryBVH_Frustum.js +17 -5
  29. package/engine/graphics/render/layers/RenderLayerUtils.js +7 -4
  30. package/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
  31. package/engine/graphics/texture/atlas/AtlasPatch.js +7 -2
  32. package/engine/graphics/texture/atlas/TextureAtlas.js +2 -2
  33. package/engine/graphics/texture/sampler/Sampler2D.js +8 -7
  34. package/engine/graphics/texture/sampler/scaleSampler2D.js +7 -10
  35. package/engine/graphics/trail/x/RibbonMaterialX.js +3 -3
  36. package/engine/graphics/trail/x/RibbonX.js +17 -2
  37. package/engine/graphics/trail/x/RibbonXPlugin.js +51 -1
  38. package/engine/grid/components/GridObstacle.js +2 -9
  39. package/engine/reference/v2/Reference.js +6 -0
  40. package/generation/theme/ThemeEngine.js +1 -1
  41. package/package.json +3 -3
  42. package/view/View.js +4 -2
@@ -6,7 +6,6 @@ import { aabb3_edge_corner_mapping } from "../aabb3/aabb3_edge_corner_mapping.js
6
6
  import { __process_point_if_within_planes } from "./__process_point_if_within_planes.js";
7
7
  import { plane_computeConvex3PlaneIntersection } from "../../geom/3d/plane/plane_computeConvex3PlaneIntersection.js";
8
8
  import { EPSILON } from "../../math/MathUtils.js";
9
- import Vector3 from "../../geom/Vector3.js";
10
9
 
11
10
  /**
12
11
  *
@@ -26,7 +25,11 @@ const scratch_aabb_planes = new Float32Array(24);
26
25
  */
27
26
  const scratch_corner_out_bitfields = new Uint32Array(8);
28
27
 
29
- const scratch_v3 = new Vector3();
28
+ /**
29
+ *
30
+ * @type {number[]}
31
+ */
32
+ const scratch_v3_array = new Float32Array(3);
30
33
 
31
34
  /**
32
35
  *
@@ -183,7 +186,7 @@ export function __detailed_box_volume_intersection(
183
186
  const c = planes[plane_address + 3];
184
187
 
185
188
  const edge_intersects = plane3_computeLineSegmentIntersection(
186
- scratch_v3,
189
+ scratch_v3_array, 0,
187
190
  corner_0_x, corner_0_y, corner_0_z,
188
191
  corner_1_x, corner_1_y, corner_1_z,
189
192
  nx, ny, nz, c
@@ -192,7 +195,7 @@ export function __detailed_box_volume_intersection(
192
195
  if (edge_intersects) {
193
196
  // a possible candidate, let's see if this point is within rest of the planes
194
197
  __process_point_if_within_planes(
195
- scratch_v3.x, scratch_v3.y, scratch_v3.z,
198
+ scratch_v3_array[0], scratch_v3_array[1], scratch_v3_array[2],
196
199
  (plane_mask ^ plane_bit_mask),
197
200
  planes,
198
201
  plane_count,
@@ -230,7 +233,7 @@ export function __detailed_box_volume_intersection(
230
233
  const cp_1 = next_orthogonal_plane_index * 4;
231
234
 
232
235
  const intersection_exists = plane_computeConvex3PlaneIntersection(
233
- scratch_v3,
236
+ scratch_v3_array, 0,
234
237
  aabb_plane_nx, aabb_plane_ny, aabb_plane_nz, aabb_plane_constant,
235
238
  planes[cp_0], planes[cp_0 + 1], planes[cp_0 + 2], planes[cp_0 + 3],
236
239
  planes[cp_1], planes[cp_1 + 1], planes[cp_1 + 2], planes[cp_1 + 3]
@@ -238,14 +241,14 @@ export function __detailed_box_volume_intersection(
238
241
 
239
242
  if (intersection_exists) {
240
243
 
241
- const point_within_box = box.containsPointWithTolerance(scratch_v3.x, scratch_v3.y, scratch_v3.z, EPSILON);
244
+ const point_within_box = box.containsPointWithTolerance(scratch_v3_array[0], scratch_v3_array[1], scratch_v3_array[2], EPSILON);
242
245
 
243
246
  if (point_within_box) {
244
247
  // point is within the AABB bounds
245
248
 
246
249
  // ThreeClippingPlaneComputingBVHVisitor.DEBUG_POINTS_2.send3(scratch_v3.x, scratch_v3.y, scratch_v3.z);
247
250
 
248
- callback.call(thisArg, scratch_v3.x, scratch_v3.y, scratch_v3.z);
251
+ callback.call(thisArg, scratch_v3_array[0], scratch_v3_array[1], scratch_v3_array[2]);
249
252
  }
250
253
  }
251
254
  }
@@ -14,6 +14,12 @@ const scratch_v3_0 = new Vector3();
14
14
 
15
15
  const scratch_v3_1 = new Vector3();
16
16
 
17
+ /**
18
+ *
19
+ * @type {number[]}
20
+ */
21
+ const scratch_v3_array = [];
22
+
17
23
  /**
18
24
  *
19
25
  * @param {Vector3} result
@@ -94,7 +100,9 @@ export function frustum3_computeNearestPointToPoint(result, planes, target_x, ta
94
100
  const plane_1 = planes[plane_1_index];
95
101
  const plane_2 = planes[plane_2_index];
96
102
 
97
- plane_three_computeConvex3PlaneIntersection(result, plane_0, plane_1, plane_2);
103
+ plane_three_computeConvex3PlaneIntersection(scratch_v3_array, 0, plane_0, plane_1, plane_2);
104
+
105
+ result.readFromArray(scratch_v3_array, 0)
98
106
  }
99
107
 
100
108
  return false;
@@ -2,19 +2,21 @@ import { v3_dot } from "../../v3_dot.js";
2
2
 
3
3
  /**
4
4
  *
5
- * @param {Vector3} result
5
+ * @param {number[]} result
6
+ * @param {number} result_offset
6
7
  * @param {Plane} a
7
8
  * @param {Plane} b
8
9
  * @param {Plane} c
9
10
  * @returns {boolean}
10
11
  */
11
- export function plane_three_computeConvex3PlaneIntersection(result, a, b, c) {
12
+ export function plane_three_computeConvex3PlaneIntersection(result, result_offset, a, b, c) {
12
13
  const a_normal = a.normal;
13
14
  const b_normal = b.normal;
14
15
  const c_normal = c.normal;
15
16
 
16
17
  return plane_computeConvex3PlaneIntersection(
17
18
  result,
19
+ result_offset,
18
20
  a_normal.x, a_normal.y, a_normal.z, a.constant,
19
21
  b_normal.x, b_normal.y, b_normal.z, b.constant,
20
22
  c_normal.x, c_normal.y, c_normal.z, c.constant,
@@ -23,7 +25,8 @@ export function plane_three_computeConvex3PlaneIntersection(result, a, b, c) {
23
25
 
24
26
  /**
25
27
  * NOTE: Based on Intersection of 3 planes, Graphics Gems 1 pg 305
26
- * @param {Vector3} result
28
+ * @param {Float32Array|number[]|vec3} result
29
+ * @param {number} result_offset
27
30
  * @param {number} a_normal_x
28
31
  * @param {number} a_normal_y
29
32
  * @param {number} a_normal_z
@@ -39,7 +42,7 @@ export function plane_three_computeConvex3PlaneIntersection(result, a, b, c) {
39
42
  * @returns {boolean} true if planes intersect, false otherwise
40
43
  */
41
44
  export function plane_computeConvex3PlaneIntersection(
42
- result,
45
+ result, result_offset,
43
46
  a_normal_x, a_normal_y, a_normal_z, a_constant,
44
47
  b_normal_x, b_normal_y, b_normal_z, b_constant,
45
48
  c_normal_x, c_normal_y, c_normal_z, c_constant
@@ -74,18 +77,14 @@ export function plane_computeConvex3PlaneIntersection(
74
77
  const d = 1 / determinant;
75
78
 
76
79
  const neg_a_constant = -a_constant;
77
- const neg_b_constant = -b_constant;
78
- const neg_c_constant = -c_constant;
79
80
 
80
- const x = (bxc_x * neg_a_constant + cxa_x * neg_b_constant + axb_x * neg_c_constant) * d;
81
- const y = (bxc_y * neg_a_constant + cxa_y * neg_b_constant + axb_y * neg_c_constant) * d;
82
- const z = (bxc_z * neg_a_constant + cxa_z * neg_b_constant + axb_z * neg_c_constant) * d;
81
+ const x = (bxc_x * neg_a_constant - cxa_x * b_constant - axb_x * c_constant) * d;
82
+ const y = (bxc_y * neg_a_constant - cxa_y * b_constant - axb_y * c_constant) * d;
83
+ const z = (bxc_z * neg_a_constant - cxa_z * b_constant - axb_z * c_constant) * d;
83
84
 
84
- result.set(
85
- x,
86
- y,
87
- z
88
- );
85
+ result[result_offset] = x;
86
+ result[result_offset + 1] = y;
87
+ result[result_offset + 2] = z;
89
88
 
90
89
  return true;
91
90
  }
@@ -0,0 +1,87 @@
1
+ import Vector3 from "../../Vector3.js";
2
+ import { BitSet } from "../../../binary/BitSet.js";
3
+
4
+ export class DenseBitVolume3D {
5
+ constructor() {
6
+ this.size = new Vector3(1, 1, 1);
7
+
8
+ this.__data = new BitSet();
9
+ this.__data.preventShrink();
10
+ }
11
+
12
+ clear() {
13
+ this.__data.reset();
14
+ }
15
+
16
+ resize(x, y, z) {
17
+ // TODO consider how we can resize while keeping the data
18
+ this.clear();
19
+
20
+ this.size.set(x, y, z);
21
+ }
22
+
23
+ /**
24
+ *
25
+ * @param {number} x
26
+ * @param {number} y
27
+ * @param {number} z
28
+ * @return {number}
29
+ * @private
30
+ */
31
+ __compute_address(x, y, z) {
32
+
33
+ const size = this.size;
34
+
35
+ const dx = size.x;
36
+ const dy = size.y;
37
+
38
+ return y * dx + z * dx * dy + x;
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @param {number} x
44
+ * @param {number} y
45
+ * @param {number} z
46
+ * @return {boolean}
47
+ */
48
+ get(x, y, z) {
49
+ const address = this.__compute_address(x, y, z);
50
+
51
+ return this.__data.get(address)
52
+ }
53
+
54
+ /**
55
+ *
56
+ * @param {boolean} value
57
+ * @param {number} x
58
+ * @param {number} y
59
+ * @param {number} z
60
+ */
61
+ set(value, x, y, z) {
62
+ const address = this.__compute_address(x, y, z);
63
+
64
+ this.__data.set(address, value);
65
+ }
66
+
67
+ /**
68
+ *
69
+ * @param {number} u x-coordinate, normalized to [0,1] range
70
+ * @param {number} v y-coordinate, normalized to [0,1] range
71
+ * @param {number} w z-coordinate, normalized to [0,1] range
72
+ * @returns {boolean}
73
+ */
74
+ sampleNearest(u, v, w) {
75
+ const s = this.size;
76
+
77
+ const dx = s.x;
78
+ const dy = s.y;
79
+ const dz = s.z;
80
+
81
+ const x = Math.round(dx * u) % dx
82
+ const y = Math.round(dy * v) % dy
83
+ const z = Math.round(dz * w) % dz
84
+
85
+ return this.get(x, y, z);
86
+ }
87
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Build a world-space oriented volume
3
+ * @param {DenseBitVolume3D} volume
4
+ * @param {AABB3} bounds
5
+ * @param {{raycast:function(source_x:number, source_y:number, source_z:number, direction_x:number, direction_y:number, direction_z:number):number}} sampler
6
+ * @param {number[]} frustum 3d frustum, defined as series of 6 planes in order: normal_x, normal_y, normal_z, plane_offset
7
+ */
8
+ export function buildVolumeFromProjectedGeometry({ volume, sampler, frustum }) {
9
+ // get frustum corners
10
+
11
+ // get first hits from "front" plane to seed the volume
12
+ for (let x = 0; x < 64; x++) {
13
+ for (let y = 0; y < 64; y++) {
14
+
15
+ }
16
+ }
17
+
18
+ // fit volume to the frustum
19
+
20
+ // create a connectivity graph to identify disconnected regions
21
+
22
+ // clear out disconnected regions starting from smallest until only one is left
23
+ }
@@ -192,7 +192,8 @@ export function computePlaneLineIntersection(out, originX, originY, originZ, dir
192
192
 
193
193
  /**
194
194
  *
195
- * @param {Vector3} result
195
+ * @param {Float32Array|number[]|vec3} result
196
+ * @param {number} result_offset
196
197
  * @param {number} x0
197
198
  * @param {number} y0
198
199
  * @param {number} z0
@@ -205,30 +206,34 @@ export function computePlaneLineIntersection(out, originX, originY, originZ, dir
205
206
  * @param {number} dist
206
207
  * @returns {boolean}
207
208
  */
208
- export function plane3_computeLineSegmentIntersection(result, x0, y0, z0, x1, y1, z1, normalX, normalY, normalZ, dist) {
209
+ export function plane3_computeLineSegmentIntersection(
210
+ result, result_offset,
211
+ x0, y0, z0,
212
+ x1, y1, z1,
213
+ normalX, normalY, normalZ, dist
214
+ ) {
215
+
209
216
  const directionX = x1 - x0;
210
217
  const directionY = y1 - y0;
211
218
  const directionZ = z1 - z0;
212
219
 
213
220
  const denom = v3_dot(directionX, directionY, directionZ, normalX, normalY, normalZ);
214
221
 
215
- const p = v3_dot(normalX, normalY, normalZ, x0, y0, z0) + dist;
216
-
217
222
  if (denom === 0) {
218
223
  return false;
219
224
  }
220
225
 
226
+ const p = v3_dot(normalX, normalY, normalZ, x0, y0, z0) + dist;
227
+
221
228
  const t = -p / denom;
222
229
 
223
230
  if (t < 0 || t > 1) {
224
231
  return false;
225
232
  }
226
233
 
227
- result.set(
228
- directionX * t + x0,
229
- directionY * t + y0,
230
- directionZ * t + z0
231
- );
234
+ result[result_offset] = directionX * t + x0;
235
+ result[result_offset + 1] = directionY * t + y0;
236
+ result[result_offset + 2] = directionZ * t + z0;
232
237
 
233
238
  return true;
234
239
 
@@ -7,7 +7,7 @@
7
7
  export function computeIntegerArrayHash(data, offset, length) {
8
8
  const end = offset + length;
9
9
 
10
- let hash = 0;
10
+ let hash = length;
11
11
 
12
12
  for (let i = offset; i < end; i++) {
13
13
  const singleValue = data[i];
@@ -79,6 +79,17 @@ function obtainCanvasCtx(width, height) {
79
79
  return gl;
80
80
  }
81
81
 
82
+ /**
83
+ *
84
+ * @param {ImageBitmap} bitmap
85
+ * @return {Sampler2D}
86
+ */
87
+ export function sampler_from_bitmap(bitmap) {
88
+ const ctx = obtainCanvasCtx(bitmap.width, bitmap.height);
89
+
90
+ return obtainSampler(bitmap, ctx);
91
+ }
92
+
82
93
  /**
83
94
  *
84
95
  * @param {ImageBitmap} a
@@ -1,47 +1,41 @@
1
1
  import { min2 } from "../../../../core/math/min2.js";
2
- import { computeIntegerArrayHash } from "../../../../core/primitives/array/computeIntegerArrayHash.js";
2
+ import { sampler_from_bitmap } from "./computeImageBitmapEquality.js";
3
3
 
4
- let canvas = null;
5
- let canvasContext = null;
6
4
 
7
5
  /**
8
6
  *
9
- * @returns {CanvasRenderingContext2D}
7
+ * @param {ImageBitmap} bitmap
8
+ * @returns {number}
10
9
  */
11
- function getCanvasContext() {
10
+ export function computeImageBitmapHash(bitmap) {
12
11
 
13
- if (canvasContext === null) {
14
- canvas = document.createElement('canvas');
12
+ const w = min2(bitmap.width, 8);
13
+ const h = min2(bitmap.height, 8);
15
14
 
16
- canvas.height = 8;
17
- canvas.width = 8;
15
+ const sampler = sampler_from_bitmap(bitmap);
18
16
 
19
- canvasContext = canvas.getContext('2d');
17
+ const sampler_data = sampler.data;
18
+ const item_size = sampler.itemSize;
20
19
 
21
- }
20
+ let hash = 0;
22
21
 
23
- return canvasContext;
22
+ for (let y = 0; y < h; y++) {
24
23
 
25
- }
24
+ const row_size = y * sampler.width;
26
25
 
27
- /**
28
- *
29
- * @param {ImageBitmap} bitmap
30
- * @returns {number}
31
- */
32
- export function computeImageBitmapHash(bitmap) {
33
- const ctx = getCanvasContext();
26
+ for (let x = 0; x < w; x++) {
34
27
 
35
- const w = min2(bitmap.width, 8);
36
- const h = min2(bitmap.height, 8);
28
+ const texel_index = x + row_size;
29
+ const address = texel_index * item_size;
37
30
 
38
- ctx.clearRect(0, 0, w, h);
31
+ for (let i = 0; i < item_size; i++) {
39
32
 
40
- ctx.drawImage(bitmap, 0, 0, w, h, 0, 0, w, h);
33
+ const v = sampler_data[address];
41
34
 
42
- const imageData = ctx.getImageData(0, 0, w, h);
43
-
44
- const data = imageData.data;
35
+ hash = (hash << 5) - hash + v;
36
+ }
37
+ }
38
+ }
45
39
 
46
- return computeIntegerArrayHash(data, 0, data.length);
40
+ return hash;
47
41
  }
@@ -15,10 +15,23 @@ import { DelayBehavior } from "../../intelligence/behavior/util/DelayBehavior.js
15
15
  import { Light } from "../../graphics/ecs/light/Light.js";
16
16
  import { TransitionPropertyVectorXBehavior } from "../../../../model/game/story/behaviors/generic/TransitionPropertyVectorXBehavior.js";
17
17
 
18
+ /**
19
+ * @readonly
20
+ * @type {number}
21
+ */
18
22
  const SHUTDOWN_GRACE_PERIOD = 60;
19
23
 
24
+ /**
25
+ *
26
+ * @type {Map<Class|function, function(T,entity?:EntityBuilder,createEntity?:function,createEntityContext?:*):number>}
27
+ */
20
28
  const component_shutdown = new Map();
21
29
 
30
+ /**
31
+ * @template T
32
+ * @param {Class<T>} type
33
+ * @param {function(T,entity?:EntityBuilder,createEntity?:function,createEntityContext?:*):number} method
34
+ */
22
35
  function addShutdown(type, method) {
23
36
  component_shutdown.set(type, method);
24
37
  }
@@ -152,6 +165,11 @@ addShutdown(SoundEmitter, (soundEmitter, builder, createEntity, createEntityThis
152
165
  * @return {number} duration in seconds until the entity is completely hidden
153
166
  */
154
167
  export function hideEntityGracefully(builder, createEntity, createEntityThisArg) {
168
+ if (!builder.isBuilt) {
169
+ // already destroyed
170
+ return 0;
171
+ }
172
+
155
173
  let delay = 0;
156
174
 
157
175
  const components = builder.element;
@@ -345,23 +345,6 @@ GraphicsEngine.prototype.start = function () {
345
345
 
346
346
  const webGLRenderer = this.renderer = new WebGLRenderer(rendererParameters);
347
347
 
348
- let g = 0;
349
- let t = 0;
350
- webGLRenderer.info.memory = {
351
- get geometries() {
352
- return g;
353
- },
354
- set geometries(v) {
355
- g = v;
356
- },
357
- get textures() {
358
- return t;
359
- },
360
- set textures(v) {
361
- t = v;
362
- }
363
- };
364
-
365
348
  //print GPU info
366
349
  const GPU_NAME = this.getGPUName();
367
350
 
@@ -95,11 +95,11 @@ function makeConfig(engine) {
95
95
  new TopDownCameraControllerSystem(graphics),
96
96
  new TopDownCameraLanderSystem(),
97
97
  new CameraSystem(graphics.scene, graphics),
98
- new MeshSystem(graphics, assetManager),
98
+ new MeshSystem(engine),
99
99
  new ClingToTerrainSystem(),
100
100
  new TerrainSystem(graphics, assetManager),
101
101
  new WaterSystem(graphics),
102
- new Trail2DSystem(graphics, assetManager),
102
+ new Trail2DSystem(engine),
103
103
  new Foliage2System(assetManager, graphics),
104
104
  new ViewportPositionSystem(graphics.viewport.size),
105
105
  new GridPosition2TransformSystem(),