@woosh/meep-engine 2.48.13 → 2.48.14

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 (51) hide show
  1. package/package.json +1 -1
  2. package/src/core/font/FontAssetLoader.js +2 -2
  3. package/src/core/math/bessel_3.js +3 -1
  4. package/src/core/path/computeFileExtension.js +3 -2
  5. package/src/engine/Engine.js +5 -3
  6. package/src/engine/achievements/AchievementManager.js +16 -16
  7. package/src/engine/asset/AssetManager.d.ts +1 -1
  8. package/src/engine/asset/AssetManager.js +58 -16
  9. package/src/engine/asset/AssetManager.spec.js +1 -1
  10. package/src/engine/asset/AssetRequest.js +19 -1
  11. package/src/engine/asset/AssetRequestScope.d.ts +3 -0
  12. package/src/engine/asset/AssetRequestScope.js +64 -0
  13. package/src/engine/asset/PendingAsset.js +1 -1
  14. package/src/engine/asset/loaders/ArrayBufferLoader.js +1 -1
  15. package/src/engine/asset/loaders/AssetLoader.d.ts +3 -1
  16. package/src/engine/asset/loaders/AssetLoader.js +3 -2
  17. package/src/engine/asset/loaders/GLTFAssetLoader.d.ts +1 -1
  18. package/src/engine/asset/loaders/GLTFAssetLoader.js +1 -1
  19. package/src/engine/asset/loaders/JavascriptAssetLoader.js +17 -12
  20. package/src/engine/asset/loaders/JsonAssetLoader.js +1 -1
  21. package/src/engine/asset/loaders/LegacyThreeJSONAssetLoader.js +4 -1
  22. package/src/engine/asset/loaders/SVGAssetLoader.js +1 -1
  23. package/src/engine/asset/loaders/SoundAssetLoader.js +1 -1
  24. package/src/engine/asset/loaders/TextAssetLoader.js +1 -1
  25. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +24 -17
  26. package/src/engine/asset/loaders/texture/TextureAssetLoader.d.ts +1 -1
  27. package/src/engine/asset/loaders/texture/TextureAssetLoader.js +1 -1
  28. package/src/engine/asset/preloader/Preloader.js +1 -1
  29. package/src/engine/ecs/foliage/ecs/Foliage2System.js +7 -5
  30. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +2 -2
  31. package/src/engine/ecs/terrain/ecs/PromiseSamplerHeight.js +16 -9
  32. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +16 -11
  33. package/src/engine/ecs/terrain/serialization/TerrainSerializationAdapter.js +1 -1
  34. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +18 -15
  35. package/src/engine/graphics/ecs/mesh/MeshSystem.js +1 -1
  36. package/src/engine/graphics/ecs/path/tube/build/TubePathBuilder.js +6 -4
  37. package/src/engine/graphics/material/getTextureImmediate.js +5 -3
  38. package/src/engine/graphics/texture/atlas/ManagedTextureAtlas.js +1 -1
  39. package/src/engine/graphics/texture/sampler/Sampler2D.js +20 -11
  40. package/src/engine/graphics/texture/sampler/filter/box.js +3 -3
  41. package/src/engine/graphics/texture/sampler/filter/kaiser_bessel_window.js +2 -1
  42. package/src/engine/graphics/texture/sampler/genericResampleSampler2D.js +9 -8
  43. package/src/engine/graphics/texture/sampler/loadSampler2D.js +18 -16
  44. package/src/engine/graphics/texture/sampler/sampler2d_scale_down_linear.js +8 -11
  45. package/src/engine/graphics/texture/virtual/tile/TileLoader.js +1 -1
  46. package/src/engine/graphics/trail/x/RibbonXPlugin.js +5 -3
  47. package/src/engine/knowledge/database/StaticKnowledgeDataTable.js +1 -1
  48. package/src/engine/sound/ecs/emitter/loadSoundTrackAsset.js +1 -1
  49. package/src/view/elements/MeshPreview.js +66 -64
  50. package/src/view/elements/image/SvgImageView.js +8 -6
  51. package/src/view/renderModel.js +1 -1
@@ -38,12 +38,14 @@ export function loadFoliageLayer(layer, assetManager) {
38
38
  reject(`Undetermined asset type for url='${modelURL}'`);
39
39
  }
40
40
 
41
- assetManager.get(modelURL, assetType, function (asset) {
42
- const mesh = asset.create();
43
- instancedFoliage.setInstance(mesh.geometry, mesh.material);
41
+ assetManager.get({
42
+ path: modelURL, type: assetType, callback: function (asset) {
43
+ const mesh = asset.create();
44
+ instancedFoliage.setInstance(mesh.geometry, mesh.material);
44
45
 
45
- resolve();
46
- }, reject);
46
+ resolve();
47
+ }, failure: reject
48
+ });
47
49
  });
48
50
 
49
51
  const result = mesh.then(function () {
@@ -4,9 +4,9 @@ import { AttachmentSockets } from "../AttachmentSockets.js";
4
4
  import { Asset } from "../../../asset/Asset.js";
5
5
 
6
6
  export class AttachmentSocketsAssetLoader extends AssetLoader {
7
- load(path, success, failure, progress) {
7
+ load(scope, path, success, failure, progress) {
8
8
 
9
- this.assetManager.promise(path, GameAssetType.JSON)
9
+ this.assetManager.promise(path, GameAssetType.JSON, { scope })
10
10
  .then(asset => {
11
11
 
12
12
  const json = asset.create();
@@ -41,19 +41,26 @@ export function promiseSamplerHeight(zRange, heightMapURL, assetManager) {
41
41
  fulfill(defaultSampler);
42
42
  } else if (heightMapURL.endsWith('.bin')) {
43
43
  //load texture from a binary file
44
- assetManager.get(heightMapURL, GameAssetType.ArrayBuffer, assetObtained, reject);
44
+ assetManager.get({
45
+ path: heightMapURL,
46
+ type: GameAssetType.ArrayBuffer,
47
+ callback: assetObtained,
48
+ failure: reject
49
+ });
45
50
  } else {
46
- assetManager.get(heightMapURL, GameAssetType.Image, function (asset) {
47
- const image = asset.create();
51
+ assetManager.get({
52
+ path: heightMapURL, type: GameAssetType.Image, callback: function (asset) {
53
+ const image = asset.create();
48
54
 
49
- // plane
50
- const imgWidth = image.width;
51
- const imgHeight = image.height;
55
+ // plane
56
+ const imgWidth = image.width;
57
+ const imgHeight = image.height;
52
58
 
53
- const samplerHeight = rgbaData2valueSampler2D(image.data, imgWidth, imgHeight, zRange, -zRange / 2);
59
+ const samplerHeight = rgbaData2valueSampler2D(image.data, imgWidth, imgHeight, zRange, -zRange / 2);
54
60
 
55
- fulfill(samplerHeight);
56
- }, reject);
61
+ fulfill(samplerHeight);
62
+ }, failure: reject
63
+ });
57
64
  }
58
65
  });
59
66
  }
@@ -20,7 +20,7 @@ export class SplatMapping {
20
20
  * How large is the map
21
21
  * @type {Vector2}
22
22
  */
23
- this.size = new Vector2(512, 512);
23
+ this.size = new Vector2(1, 1);
24
24
 
25
25
  /**
26
26
  *
@@ -475,8 +475,9 @@ export class SplatMapping {
475
475
  * @param {number} width
476
476
  * @param {number} height
477
477
  * @param {number} depth
478
+ * @param {boolean} [keep_data]
478
479
  */
479
- resize(width, height, depth) {
480
+ resize(width, height, depth, keep_data = true) {
480
481
  const oldWidth = this.size.x;
481
482
  const oldHeight = this.size.y;
482
483
  const oldDepth = this.depth;
@@ -506,19 +507,23 @@ export class SplatMapping {
506
507
  weightImage.depth = depth;
507
508
  weightImage.data = new Uint8Array(newLayerSize * depth);
508
509
 
509
- if (oldWidth === width && oldHeight === height) {
510
- // dimensions haven't changed, we can copy data directly
511
- typed_array_copy(oldWeightData, weightImage.data);
512
- } else {
510
+ if (keep_data) {
513
511
 
514
- // different dimensions, copy layer-by-layer
515
- for (let d = 0; d < min2(depth, oldDepth); d++) {
512
+ if (oldWidth === width && oldHeight === height) {
513
+ // dimensions haven't changed, we can copy data directly
514
+ typed_array_copy(oldWeightData, weightImage.data);
515
+ } else {
516
516
 
517
- const source = new Sampler2D(oldWeightData.subarray(d * oldLayerSize, (d + 1) * oldLayerSize), 1, oldWidth, oldHeight);
518
- const target = new Sampler2D(weightImage.data.subarray(d * newLayerSize, (d + 1) * newLayerSize), 1, width, height);
517
+ // different dimensions, copy layer-by-layer
518
+ for (let d = 0; d < min2(depth, oldDepth); d++) {
519
519
 
520
- scaleSampler2D(source, target);
520
+ const source = new Sampler2D(oldWeightData.subarray(d * oldLayerSize, (d + 1) * oldLayerSize), 1, oldWidth, oldHeight);
521
+ const target = new Sampler2D(weightImage.data.subarray(d * newLayerSize, (d + 1) * newLayerSize), 1, width, height);
522
+
523
+ scaleSampler2D(source, target);
524
+ }
521
525
  }
526
+
522
527
  }
523
528
 
524
529
  weightTexture.needsUpdate = true;
@@ -164,7 +164,7 @@ export class TerrainSerializationAdapter extends BinaryClassSerializationAdapter
164
164
  const splat_size_x = buffer.readUintVar();
165
165
  const splat_size_y = buffer.readUintVar();
166
166
 
167
- value.splat.resize(splat_size_x, splat_size_y, layer_count);
167
+ value.splat.resize(splat_size_x, splat_size_y, layer_count, false);
168
168
 
169
169
  const weightData = value.splat.weightData;
170
170
 
@@ -4,25 +4,28 @@ import { Asset } from "../../../../../../../asset/Asset.js";
4
4
  import { readAnimationGraphDefinitionFromJSON } from "./readAnimationGraphDefinitionFromJSON.js";
5
5
 
6
6
  export class AnimationGraphDefinitionAssetLoader extends AssetLoader {
7
- load(path, success, failure, progress) {
7
+ load(scope, path, success, failure, progress) {
8
8
 
9
9
  this.assetManager.get(
10
- path,
11
- GameAssetType.JSON,
12
- jsonAsset => {
13
- const json = jsonAsset.create();
10
+ {
11
+ scope: scope,
12
+ path: path,
13
+ type: GameAssetType.JSON,
14
+ callback: jsonAsset => {
15
+ const json = jsonAsset.create();
14
16
 
15
- const asset = new Asset(
16
- () => {
17
- return readAnimationGraphDefinitionFromJSON(json);
18
- },
19
- 1
20
- );
17
+ const asset = new Asset(
18
+ () => {
19
+ return readAnimationGraphDefinitionFromJSON(json);
20
+ },
21
+ 1
22
+ );
21
23
 
22
- success(asset);
23
- },
24
- failure,
25
- progress
24
+ success(asset);
25
+ },
26
+ failure: failure,
27
+ progress: progress
28
+ }
26
29
  );
27
30
 
28
31
  }
@@ -427,7 +427,7 @@ export class MeshSystem extends System {
427
427
 
428
428
  } else {
429
429
  // load the asset
430
- am.get(component.url, assetType, assetLoaded, assetFailure);
430
+ am.get({ path: component.url, type: assetType, callback: assetLoaded, failure: assetFailure });
431
431
  }
432
432
  }
433
433
 
@@ -67,11 +67,13 @@ function make_material(style, am) {
67
67
 
68
68
  material_def = new MeshMatcapMaterial();
69
69
 
70
- am.get(style.material.texture, GameAssetType.Texture, asset => {
71
- material_def.matcap = asset.create();
70
+ am.get({
71
+ path: style.material.texture, type: GameAssetType.Texture, callback: asset => {
72
+ material_def.matcap = asset.create();
72
73
 
73
- material_def.needsUpdate = true;
74
- }, console.error);
74
+ material_def.needsUpdate = true;
75
+ }, failure: console.error
76
+ });
75
77
 
76
78
  } else {
77
79
  throw new Error(`Unsupported material type '${material_type}'`);
@@ -11,9 +11,11 @@ export function getTextureImmediate(url, assetManager) {
11
11
 
12
12
  let t;
13
13
 
14
- assetManager.get(url, GameAssetType.DeferredTexture, function (asset) {
15
- t = asset.create();
16
- }, noop);
14
+ assetManager.get({
15
+ path: url, type: GameAssetType.DeferredTexture, callback: function (asset) {
16
+ t = asset.create();
17
+ }, failure: noop
18
+ });
17
19
 
18
20
  return t;
19
21
  }
@@ -161,7 +161,7 @@ export class ManagedAtlas {
161
161
 
162
162
  counterLoadingAssets++;
163
163
 
164
- assetManager.get(url, GameAssetType.Image, onLoad, onFailure);
164
+ assetManager.get({ path: url, type: GameAssetType.Image, callback: onLoad, failure: onFailure });
165
165
 
166
166
  });
167
167
  }
@@ -192,8 +192,8 @@ export class Sampler2D {
192
192
  * @returns {number}
193
193
  */
194
194
  sampleChannelCatmullRomUV(u, v, channel) {
195
- const x = u * (this.width - 1);
196
- const y = v * (this.height - 1);
195
+ const x = u * (this.width) - 0.5;
196
+ const y = v * (this.height) - 0.5;
197
197
 
198
198
  return this.sampleChannelCatmullRom(x, y, channel);
199
199
  }
@@ -210,8 +210,8 @@ export class Sampler2D {
210
210
  // We're going to sample a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
211
211
  // down the sample location to get the exact center of our "starting" texel. The starting texel will be at
212
212
  // location [1, 1] in the grid, where [0, 0] is the top-left corner.
213
- const texPos1_x = Math.floor(x - 0.5) + 0.5;
214
- const texPos1_y = Math.floor(y - 0.5) + 0.5;
213
+ const texPos1_x = Math.floor(x);
214
+ const texPos1_y = Math.floor(y);
215
215
 
216
216
  // Compute the fractional offset from our starting texel to our original sample location, which we'll
217
217
  // feed into the Catmull-Rom spline function to get our filter weights.
@@ -287,8 +287,8 @@ export class Sampler2D {
287
287
  * @returns {number}
288
288
  */
289
289
  sampleChannelBicubicUV(u, v, channel) {
290
- const x = u * (this.width - 1);
291
- const y = v * (this.height - 1);
290
+ const x = u * (this.width);
291
+ const y = v * (this.height);
292
292
 
293
293
  return this.sampleChannelBicubic(x - 0.5, y - 0.5, channel);
294
294
  }
@@ -432,8 +432,8 @@ export class Sampler2D {
432
432
  * @return {number}
433
433
  */
434
434
  sampleChannelBilinearUV(u, v, channel) {
435
- const x = u * (this.width - 1);
436
- const y = v * (this.height - 1);
435
+ const x = u * this.width - 0.5;
436
+ const y = v * this.height - 0.5;
437
437
 
438
438
  return this.sampleChannelBilinear(x, y, channel);
439
439
  }
@@ -519,11 +519,20 @@ export class Sampler2D {
519
519
  return mix(s0, s1, yd);
520
520
  }
521
521
 
522
+ /**
523
+ *
524
+ * @param {number} u
525
+ * @param {number} v
526
+ * @param {ArrayLike<number>} result
527
+ */
522
528
  sampleNearestUV(u, v, result) {
523
- const x = Math.round(u * (this.width - 1));
524
- const y = Math.round(v * (this.height - 1));
529
+ const w = this.width;
530
+ const h = this.height;
531
+
532
+ const x = Math.round(u * w - 0.5);
533
+ const y = Math.round(v * h - 0.5);
525
534
 
526
- this.read(min2(x, this.width - 1), min2(y, this.height - 1), result);
535
+ this.read(clamp(x, 0, w - 1), clamp(y, 0, h - 1), result);
527
536
  }
528
537
 
529
538
  /**
@@ -4,13 +4,13 @@
4
4
  * @returns {number}
5
5
  */
6
6
  export function box(x) {
7
- if (x < -0.5) {
7
+ if (x < -1) {
8
8
  return 0;
9
9
  }
10
- if (x <= 0.5) {
10
+ if (x <= 1) {
11
11
  return 1;
12
12
  }
13
13
  return 0;
14
14
  }
15
15
 
16
- box.support = 0.5;
16
+ box.support = 1;
@@ -3,6 +3,7 @@ import { clamp } from "../../../../../core/math/clamp.js";
3
3
 
4
4
  const PI3 = 3.0 * Math.PI;
5
5
  const BESSEL_3_PI_3 = bessel_3(PI3);
6
+ const INV_BESSEL_3_PI_3 = 1 / BESSEL_3_PI_3;
6
7
 
7
8
  /**
8
9
  *
@@ -13,7 +14,7 @@ const BESSEL_3_PI_3 = bessel_3(PI3);
13
14
  export function kaiser_bessel_window(x) {
14
15
  const i = clamp(x * 0.6666666666666666, -1.0, 1.0);
15
16
  const t = Math.sqrt(1.0 - i * i);
16
- return bessel_3(PI3 * t) / BESSEL_3_PI_3;
17
+ return bessel_3(PI3 * t) * INV_BESSEL_3_PI_3;
17
18
  }
18
19
 
19
20
  kaiser_bessel_window.support = 2;
@@ -18,6 +18,7 @@ export function genericResampleSampler2D(source, target) {
18
18
  const kernel_height = max2(1, Math.ceil(v_scale));
19
19
 
20
20
  const kernel_size = kernel_width * kernel_height;
21
+ const kernel_size_inv = 1 / kernel_size;
21
22
 
22
23
  const itemSize = source.itemSize;
23
24
 
@@ -30,16 +31,15 @@ export function genericResampleSampler2D(source, target) {
30
31
  let i;
31
32
 
32
33
  for (column_index = 0; column_index < target_height; column_index++) {
34
+
35
+ const source_y = column_index * v_scale;
36
+
33
37
  for (row_index = 0; row_index < target_width; row_index++) {
34
38
 
35
39
  // figure out source offset
36
40
  const source_x = row_index * u_scale;
37
- const source_y = column_index * v_scale;
38
41
 
39
- // reset sample
40
- for (i = 0; i < itemSize; i++) {
41
- sample[i] = 0;
42
- }
42
+ const output_texel_address = (column_index * target_width + row_index) * itemSize;
43
43
 
44
44
  // accumulate kernel samples
45
45
  for (k_y = 0; k_y < kernel_height; k_y++) {
@@ -55,9 +55,10 @@ export function genericResampleSampler2D(source, target) {
55
55
 
56
56
  for (i = 0; i < itemSize; i++) {
57
57
  // dilute sample
58
- const channel_value = sample[i] / kernel_size;
59
- // write out
60
- target.data[(column_index * target_width + row_index) * itemSize + i] = channel_value;
58
+ target.data[output_texel_address + i] = sample[i] * kernel_size_inv;
59
+
60
+ //reset sample
61
+ sample[i] = 0;
61
62
  }
62
63
 
63
64
  }
@@ -13,24 +13,26 @@ import { GameAssetType } from "../../../asset/GameAssetType.js";
13
13
  */
14
14
  export default function loadSampler2D(url, assetManager) {
15
15
  return new Promise(function (resolve, reject) {
16
- assetManager.get(url, GameAssetType.Image, (asset) => {
17
- const imageData = asset.create();
16
+ assetManager.get({
17
+ path: url, type: GameAssetType.Image, callback: (asset) => {
18
+ const imageData = asset.create();
18
19
 
19
- const width = imageData.width;
20
- const height = imageData.height;
20
+ const width = imageData.width;
21
+ const height = imageData.height;
21
22
 
22
- const data = imageData.data;
23
+ const data = imageData.data;
23
24
 
24
- //
25
- const bufferSize = width * height;
26
- const buffer = new Float32Array(bufferSize);
27
- //
28
- for (let i = 0; i < bufferSize; i++) {
29
- const j = (i * 4);
30
- buffer[i] = (data[j] + data[j + 1] + data[j + 2]) / 765;
31
- }
32
- const sampler2D = new Sampler2D(buffer, 1, width, height);
33
- resolve(sampler2D);
34
- }, reject);
25
+ //
26
+ const bufferSize = width * height;
27
+ const buffer = new Float32Array(bufferSize);
28
+ //
29
+ for (let i = 0; i < bufferSize; i++) {
30
+ const j = (i * 4);
31
+ buffer[i] = (data[j] + data[j + 1] + data[j + 2]) / 765;
32
+ }
33
+ const sampler2D = new Sampler2D(buffer, 1, width, height);
34
+ resolve(sampler2D);
35
+ }, failure: reject
36
+ });
35
37
  });
36
38
  };
@@ -29,13 +29,13 @@ export function sampler2d_scale_down_linear(input, output) {
29
29
 
30
30
  const itemSize = input.itemSize;
31
31
 
32
- const sample = new Array(itemSize);
32
+ const sample = new Float64Array(itemSize);
33
33
 
34
34
  const sampleSize = sW * sH;
35
35
  const sampleSizeInv = 1 / sampleSize;
36
36
 
37
- const iData = input.data;
38
- const oData = output.data;
37
+ const input_data = input.data;
38
+ const output_data = output.data;
39
39
 
40
40
  let i, j, k;
41
41
  let x, y;
@@ -50,11 +50,6 @@ export function sampler2d_scale_down_linear(input, output) {
50
50
 
51
51
  const output_texel_address = row_address + x * itemSize;
52
52
 
53
- for (i = 0; i < itemSize; i++) {
54
- // reset sample
55
- sample[i] = 0;
56
- }
57
-
58
53
  const sampleOffsetX = x * sW;
59
54
 
60
55
  // accumulate sample
@@ -67,15 +62,17 @@ export function sampler2d_scale_down_linear(input, output) {
67
62
  const iAddress = (texel_offset + i) * itemSize;
68
63
 
69
64
  for (k = 0; k < itemSize; k++) {
70
- sample[k] += iData[k + iAddress];
65
+ sample[k] += input_data[k + iAddress];
71
66
  }
72
67
 
73
68
  }
74
69
  }
75
70
 
76
- // dilute the sample
77
71
  for (i = 0; i < itemSize; i++) {
78
- oData[output_texel_address + i] = sample[i] * sampleSizeInv;
72
+ // dilute the sample
73
+ output_data[output_texel_address + i] = sample[i] * sampleSizeInv;
74
+ //reset sample
75
+ sample[i] = 0;
79
76
  }
80
77
 
81
78
 
@@ -147,7 +147,7 @@ export class TileLoader {
147
147
  }
148
148
 
149
149
  //do load
150
- this.assetManager.get('image', url, success, failure);
150
+ this.assetManager.get({ path: 'image', type: url, callback: success, failure: failure });
151
151
  }
152
152
 
153
153
  /**
@@ -115,9 +115,11 @@ export class RibbonXPlugin extends EnginePlugin {
115
115
  if (spec.diffuse !== null) {
116
116
  const am = this.engine.assetManager;
117
117
 
118
- am.get(spec.diffuse, GameAssetType.Texture, (asset) => {
119
- material.uniforms.uDiffuse.value = asset.create();
120
- }, console.warn);
118
+ am.get({
119
+ path: spec.diffuse, type: GameAssetType.Texture, callback: (asset) => {
120
+ material.uniforms.uDiffuse.value = asset.create();
121
+ }, failure: console.warn
122
+ });
121
123
 
122
124
  material.defines.USE_TEXTURE = true;
123
125
  }
@@ -116,7 +116,7 @@ export class StaticKnowledgeDataTable {
116
116
  * @returns {T|null}
117
117
  */
118
118
  get(id) {
119
- assert.typeOf(id, 'string', 'id');
119
+ assert.isString(id, 'id');
120
120
 
121
121
  const element = this.elements[id];
122
122
 
@@ -37,5 +37,5 @@ export function loadSoundTrackAsset(track, assetManager, resolve = noop, reject
37
37
  asset_path = track_url;
38
38
  }
39
39
 
40
- assetManager.get(asset_path, GameAssetType.Sound, resolve, reject);
40
+ assetManager.get({ path: asset_path, type: GameAssetType.Sound, callback: resolve, failure: reject });
41
41
  }