@woosh/meep-engine 2.97.0 → 2.98.0

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 (122) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/build/meep.cjs +828 -660
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +828 -660
  5. package/package.json +1 -1
  6. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +1 -1
  7. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +1 -1
  8. package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray.d.ts.map +1 -1
  9. package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray.js +3 -2
  10. package/src/core/collection/array/arrayQuickSort.js +2 -2
  11. package/src/core/collection/array/array_compute_max.d.ts +9 -0
  12. package/src/core/collection/array/array_compute_max.d.ts.map +1 -0
  13. package/src/core/collection/array/{computeArrayMax.js → array_compute_max.js} +1 -1
  14. package/src/core/collection/array/array_compute_min.d.ts +9 -0
  15. package/src/core/collection/array/array_compute_min.d.ts.map +1 -0
  16. package/src/core/collection/array/{computeArrayMin.js → array_compute_min.js} +1 -1
  17. package/src/core/collection/array/array_compute_min_max.d.ts.map +1 -1
  18. package/src/core/collection/array/array_compute_min_max.js +1 -0
  19. package/src/core/collection/array/array_swap.d.ts.map +1 -1
  20. package/src/core/collection/array/array_swap.js +11 -8
  21. package/src/core/collection/array/array_swap_one.d.ts +8 -0
  22. package/src/core/collection/array/array_swap_one.d.ts.map +1 -0
  23. package/src/core/collection/array/{arraySwapElements.js → array_swap_one.js} +1 -1
  24. package/src/core/collection/array/iterator/AbstractArrayIterator.d.ts.map +1 -0
  25. package/src/core/collection/array/iterator/ArrayIteratorRandom.d.ts.map +1 -0
  26. package/src/core/collection/array/{ArrayIteratorRandom.js → iterator/ArrayIteratorRandom.js} +2 -2
  27. package/src/core/collection/array/iterator/ArrayIteratorSequential.d.ts.map +1 -0
  28. package/src/core/collection/array/randomizeArrayElementOrder.js +2 -2
  29. package/src/core/collection/map/HashMap.js +10 -10
  30. package/src/core/collection/map/ObservedMap.d.ts +7 -4
  31. package/src/core/collection/map/ObservedMap.d.ts.map +1 -1
  32. package/src/core/collection/map/ObservedMap.js +4 -1
  33. package/src/core/collection/queue/Deque.d.ts.map +1 -1
  34. package/src/core/collection/queue/Deque.js +82 -36
  35. package/src/core/geom/3d/aabb/aabb3_intersects_ray.js +10 -10
  36. package/src/core/parser/simple/ParserError.d.ts +11 -6
  37. package/src/core/parser/simple/ParserError.d.ts.map +1 -1
  38. package/src/core/parser/simple/ParserError.js +51 -4
  39. package/src/core/parser/simple/Token.d.ts.map +1 -1
  40. package/src/core/parser/simple/Token.js +8 -2
  41. package/src/core/parser/simple/TokenType.d.ts +1 -5
  42. package/src/core/parser/simple/TokenType.d.ts.map +1 -1
  43. package/src/core/parser/simple/TokenType.js +1 -1
  44. package/src/core/parser/simple/readBooleanToken.d.ts.map +1 -1
  45. package/src/core/parser/simple/readBooleanToken.js +6 -1
  46. package/src/core/parser/simple/readHexToken.d.ts.map +1 -1
  47. package/src/core/parser/simple/readHexToken.js +7 -2
  48. package/src/core/parser/simple/readIdentifierToken.d.ts.map +1 -1
  49. package/src/core/parser/simple/readIdentifierToken.js +6 -1
  50. package/src/core/parser/simple/readLiteralToken.d.ts.map +1 -1
  51. package/src/core/parser/simple/readLiteralToken.js +8 -3
  52. package/src/core/parser/simple/readNumberToken.d.ts.map +1 -1
  53. package/src/core/parser/simple/readNumberToken.js +7 -2
  54. package/src/core/parser/simple/readReferenceToken.d.ts.map +1 -1
  55. package/src/core/parser/simple/readReferenceToken.js +6 -1
  56. package/src/core/parser/simple/readStringToken.d.ts.map +1 -1
  57. package/src/core/parser/simple/readStringToken.js +6 -1
  58. package/src/core/parser/simple/readUnsignedIntegerToken.d.ts.map +1 -1
  59. package/src/core/parser/simple/readUnsignedIntegerToken.js +7 -2
  60. package/src/core/parser/simple/skipWhitespace.d.ts.map +1 -1
  61. package/src/core/parser/simple/skipWhitespace.js +8 -0
  62. package/src/core/primitives/strings/string_repeat.d.ts +9 -0
  63. package/src/core/primitives/strings/string_repeat.d.ts.map +1 -0
  64. package/src/core/primitives/strings/string_repeat.js +26 -0
  65. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  66. package/src/engine/development/performance/RingBufferMetric.d.ts.map +1 -1
  67. package/src/engine/development/performance/RingBufferMetric.js +5 -5
  68. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts.map +1 -1
  69. package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +15 -22
  70. package/src/engine/graphics/ecs/camera/Camera.d.ts.map +1 -1
  71. package/src/engine/graphics/ecs/camera/Camera.js +23 -16
  72. package/src/engine/graphics/filter/ImageFilter.d.ts +2 -2
  73. package/src/engine/graphics/filter/ImageFilter.d.ts.map +1 -1
  74. package/src/engine/graphics/filter/ImageFilter.js +3 -3
  75. package/src/engine/graphics/render/RendererPool.d.ts +14 -1
  76. package/src/engine/graphics/render/RendererPool.d.ts.map +1 -1
  77. package/src/engine/graphics/render/RendererPool.js +43 -1
  78. package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
  79. package/src/engine/graphics/sh3/path_tracer/PathTracer.d.ts +2 -1
  80. package/src/engine/graphics/sh3/path_tracer/PathTracer.d.ts.map +1 -1
  81. package/src/engine/graphics/sh3/path_tracer/PathTracer.js +23 -50
  82. package/src/engine/graphics/sh3/path_tracer/getBiasedNormalSample.d.ts +9 -0
  83. package/src/engine/graphics/sh3/path_tracer/getBiasedNormalSample.d.ts.map +1 -1
  84. package/src/engine/graphics/sh3/path_tracer/getBiasedNormalSample.js +53 -3
  85. package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +3 -3
  86. package/src/engine/graphics/texture/sampler/convertTexture2Sampler2D.d.ts +1 -1
  87. package/src/engine/graphics/texture/sampler/convertTexture2Sampler2D.d.ts.map +1 -1
  88. package/src/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +42 -36
  89. package/src/engine/graphics/texture/sampler/debug/debug_draw_sampler.d.ts +3 -0
  90. package/src/engine/graphics/texture/sampler/debug/debug_draw_sampler.d.ts.map +1 -0
  91. package/src/engine/graphics/texture/sampler/debug/debug_draw_sampler.js +34 -0
  92. package/src/engine/graphics/texture/sampler/debug/debug_draw_sampler_grid.d.ts +10 -0
  93. package/src/engine/graphics/texture/sampler/debug/debug_draw_sampler_grid.d.ts.map +1 -0
  94. package/src/engine/graphics/texture/sampler/debug/debug_draw_sampler_grid.js +89 -0
  95. package/src/engine/graphics/texture/sampler/debug/prototypeSamplerFiltering.d.ts.map +1 -0
  96. package/src/engine/graphics/texture/sampler/{prototypeSamplerFiltering.js → debug/prototypeSamplerFiltering.js} +105 -113
  97. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.d.ts.map +1 -1
  98. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +8 -8
  99. package/src/generation/markers/GridActionRuleSet.d.ts.map +1 -1
  100. package/src/generation/markers/GridActionRuleSet.js +5 -5
  101. package/src/core/binary/byteArrayToString.d.ts +0 -9
  102. package/src/core/binary/byteArrayToString.d.ts.map +0 -1
  103. package/src/core/binary/byteArrayToString.js +0 -28
  104. package/src/core/collection/array/AbstractArrayIterator.d.ts.map +0 -1
  105. package/src/core/collection/array/ArrayIteratorRandom.d.ts.map +0 -1
  106. package/src/core/collection/array/ArrayIteratorSequential.d.ts.map +0 -1
  107. package/src/core/collection/array/arrayPickMinElement.d.ts +0 -8
  108. package/src/core/collection/array/arrayPickMinElement.d.ts.map +0 -1
  109. package/src/core/collection/array/arrayPickMinElement.js +0 -43
  110. package/src/core/collection/array/arraySwapElements.d.ts +0 -8
  111. package/src/core/collection/array/arraySwapElements.d.ts.map +0 -1
  112. package/src/core/collection/array/computeArrayMax.d.ts +0 -9
  113. package/src/core/collection/array/computeArrayMax.d.ts.map +0 -1
  114. package/src/core/collection/array/computeArrayMin.d.ts +0 -9
  115. package/src/core/collection/array/computeArrayMin.d.ts.map +0 -1
  116. package/src/engine/graphics/texture/sampler/prototypeSamplerFiltering.d.ts.map +0 -1
  117. /package/src/core/collection/array/{AbstractArrayIterator.d.ts → iterator/AbstractArrayIterator.d.ts} +0 -0
  118. /package/src/core/collection/array/{AbstractArrayIterator.js → iterator/AbstractArrayIterator.js} +0 -0
  119. /package/src/core/collection/array/{ArrayIteratorRandom.d.ts → iterator/ArrayIteratorRandom.d.ts} +0 -0
  120. /package/src/core/collection/array/{ArrayIteratorSequential.d.ts → iterator/ArrayIteratorSequential.d.ts} +0 -0
  121. /package/src/core/collection/array/{ArrayIteratorSequential.js → iterator/ArrayIteratorSequential.js} +0 -0
  122. /package/src/engine/graphics/texture/sampler/{prototypeSamplerFiltering.d.ts → debug/prototypeSamplerFiltering.d.ts} +0 -0
package/build/meep.cjs CHANGED
@@ -53177,7 +53177,7 @@ const SCRATCH_UINT32_TRAVERSAL_STACK = new Uint32Array(781250);
53177
53177
  */
53178
53178
  SCRATCH_UINT32_TRAVERSAL_STACK.pointer = 0;
53179
53179
 
53180
- const fabsf$1 = Math.abs;
53180
+ const abs = Math.abs;
53181
53181
 
53182
53182
  /**
53183
53183
  * NOTES:
@@ -53214,7 +53214,7 @@ function aabb3_intersects_ray(
53214
53214
  const diff_x = origin_x - center_x;
53215
53215
 
53216
53216
 
53217
- if (diff_x * direction_x >= 0.0 && fabsf$1(diff_x) > extents_x) {
53217
+ if (diff_x * direction_x >= 0.0 && abs(diff_x) > extents_x) {
53218
53218
  return false;
53219
53219
  }
53220
53220
 
@@ -53226,7 +53226,7 @@ function aabb3_intersects_ray(
53226
53226
  const diff_y = origin_y - center_y;
53227
53227
 
53228
53228
 
53229
- if (diff_y * direction_y >= 0.0 && fabsf$1(diff_y) > extents_y) {
53229
+ if (diff_y * direction_y >= 0.0 && abs(diff_y) > extents_y) {
53230
53230
  return false;
53231
53231
  }
53232
53232
 
@@ -53238,28 +53238,28 @@ function aabb3_intersects_ray(
53238
53238
  const diff_z = origin_z - center_z;
53239
53239
 
53240
53240
 
53241
- if (diff_z * direction_z >= 0.0 && fabsf$1(diff_z) > extents_z) {
53241
+ if (diff_z * direction_z >= 0.0 && abs(diff_z) > extents_z) {
53242
53242
  return false;
53243
53243
  }
53244
53244
 
53245
- const abs_direction_y = fabsf$1(direction_y);
53246
- const abs_direction_z = fabsf$1(direction_z);
53245
+ const abs_direction_y = abs(direction_y);
53246
+ const abs_direction_z = abs(direction_z);
53247
53247
 
53248
- const f0 = fabsf$1(direction_y * diff_z - direction_z * diff_y);
53248
+ const f0 = abs(direction_y * diff_z - direction_z * diff_y);
53249
53249
 
53250
53250
  if (f0 > extents_y * abs_direction_z + extents_z * abs_direction_y) {
53251
53251
  return false;
53252
53252
  }
53253
53253
 
53254
- const abs_direction_x = fabsf$1(direction_x);
53254
+ const abs_direction_x = abs(direction_x);
53255
53255
 
53256
- const f1 = fabsf$1(direction_z * diff_x - direction_x * diff_z);
53256
+ const f1 = abs(direction_z * diff_x - direction_x * diff_z);
53257
53257
 
53258
53258
  if (f1 > extents_x * abs_direction_z + extents_z * abs_direction_x) {
53259
53259
  return false;
53260
53260
  }
53261
53261
 
53262
- const f2 = fabsf$1(direction_x * diff_y - direction_y * diff_x);
53262
+ const f2 = abs(direction_x * diff_y - direction_y * diff_x);
53263
53263
 
53264
53264
  return f2 <= extents_x * abs_direction_y + extents_y * abs_direction_x;
53265
53265
  }
@@ -53338,8 +53338,8 @@ function bvh_query_leaves_ray(
53338
53338
  if (child_1 !== NULL_NODE) {
53339
53339
 
53340
53340
  // this is not a leaf node, push children onto traversal stack
53341
- stack$9[stack$9.pointer++] = child_1;
53342
53341
  stack$9[stack$9.pointer++] = uint32[address + COLUMN_CHILD_2];
53342
+ stack$9[stack$9.pointer++] = child_1;
53343
53343
 
53344
53344
  } else {
53345
53345
  // leaf node
@@ -54953,19 +54953,22 @@ function ceilPowerOfTwo(v) {
54953
54953
  * @param {number} b_offset
54954
54954
  * @param {number} length How many elements should be moved
54955
54955
  */
54956
- function array_swap(a, a_offset, b, b_offset, length) {
54957
-
54958
- let i, j, k;
54956
+ function array_swap(
54957
+ a, a_offset,
54958
+ b, b_offset,
54959
+ length
54960
+ ) {
54959
54961
 
54960
- for (k = 0; k < length; k++) {
54961
- i = a_offset + k;
54962
- j = b_offset + k;
54962
+ for (let k = 0; k < length; k++) {
54963
+ const i = a_offset + k;
54964
+ const j = b_offset + k;
54963
54965
 
54964
- const t = b[j];
54966
+ const swap = b[j];
54965
54967
 
54966
54968
  b[j] = a[i];
54967
- a[i] = t;
54969
+ a[i] = swap;
54968
54970
  }
54971
+
54969
54972
  }
54970
54973
 
54971
54974
  //
@@ -58825,25 +58828,138 @@ class TerrainTileManager {
58825
58828
  }
58826
58829
  }
58827
58830
 
58831
+ class WebGLRendererPool {
58832
+
58833
+ used = new Set();
58834
+
58835
+ get() {
58836
+ const canvas = document.createElement('canvas');
58837
+ const context = canvas.getContext('webgl2', { antialias: true });
58838
+
58839
+ const renderer = new WebGLRenderer({
58840
+ alpha: true,
58841
+ context,
58842
+ canvas
58843
+ });
58844
+
58845
+ this.used.add(renderer);
58846
+ return renderer;
58847
+ }
58848
+
58849
+ /**
58850
+ *
58851
+ * @param {THREE.WebGLRenderer} renderer
58852
+ * @returns {boolean}
58853
+ */
58854
+ release(renderer) {
58855
+ if (!this.used.has(renderer)) {
58856
+ //not from this pool
58857
+ return false;
58858
+ }
58859
+ this.used.delete(renderer);
58860
+
58861
+ renderer.forceContextLoss();
58862
+ renderer.dispose();
58863
+ renderer.domElement = null;
58864
+
58865
+ return true;
58866
+ }
58867
+
58868
+ /**
58869
+ * After callback returns, renderer is released back into the pool
58870
+ * @template T
58871
+ * @param {function(renderer:WebGLRenderer):T} callback
58872
+ * @param {*} [thisArg]
58873
+ */
58874
+ use(callback, thisArg) {
58875
+
58876
+ const renderer = this.get();
58877
+
58878
+ try {
58879
+ const result = callback.call(thisArg, renderer);
58880
+
58881
+ if (result instanceof Promise) {
58882
+ }
58883
+
58884
+ return result;
58885
+
58886
+ } finally {
58887
+
58888
+ this.release(renderer);
58889
+ }
58890
+
58891
+ }
58892
+
58893
+ /**
58894
+ * @template T
58895
+ * @param {function(renderer:WebGLRenderer):Promise<T>} callback
58896
+ * @param {*} [thisArg]
58897
+ */
58898
+ async useAsync(callback, thisArg) {
58899
+
58900
+ const renderer = this.get();
58901
+
58902
+ try {
58903
+ await callback.call(thisArg, renderer);
58904
+ } finally {
58905
+ this.release(renderer);
58906
+ }
58907
+ }
58908
+
58909
+ static global = new WebGLRendererPool();
58910
+ }
58911
+
58912
+ /**
58913
+ *
58914
+ * @param {Sampler2D} sampler
58915
+ * @param {THREE.DataTexture} texture
58916
+ */
58917
+ function writeSample2DDataToDataTexture(sampler, texture) {
58918
+ if (sampler.itemSize === 1) {
58919
+ if (texture.format !== RedFormat && texture.format !== LuminanceFormat) {
58920
+ throw new Error('itemSize is 1 and texture.format is not RedFormat');
58921
+ }
58922
+ } else if (sampler.itemSize === 2) {
58923
+ if (texture.format !== RGFormat) {
58924
+ throw new Error('itemSize is 2 and texture.format is not RGFormat');
58925
+ }
58926
+ } else if (sampler.itemSize === 3) {
58927
+ if (texture.format !== RGBFormat) {
58928
+ throw new Error('itemSize is 2 and texture.format is not RGBFormat');
58929
+ }
58930
+ } else if (sampler.itemSize === 4) {
58931
+ if (texture.format !== RGBAFormat) {
58932
+ throw new Error('itemSize is 2 and texture.format is not RGBAFormat');
58933
+ }
58934
+ } else {
58935
+ throw new Error('Unsupported itemSize');
58936
+ }
58937
+
58938
+ if (texture.image.data !== sampler.data) {
58939
+ // dispose of previous texture data
58940
+ texture.dispose();
58941
+ }
58942
+
58943
+ texture.image.data = sampler.data;
58944
+ texture.image.width = sampler.width;
58945
+ texture.image.height = sampler.height;
58946
+
58947
+ texture.needsUpdate = true;
58948
+ }
58949
+
58828
58950
  /**
58829
58951
  * Created by Alex on 10/11/2014.
58830
58952
  */
58831
58953
 
58832
- const AmbientOcclusionShader = function () {
58954
+
58955
+ const NormalMapShader = function () {
58833
58956
  return {
58834
58957
 
58835
58958
  uniforms: {
58836
58959
 
58837
- "normalMap": { type: "t", value: null },
58838
58960
  "heightMap": { type: "t", value: null },
58839
- "world_size": { type: "v2", value: new Vector2$1(512, 512) },
58840
- "rayLength": { type: 'f', value: 17 }
58841
-
58842
- },
58961
+ "resolution": { type: "v2", value: new Vector2$1(512, 512) }
58843
58962
 
58844
- defines: {
58845
- 'NUM_SAMPLES': 64,
58846
- 'NUM_RINGS': 7,
58847
58963
  },
58848
58964
 
58849
58965
  vertexShader: [
@@ -58859,102 +58975,53 @@ const AmbientOcclusionShader = function () {
58859
58975
 
58860
58976
  ].join("\n"),
58861
58977
 
58978
+ /**
58979
+ * Reference: https://stackoverflow.com/questions/49640250/calculate-normals-from-heightmap
58980
+ */
58862
58981
  fragmentShader: [
58863
- `
58864
- uniform sampler2D normalMap;
58865
- uniform sampler2D heightMap;
58866
- uniform float rayLength;
58867
- uniform vec2 world_size;
58982
+ "uniform vec2 resolution;",
58983
+ "uniform sampler2D heightMap;",
58868
58984
 
58869
- varying vec2 vUv;
58985
+ "#define sqrt2 1.41421356237;",
58986
+
58987
+ "varying vec2 vUv;",
58988
+
58989
+ "void main() {",
58990
+ " float uStep = 1.0/resolution.x;",
58991
+ " float vStep = 1.0/resolution.y;",
58992
+ //
58993
+ //
58994
+ " float top = texture2D( heightMap, vUv + vec2(0, -vStep)).x;",
58995
+ " float bottom = texture2D( heightMap, vUv + vec2(0, +vStep)).x;",
58996
+ " float left = texture2D( heightMap, vUv + vec2(-uStep, 0)).x;",
58997
+ " float right = texture2D( heightMap, vUv + vec2(+uStep, 0)).x;",
58998
+ //
58999
+
59000
+ " float dX = (right ) - ( left);",
59001
+ " float dY = ( bottom ) - ( top);",
59002
+ " float dZ = 2.0;",
59003
+ " vec3 n = normalize(vec3(dX, dY, dZ));",
59004
+
59005
+ " gl_FragColor = vec4( n*0.5+0.5, 1.0 );",
59006
+
59007
+ "}"
58870
59008
 
58871
- vec3 get(float x, float y){
58872
- vec2 _uv = vUv.xy + vec2(x,y) / world_size;
58873
- float h = texture2D(heightMap, _uv).x;
58874
- return vec3( _uv.x * world_size.x, h, _uv.y * world_size.y );
58875
- }
58876
-
58877
- float hash1( float n )
58878
- {
58879
- return fract( n*17.0*fract( n*0.3183099 ) );
58880
- }
58881
-
58882
- float hash1( vec2 p )
58883
- {
58884
- p = 50.0*fract( p*0.3183099 );
58885
- return fract( p.x*p.y*(p.x+p.y) );
58886
- }
58887
-
58888
- // Non-sin based hash function, fast and has good randomness
58889
- float hash12(vec2 p){
58890
- vec3 p3 = fract(vec3(p.xyx) * .1031);
58891
- p3 += dot(p3, p3.yzx + 33.33);
58892
- return fract((p3.x + p3.y) * p3.z);
58893
- }
58894
-
58895
- const float bias = 0.001;
58896
-
58897
- float pow2(float x){
58898
- return x*x;
58899
- }
58900
-
58901
- float getOcclusion(vec3 origin, vec3 normal, vec3 hit_position){
58902
- vec3 viewDelta = hit_position - origin;
58903
-
58904
- float viewDistance = length( viewDelta );
58905
-
58906
- float vn = dot( normal, viewDelta );
58907
- float a2 = (vn) / viewDistance - bias;
58908
- float a1 = (1.0 + pow2( viewDistance ) );
58909
-
58910
- return max(0.0, a2) / a1;
58911
- }
58912
-
58913
- const float PI2 = 6.28318530717958;
58914
- const float kernelRadius = 100.0;
58915
-
58916
- const float ANGLE_STEP = PI2 * float( NUM_RINGS ) / float( NUM_SAMPLES );
58917
- const float INV_NUM_SAMPLES = 1.0 / float( NUM_SAMPLES );
58918
-
58919
- float getAmbientOcclusion(vec3 world_position, vec3 world_normal){
58920
- // jsfiddle that shows sample pattern: https://jsfiddle.net/a16ff1p7/
58921
- float angle = hash12( vUv ) * PI2;
58922
- vec2 radius = vec2( rayLength * INV_NUM_SAMPLES );
58923
-
58924
- float occlusionSum = 0.0;
58925
- float weightSum = 0.0;
58926
-
58927
- for( int i = 0; i < NUM_SAMPLES; i ++ ) {
58928
- vec2 sampleUv = vec2( cos( angle ), sin( angle ) ) * radius * float(i+1);
58929
-
58930
- angle += ANGLE_STEP;
58931
-
58932
- vec3 sample_pos = get(sampleUv.x, sampleUv.y);
58933
-
58934
- occlusionSum += getOcclusion(world_position, world_normal, sample_pos);
58935
- weightSum += 1.0;
58936
- }
58937
-
58938
- return occlusionSum/weightSum;
58939
- }
58940
-
58941
- void main() {
58942
- vec3 pos = get(0.0, 0.0);
58943
-
58944
- vec3 normal = texture2D( normalMap, vUv ).xzy;
58945
-
58946
- float occlusion = getAmbientOcclusion(pos, normal);
58947
-
58948
- float incident = 1.0 - occlusion;
58949
-
58950
- gl_FragColor = vec4(pow(incident,10.0), 0.0, 0.0, 1.0);
58951
- }
58952
- `
58953
59009
  ].join('\n')
58954
59010
 
58955
59011
  }
58956
59012
  };
58957
59013
 
59014
+ const FULL_SCREEN_QUAD_VERTEX_SHADER = `
59015
+ varying vec2 vUv;
59016
+
59017
+ void main() {
59018
+
59019
+ vUv = uv;
59020
+
59021
+ gl_Position = vec4( (uv - 0.5)*2.0, 0.0, 1.0 );
59022
+
59023
+ }`;
59024
+
58958
59025
  const FULL_SCREEN_TRIANGLE_GEOMETRY = new BufferGeometry();
58959
59026
  FULL_SCREEN_TRIANGLE_GEOMETRY.setAttribute(
58960
59027
  'position',
@@ -58972,17 +59039,6 @@ FULL_SCREEN_TRIANGLE_GEOMETRY.setAttribute(
58972
59039
  )
58973
59040
  );
58974
59041
 
58975
- const FULL_SCREEN_QUAD_VERTEX_SHADER = `
58976
- varying vec2 vUv;
58977
-
58978
- void main() {
58979
-
58980
- vUv = uv;
58981
-
58982
- gl_Position = vec4( (uv - 0.5)*2.0, 0.0, 1.0 );
58983
-
58984
- }`;
58985
-
58986
59042
  /**
58987
59043
  * Created by Alex on 09/11/2014.
58988
59044
  */
@@ -58994,7 +59050,7 @@ const FULL_SCREEN_QUAD_VERTEX_SHADER = `
58994
59050
  * @param {number} width
58995
59051
  * @param {number} height
58996
59052
  * @param {{vertexShader?:string,fragmentShader:string, uniforms?:Object, defines?:Object}} processShader
58997
- * @param {Uint8Array} [destination]
59053
+ * @param {Uint8Array|Uint8ClampedArray} [destination]
58998
59054
  * @return {{array: Uint8Array, renderer: WebGLRenderer}}
58999
59055
  */
59000
59056
  function processTexture(
@@ -59005,7 +59061,7 @@ function processTexture(
59005
59061
  destination
59006
59062
  ) {
59007
59063
  if (destination === undefined) {
59008
- destination = new Uint8Array(width * height * 4);
59064
+ destination = new Uint8ClampedArray(width * height * 4);
59009
59065
  }
59010
59066
 
59011
59067
  //make a webgl renderer with orthographic camera
@@ -59175,6 +59231,207 @@ function sampler2DtoFloat32Texture(sampler) {
59175
59231
  return texture;
59176
59232
  }
59177
59233
 
59234
+ /**
59235
+ * Created by Alex on 15/11/2014.
59236
+ */
59237
+
59238
+
59239
+
59240
+ function convertChannel(v) {
59241
+ return (v) / 255 - 0.5;
59242
+ }
59243
+
59244
+ /**
59245
+ *
59246
+ * @param {number[]|Uint8Array} source
59247
+ * @returns {Float32Array}
59248
+ */
59249
+ function rgbaArray2RGB(source) {
59250
+ const length = source.length;
59251
+ const numPixels = Math.floor(length / 4);
59252
+ const target = new Float32Array(numPixels * 3);
59253
+ //
59254
+ let h;
59255
+ for (let i = 0; i < numPixels; i++) {
59256
+ const j = i * 4;
59257
+ const k = i * 3;
59258
+ //normalize source to normal vectors
59259
+ let x = convertChannel(source[j]);
59260
+ let y = convertChannel(source[j + 1]);
59261
+ let z = convertChannel(source[j + 2]);
59262
+ //
59263
+ h = Math.sqrt(x * x + y * y + z * z);
59264
+
59265
+ x /= h;
59266
+ y /= h;
59267
+ z /= h;
59268
+ //
59269
+ target[k] = x;
59270
+ target[k + 1] = y;
59271
+ target[k + 2] = z;
59272
+ }
59273
+ return target;
59274
+ }
59275
+
59276
+ /**
59277
+ *
59278
+ * @param {WebGLRenderer} renderer
59279
+ * @param {Sampler2D} sampler
59280
+ * @returns {Sampler2D}
59281
+ */
59282
+ function heightMap2NormalMap(renderer, sampler) {
59283
+
59284
+ const width = sampler.width;
59285
+ const height = sampler.height;
59286
+
59287
+ const texture = sampler2DtoFloat32Texture(sampler);
59288
+
59289
+ //construct shader
59290
+ const shader = new NormalMapShader();
59291
+ shader.uniforms.heightMap.value = texture;
59292
+ shader.uniforms.resolution.value.set(width, height);
59293
+
59294
+ //perform filtering
59295
+ const result = processTexture(renderer, width, height, shader);
59296
+
59297
+ //create the sampler
59298
+ const array = result.array;
59299
+ const rgb = rgbaArray2RGB(array);
59300
+
59301
+ //reduce array's alpha component
59302
+ return new Sampler2D(rgb, 3, width, height);
59303
+ }
59304
+
59305
+ /**
59306
+ * Created by Alex on 10/11/2014.
59307
+ */
59308
+
59309
+ const AmbientOcclusionShader = function () {
59310
+ return {
59311
+
59312
+ uniforms: {
59313
+
59314
+ "normalMap": { type: "t", value: null },
59315
+ "heightMap": { type: "t", value: null },
59316
+ "world_size": { type: "v2", value: new Vector2$1(512, 512) },
59317
+ "rayLength": { type: 'f', value: 17 }
59318
+
59319
+ },
59320
+
59321
+ defines: {
59322
+ 'NUM_SAMPLES': 64,
59323
+ 'NUM_RINGS': 7,
59324
+ },
59325
+
59326
+ vertexShader: [
59327
+
59328
+ "varying vec2 vUv;",
59329
+
59330
+ "void main() {",
59331
+
59332
+ "vUv = uv;",
59333
+ "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
59334
+
59335
+ "}"
59336
+
59337
+ ].join("\n"),
59338
+
59339
+ fragmentShader: [
59340
+ `
59341
+ uniform sampler2D normalMap;
59342
+ uniform sampler2D heightMap;
59343
+ uniform float rayLength;
59344
+ uniform vec2 world_size;
59345
+
59346
+ varying vec2 vUv;
59347
+
59348
+ vec3 get(float x, float y){
59349
+ vec2 _uv = vUv.xy + vec2(x,y) / world_size;
59350
+ float h = texture2D(heightMap, _uv).x;
59351
+ return vec3( _uv.x * world_size.x, h, _uv.y * world_size.y );
59352
+ }
59353
+
59354
+ float hash1( float n )
59355
+ {
59356
+ return fract( n*17.0*fract( n*0.3183099 ) );
59357
+ }
59358
+
59359
+ float hash1( vec2 p )
59360
+ {
59361
+ p = 50.0*fract( p*0.3183099 );
59362
+ return fract( p.x*p.y*(p.x+p.y) );
59363
+ }
59364
+
59365
+ // Non-sin based hash function, fast and has good randomness
59366
+ float hash12(vec2 p){
59367
+ vec3 p3 = fract(vec3(p.xyx) * .1031);
59368
+ p3 += dot(p3, p3.yzx + 33.33);
59369
+ return fract((p3.x + p3.y) * p3.z);
59370
+ }
59371
+
59372
+ const float bias = 0.001;
59373
+
59374
+ float pow2(float x){
59375
+ return x*x;
59376
+ }
59377
+
59378
+ float getOcclusion(vec3 origin, vec3 normal, vec3 hit_position){
59379
+ vec3 viewDelta = hit_position - origin;
59380
+
59381
+ float viewDistance = length( viewDelta );
59382
+
59383
+ float vn = dot( normal, viewDelta );
59384
+ float a2 = (vn) / viewDistance - bias;
59385
+ float a1 = (1.0 + pow2( viewDistance ) );
59386
+
59387
+ return max(0.0, a2) / a1;
59388
+ }
59389
+
59390
+ const float PI2 = 6.28318530717958;
59391
+ const float kernelRadius = 100.0;
59392
+
59393
+ const float ANGLE_STEP = PI2 * float( NUM_RINGS ) / float( NUM_SAMPLES );
59394
+ const float INV_NUM_SAMPLES = 1.0 / float( NUM_SAMPLES );
59395
+
59396
+ float getAmbientOcclusion(vec3 world_position, vec3 world_normal){
59397
+ // jsfiddle that shows sample pattern: https://jsfiddle.net/a16ff1p7/
59398
+ float angle = hash12( vUv ) * PI2;
59399
+ vec2 radius = vec2( rayLength * INV_NUM_SAMPLES );
59400
+
59401
+ float occlusionSum = 0.0;
59402
+ float weightSum = 0.0;
59403
+
59404
+ for( int i = 0; i < NUM_SAMPLES; i ++ ) {
59405
+ vec2 sampleUv = vec2( cos( angle ), sin( angle ) ) * radius * float(i+1);
59406
+
59407
+ angle += ANGLE_STEP;
59408
+
59409
+ vec3 sample_pos = get(sampleUv.x, sampleUv.y);
59410
+
59411
+ occlusionSum += getOcclusion(world_position, world_normal, sample_pos);
59412
+ weightSum += 1.0;
59413
+ }
59414
+
59415
+ return occlusionSum/weightSum;
59416
+ }
59417
+
59418
+ void main() {
59419
+ vec3 pos = get(0.0, 0.0);
59420
+
59421
+ vec3 normal = texture2D( normalMap, vUv ).xzy;
59422
+
59423
+ float occlusion = getAmbientOcclusion(pos, normal);
59424
+
59425
+ float incident = 1.0 - occlusion;
59426
+
59427
+ gl_FragColor = vec4(pow(incident,10.0), 0.0, 0.0, 1.0);
59428
+ }
59429
+ `
59430
+ ].join('\n')
59431
+
59432
+ }
59433
+ };
59434
+
59178
59435
  const KERNEL_SIZE = 15;
59179
59436
 
59180
59437
  const fragment$1 = `
@@ -59372,219 +59629,6 @@ function normalMap2OcclusionMap(
59372
59629
  return result;
59373
59630
  }
59374
59631
 
59375
- /**
59376
- * Created by Alex on 10/11/2014.
59377
- */
59378
-
59379
-
59380
- const NormalMapShader = function () {
59381
- return {
59382
-
59383
- uniforms: {
59384
-
59385
- "heightMap": { type: "t", value: null },
59386
- "resolution": { type: "v2", value: new Vector2$1(512, 512) }
59387
-
59388
- },
59389
-
59390
- vertexShader: [
59391
-
59392
- "varying vec2 vUv;",
59393
-
59394
- "void main() {",
59395
-
59396
- "vUv = uv;",
59397
- "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
59398
-
59399
- "}"
59400
-
59401
- ].join("\n"),
59402
-
59403
- /**
59404
- * Reference: https://stackoverflow.com/questions/49640250/calculate-normals-from-heightmap
59405
- */
59406
- fragmentShader: [
59407
- "uniform vec2 resolution;",
59408
- "uniform sampler2D heightMap;",
59409
-
59410
- "#define sqrt2 1.41421356237;",
59411
-
59412
- "varying vec2 vUv;",
59413
-
59414
- "void main() {",
59415
- " float uStep = 1.0/resolution.x;",
59416
- " float vStep = 1.0/resolution.y;",
59417
- //
59418
- //
59419
- " float top = texture2D( heightMap, vUv + vec2(0, -vStep)).x;",
59420
- " float bottom = texture2D( heightMap, vUv + vec2(0, +vStep)).x;",
59421
- " float left = texture2D( heightMap, vUv + vec2(-uStep, 0)).x;",
59422
- " float right = texture2D( heightMap, vUv + vec2(+uStep, 0)).x;",
59423
- //
59424
-
59425
- " float dX = (right ) - ( left);",
59426
- " float dY = ( bottom ) - ( top);",
59427
- " float dZ = 2.0;",
59428
- " vec3 n = normalize(vec3(dX, dY, dZ));",
59429
-
59430
- " gl_FragColor = vec4( n*0.5+0.5, 1.0 );",
59431
-
59432
- "}"
59433
-
59434
- ].join('\n')
59435
-
59436
- }
59437
- };
59438
-
59439
- /**
59440
- * Created by Alex on 15/11/2014.
59441
- */
59442
-
59443
-
59444
-
59445
- function convertChannel(v) {
59446
- return (v) / 255 - 0.5;
59447
- }
59448
-
59449
- /**
59450
- *
59451
- * @param {number[]|Uint8Array} source
59452
- * @returns {Float32Array}
59453
- */
59454
- function rgbaArray2RGB(source) {
59455
- const length = source.length;
59456
- const numPixels = Math.floor(length / 4);
59457
- const target = new Float32Array(numPixels * 3);
59458
- //
59459
- let h;
59460
- for (let i = 0; i < numPixels; i++) {
59461
- const j = i * 4;
59462
- const k = i * 3;
59463
- //normalize source to normal vectors
59464
- let x = convertChannel(source[j]);
59465
- let y = convertChannel(source[j + 1]);
59466
- let z = convertChannel(source[j + 2]);
59467
- //
59468
- h = Math.sqrt(x * x + y * y + z * z);
59469
-
59470
- x /= h;
59471
- y /= h;
59472
- z /= h;
59473
- //
59474
- target[k] = x;
59475
- target[k + 1] = y;
59476
- target[k + 2] = z;
59477
- }
59478
- return target;
59479
- }
59480
-
59481
- /**
59482
- *
59483
- * @param {WebGLRenderer} renderer
59484
- * @param {Sampler2D} sampler
59485
- * @returns {Sampler2D}
59486
- */
59487
- function heightMap2NormalMap(renderer, sampler) {
59488
-
59489
- const width = sampler.width;
59490
- const height = sampler.height;
59491
-
59492
- const texture = sampler2DtoFloat32Texture(sampler);
59493
-
59494
- //construct shader
59495
- const shader = new NormalMapShader();
59496
- shader.uniforms.heightMap.value = texture;
59497
- shader.uniforms.resolution.value.set(width, height);
59498
-
59499
- //perform filtering
59500
- const result = processTexture(renderer, width, height, shader);
59501
-
59502
- //create the sampler
59503
- const array = result.array;
59504
- const rgb = rgbaArray2RGB(array);
59505
-
59506
- //reduce array's alpha component
59507
- return new Sampler2D(rgb, 3, width, height);
59508
- }
59509
-
59510
- class WebGLRendererPool {
59511
-
59512
- used = new Set();
59513
-
59514
- get(options) {
59515
- const canvas = document.createElement('canvas');
59516
- const context = canvas.getContext('webgl2', { antialias: true });
59517
-
59518
- const renderer = new WebGLRenderer({
59519
- alpha: true,
59520
- context,
59521
- canvas
59522
- });
59523
-
59524
- this.used.add(renderer);
59525
- return renderer;
59526
- }
59527
-
59528
- /**
59529
- *
59530
- * @param {THREE.WebGLRenderer} renderer
59531
- * @returns {boolean}
59532
- */
59533
- release(renderer) {
59534
- if (!this.used.has(renderer)) {
59535
- //not from this pool
59536
- return false;
59537
- }
59538
- this.used.delete(renderer);
59539
-
59540
- renderer.forceContextLoss();
59541
- renderer.dispose();
59542
- renderer.domElement = null;
59543
-
59544
- return true;
59545
- }
59546
-
59547
- static global = new WebGLRendererPool();
59548
- }
59549
-
59550
- /**
59551
- *
59552
- * @param {Sampler2D} sampler
59553
- * @param {THREE.DataTexture} texture
59554
- */
59555
- function writeSample2DDataToDataTexture(sampler, texture) {
59556
- if (sampler.itemSize === 1) {
59557
- if (texture.format !== RedFormat && texture.format !== LuminanceFormat) {
59558
- throw new Error('itemSize is 1 and texture.format is not RedFormat');
59559
- }
59560
- } else if (sampler.itemSize === 2) {
59561
- if (texture.format !== RGFormat) {
59562
- throw new Error('itemSize is 2 and texture.format is not RGFormat');
59563
- }
59564
- } else if (sampler.itemSize === 3) {
59565
- if (texture.format !== RGBFormat) {
59566
- throw new Error('itemSize is 2 and texture.format is not RGBFormat');
59567
- }
59568
- } else if (sampler.itemSize === 4) {
59569
- if (texture.format !== RGBAFormat) {
59570
- throw new Error('itemSize is 2 and texture.format is not RGBAFormat');
59571
- }
59572
- } else {
59573
- throw new Error('Unsupported itemSize');
59574
- }
59575
-
59576
- if (texture.image.data !== sampler.data) {
59577
- // dispose of previous texture data
59578
- texture.dispose();
59579
- }
59580
-
59581
- texture.image.data = sampler.data;
59582
- texture.image.width = sampler.width;
59583
- texture.image.height = sampler.height;
59584
-
59585
- texture.needsUpdate = true;
59586
- }
59587
-
59588
59632
  /**
59589
59633
  *
59590
59634
  * @param {WebGLRenderer} renderer
@@ -59653,32 +59697,25 @@ function promiseSamplerAO(
59653
59697
  function buildLightTexture({
59654
59698
  texture,
59655
59699
  heightSampler,
59656
- resolution= new Vector2(texture.image.width, texture.image.height),
59700
+ resolution = new Vector2(texture.image.width, texture.image.height),
59657
59701
  rayLength = 11,
59658
59702
  worldSize = resolution
59659
59703
  }) {
59660
59704
 
59661
- const renderer = WebGLRendererPool.global.get();
59705
+ return WebGLRendererPool.global.useAsync(async renderer => {
59706
+ const normal = promiseSamplerNormal(renderer, heightSampler);
59662
59707
 
59663
- const normal = promiseSamplerNormal(renderer, heightSampler);
59664
- const ao = promiseSamplerAO({
59665
- renderer: renderer,
59666
- pSamplerNormal: normal,
59667
- samplerHeight: heightSampler,
59668
- resolution: resolution,
59669
- rayLength: rayLength,
59670
- worldSize
59671
- });
59672
-
59673
- const promise = ao.then(sampler => {
59674
- writeSample2DDataToDataTexture(sampler, texture);
59675
- });
59708
+ const ao = await promiseSamplerAO({
59709
+ renderer: renderer,
59710
+ pSamplerNormal: normal,
59711
+ samplerHeight: heightSampler,
59712
+ resolution: resolution,
59713
+ rayLength: rayLength,
59714
+ worldSize
59715
+ });
59676
59716
 
59677
- Promise.all([normal, ao]).finally(() => {
59678
- WebGLRendererPool.global.release(renderer);
59717
+ writeSample2DDataToDataTexture(ao, texture);
59679
59718
  });
59680
-
59681
- return promise;
59682
59719
  }
59683
59720
 
59684
59721
  const GridTransformKind = {
@@ -59767,7 +59804,7 @@ function invokeObjectHash(object) {
59767
59804
  * @param {number} index0
59768
59805
  * @param {number} index1
59769
59806
  */
59770
- function arraySwapElements(array, index0, index1) {
59807
+ function array_swap_one(array, index0, index1) {
59771
59808
  const t = array[index0];
59772
59809
 
59773
59810
  array[index0] = array[index1];
@@ -59821,7 +59858,7 @@ function generate_next_linear_congruential_index(index, mask) {
59821
59858
  /**
59822
59859
  * @template K,V
59823
59860
  */
59824
- class MapEntry {
59861
+ class HashMapEntry {
59825
59862
  /**
59826
59863
  *
59827
59864
  * @param {K} key
@@ -59909,7 +59946,7 @@ const UNDEFINED_BIN_INDEX = ~0;
59909
59946
 
59910
59947
  /**
59911
59948
  * @template K,V
59912
- * @param {MapEntry<K,V>} record
59949
+ * @param {HashMapEntry<K,V>} record
59913
59950
  * @param {number} hash
59914
59951
  * @param {K} key
59915
59952
  * @param {function(a:K,b:K):boolean} equality_op
@@ -59949,7 +59986,7 @@ class HashMap {
59949
59986
 
59950
59987
  /**
59951
59988
  * Note that dead entries are marked as such with a special reserved hash values, so records can be reused for new entries
59952
- * @type {Array<MapEntry<K,V>>}
59989
+ * @type {Array<HashMapEntry<K,V>>}
59953
59990
  */
59954
59991
  #entries = new Array(0);
59955
59992
 
@@ -60127,7 +60164,7 @@ class HashMap {
60127
60164
  entry.key = k;
60128
60165
  entry.value = v;
60129
60166
  } else {
60130
- this.#entries[i] = new MapEntry(k, v, hash);
60167
+ this.#entries[i] = new HashMapEntry(k, v, hash);
60131
60168
  }
60132
60169
 
60133
60170
  return i;
@@ -60135,7 +60172,7 @@ class HashMap {
60135
60172
 
60136
60173
  /**
60137
60174
  *
60138
- * @param {MapEntry<K,V>} entry
60175
+ * @param {HashMapEntry<K,V>} entry
60139
60176
  */
60140
60177
  #deallocate(entry) {
60141
60178
 
@@ -60392,7 +60429,7 @@ class HashMap {
60392
60429
  }
60393
60430
 
60394
60431
  /**
60395
- * @type {MapEntry<K,V>}
60432
+ * @type {HashMapEntry<K,V>}
60396
60433
  */
60397
60434
  const entry = this.#entries[bin - ENTRY_BASE];
60398
60435
 
@@ -60443,7 +60480,7 @@ class HashMap {
60443
60480
 
60444
60481
  if (new_index !== existing_entry_index) {
60445
60482
  // move entries to the new position, compacting holes
60446
- arraySwapElements(entries, new_index, existing_entry_index);
60483
+ array_swap_one(entries, new_index, existing_entry_index);
60447
60484
  }
60448
60485
 
60449
60486
  let bin_index = this.#compute_bin_index(hash);
@@ -60497,7 +60534,7 @@ class HashMap {
60497
60534
  }
60498
60535
 
60499
60536
  /**
60500
- * @type {MapEntry<K,V>}
60537
+ * @type {HashMapEntry<K,V>}
60501
60538
  */
60502
60539
  const entry = entries[bin - ENTRY_BASE];
60503
60540
 
@@ -60568,7 +60605,7 @@ class HashMap {
60568
60605
  }
60569
60606
 
60570
60607
  /**
60571
- * @type {MapEntry<K,V>}
60608
+ * @type {HashMapEntry<K,V>}
60572
60609
  */
60573
60610
  const entry = entries[bin - ENTRY_BASE];
60574
60611
 
@@ -67266,6 +67303,37 @@ function computeFileExtension(path) {
67266
67303
  }
67267
67304
  }
67268
67305
 
67306
+ /**
67307
+ * @param {Uint8Array} input
67308
+ * @param {number} width
67309
+ * @param {number} height
67310
+ * @param {number} channel_count
67311
+ */
67312
+ function flipArrayInPlace(input, width, height, channel_count = 4) {
67313
+ const row_size = width * channel_count;
67314
+ let t, x0, x1;
67315
+ let i = 0;
67316
+ const column_count = height >> 1;
67317
+
67318
+ for (; i < column_count; i++) {
67319
+
67320
+ //swap lines
67321
+ const k = (height - i - 1) * row_size;
67322
+ const m = i * row_size;
67323
+
67324
+ for (let j = 0; j < row_size; j++) {
67325
+ x0 = m + j;
67326
+ x1 = k + j;
67327
+
67328
+ t = input[x0];
67329
+
67330
+ input[x0] = input[x1];
67331
+ input[x1] = t;
67332
+ }
67333
+
67334
+ }
67335
+ }
67336
+
67269
67337
  /**
67270
67338
  * @author alteredq / http://alteredqualia.com/
67271
67339
  *
@@ -67312,37 +67380,6 @@ const CopyShader = {
67312
67380
 
67313
67381
  };
67314
67382
 
67315
- /**
67316
- * @param {Uint8Array} input
67317
- * @param {number} width
67318
- * @param {number} height
67319
- * @param {number} channel_count
67320
- */
67321
- function flipArrayInPlace(input, width, height, channel_count = 4) {
67322
- const row_size = width * channel_count;
67323
- let t, x0, x1;
67324
- let i = 0;
67325
- const column_count = height >> 1;
67326
-
67327
- for (; i < column_count; i++) {
67328
-
67329
- //swap lines
67330
- const k = (height - i - 1) * row_size;
67331
- const m = i * row_size;
67332
-
67333
- for (let j = 0; j < row_size; j++) {
67334
- x0 = m + j;
67335
- x1 = k + j;
67336
-
67337
- t = input[x0];
67338
-
67339
- input[x0] = input[x1];
67340
- input[x1] = t;
67341
- }
67342
-
67343
- }
67344
- }
67345
-
67346
67383
  const DEFAULT_TEXTURE_WIDTH = 512;
67347
67384
  const DEFAULT_TEXTURE_HEIGHT = 512;
67348
67385
 
@@ -67351,39 +67388,47 @@ const DEFAULT_TEXTURE_HEIGHT = 512;
67351
67388
  * @param {Texture} texture
67352
67389
  * @param {number} [width]
67353
67390
  * @param {number} [height]
67354
- * @param {boolean} flipY
67391
+ * @param {boolean} [flipY]
67355
67392
  * @return {Sampler2D}
67356
67393
  */
67357
- function convertTexture2Sampler2D(texture, width, height, flipY = true) {
67394
+ function convertTexture2Sampler2D(
67395
+ texture,
67396
+ width,
67397
+ height,
67398
+ flipY = true
67399
+ ) {
67400
+ let _height = height;
67401
+ let _width = width;
67402
+
67358
67403
  // TODO take channel count into account
67359
67404
 
67360
- if (width === undefined || height === undefined) {
67405
+ if (_width === undefined || _height === undefined) {
67361
67406
 
67362
67407
  //figure out texture size
67363
67408
  const image = texture.image;
67364
67409
 
67365
67410
  if (image !== undefined && image !== null) {
67366
- if (width === undefined) {
67411
+ if (_width === undefined) {
67367
67412
  if (typeof image.width === "number") {
67368
- width = image.width;
67413
+ _width = image.width;
67369
67414
  } else {
67370
- width = DEFAULT_TEXTURE_WIDTH;
67415
+ _width = DEFAULT_TEXTURE_WIDTH;
67371
67416
  }
67372
67417
  }
67373
- if (height === undefined) {
67418
+ if (_height === undefined) {
67374
67419
  if (typeof image.height === "number") {
67375
- height = image.height;
67420
+ _height = image.height;
67376
67421
  } else {
67377
- height = DEFAULT_TEXTURE_HEIGHT;
67422
+ _height = DEFAULT_TEXTURE_HEIGHT;
67378
67423
  }
67379
67424
  }
67380
67425
  } else {
67381
- if (width === undefined) {
67382
- width = DEFAULT_TEXTURE_WIDTH;
67426
+ if (_width === undefined) {
67427
+ _width = DEFAULT_TEXTURE_WIDTH;
67383
67428
  }
67384
67429
 
67385
- if (height === undefined) {
67386
- height = DEFAULT_TEXTURE_HEIGHT;
67430
+ if (_height === undefined) {
67431
+ _height = DEFAULT_TEXTURE_HEIGHT;
67387
67432
  }
67388
67433
  }
67389
67434
 
@@ -67391,34 +67436,32 @@ function convertTexture2Sampler2D(texture, width, height, flipY = true) {
67391
67436
 
67392
67437
  // TODO add special case for DataTexture
67393
67438
 
67394
- const renderer = WebGLRendererPool.global.get({});
67439
+ const built = WebGLRendererPool.global.use(renderer => {
67395
67440
 
67396
- const ctx = renderer.getContext();
67441
+ const ctx = renderer.getContext();
67397
67442
 
67398
- //support for compressed textures
67399
- ctx.getExtension("WEBGL_compressed_texture_s3tc");
67443
+ //support for compressed textures
67444
+ ctx.getExtension("WEBGL_compressed_texture_s3tc");
67400
67445
 
67401
- const built = processTexture(renderer, width, height, {
67402
- vertexShader: CopyShader.vertexShader,
67403
- fragmentShader: CopyShader.fragmentShader,
67404
- uniforms: {
67405
- tDiffuse: {
67406
- value: texture,
67407
- type: 't'
67408
- },
67409
- opacity: { value: 1.0 }
67410
- }
67411
- });
67446
+ return processTexture(renderer, _width, _height, {
67447
+ vertexShader: CopyShader.vertexShader,
67448
+ fragmentShader: CopyShader.fragmentShader,
67449
+ uniforms: {
67450
+ tDiffuse: {
67451
+ value: texture,
67452
+ type: 't'
67453
+ },
67454
+ opacity: { value: 1.0 }
67455
+ }
67456
+ });
67412
67457
 
67413
- WebGLRendererPool.global.release(renderer);
67458
+ });
67414
67459
 
67415
67460
  if (flipY) {
67416
- flipArrayInPlace(built.array, width, height);
67461
+ flipArrayInPlace(built.array, _width, _height);
67417
67462
  }
67418
67463
 
67419
- const sampler = new Sampler2D(built.array, 4, width, height);
67420
-
67421
- return sampler;
67464
+ return new Sampler2D(built.array, 4, _width, _height);
67422
67465
  }
67423
67466
 
67424
67467
  /**
@@ -69049,10 +69092,14 @@ class Camera {
69049
69092
  * @param {Camera|THREE.PerspectiveCamera|THREE.OrthographicCamera} camera
69050
69093
  * @param {number} x
69051
69094
  * @param {number} y
69052
- * @param {Vector3} source
69053
- * @param {Vector3} direction
69095
+ * @param {Vector3} out_source
69096
+ * @param {Vector3} out_direction
69054
69097
  */
69055
- static projectRay(camera, x, y, source, direction) {
69098
+ static projectRay(
69099
+ camera,
69100
+ x, y,
69101
+ out_source, out_direction
69102
+ ) {
69056
69103
 
69057
69104
  // assert.ok(x >= -1, `X(=${x}) must be greater than or equal to -1.0, not a clip-space coordinate`);
69058
69105
  // assert.ok(x <= 1, `X(=${x}) must be less than or equal to 1.0, not a clip-space coordinate`);
@@ -69061,7 +69108,10 @@ class Camera {
69061
69108
  // assert.ok(y <= 1, `Y(=${y}) must be less than or equal to 1.0, not a clip-space coordinate`);
69062
69109
 
69063
69110
  if (camera.isPerspectiveCamera || camera.isOrthographicCamera) {
69064
- scratch_v3_1.setFromMatrixPosition(camera.matrixWorld.elements);
69111
+ const m4_world = camera.matrixWorld.elements;
69112
+ const m4_projection_inverse = camera.projectionMatrixInverse.elements;
69113
+
69114
+ scratch_v3_1.setFromMatrixPosition(m4_world);
69065
69115
 
69066
69116
  scratch_v3_0.set(x, y, 0.5);
69067
69117
 
@@ -69070,16 +69120,16 @@ class Camera {
69070
69120
  unprojectPoint(
69071
69121
  scratch_v3_0,
69072
69122
  scratch_v3_0,
69073
- camera.projectionMatrixInverse.elements,
69074
- camera.matrixWorld.elements
69123
+ m4_projection_inverse,
69124
+ m4_world
69075
69125
  );
69076
69126
 
69077
69127
  //get direction
69078
69128
  scratch_v3_0.sub(scratch_v3_1);
69079
69129
  scratch_v3_0.normalize();
69080
69130
 
69081
- source.copy(scratch_v3_1);
69082
- direction.copy(scratch_v3_0);
69131
+ out_source.copy(scratch_v3_1);
69132
+ out_direction.copy(scratch_v3_0);
69083
69133
 
69084
69134
  } else {
69085
69135
  throw new Error('Unsupported camera type');
@@ -74590,7 +74640,7 @@ function arrayQuickSort(
74590
74640
  data,
74591
74641
  score_function, score_function_context,
74592
74642
  start, end,
74593
- swap_operator = arraySwapElements, swap_context = undefined
74643
+ swap_operator = array_swap_one, swap_context = undefined
74594
74644
  ) {
74595
74645
  if (start >= end) {
74596
74646
  // section of 0 size, nothing to sort
@@ -81315,6 +81365,7 @@ class Token {
81315
81365
  * @param {T} type
81316
81366
  */
81317
81367
  constructor(value, start, end, name, type) {
81368
+
81318
81369
  /**
81319
81370
  * @readonly
81320
81371
  * @type {V}
@@ -81364,8 +81415,7 @@ class Token {
81364
81415
  * @return {number}
81365
81416
  */
81366
81417
  hash() {
81367
- // TODO make an actual hash
81368
- return 0;
81418
+ return this.start ^ (this.end << 16);
81369
81419
  }
81370
81420
  }
81371
81421
 
@@ -81381,10 +81431,71 @@ const TooltipTokenType = {
81381
81431
  ReferenceValue: 4,
81382
81432
  };
81383
81433
 
81384
- function ParserError(position, message, input) {
81385
- this.position = position;
81386
- this.message = message;
81387
- this.input = input;
81434
+ /**
81435
+ * Repeat a given piece of text a {@link count} times
81436
+ * @example "ABC_" repeated 2 times results in "ABC_ABC_"
81437
+ * @param {string} what
81438
+ * @param {number} count
81439
+ * @return {string}
81440
+ */
81441
+ function string_repeat(what, count) {
81442
+
81443
+ if (count <= 0) {
81444
+ // special case
81445
+ return "";
81446
+ }
81447
+
81448
+ let out = what;
81449
+
81450
+ for (let i = 1; i < count; i++) {
81451
+ out += what;
81452
+ }
81453
+
81454
+ return out;
81455
+ }
81456
+
81457
+ class ParserError extends Error {
81458
+ /**
81459
+ *
81460
+ * @param {number} position
81461
+ * @param {string} message
81462
+ * @param {string} input
81463
+ */
81464
+ constructor(
81465
+ position,
81466
+ message,
81467
+ input
81468
+ ) {
81469
+
81470
+ super();
81471
+
81472
+ this.position = position;
81473
+ this.message = message;
81474
+ this.input = input;
81475
+ }
81476
+
81477
+ getDetails() {
81478
+ const input = this.input;
81479
+ const position = this.position;
81480
+
81481
+ // get snippet around where the problem has occurred
81482
+ const input_start = max2(0, position - 10);
81483
+
81484
+ const input_end = min2(input.length, position + 10);
81485
+
81486
+ const snippet = input.slice(input_start, input_end);
81487
+
81488
+ const offset_into_snippet = position - input_start;
81489
+
81490
+ // a piece of text with marker to show where the error occurs
81491
+ const arrow_text = string_repeat(" ", offset_into_snippet) + "^";
81492
+
81493
+ return snippet + "\n" + arrow_text;
81494
+ }
81495
+
81496
+ toString() {
81497
+ return `[ParseError] ${this.message}. Error at position ${this.position} near:\n${this.getDetails()}`
81498
+ }
81388
81499
  }
81389
81500
 
81390
81501
  /**
@@ -81480,28 +81591,6 @@ class KeyValuePair {
81480
81591
  }
81481
81592
  }
81482
81593
 
81483
- /**
81484
- *
81485
- * @param {string} text
81486
- * @param {number} cursor
81487
- * @param {number} length
81488
- * @returns {number}
81489
- */
81490
- function skipWhitespace(text, cursor, length) {
81491
- let i = cursor;
81492
- let char;
81493
- while (i < length) {
81494
- char = text.charAt(i);
81495
-
81496
- if (char === ' ' || char === '\n' || char === '\t') {
81497
- i++;
81498
- } else {
81499
- break;
81500
- }
81501
- }
81502
- return i;
81503
- }
81504
-
81505
81594
  /**
81506
81595
  *
81507
81596
  * @enum {string}
@@ -81516,7 +81605,7 @@ const DataType = {
81516
81605
  };
81517
81606
 
81518
81607
  /**
81519
- * @enum {{LiteralString: string, LiteralNumber: string, LiteralBoolean: string}}
81608
+ * @enum {string}
81520
81609
  */
81521
81610
  const TokenType = {
81522
81611
  LiteralString: "literal-string",
@@ -81534,6 +81623,7 @@ const TokenType = {
81534
81623
  * @returns {Token}
81535
81624
  */
81536
81625
  function readBooleanToken(text, cursor, length) {
81626
+
81537
81627
  const firstChar = text.charAt(cursor);
81538
81628
 
81539
81629
  let value;
@@ -81560,96 +81650,6 @@ function readBooleanToken(text, cursor, length) {
81560
81650
  return new Token(value, cursor, end, TokenType.LiteralBoolean, DataType.Boolean);
81561
81651
  }
81562
81652
 
81563
- /**
81564
- *
81565
- * @param {string} text
81566
- * @param {number} cursor
81567
- * @returns {string}
81568
- */
81569
- function readQuote(text, cursor) {
81570
- const char = text.charAt(cursor);
81571
-
81572
- if (char !== '"' && char !== '\'') {
81573
- throw new ParserError(cursor, "Expected \", found " + char + " instead", text);
81574
- }
81575
-
81576
- return char;
81577
- }
81578
-
81579
- /**
81580
- *
81581
- * @param {string} text
81582
- * @param {number} cursor
81583
- * @param {number} length
81584
- * @returns {Token}
81585
- */
81586
- function readStringToken(text, cursor, length) {
81587
- let i = cursor;
81588
-
81589
- const openingQuote = readQuote(text, i);
81590
-
81591
- i++;
81592
-
81593
- let char;
81594
-
81595
- let value = '';
81596
- const lastPossibleChar = length - 1;
81597
-
81598
- for (; i < lastPossibleChar; i++) {
81599
- char = text.charAt(i);
81600
-
81601
- if (char === '\\') {
81602
- i++;
81603
- //read escape sequence
81604
- char = text.charAt(i);
81605
-
81606
- switch (char) {
81607
- case 'n':
81608
- value += '\n';
81609
- break;
81610
- case 't':
81611
- value += '\t';
81612
- break;
81613
- case 'r':
81614
- value += '\r';
81615
- break;
81616
- case 'b':
81617
- value += '\b';
81618
- break;
81619
- case 'f':
81620
- value += '\f';
81621
- break;
81622
- case 'v':
81623
- value += '\v';
81624
- break;
81625
- case '0':
81626
- value += '\0';
81627
- break;
81628
- case '\\':
81629
- case "'":
81630
- case '"':
81631
- default:
81632
- value += char;
81633
- break;
81634
- }
81635
- } else if (char !== openingQuote) {
81636
- value += char;
81637
- } else {
81638
- break;
81639
- }
81640
- }
81641
-
81642
- char = text.charAt(i);
81643
-
81644
- if (char !== openingQuote) {
81645
- throw new ParserError(cursor, "Expected string terminator : " + openingQuote + ", but found '" + char + "' instead", text);
81646
- }
81647
-
81648
- i++;
81649
-
81650
- return new Token(value, cursor, i, TokenType.LiteralString, DataType.String);
81651
- }
81652
-
81653
81653
  /**
81654
81654
  *
81655
81655
  * @param {string} text
@@ -81658,6 +81658,7 @@ function readStringToken(text, cursor, length) {
81658
81658
  * @returns {Token}
81659
81659
  */
81660
81660
  function readHexToken(text, cursor, length) {
81661
+
81661
81662
  const c0 = text.charAt(cursor);
81662
81663
  const c1 = text.charAt(cursor + 1);
81663
81664
 
@@ -81739,7 +81740,7 @@ function readHexToken(text, cursor, length) {
81739
81740
  }
81740
81741
 
81741
81742
 
81742
- return new Token(value, cursor, i, null, DataType.Number);
81743
+ return new Token(value, cursor, i, "uint", DataType.Number);
81743
81744
  }
81744
81745
 
81745
81746
  /**
@@ -81750,6 +81751,7 @@ function readHexToken(text, cursor, length) {
81750
81751
  * @returns {Token}
81751
81752
  */
81752
81753
  function readUnsignedIntegerToken(text, cursor, length) {
81754
+
81753
81755
  let i = cursor;
81754
81756
 
81755
81757
  let value = 0;
@@ -81801,7 +81803,32 @@ function readUnsignedIntegerToken(text, cursor, length) {
81801
81803
  }
81802
81804
 
81803
81805
 
81804
- return new Token(value, cursor, i, null, DataType.Number);
81806
+ return new Token(value, cursor, i, "uint", DataType.Number);
81807
+ }
81808
+
81809
+ /**
81810
+ *
81811
+ * @param {string} text
81812
+ * @param {number} cursor
81813
+ * @param {number} length
81814
+ * @returns {number}
81815
+ */
81816
+ function skipWhitespace(text, cursor, length) {
81817
+
81818
+ let i = cursor;
81819
+ let char;
81820
+
81821
+ while (i < length) {
81822
+ char = text.charAt(i);
81823
+
81824
+ if (char === ' ' || char === '\n' || char === '\t') {
81825
+ i++;
81826
+ } else {
81827
+ break;
81828
+ }
81829
+ }
81830
+
81831
+ return i;
81805
81832
  }
81806
81833
 
81807
81834
  /**
@@ -81812,6 +81839,7 @@ function readUnsignedIntegerToken(text, cursor, length) {
81812
81839
  * @returns {Token}
81813
81840
  */
81814
81841
  function readNumberToken(text, cursor, length) {
81842
+
81815
81843
  let i = cursor;
81816
81844
 
81817
81845
  //read optional sign
@@ -81871,6 +81899,97 @@ function readNumberToken(text, cursor, length) {
81871
81899
  return new Token(value, cursor, i, TokenType.LiteralNumber, DataType.Number);
81872
81900
  }
81873
81901
 
81902
+ /**
81903
+ *
81904
+ * @param {string} text
81905
+ * @param {number} cursor
81906
+ * @returns {string}
81907
+ */
81908
+ function readQuote(text, cursor) {
81909
+ const char = text.charAt(cursor);
81910
+
81911
+ if (char !== '"' && char !== '\'') {
81912
+ throw new ParserError(cursor, "Expected \", found " + char + " instead", text);
81913
+ }
81914
+
81915
+ return char;
81916
+ }
81917
+
81918
+ /**
81919
+ *
81920
+ * @param {string} text
81921
+ * @param {number} cursor
81922
+ * @param {number} length
81923
+ * @returns {Token}
81924
+ */
81925
+ function readStringToken(text, cursor, length) {
81926
+
81927
+ let i = cursor;
81928
+
81929
+ const openingQuote = readQuote(text, i);
81930
+
81931
+ i++;
81932
+
81933
+ let char;
81934
+
81935
+ let value = '';
81936
+ const lastPossibleChar = length - 1;
81937
+
81938
+ for (; i < lastPossibleChar; i++) {
81939
+ char = text.charAt(i);
81940
+
81941
+ if (char === '\\') {
81942
+ i++;
81943
+ //read escape sequence
81944
+ char = text.charAt(i);
81945
+
81946
+ switch (char) {
81947
+ case 'n':
81948
+ value += '\n';
81949
+ break;
81950
+ case 't':
81951
+ value += '\t';
81952
+ break;
81953
+ case 'r':
81954
+ value += '\r';
81955
+ break;
81956
+ case 'b':
81957
+ value += '\b';
81958
+ break;
81959
+ case 'f':
81960
+ value += '\f';
81961
+ break;
81962
+ case 'v':
81963
+ value += '\v';
81964
+ break;
81965
+ case '0':
81966
+ value += '\0';
81967
+ break;
81968
+ case '\\':
81969
+ case "'":
81970
+ case '"':
81971
+ default:
81972
+ value += char;
81973
+ break;
81974
+ }
81975
+ } else if (char !== openingQuote) {
81976
+ value += char;
81977
+ } else {
81978
+ break;
81979
+ }
81980
+ }
81981
+
81982
+ char = text.charAt(i);
81983
+
81984
+ if (char !== openingQuote) {
81985
+ throw new ParserError(cursor, "Expected string terminator : " + openingQuote + ", but found '" + char + "' instead", text);
81986
+ }
81987
+
81988
+ i++;
81989
+
81990
+ return new Token(value, cursor, i, TokenType.LiteralString, DataType.String);
81991
+ }
81992
+
81874
81993
  /**
81875
81994
  *
81876
81995
  * @param {string} text
@@ -81929,6 +82048,7 @@ function readArrayLiteral(text, cursor, length) {
81929
82048
  * @returns {Token}
81930
82049
  */
81931
82050
  function readLiteralToken(text, cursor, length) {
82051
+
81932
82052
  const firstChar = text.charAt(cursor);
81933
82053
 
81934
82054
  switch (firstChar) {
@@ -83908,11 +84028,14 @@ class BinaryHeap {
83908
84028
  }
83909
84029
  }
83910
84030
 
84031
+ /**
84032
+ * Decorator that wraps another map and lets you observe mutations
84033
+ * @template K,V
84034
+ */
83911
84035
  class ObservedMap {
83912
84036
  /**
83913
84037
  * @template K,V
83914
84038
  * @constructor
83915
- * @property {number} size
83916
84039
  */
83917
84040
  constructor(source = new Map()) {
83918
84041
  this.on = {
@@ -83995,10 +84118,11 @@ const STATUS_NORMAL = 2;
83995
84118
  class Deque {
83996
84119
  /**
83997
84120
  * @template T
84121
+ * @param {number} [min_size]
83998
84122
  */
83999
- constructor(minSize = DEFAULT_SIZE) {
84123
+ constructor(min_size = DEFAULT_SIZE) {
84000
84124
 
84001
- const size = ceilPowerOfTwo(max2(1, minSize));
84125
+ const size = ceilPowerOfTwo(max2(1, min_size));
84002
84126
 
84003
84127
  /**
84004
84128
  * Using static array allocator to preserve data locality.
@@ -84009,15 +84133,31 @@ class Deque {
84009
84133
  */
84010
84134
  this.__data = new Array(size);
84011
84135
 
84136
+ /**
84137
+ *
84138
+ * @type {number}
84139
+ * @private
84140
+ */
84012
84141
  this.__head = 0;
84142
+ /**
84143
+ *
84144
+ * @type {number}
84145
+ * @private
84146
+ */
84013
84147
  this.__tail = 0;
84014
84148
 
84149
+ /**
84150
+ *
84151
+ * @type {number}
84152
+ * @private
84153
+ */
84015
84154
  this.__status = STATUS_EMPTY;
84016
84155
  }
84017
84156
 
84018
84157
  /**
84019
84158
  *
84020
84159
  * @param {boolean} adding
84160
+ * @private
84021
84161
  */
84022
84162
  resetStatus(adding) {
84023
84163
  const head = this.__head;
@@ -84036,11 +84176,12 @@ class Deque {
84036
84176
  * @returns {number}
84037
84177
  * @private
84038
84178
  */
84039
- __circularBiggerPos(current) {
84040
- // TODO this can be done faster using mod operator (%)
84179
+ __circular_next_position(current) {
84041
84180
  const next = current + 1;
84042
84181
 
84043
- return (next >= this.__data.length) ? 0 : next;
84182
+ const length = this.__data.length;
84183
+
84184
+ return (next >= length) ? 0 : next;
84044
84185
  }
84045
84186
 
84046
84187
  /**
@@ -84049,43 +84190,57 @@ class Deque {
84049
84190
  * @returns {number}
84050
84191
  * @private
84051
84192
  */
84052
- __circularSmallerPos(current) {
84193
+ __circular_previous_position(current) {
84053
84194
  const prev = current - 1;
84054
84195
  return (prev < 0) ? (this.__data.length - 1) : prev;
84055
84196
  }
84056
84197
 
84057
- __checkAndExpand() {
84198
+ __check_and_expand() {
84058
84199
  const status = this.__status;
84200
+
84059
84201
  if (status !== STATUS_FULL) {
84202
+ // queue still has space, we're done
84060
84203
  return;
84061
84204
  }
84205
+
84062
84206
  const length = this.__data.length;
84063
84207
 
84064
- if (Number.MAX_SAFE_INTEGER === length) {
84208
+ if (UINT32_MAX === length) {
84065
84209
  throw new Error('Maximum array size exceeded');
84066
84210
  }
84067
84211
 
84068
- let newLength = length * 2;
84212
+ let new_length = length * 2;
84213
+
84069
84214
  // bigger than Integer.MAX_VALUE
84070
- if (newLength < 0) {
84071
- newLength = Number.MAX_SAFE_INTEGER;
84215
+ if (new_length > UINT32_MAX) {
84216
+ new_length = UINT32_MAX;
84072
84217
  }
84073
84218
 
84074
- const newElements = new Array(newLength);
84219
+ /**
84220
+ *
84221
+ * @type {T[]}
84222
+ */
84223
+ const new_data = new Array(new_length);
84075
84224
 
84076
- // copy front portion of data
84077
84225
  const head = this.__head;
84078
84226
 
84079
- array_copy(this.__data, head, newElements, 0, length - head);
84080
- array_copy(this.__data, 0, newElements, length - head, head);
84227
+ // copy the front portion
84228
+ array_copy(this.__data, head, new_data, 0, length - head);
84229
+ // copy the remainder
84230
+ array_copy(this.__data, 0, new_data, length - head, head);
84081
84231
 
84082
84232
  this.__head = 0;
84083
84233
  this.__tail = length;
84234
+
84084
84235
  this.__status = STATUS_NORMAL;
84085
84236
 
84086
- this.__data = newElements;
84237
+ this.__data = new_data;
84087
84238
  }
84088
84239
 
84240
+ /**
84241
+ *
84242
+ * @return {boolean}
84243
+ */
84089
84244
  isEmpty() {
84090
84245
  return this.size() === 0;
84091
84246
  }
@@ -84097,7 +84252,7 @@ class Deque {
84097
84252
 
84098
84253
  do {
84099
84254
  this.__data[cursor] = undefined;
84100
- cursor = this.__circularBiggerPos(cursor);
84255
+ cursor = this.__circular_next_position(cursor);
84101
84256
  } while (cursor !== tail);
84102
84257
 
84103
84258
  this.__status = STATUS_EMPTY;
@@ -84126,32 +84281,45 @@ class Deque {
84126
84281
  /**
84127
84282
  *
84128
84283
  * @param {number} current
84129
- * @param {boolean} frontShift
84284
+ * @param {boolean} shift_front should we shift elements before the removed element or after?
84130
84285
  * @private
84131
84286
  */
84132
- __removeInternal(current, frontShift) {
84287
+ __remove_internal(current, shift_front) {
84133
84288
  let cursor = current;
84134
- if (frontShift) {
84289
+
84290
+ if (shift_front) {
84291
+
84292
+ // shift towards tail
84293
+
84135
84294
  const head = this.__head;
84295
+
84136
84296
  while (cursor !== head) {
84137
- const next = this.__circularSmallerPos(cursor);
84297
+ const next = this.__circular_previous_position(cursor);
84138
84298
  this.__data[cursor] = this.__data[next];
84139
84299
  cursor = next;
84140
84300
  }
84141
- this.__head = this.__circularBiggerPos(head);
84301
+
84302
+ this.__head = this.__circular_next_position(head);
84303
+
84142
84304
  } else {
84305
+
84306
+ // shift towards head
84307
+
84143
84308
  const tail = this.__tail;
84144
84309
 
84145
84310
  while (cursor !== tail) {
84146
- const next = this.__circularBiggerPos(cursor);
84311
+ const next = this.__circular_next_position(cursor);
84147
84312
  this.__data[cursor] = this.__data[next];
84148
84313
  cursor = next;
84149
84314
  }
84150
84315
 
84151
- this.__tail = this.__circularSmallerPos(tail);
84316
+ this.__tail = this.__circular_previous_position(tail);
84317
+
84152
84318
  }
84153
84319
 
84320
+ // fill in slot of last moved element
84154
84321
  this.__data[cursor] = undefined;
84322
+
84155
84323
  this.resetStatus(false);
84156
84324
  }
84157
84325
 
@@ -84167,7 +84335,7 @@ class Deque {
84167
84335
  return false;
84168
84336
  }
84169
84337
 
84170
- this.__removeInternal(i, true);
84338
+ this.__remove_internal(i, true);
84171
84339
 
84172
84340
  return true;
84173
84341
  }
@@ -84211,20 +84379,20 @@ class Deque {
84211
84379
  * @param {T} e
84212
84380
  */
84213
84381
  addFirst(e) {
84214
- this.__checkAndExpand();
84215
- this.__head = this.__circularSmallerPos(this.__head);
84382
+ this.__check_and_expand();
84383
+ this.__head = this.__circular_previous_position(this.__head);
84216
84384
  this.__data[this.__head] = e;
84217
84385
  this.resetStatus(true);
84218
84386
  }
84219
84387
 
84220
84388
  /**
84221
84389
  * Remove element from the front of the queue
84222
- * @returns {T}
84390
+ * @returns {T|undefined}
84223
84391
  */
84224
84392
  removeFirst() {
84225
84393
  const element = this.__data[this.__head];
84226
84394
  this.__data[this.__head] = undefined;
84227
- this.__head = this.__circularBiggerPos(this.__head);
84395
+ this.__head = this.__circular_next_position(this.__head);
84228
84396
  this.resetStatus(false);
84229
84397
  return element;
84230
84398
  }
@@ -84242,9 +84410,9 @@ class Deque {
84242
84410
  * @param {T} e
84243
84411
  */
84244
84412
  addLast(e) {
84245
- this.__checkAndExpand();
84413
+ this.__check_and_expand();
84246
84414
  this.__data[this.__tail] = e;
84247
- this.__tail = this.__circularBiggerPos(this.__tail);
84415
+ this.__tail = this.__circular_next_position(this.__tail);
84248
84416
  this.resetStatus(true);
84249
84417
  }
84250
84418
 
@@ -84253,7 +84421,7 @@ class Deque {
84253
84421
  * @returns {T}
84254
84422
  */
84255
84423
  removeLast() {
84256
- const last = this.__circularSmallerPos(this.__tail);
84424
+ const last = this.__circular_previous_position(this.__tail);
84257
84425
  const element = this.__data[last];
84258
84426
  this.__data[last] = undefined;
84259
84427
  this.__tail = last;
@@ -84264,10 +84432,10 @@ class Deque {
84264
84432
 
84265
84433
  /**
84266
84434
  * Peek element from the end of the queue without removing it
84267
- * @returns {T}
84435
+ * @returns {T|undefined}
84268
84436
  */
84269
84437
  getLast() {
84270
- const last = this.__circularSmallerPos(this.__tail);
84438
+ const last = this.__circular_previous_position(this.__tail);
84271
84439
  return this.__data[last];
84272
84440
  }
84273
84441
  }
@@ -85975,35 +86143,44 @@ Preloader.prototype.load = function (assetManager) {
85975
86143
  return this;
85976
86144
  };
85977
86145
 
85978
- class AbstractMetric {
85979
- /**
85980
- *
85981
- * @param {number} value
85982
- * @returns {void}
85983
- */
85984
- record(value) {
85985
- throw new Error('Not implemented');
85986
- }
86146
+ /**
86147
+ * @template V
86148
+ * @param {V[]} data
86149
+ * @param {number} [start]
86150
+ * @param {number} [end]
86151
+ * @return {number}
86152
+ */
86153
+ function array_compute_max(data, start = 0, end = data.length) {
86154
+ let result = Number.NEGATIVE_INFINITY;
85987
86155
 
85988
- /**
85989
- * @returns {number|undefined}
85990
- */
85991
- getLastRecord() {
85992
- throw new Error('Not implemented');
86156
+ for (let i = start; i < end; i++) {
86157
+ const value = data[i];
86158
+ if (value > result) {
86159
+ result = value;
86160
+ }
85993
86161
  }
85994
86162
 
85995
- /**
85996
- *
85997
- * @param {MetricStatistics} result
85998
- * @returns {boolean} whether metric was successfully computed or not
85999
- */
86000
- computeStats(result) {
86001
- throw new Error('Not implemented');
86002
- }
86163
+ return result;
86164
+ }
86165
+
86166
+ /**
86167
+ * @template V
86168
+ * @param {V[]} data
86169
+ * @param {number} [start]
86170
+ * @param {number} [end]
86171
+ * @return {number}
86172
+ */
86173
+ function array_compute_min(data, start = 0, end = data.length) {
86174
+ let result = Number.POSITIVE_INFINITY;
86003
86175
 
86004
- clear() {
86005
- throw new Error('Not implemented');
86176
+ for (let i = start; i < end; i++) {
86177
+ const value = data[i];
86178
+ if (value < result) {
86179
+ result = value;
86180
+ }
86006
86181
  }
86182
+
86183
+ return result;
86007
86184
  }
86008
86185
 
86009
86186
  class RingBuffer {
@@ -86273,44 +86450,35 @@ function computeStatisticalPartialMedian(values, start, end) {
86273
86450
  return copy[position];
86274
86451
  }
86275
86452
 
86276
- /**
86277
- * @template V
86278
- * @param {V[]} data
86279
- * @param {number} [start]
86280
- * @param {number} [end]
86281
- * @return {number}
86282
- */
86283
- function computeArrayMax(data, start = 0, end = data.length) {
86284
- let result = Number.NEGATIVE_INFINITY;
86285
-
86286
- for (let i = start; i < end; i++) {
86287
- const value = data[i];
86288
- if (value > result) {
86289
- result = value;
86290
- }
86453
+ class AbstractMetric {
86454
+ /**
86455
+ *
86456
+ * @param {number} value
86457
+ * @returns {void}
86458
+ */
86459
+ record(value) {
86460
+ throw new Error('Not implemented');
86291
86461
  }
86292
86462
 
86293
- return result;
86294
- }
86295
-
86296
- /**
86297
- * @template V
86298
- * @param {V[]} data
86299
- * @param {number} [start]
86300
- * @param {number} [end]
86301
- * @return {number}
86302
- */
86303
- function computeArrayMin(data, start = 0, end = data.length) {
86304
- let result = Number.POSITIVE_INFINITY;
86463
+ /**
86464
+ * @returns {number|undefined}
86465
+ */
86466
+ getLastRecord() {
86467
+ throw new Error('Not implemented');
86468
+ }
86305
86469
 
86306
- for (let i = start; i < end; i++) {
86307
- const value = data[i];
86308
- if (value < result) {
86309
- result = value;
86310
- }
86470
+ /**
86471
+ *
86472
+ * @param {MetricStatistics} result
86473
+ * @returns {boolean} whether metric was successfully computed or not
86474
+ */
86475
+ computeStats(result) {
86476
+ throw new Error('Not implemented');
86311
86477
  }
86312
86478
 
86313
- return result;
86479
+ clear() {
86480
+ throw new Error('Not implemented');
86481
+ }
86314
86482
  }
86315
86483
 
86316
86484
  class RingBufferMetric extends AbstractMetric {
@@ -86367,8 +86535,8 @@ class RingBufferMetric extends AbstractMetric {
86367
86535
 
86368
86536
  result.mean = computeStatisticalMean(array, 0, data_count);
86369
86537
  result.median = computeStatisticalPartialMedian(array, 0, data_count - 1);
86370
- result.max = computeArrayMax(array, 0, data_count);
86371
- result.min = computeArrayMin(array, 0, data_count);
86538
+ result.max = array_compute_max(array, 0, data_count);
86539
+ result.min = array_compute_min(array, 0, data_count);
86372
86540
 
86373
86541
  return true;
86374
86542
 
@@ -110072,7 +110240,7 @@ class LightManager {
110072
110240
  __build_view_frustum(camera) {
110073
110241
  frustum_from_camera(camera, this.__view_frustum, false);
110074
110242
 
110075
- arraySwapElements(this.__view_frustum.planes, 4, 5);
110243
+ array_swap_one(this.__view_frustum.planes, 4, 5);
110076
110244
 
110077
110245
  this.__build_view_frustum_points();
110078
110246
  }