@woosh/meep-engine 2.100.0 → 2.100.2

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 (58) hide show
  1. package/build/meep.cjs +574 -19
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +574 -19
  4. package/package.json +1 -1
  5. package/src/core/color/Color.d.ts.map +1 -1
  6. package/src/core/color/Color.js +39 -8
  7. package/src/core/color/oklab/Okhsv.spec.d.ts +2 -0
  8. package/src/core/color/oklab/Okhsv.spec.d.ts.map +1 -0
  9. package/src/core/color/oklab/Okhsv.spec.js +17 -0
  10. package/src/core/color/oklab/XYZ.spec.js +2 -2
  11. package/src/core/color/oklab/compute_max_saturation.d.ts +11 -0
  12. package/src/core/color/oklab/compute_max_saturation.d.ts.map +1 -0
  13. package/src/core/color/oklab/compute_max_saturation.js +84 -0
  14. package/src/core/color/oklab/find_cusp.d.ts +10 -0
  15. package/src/core/color/oklab/find_cusp.d.ts.map +1 -0
  16. package/src/core/color/oklab/find_cusp.js +27 -0
  17. package/src/core/color/oklab/find_gamut_intersection.d.ts +15 -0
  18. package/src/core/color/oklab/find_gamut_intersection.d.ts.map +1 -0
  19. package/src/core/color/oklab/find_gamut_intersection.js +101 -0
  20. package/src/core/color/oklab/linear_srgb_to_okhsv.d.ts +9 -0
  21. package/src/core/color/oklab/linear_srgb_to_okhsv.d.ts.map +1 -0
  22. package/src/core/color/oklab/linear_srgb_to_okhsv.js +74 -0
  23. package/src/core/color/oklab/linear_srgb_to_oklab.d.ts +9 -0
  24. package/src/core/color/oklab/linear_srgb_to_oklab.d.ts.map +1 -0
  25. package/src/core/color/oklab/linear_srgb_to_oklab.js +20 -0
  26. package/src/core/color/oklab/okhsv_to_linear_srgb.d.ts +9 -0
  27. package/src/core/color/oklab/okhsv_to_linear_srgb.d.ts.map +1 -0
  28. package/src/core/color/oklab/okhsv_to_linear_srgb.js +59 -0
  29. package/src/core/color/oklab/oklab_to_linear_srgb.d.ts +10 -0
  30. package/src/core/color/oklab/oklab_to_linear_srgb.d.ts.map +1 -0
  31. package/src/core/color/oklab/oklab_to_linear_srgb.js +21 -0
  32. package/src/core/color/oklab/oklab_to_xyz.d.ts +5 -2
  33. package/src/core/color/oklab/oklab_to_xyz.d.ts.map +1 -1
  34. package/src/core/color/oklab/oklab_to_xyz.js +5 -5
  35. package/src/core/color/oklab/oklab_to_xyz.spec.js +4 -4
  36. package/src/core/color/oklab/toe.d.ts +13 -0
  37. package/src/core/color/oklab/toe.d.ts.map +1 -0
  38. package/src/core/color/oklab/toe.js +22 -0
  39. package/src/core/color/oklab/xyz_to_oklab.d.ts +5 -2
  40. package/src/core/color/oklab/xyz_to_oklab.d.ts.map +1 -1
  41. package/src/core/color/oklab/xyz_to_oklab.js +5 -5
  42. package/src/core/color/oklab/xyz_to_oklab.spec.js +4 -4
  43. package/src/engine/animation/async/prototypeAsyncAnimation.d.ts +2 -0
  44. package/src/engine/animation/async/prototypeAsyncAnimation.d.ts.map +1 -0
  45. package/src/engine/animation/async/prototypeAsyncAnimation.js +344 -0
  46. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  47. package/src/engine/asset/AssetManager.js +17 -0
  48. package/src/engine/asset/loaders/ArrayBufferLoader.d.ts.map +1 -1
  49. package/src/engine/asset/loaders/ArrayBufferLoader.js +22 -2
  50. package/src/engine/ecs/Entity.d.ts.map +1 -1
  51. package/src/engine/ecs/Entity.js +1 -0
  52. package/src/engine/ecs/terrain/ecs/TerrainSystem.d.ts.map +1 -1
  53. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +3 -3
  54. package/src/engine/input/ecs/systems/InputControllerSystem.d.ts.map +1 -1
  55. package/src/engine/input/ecs/systems/InputControllerSystem.js +4 -8
  56. package/src/engine/intelligence/behavior/util/RandomDelayBehavior.d.ts +46 -0
  57. package/src/engine/intelligence/behavior/util/RandomDelayBehavior.d.ts.map +1 -0
  58. package/src/engine/intelligence/behavior/util/RandomDelayBehavior.js +85 -0
package/build/meep.cjs CHANGED
@@ -41386,6 +41386,133 @@ class FileLoader extends Loader {
41386
41386
 
41387
41387
  }
41388
41388
 
41389
+ /**
41390
+ * Abstract Base class to block based textures loader (dds, pvr, ...)
41391
+ *
41392
+ * Sub classes have to implement the parse() method which will be used in load().
41393
+ */
41394
+
41395
+ class CompressedTextureLoader extends Loader {
41396
+
41397
+ constructor( manager ) {
41398
+
41399
+ super( manager );
41400
+
41401
+ }
41402
+
41403
+ load( url, onLoad, onProgress, onError ) {
41404
+
41405
+ const scope = this;
41406
+
41407
+ const images = [];
41408
+
41409
+ const texture = new CompressedTexture();
41410
+
41411
+ const loader = new FileLoader( this.manager );
41412
+ loader.setPath( this.path );
41413
+ loader.setResponseType( 'arraybuffer' );
41414
+ loader.setRequestHeader( this.requestHeader );
41415
+ loader.setWithCredentials( scope.withCredentials );
41416
+
41417
+ let loaded = 0;
41418
+
41419
+ function loadTexture( i ) {
41420
+
41421
+ loader.load( url[ i ], function ( buffer ) {
41422
+
41423
+ const texDatas = scope.parse( buffer, true );
41424
+
41425
+ images[ i ] = {
41426
+ width: texDatas.width,
41427
+ height: texDatas.height,
41428
+ format: texDatas.format,
41429
+ mipmaps: texDatas.mipmaps
41430
+ };
41431
+
41432
+ loaded += 1;
41433
+
41434
+ if ( loaded === 6 ) {
41435
+
41436
+ if ( texDatas.mipmapCount === 1 ) texture.minFilter = LinearFilter;
41437
+
41438
+ texture.image = images;
41439
+ texture.format = texDatas.format;
41440
+ texture.needsUpdate = true;
41441
+
41442
+ if ( onLoad ) onLoad( texture );
41443
+
41444
+ }
41445
+
41446
+ }, onProgress, onError );
41447
+
41448
+ }
41449
+
41450
+ if ( Array.isArray( url ) ) {
41451
+
41452
+ for ( let i = 0, il = url.length; i < il; ++ i ) {
41453
+
41454
+ loadTexture( i );
41455
+
41456
+ }
41457
+
41458
+ } else {
41459
+
41460
+ // compressed cubemap texture stored in a single DDS file
41461
+
41462
+ loader.load( url, function ( buffer ) {
41463
+
41464
+ const texDatas = scope.parse( buffer, true );
41465
+
41466
+ if ( texDatas.isCubemap ) {
41467
+
41468
+ const faces = texDatas.mipmaps.length / texDatas.mipmapCount;
41469
+
41470
+ for ( let f = 0; f < faces; f ++ ) {
41471
+
41472
+ images[ f ] = { mipmaps: [] };
41473
+
41474
+ for ( let i = 0; i < texDatas.mipmapCount; i ++ ) {
41475
+
41476
+ images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
41477
+ images[ f ].format = texDatas.format;
41478
+ images[ f ].width = texDatas.width;
41479
+ images[ f ].height = texDatas.height;
41480
+
41481
+ }
41482
+
41483
+ }
41484
+
41485
+ texture.image = images;
41486
+
41487
+ } else {
41488
+
41489
+ texture.image.width = texDatas.width;
41490
+ texture.image.height = texDatas.height;
41491
+ texture.mipmaps = texDatas.mipmaps;
41492
+
41493
+ }
41494
+
41495
+ if ( texDatas.mipmapCount === 1 ) {
41496
+
41497
+ texture.minFilter = LinearFilter;
41498
+
41499
+ }
41500
+
41501
+ texture.format = texDatas.format;
41502
+ texture.needsUpdate = true;
41503
+
41504
+ if ( onLoad ) onLoad( texture );
41505
+
41506
+ }, onProgress, onError );
41507
+
41508
+ }
41509
+
41510
+ return texture;
41511
+
41512
+ }
41513
+
41514
+ }
41515
+
41389
41516
  class ImageLoader extends Loader {
41390
41517
 
41391
41518
  constructor( manager ) {
@@ -53661,14 +53788,15 @@ function sRGB_to_linear(
53661
53788
  }
53662
53789
 
53663
53790
  /**
53791
+ * @extends {Array.<number>}
53664
53792
  * @class
53665
53793
  */
53666
53794
  class Color {
53667
53795
  /**
53668
53796
  *
53669
- * @param {number} r value from 0 to 1
53670
- * @param {number} g value from 0 to 1
53671
- * @param {number} b value from 0 to 1
53797
+ * @param {number} [r] Red from 0 to 1
53798
+ * @param {number} [g] Green from 0 to 1
53799
+ * @param {number} [b] Blue from 0 to 1
53672
53800
  * @param {number} [a] value from 0 to 1 Alpha channel (transparency)
53673
53801
  */
53674
53802
  constructor(r = 0, g = 0, b = 0, a = 1) {
@@ -53788,6 +53916,20 @@ class Color {
53788
53916
  this.set(r, g, b, this.a);
53789
53917
  }
53790
53918
 
53919
+ /**
53920
+ *
53921
+ * @param {number} r
53922
+ * @param {number} g
53923
+ * @param {number} b
53924
+ */
53925
+ setRGBUint8(r, g, b) {
53926
+ this.setRGB(
53927
+ uint82float(r),
53928
+ uint82float(g),
53929
+ uint82float(b),
53930
+ );
53931
+ }
53932
+
53791
53933
  /**
53792
53934
  * set alpha
53793
53935
  * @param {number} a
@@ -53805,11 +53947,23 @@ class Color {
53805
53947
  */
53806
53948
  set(r, g, b, a) {
53807
53949
 
53950
+ // remember old values
53808
53951
  const _r = this.r;
53809
53952
  const _g = this.g;
53810
53953
  const _b = this.b;
53811
53954
  const _a = this.a;
53812
53955
 
53956
+ if (
53957
+ _r === r
53958
+ && _g === g
53959
+ && _b === b
53960
+ && _a === a
53961
+ ) {
53962
+ // no change
53963
+ return;
53964
+ }
53965
+
53966
+ // set new values
53813
53967
  this.r = r;
53814
53968
  this.g = g;
53815
53969
  this.b = b;
@@ -54051,7 +54205,7 @@ class Color {
54051
54205
  const g = (value >> 8) & 0xFF;
54052
54206
  const b = (value) & 0xFF;
54053
54207
 
54054
- this.setRGB(r / 255, g / 255, b / 255);
54208
+ this.setRGBUint8(r, g, b);
54055
54209
  }
54056
54210
 
54057
54211
  /**
@@ -54116,8 +54270,7 @@ class Color {
54116
54270
  }
54117
54271
 
54118
54272
  fromJSON({ r, g, b, a = 1 }) {
54119
- this.setRGB(r, g, b);
54120
- this.a = a;
54273
+ this.set(r, g, b, a);
54121
54274
  }
54122
54275
 
54123
54276
  toJSON() {
@@ -54171,8 +54324,7 @@ class Color {
54171
54324
  const b = buffer.readFloat32();
54172
54325
  const a = buffer.readFloat32();
54173
54326
 
54174
- this.setRGB(r, g, b);
54175
- this.a = a;
54327
+ this.set(r, g, b, a);
54176
54328
  }
54177
54329
 
54178
54330
  /**
@@ -67675,13 +67827,17 @@ class ArrayBufferLoader extends AssetLoader {
67675
67827
 
67676
67828
  }
67677
67829
 
67830
+ /**
67831
+ * @type {ReadableStreamDefaultReader<Uint8Array>}
67832
+ */
67678
67833
  const reader = response.body.getReader();
67834
+
67679
67835
  const contentLength = response.headers.get('Content-Length');
67680
67836
  const total = contentLength ? parseInt(contentLength) : 0;
67681
67837
  let loaded = 0;
67682
67838
 
67683
67839
  // periodically read data into the new stream tracking while download progress
67684
- const stream = new ReadableStream({
67840
+ const stream_prototype = {
67685
67841
  type: "bytes",
67686
67842
  start(controller) {
67687
67843
 
@@ -67710,7 +67866,22 @@ class ArrayBufferLoader extends AssetLoader {
67710
67866
 
67711
67867
  }
67712
67868
 
67713
- });
67869
+ };
67870
+
67871
+ /**
67872
+ * @type {ReadableStream}
67873
+ */
67874
+ let stream;
67875
+
67876
+ try {
67877
+ stream = new ReadableStream(stream_prototype);
67878
+ } catch (e) {
67879
+ /*
67880
+ Workaround for Safari bug: "TypeError: ReadableByteStreamController is not implemented"
67881
+ By not wrapping the response we lose the ability to track progress, but that's not a critical issue in most cases
67882
+ */
67883
+ return response;
67884
+ }
67714
67885
 
67715
67886
  return new Response(stream);
67716
67887
  }
@@ -68176,6 +68347,377 @@ class ImageRGBADataLoader extends AssetLoader {
68176
68347
  }
68177
68348
  }
68178
68349
 
68350
+ class DDSLoader extends CompressedTextureLoader {
68351
+
68352
+ constructor( manager ) {
68353
+
68354
+ super( manager );
68355
+
68356
+ }
68357
+
68358
+ parse( buffer, loadMipmaps ) {
68359
+
68360
+ const dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
68361
+
68362
+ // Adapted from @toji's DDS utils
68363
+ // https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
68364
+
68365
+ // All values and structures referenced from:
68366
+ // http://msdn.microsoft.com/en-us/library/bb943991.aspx/
68367
+
68368
+ const DDS_MAGIC = 0x20534444;
68369
+
68370
+ // let DDSD_CAPS = 0x1;
68371
+ // let DDSD_HEIGHT = 0x2;
68372
+ // let DDSD_WIDTH = 0x4;
68373
+ // let DDSD_PITCH = 0x8;
68374
+ // let DDSD_PIXELFORMAT = 0x1000;
68375
+ const DDSD_MIPMAPCOUNT = 0x20000;
68376
+ // let DDSD_LINEARSIZE = 0x80000;
68377
+ // let DDSD_DEPTH = 0x800000;
68378
+
68379
+ // let DDSCAPS_COMPLEX = 0x8;
68380
+ // let DDSCAPS_MIPMAP = 0x400000;
68381
+ // let DDSCAPS_TEXTURE = 0x1000;
68382
+
68383
+ const DDSCAPS2_CUBEMAP = 0x200;
68384
+ const DDSCAPS2_CUBEMAP_POSITIVEX = 0x400;
68385
+ const DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800;
68386
+ const DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000;
68387
+ const DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000;
68388
+ const DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000;
68389
+ const DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000;
68390
+ // let DDSCAPS2_VOLUME = 0x200000;
68391
+
68392
+ // let DDPF_ALPHAPIXELS = 0x1;
68393
+ // let DDPF_ALPHA = 0x2;
68394
+ const DDPF_FOURCC = 0x4;
68395
+ // let DDPF_RGB = 0x40;
68396
+ // let DDPF_YUV = 0x200;
68397
+ // let DDPF_LUMINANCE = 0x20000;
68398
+
68399
+ function fourCCToInt32( value ) {
68400
+
68401
+ return value.charCodeAt( 0 ) +
68402
+ ( value.charCodeAt( 1 ) << 8 ) +
68403
+ ( value.charCodeAt( 2 ) << 16 ) +
68404
+ ( value.charCodeAt( 3 ) << 24 );
68405
+
68406
+ }
68407
+
68408
+ function loadARGBMip( buffer, dataOffset, width, height ) {
68409
+
68410
+ const dataLength = width * height * 4;
68411
+ const srcBuffer = new Uint8Array( buffer, dataOffset, dataLength );
68412
+ const byteArray = new Uint8Array( dataLength );
68413
+ let dst = 0;
68414
+ let src = 0;
68415
+ for ( let y = 0; y < height; y ++ ) {
68416
+
68417
+ for ( let x = 0; x < width; x ++ ) {
68418
+
68419
+ const b = srcBuffer[ src ]; src ++;
68420
+ const g = srcBuffer[ src ]; src ++;
68421
+ const r = srcBuffer[ src ]; src ++;
68422
+ const a = srcBuffer[ src ]; src ++;
68423
+ byteArray[ dst ] = r; dst ++; //r
68424
+ byteArray[ dst ] = g; dst ++; //g
68425
+ byteArray[ dst ] = b; dst ++; //b
68426
+ byteArray[ dst ] = a; dst ++; //a
68427
+
68428
+ }
68429
+
68430
+ }
68431
+
68432
+ return byteArray;
68433
+
68434
+ }
68435
+
68436
+ const FOURCC_DXT1 = fourCCToInt32( 'DXT1' );
68437
+ const FOURCC_DXT3 = fourCCToInt32( 'DXT3' );
68438
+ const FOURCC_DXT5 = fourCCToInt32( 'DXT5' );
68439
+ const FOURCC_ETC1 = fourCCToInt32( 'ETC1' );
68440
+
68441
+ const headerLengthInt = 31; // The header length in 32 bit ints
68442
+
68443
+ // Offsets into the header array
68444
+
68445
+ const off_magic = 0;
68446
+
68447
+ const off_size = 1;
68448
+ const off_flags = 2;
68449
+ const off_height = 3;
68450
+ const off_width = 4;
68451
+
68452
+ const off_mipmapCount = 7;
68453
+
68454
+ const off_pfFlags = 20;
68455
+ const off_pfFourCC = 21;
68456
+ const off_RGBBitCount = 22;
68457
+ const off_RBitMask = 23;
68458
+ const off_GBitMask = 24;
68459
+ const off_BBitMask = 25;
68460
+ const off_ABitMask = 26;
68461
+
68462
+ // let off_caps = 27;
68463
+ const off_caps2 = 28;
68464
+ // let off_caps3 = 29;
68465
+ // let off_caps4 = 30;
68466
+
68467
+ // Parse header
68468
+
68469
+ const header = new Int32Array( buffer, 0, headerLengthInt );
68470
+
68471
+ if ( header[ off_magic ] !== DDS_MAGIC ) {
68472
+ return dds;
68473
+
68474
+ }
68475
+
68476
+ if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
68477
+ return dds;
68478
+
68479
+ }
68480
+
68481
+ let blockBytes;
68482
+
68483
+ const fourCC = header[ off_pfFourCC ];
68484
+
68485
+ let isRGBAUncompressed = false;
68486
+
68487
+ switch ( fourCC ) {
68488
+
68489
+ case FOURCC_DXT1:
68490
+
68491
+ blockBytes = 8;
68492
+ dds.format = RGB_S3TC_DXT1_Format;
68493
+ break;
68494
+
68495
+ case FOURCC_DXT3:
68496
+
68497
+ blockBytes = 16;
68498
+ dds.format = RGBA_S3TC_DXT3_Format;
68499
+ break;
68500
+
68501
+ case FOURCC_DXT5:
68502
+
68503
+ blockBytes = 16;
68504
+ dds.format = RGBA_S3TC_DXT5_Format;
68505
+ break;
68506
+
68507
+ case FOURCC_ETC1:
68508
+
68509
+ blockBytes = 8;
68510
+ dds.format = RGB_ETC1_Format;
68511
+ break;
68512
+
68513
+ default:
68514
+
68515
+ if ( header[ off_RGBBitCount ] === 32
68516
+ && header[ off_RBitMask ] & 0xff0000
68517
+ && header[ off_GBitMask ] & 0xff00
68518
+ && header[ off_BBitMask ] & 0xff
68519
+ && header[ off_ABitMask ] & 0xff000000 ) {
68520
+
68521
+ isRGBAUncompressed = true;
68522
+ blockBytes = 64;
68523
+ dds.format = RGBAFormat;
68524
+
68525
+ } else {
68526
+ return dds;
68527
+
68528
+ }
68529
+
68530
+ }
68531
+
68532
+ dds.mipmapCount = 1;
68533
+
68534
+ if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
68535
+
68536
+ dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
68537
+
68538
+ }
68539
+
68540
+ const caps2 = header[ off_caps2 ];
68541
+ dds.isCubemap = caps2 & DDSCAPS2_CUBEMAP ? true : false;
68542
+ if ( dds.isCubemap && (
68543
+ ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEX ) ||
68544
+ ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX ) ||
68545
+ ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEY ) ||
68546
+ ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY ) ||
68547
+ ! ( caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ ) ||
68548
+ ! ( caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ )
68549
+ ) ) {
68550
+ return dds;
68551
+
68552
+ }
68553
+
68554
+ dds.width = header[ off_width ];
68555
+ dds.height = header[ off_height ];
68556
+
68557
+ let dataOffset = header[ off_size ] + 4;
68558
+
68559
+ // Extract mipmaps buffers
68560
+
68561
+ const faces = dds.isCubemap ? 6 : 1;
68562
+
68563
+ for ( let face = 0; face < faces; face ++ ) {
68564
+
68565
+ let width = dds.width;
68566
+ let height = dds.height;
68567
+
68568
+ for ( let i = 0; i < dds.mipmapCount; i ++ ) {
68569
+
68570
+ let byteArray, dataLength;
68571
+
68572
+ if ( isRGBAUncompressed ) {
68573
+
68574
+ byteArray = loadARGBMip( buffer, dataOffset, width, height );
68575
+ dataLength = byteArray.length;
68576
+
68577
+ } else {
68578
+
68579
+ dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
68580
+ byteArray = new Uint8Array( buffer, dataOffset, dataLength );
68581
+
68582
+ }
68583
+
68584
+ const mipmap = { 'data': byteArray, 'width': width, 'height': height };
68585
+ dds.mipmaps.push( mipmap );
68586
+
68587
+ dataOffset += dataLength;
68588
+
68589
+ width = Math.max( width >> 1, 1 );
68590
+ height = Math.max( height >> 1, 1 );
68591
+
68592
+ }
68593
+
68594
+ }
68595
+
68596
+ return dds;
68597
+
68598
+ }
68599
+
68600
+ }
68601
+
68602
+ /**
68603
+ *
68604
+ * @param {Texture} t
68605
+ * @returns {Texture}
68606
+ */
68607
+ function cloneTexture(t) {
68608
+ const clone = t.clone();
68609
+
68610
+ //apparently cloned textures need this trick to work
68611
+ clone.needsUpdate = true;
68612
+
68613
+ return clone;
68614
+ }
68615
+
68616
+ function loadDDSTexture(path, success, failure, progress) {
68617
+ function computeByteSize(texture) {
68618
+ let result = 0;
68619
+ const images = texture.image;
68620
+ for (let i = 0; i < images.length; i++) {
68621
+ const image = images[i];
68622
+ const mipmaps = image.mipmaps;
68623
+ for (let j = 0; j < mipmaps.length; j++) {
68624
+ const mipmap = mipmaps[j];
68625
+ /**
68626
+ * @type {Uint8Array}
68627
+ */
68628
+ const data = mipmap.data;
68629
+ result += data.length;
68630
+ }
68631
+ }
68632
+ return result;
68633
+ }
68634
+
68635
+ const loader = new DDSLoader();
68636
+ loader.load(path, function (texture) {
68637
+ const byteSize = computeByteSize(texture);
68638
+
68639
+ function factory() {
68640
+ return cloneTexture(texture);
68641
+ }
68642
+
68643
+ const asset = new Asset(factory, byteSize);
68644
+
68645
+ success(asset);
68646
+
68647
+ }, progress, failure);
68648
+ }
68649
+
68650
+ const textureLoader = new TextureLoader();
68651
+
68652
+ /**
68653
+ *
68654
+ * @param {Texture} texture
68655
+ * @return {number}
68656
+ */
68657
+ function computeTextureByteSize(texture) {
68658
+ const image = texture.image;
68659
+ if (image instanceof ImageData) {
68660
+ return image.array.length;
68661
+ } else {
68662
+ //TODO do actual computation
68663
+ //don't know
68664
+ return 1;
68665
+ }
68666
+ }
68667
+ function loadStandardImageTexture(path, success, failure, progress) {
68668
+
68669
+
68670
+
68671
+ textureLoader.load(path, function (texture) {
68672
+
68673
+ texture.flipY = false;
68674
+
68675
+ const byteSize = computeTextureByteSize(texture);
68676
+
68677
+ const asset = new Asset(function () {
68678
+ return cloneTexture(texture);
68679
+ }, byteSize);
68680
+
68681
+ success(asset);
68682
+ }, progress, failure);
68683
+ }
68684
+
68685
+ class TextureAssetLoader extends AssetLoader {
68686
+ load(scope, path, success, failure, progress) {
68687
+ //figure out what kind of a texture it is
68688
+ let fileExtension = computeFileExtension(path);
68689
+
68690
+ if (fileExtension === null) {
68691
+ //check if it's a data path
68692
+
68693
+ const match = path.match(/^data\:image\/([a-zA-Z0-9]+)\;/);
68694
+
68695
+ if (match === null) {
68696
+ throw new Error(`no file extension on path '${path}'`);
68697
+
68698
+ } else {
68699
+ //seems ok
68700
+ fileExtension = match[1];
68701
+ }
68702
+
68703
+ }
68704
+
68705
+ const lowerCaseExtension = fileExtension.toLowerCase();
68706
+ switch (lowerCaseExtension) {
68707
+ case 'dds':
68708
+ loadDDSTexture(path, success, failure, progress);
68709
+ break;
68710
+ case 'png':
68711
+ case 'jpg':
68712
+ loadStandardImageTexture(path, success, failure, progress);
68713
+ break;
68714
+ default:
68715
+ throw new Error(`Unsupported texture file format: '${lowerCaseExtension}'`);
68716
+
68717
+ }
68718
+ }
68719
+ }
68720
+
68179
68721
  /**
68180
68722
  * Utility class for managing connection between listeners to signals
68181
68723
  */
@@ -69746,9 +70288,8 @@ class TerrainSystem extends System {
69746
70288
 
69747
70289
  const am = this.assetManager;
69748
70290
 
69749
- if (!am.hasLoaderForType('image')) {
69750
- await am.registerLoader('image', new ImageRGBADataLoader());
69751
- }
70291
+ await am.tryRegisterLoader('image', new ImageRGBADataLoader());
70292
+ await am.tryRegisterLoader('texture', new TextureAssetLoader());
69752
70293
 
69753
70294
  readyCallback();
69754
70295
  }
@@ -72775,6 +73316,7 @@ class Entity {
72775
73316
 
72776
73317
  /**
72777
73318
  * Similar to {@link #getComponent}, instead of returning null - throws an exception
73319
+ * @template T
72778
73320
  * @param {Class<T>} klass
72779
73321
  * @returns {T}
72780
73322
  */
@@ -85825,6 +86367,23 @@ class AssetManager {
85825
86367
  return true;
85826
86368
  }
85827
86369
 
86370
+ /**
86371
+ * Will register loader only if none exists for this type
86372
+ * @template T
86373
+ * @param {string} type
86374
+ * @param {AssetLoader<T>} loader
86375
+ * @returns {Promise<boolean>} true if registered , false otherwise
86376
+ */
86377
+ async tryRegisterLoader(type, loader) {
86378
+ if (this.hasLoaderForType(type)) {
86379
+ return false;
86380
+ }
86381
+
86382
+ await this.registerLoader(type, loader);
86383
+
86384
+ return true;
86385
+ }
86386
+
85828
86387
  /**
85829
86388
  * @template T
85830
86389
  * @param {string} type
@@ -114122,12 +114681,8 @@ function getOrCreateProxy(proxies, path, signal) {
114122
114681
  * @param {InputControllerBinding} binding
114123
114682
  */
114124
114683
  Proxy.prototype.add = function (binding) {
114125
- if (this.signal.isDispatching()) {
114126
- // handler is currently running, adding the binding could trigger it immediately. Deferring the registration allows us to avoid this
114127
- this.deferred.push(binding);
114128
- } else {
114129
- this.registerBinding(binding);
114130
- }
114684
+ //TODO handle case where binding is added mid-dispatch
114685
+ this.registerBinding(binding);
114131
114686
  };
114132
114687
 
114133
114688
  /**