@woosh/meep-engine 2.69.0 → 2.71.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 (50) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/build/meep.cjs +498 -429
  4. package/build/meep.min.js +1 -1
  5. package/build/meep.module.js +498 -429
  6. package/package.json +1 -1
  7. package/src/core/__module.js +1 -0
  8. package/src/core/binary/BinaryBuffer.js +37 -31
  9. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +21 -24
  10. package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +2 -4
  11. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +3 -2
  12. package/src/core/geom/3d/morton/v3_morton_encode_bounded.js +34 -0
  13. package/src/core/geom/3d/morton/v3_morton_encode_transformed.js +2 -1
  14. package/src/core/geom/3d/quaternion/quat3_createFromAxisAngle.js +11 -0
  15. package/src/core/geom/3d/quaternion/quat_decode_from_uint32.js +53 -0
  16. package/src/core/geom/3d/quaternion/quat_encode_to_uint32.js +105 -0
  17. package/src/core/geom/Quaternion.js +8 -142
  18. package/src/core/geom/Vector2.js +6 -7
  19. package/src/core/geom/Vector3.js +15 -82
  20. package/src/core/geom/vec3/v3_binary_equality_decode.js +44 -0
  21. package/src/core/geom/vec3/v3_binary_equality_encode.js +47 -0
  22. package/src/core/math/remap.js +5 -1
  23. package/src/core/math/statistics/computeStatisticalPartialMedian.js +1 -1
  24. package/src/core/primitives/numbers/computeHashFloat.js +2 -2
  25. package/src/core/process/task/Task.js +53 -34
  26. package/src/engine/achievements/AchievementManager.js +19 -19
  27. package/src/engine/animation/curve/compression/prototypeCurveCompression.js +6 -6
  28. package/src/engine/animation/curve/draw/build_plot_entity_from_array.js +11 -6
  29. package/src/engine/ecs/dynamic_actions/DynamicActor.js +5 -10
  30. package/src/engine/ecs/dynamic_actions/DynamicActorSystem.js +82 -89
  31. package/src/engine/ecs/dynamic_actions/RuleExecution.js +10 -12
  32. package/src/engine/ecs/gui/GUIElement.js +44 -61
  33. package/src/engine/ecs/gui/GUIElementSystem.js +26 -24
  34. package/src/engine/ecs/gui/hud/HeadsUpDisplay.js +12 -15
  35. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +15 -15
  36. package/src/engine/ecs/gui/parallax/GuiElementParallax.js +3 -3
  37. package/src/engine/ecs/gui/parallax/GuiElementParallaxSystem.js +2 -2
  38. package/src/engine/ecs/gui/position/ViewportPosition.js +5 -50
  39. package/src/engine/ecs/gui/position/ViewportPositionSerializationAdapter.js +42 -0
  40. package/src/engine/ecs/transform/Transform.js +8 -9
  41. package/src/engine/ecs/transform/TransformSerializationAdapter.js +20 -14
  42. package/src/engine/graphics/ecs/mesh/Mesh.js +11 -11
  43. package/src/engine/graphics/impostors/octahedral/prototypeBaker.js +20 -20
  44. package/src/engine/graphics/texture/sprite/prototypeSpriteCutoutGeometry.js +12 -12
  45. package/src/engine/navigation/ecs/components/PathSerializationAdapter.js +1 -4
  46. package/src/core/binary/ValidatingBitSetWrapper.js +0 -81
  47. package/src/core/binary/jsonToStringToByteArray.js +0 -27
  48. package/src/engine/ecs/components/AreaOfEffect.js +0 -12
  49. package/src/engine/ecs/components/Mortality.js +0 -27
  50. package/src/engine/ecs/systems/AreaOfEffectSystem.js +0 -48
package/build/meep.cjs CHANGED
@@ -1764,6 +1764,27 @@ function clamp$1(value, min, max) {
1764
1764
  }
1765
1765
  }
1766
1766
 
1767
+ /**
1768
+ * Very small value, used for comparison when compensation for rounding error is required
1769
+ * @type {number}
1770
+ */
1771
+ const EPSILON = 0.000001;
1772
+
1773
+ /**
1774
+ * Comparison of two numbers with a given tolerance
1775
+ * @param {number} a
1776
+ * @param {number} b
1777
+ * @param {number} tolerance
1778
+ * @returns {boolean}
1779
+ */
1780
+ function epsilonEquals(a, b, tolerance) {
1781
+ assert.isNumber(a, 'a');
1782
+ assert.isNumber(b, 'b');
1783
+ assert.isNumber(tolerance, 'tolerance');
1784
+
1785
+ return Math.abs(a - b) <= tolerance;
1786
+ }
1787
+
1767
1788
  /**
1768
1789
  * Linear interpolation between two values controlled by a given fraction
1769
1790
  * @param {number} a
@@ -1775,13 +1796,190 @@ function lerp$1(a, b, fraction) {
1775
1796
  return (b - a) * fraction + a;
1776
1797
  }
1777
1798
 
1799
+ /**
1800
+ * Returns lowest value out of 2 supplied
1801
+ * @param {number} a
1802
+ * @param {number} b
1803
+ * @returns {number}
1804
+ */
1805
+ function min2(a, b) {
1806
+ return a < b ? a : b;
1807
+ }
1808
+
1778
1809
  /**
1779
1810
  *
1780
1811
  * @param {number} v
1781
- * @returns {number} +1 if v>0, 0 if v == 0, -1 if v<0
1812
+ * @returns {number}
1782
1813
  */
1783
- function sign$1(v) {
1784
- return v > 0 ? 1 : (v < 0 ? -1 : 0);
1814
+ function computeHashFloat(v) {
1815
+ //we break the number up into fractional and whole parts
1816
+ const whole = v | 0;
1817
+
1818
+ const fraction = v - whole;
1819
+
1820
+ //fractional part is scaled up into int32 range, this inexact method, as it will produce 0 hash for values below a certain threshold
1821
+ const fractionHash = fraction * 1367130550;
1822
+
1823
+ //take XOR of both parts
1824
+ return fractionHash ^ whole;
1825
+ }
1826
+
1827
+ const K = Math.SQRT1_2 / 511;
1828
+
1829
+ /**
1830
+ * Based on GDC talk from Bungie on destiny, compressing quaternions for animation
1831
+ * @param {number[]} output
1832
+ * @param {number} output_offset
1833
+ * @param {number} value
1834
+ */
1835
+ function quat_decode_from_uint32(output, output_offset, value) {
1836
+ //read components
1837
+ const max = value & 0x3;
1838
+
1839
+ const iv0 = (value >> 2) & 0x3FF;
1840
+ const iv1 = (value >> 12) & 0x3FF;
1841
+ const iv2 = (value >> 22) & 0x3FF;
1842
+
1843
+ //scale components back to quaternion range
1844
+ const v0 = iv0 * K - Math.SQRT1_2;
1845
+ const v1 = iv1 * K - Math.SQRT1_2;
1846
+ const v2 = iv2 * K - Math.SQRT1_2;
1847
+
1848
+ //restore dropped component using quaternion identity: x^2 + y^2 + z^2 + w^2 = 1
1849
+ const dropped_2 = 1 - v0 * v0 - v1 * v1 - v2 * v2;
1850
+ const dropped = Math.sqrt(dropped_2);
1851
+
1852
+ let x, y, z, w;
1853
+ if (max === 0) {
1854
+ x = dropped;
1855
+ y = v0;
1856
+ z = v1;
1857
+ w = v2;
1858
+ } else if (max === 1) {
1859
+ x = v0;
1860
+ y = dropped;
1861
+ z = v1;
1862
+ w = v2;
1863
+ } else if (max === 2) {
1864
+ x = v0;
1865
+ y = v1;
1866
+ z = dropped;
1867
+ w = v2;
1868
+ } else {
1869
+ x = v0;
1870
+ y = v1;
1871
+ z = v2;
1872
+ w = dropped;
1873
+ }
1874
+
1875
+ output[output_offset] = x;
1876
+ output[output_offset + 1] = y;
1877
+ output[output_offset + 2] = z;
1878
+ output[output_offset + 3] = w;
1879
+ }
1880
+
1881
+ /**
1882
+ * Based on GDC talk from Bungie on destiny, compressing quaternions for animation
1883
+ * @param {number} x
1884
+ * @param {number} y
1885
+ * @param {number} z
1886
+ * @param {number} w
1887
+ * @returns {number}
1888
+ */
1889
+ function quat_encode_to_uint32(x, y, z, w) {
1890
+
1891
+ const absX = Math.abs(x);
1892
+ const absY = Math.abs(y);
1893
+ const absZ = Math.abs(z);
1894
+ const absW = Math.abs(w);
1895
+
1896
+ let v0, v1, v2, dropped, max;
1897
+
1898
+ //pick max component
1899
+ if (absY > absX) {
1900
+ if (absY > absZ) {
1901
+ if (absY > absW) {
1902
+ //absY is max
1903
+ max = 1;
1904
+ } else {
1905
+ //absW is max
1906
+ max = 3;
1907
+ }
1908
+ } else if (absZ > absW) {
1909
+ //absZ is max
1910
+ max = 2;
1911
+ } else {
1912
+ //absW is max
1913
+ max = 3;
1914
+ }
1915
+ } else if (absX > absZ) {
1916
+ if (absX > absW) {
1917
+ max = 0;
1918
+ } else {
1919
+ max = 3;
1920
+ }
1921
+ } else if (absZ > absW) {
1922
+ max = 2;
1923
+ } else {
1924
+ max = 3;
1925
+ }
1926
+
1927
+
1928
+ //max will be dropped
1929
+ if (max === 0) {
1930
+ //dropping x
1931
+ v0 = y;
1932
+ v1 = z;
1933
+ v2 = w;
1934
+
1935
+ dropped = x;
1936
+ } else if (max === 1) {
1937
+ //dropping y
1938
+ v0 = x;
1939
+ v1 = z;
1940
+ v2 = w;
1941
+
1942
+ dropped = y;
1943
+ } else if (max === 2) {
1944
+ //dropping z
1945
+ v0 = x;
1946
+ v1 = y;
1947
+ v2 = w;
1948
+
1949
+ dropped = z;
1950
+ } else {
1951
+ //dropping w
1952
+ v0 = x;
1953
+ v1 = y;
1954
+ v2 = z;
1955
+
1956
+ dropped = w;
1957
+ }
1958
+
1959
+ if (dropped < 0) {
1960
+ //reconstructing dropped value is only possible if it is positive, so we invert the quaternion to make dropped value positive
1961
+ v0 = -v0;
1962
+ v1 = -v1;
1963
+ v2 = -v2;
1964
+ }
1965
+
1966
+ const l = Math.hypot(v0, v1, v2, dropped);
1967
+ const m = 511 / (l * Math.SQRT1_2);
1968
+
1969
+ //re-normalize the remaining components to 10 bit UINT value
1970
+ const oV0 = Math.round(v0 * m + 511);
1971
+ const oV1 = Math.round(v1 * m + 511);
1972
+ const oV2 = Math.round(v2 * m + 511);
1973
+
1974
+ assert.ok(oV0 <= 1023 && oV0 >= 0, `expected 0 <= ov0 <= 1023, instead was '${oV0}'`);
1975
+ assert.ok(oV1 <= 1023 && oV1 >= 0, `expected 0 <= ov1 <= 1023, instead was '${oV1}'`);
1976
+ assert.ok(oV2 <= 1023 && oV2 >= 0, `expected 0 <= ov2 <= 1023, instead was '${oV2}'`);
1977
+
1978
+
1979
+ return (max & 0x3)
1980
+ | ((oV0 & 0x3FF) << 2)
1981
+ | ((oV1 & 0x3FF) << 12)
1982
+ | ((oV2 & 0x3FF) << 22);
1785
1983
  }
1786
1984
 
1787
1985
  /**
@@ -1800,13 +1998,11 @@ function v3_dot(x0, y0, z0, x1, y1, z1) {
1800
1998
 
1801
1999
  /**
1802
2000
  *
1803
- * @param {number} x
1804
- * @param {number} y
1805
- * @param {number} z
1806
- * @return {number}
2001
+ * @param {number} v
2002
+ * @returns {number} +1 if v>0, 0 if v == 0, -1 if v<0
1807
2003
  */
1808
- function v3_length_sqr(x, y, z) {
1809
- return x * x + y * y + z * z;
2004
+ function sign$1(v) {
2005
+ return v > 0 ? 1 : (v < 0 ? -1 : 0);
1810
2006
  }
1811
2007
 
1812
2008
  /**
@@ -1862,6 +2058,110 @@ function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
1862
2058
  return clamp$1(d / l, -1, 1);
1863
2059
  }
1864
2060
 
2061
+ /**
2062
+ *
2063
+ * @param {BinaryBuffer} buffer
2064
+ * @param {number[]} result
2065
+ * @param {number} result_offset
2066
+ */
2067
+ function v3_binary_equality_decode(buffer, result, result_offset) {
2068
+ const header = buffer.readUint8();
2069
+
2070
+ let x = 0;
2071
+ let y = 0;
2072
+ let z = 0;
2073
+
2074
+ if ((header & 7) === 7) {
2075
+ //all scale components are the same
2076
+ x = buffer.readFloat32();
2077
+ y = x;
2078
+ z = x;
2079
+ } else if ((header & 1) === 1) {
2080
+ //X and Y are the same, Z is different
2081
+ x = buffer.readFloat32();
2082
+ y = x;
2083
+ z = buffer.readFloat32();
2084
+ } else if ((header & 2) === 2) {
2085
+ //Y and Z are the same, X is different
2086
+ x = buffer.readFloat32();
2087
+ y = buffer.readFloat32();
2088
+ z = y;
2089
+ } else if ((header & 4) === 4) {
2090
+ //X and Z are the same, Y is different
2091
+ x = buffer.readFloat32();
2092
+ y = buffer.readFloat32();
2093
+ z = x;
2094
+ } else {
2095
+ //scale components are different
2096
+ x = buffer.readFloat32();
2097
+ y = buffer.readFloat32();
2098
+ z = buffer.readFloat32();
2099
+ }
2100
+
2101
+ result[result_offset] = x;
2102
+ result[result_offset + 1] = y;
2103
+ result[result_offset + 2] = z;
2104
+ }
2105
+
2106
+ /**
2107
+ *
2108
+ * @param {BinaryBuffer} buffer
2109
+ * @param {number} x
2110
+ * @param {number} y
2111
+ * @param {number} z
2112
+ */
2113
+ function v3_binary_equality_encode(buffer, x, y, z){
2114
+
2115
+ let header = 0;
2116
+
2117
+ if (x === y) {
2118
+ header |= 1;
2119
+ }
2120
+
2121
+ if (y === z) {
2122
+ header |= 2;
2123
+ }
2124
+
2125
+ if (x === z) {
2126
+ header |= 4;
2127
+ }
2128
+
2129
+ buffer.writeUint8(header);
2130
+
2131
+ if ((header & 7) === 7) {
2132
+ //all components are the same
2133
+ buffer.writeFloat32(x);
2134
+ } else if (header === 1) {
2135
+ //X and Y are the same, Z is different
2136
+ buffer.writeFloat32(x);
2137
+ buffer.writeFloat32(z);
2138
+ } else if (header === 2) {
2139
+ //Y and Z are the same, X is different
2140
+ buffer.writeFloat32(x);
2141
+ buffer.writeFloat32(y);
2142
+ } else if (header === 4) {
2143
+ //X and Z are the same, Y is different
2144
+ buffer.writeFloat32(x);
2145
+ buffer.writeFloat32(y);
2146
+ } else {
2147
+ //scale components are different
2148
+ buffer.writeFloat32(x);
2149
+ buffer.writeFloat32(y);
2150
+ buffer.writeFloat32(z);
2151
+ }
2152
+ }
2153
+
2154
+ /**
2155
+ *
2156
+ * @param {number} x
2157
+ * @param {number} y
2158
+ * @param {number} z
2159
+ * @return {number}
2160
+ */
2161
+ function v3_length_sqr(x, y, z) {
2162
+ return x * x + y * y + z * z;
2163
+ }
2164
+
1865
2165
  /**
1866
2166
  *
1867
2167
  * @param {Vector3} result
@@ -1933,45 +2233,6 @@ function v3_slerp(
1933
2233
  result.set(x, y, z);
1934
2234
  }
1935
2235
 
1936
- /**
1937
- *
1938
- * @param {number} v
1939
- * @returns {number}
1940
- */
1941
- function computeHashFloat(v) {
1942
- //we break the number up into fractional and whole parts
1943
- const fraction = v % 1;
1944
-
1945
- const whole = v | 0;
1946
-
1947
- //fractional part is scaled up into int32 range, this inexact method, as it will produce 0 hash for values below a certain threshold
1948
- const fractionHash = fraction * 1367130550;
1949
-
1950
- //take XOR of both parts
1951
- return fractionHash ^ whole;
1952
- }
1953
-
1954
- /**
1955
- * Comparison of two numbers with a given tolerance
1956
- * @param {number} a
1957
- * @param {number} b
1958
- * @param {number} tolerance
1959
- * @returns {boolean}
1960
- */
1961
- function epsilonEquals(a, b, tolerance) {
1962
- assert.isNumber(a, 'a');
1963
- assert.isNumber(b, 'b');
1964
- assert.isNumber(tolerance, 'tolerance');
1965
-
1966
- return Math.abs(a - b) <= tolerance;
1967
- }
1968
-
1969
- /**
1970
- * Very small value, used for comparison when compensation for rounding error is required
1971
- * @type {number}
1972
- */
1973
- const EPSILON = 0.000001;
1974
-
1975
2236
  /**
1976
2237
  * @author Alex Goldring
1977
2238
  * @copyright Alex Goldring 2015
@@ -2816,100 +3077,31 @@ let Vector3$1 = class Vector3 {
2816
3077
  /**
2817
3078
  *
2818
3079
  * @param {BinaryBuffer} buffer
3080
+ * @deprecated use dedicated method directly instead
2819
3081
  */
2820
3082
  toBinaryBufferFloat32_EqualityEncoded(buffer) {
2821
3083
  const x = this.x;
2822
3084
  const y = this.y;
2823
3085
  const z = this.z;
2824
3086
 
2825
- let header = 0;
2826
-
2827
- if (x === y) {
2828
- header |= 1;
2829
- }
2830
-
2831
- if (y === z) {
2832
- header |= 2;
2833
- }
2834
-
2835
- if (x === z) {
2836
- header |= 4;
2837
- }
2838
-
2839
- buffer.writeUint8(header);
2840
-
2841
- if ((header & 7) === 7) {
2842
- //all components are the same
2843
- buffer.writeFloat32(x);
2844
- } else if (header === 1) {
2845
- //X and Y are the same, Z is different
2846
- buffer.writeFloat32(x);
2847
- buffer.writeFloat32(z);
2848
- } else if (header === 2) {
2849
- //Y and Z are the same, X is different
2850
- buffer.writeFloat32(x);
2851
- buffer.writeFloat32(y);
2852
- } else if (header === 4) {
2853
- //X and Z are the same, Y is different
2854
- buffer.writeFloat32(x);
2855
- buffer.writeFloat32(y);
2856
- } else {
2857
- //scale components are different
2858
- buffer.writeFloat32(x);
2859
- buffer.writeFloat32(y);
2860
- buffer.writeFloat32(z);
2861
- }
3087
+ v3_binary_equality_encode(buffer, x, y, z);
2862
3088
  }
2863
3089
 
2864
3090
  /**
2865
3091
  * Uses an extra byte for a header. Only writes unique components. Useful for things like scale where all components usually have the same value
2866
3092
  * @param {BinaryBuffer} buffer
3093
+ * @deprecated use dedicated method directly instead
2867
3094
  */
2868
3095
  fromBinaryBufferFloat32_EqualityEncoded(buffer) {
2869
- const header = buffer.readUint8();
2870
-
2871
- let x = 0;
2872
- let y = 0;
2873
- let z = 0;
2874
-
2875
- if ((header & 7) === 7) {
2876
- //all scale components are the same
2877
- x = buffer.readFloat32();
2878
- y = x;
2879
- z = x;
2880
- } else if ((header & 1) === 1) {
2881
- //X and Y are the same, Z is different
2882
- x = buffer.readFloat32();
2883
- y = x;
2884
- z = buffer.readFloat32();
2885
- } else if ((header & 2) === 2) {
2886
- //Y and Z are the same, X is different
2887
- x = buffer.readFloat32();
2888
- y = buffer.readFloat32();
2889
- z = y;
2890
- } else if ((header & 4) === 4) {
2891
- //X and Z are the same, Y is different
2892
- x = buffer.readFloat32();
2893
- y = buffer.readFloat32();
2894
- z = x;
2895
- } else {
2896
- //scale components are different
2897
- x = buffer.readFloat32();
2898
- y = buffer.readFloat32();
2899
- z = buffer.readFloat32();
2900
- }
2901
-
2902
- this.set(x, y, z);
3096
+ v3_binary_equality_decode(buffer, this, 0);
2903
3097
  }
2904
3098
 
2905
3099
  hash() {
2906
- let hash = computeHashFloat(this.x);
2907
-
2908
- hash = ((hash << 5) - hash) + computeHashFloat(this.y);
2909
-
2910
- hash = ((hash << 5) - hash) + computeHashFloat(this.z);
3100
+ const x = computeHashFloat(this.x);
3101
+ const y = computeHashFloat(this.y);
3102
+ const z = computeHashFloat(this.z);
2911
3103
 
2912
- return hash;
3104
+ return x ^ (y << 1) ^ (z << 2);
2913
3105
  }
2914
3106
 
2915
3107
 
@@ -3067,16 +3259,6 @@ Vector3$1.typeName = "Vector3";
3067
3259
  */
3068
3260
  Vector3$1._dot = v3_dot;
3069
3261
 
3070
- /**
3071
- * Returns lowest value out of 2 supplied
3072
- * @param {number} a
3073
- * @param {number} b
3074
- * @returns {number}
3075
- */
3076
- function min2(a, b) {
3077
- return a < b ? a : b;
3078
- }
3079
-
3080
3262
  /**
3081
3263
  * Created by Alex on 10/03/14.
3082
3264
  */
@@ -3086,18 +3268,6 @@ const forward = new Vector3$1();
3086
3268
  const up = new Vector3$1();
3087
3269
  const right = new Vector3$1();
3088
3270
 
3089
- /**
3090
- * just in case you need that function also
3091
- * @param {Vector3} axis
3092
- * @param {number} angle
3093
- * @param {Quaternion} result
3094
- */
3095
- function quat3_createFromAxisAngle(axis, angle, result) {
3096
- const halfAngle = angle * .5;
3097
- const s = Math.sin(halfAngle);
3098
- result.set(axis.x * s, axis.y * s, axis.z * s, Math.cos(halfAngle));
3099
- }
3100
-
3101
3271
  let Quaternion$1 = class Quaternion {
3102
3272
  /**
3103
3273
  *
@@ -4520,31 +4690,7 @@ let Quaternion$1 = class Quaternion {
4520
4690
  * @param {number} value
4521
4691
  */
4522
4692
  decodeFromUint32(value) {
4523
- //read components
4524
- const max = value & 0x3;
4525
-
4526
- const iv0 = (value >> 2) & 0x3FF;
4527
- const iv1 = (value >> 12) & 0x3FF;
4528
- const iv2 = (value >> 22) & 0x3FF;
4529
-
4530
- //scale components back to quaternion range
4531
- const v0 = (iv0 / 511 - 1) * K_CONST;
4532
- const v1 = (iv1 / 511 - 1) * K_CONST;
4533
- const v2 = (iv2 / 511 - 1) * K_CONST;
4534
-
4535
- //restore dropped component using quaternion identity: x^2 + y^2 + z^2 + w^2 = 1
4536
- const dropped_2 = 1 - v0 * v0 - v1 * v1 - v2 * v2;
4537
- const dropped = Math.sqrt(dropped_2);
4538
-
4539
- if (max === 0) {
4540
- this.set(dropped, v0, v1, v2);
4541
- } else if (max === 1) {
4542
- this.set(v0, dropped, v1, v2);
4543
- } else if (max === 2) {
4544
- this.set(v0, v1, dropped, v2);
4545
- } else {
4546
- this.set(v0, v1, v2, dropped);
4547
- }
4693
+ quat_decode_from_uint32(this, 0, value);
4548
4694
  }
4549
4695
 
4550
4696
  /**
@@ -4552,107 +4698,7 @@ let Quaternion$1 = class Quaternion {
4552
4698
  * @returns {number}
4553
4699
  */
4554
4700
  encodeToUint32() {
4555
- const x = this.x;
4556
- const y = this.y;
4557
- const z = this.z;
4558
- const w = this.w;
4559
-
4560
- const absX = Math.abs(x);
4561
- const absY = Math.abs(y);
4562
- const absZ = Math.abs(z);
4563
- const absW = Math.abs(w);
4564
-
4565
- let max = 0;
4566
-
4567
- //pick max component
4568
- if (absY > absX) {
4569
- if (absY > absZ) {
4570
- if (absY > absW) {
4571
- //absY is max
4572
- max = 1;
4573
- } else {
4574
- //absW is max
4575
- max = 3;
4576
- }
4577
- } else if (absZ > absW) {
4578
- //absZ is max
4579
- max = 2;
4580
- } else {
4581
- //absW is max
4582
- max = 3;
4583
- }
4584
- } else if (absX > absZ) {
4585
- if (absX > absW) {
4586
- max = 0;
4587
- } else {
4588
- max = 3;
4589
- }
4590
- } else if (absZ > absW) {
4591
- max = 2;
4592
- } else {
4593
- max = 3;
4594
- }
4595
-
4596
- let v0, v1, v2, dropped;
4597
-
4598
- //max will be dropped
4599
- if (max === 0) {
4600
- //dropping x
4601
- v0 = y;
4602
- v1 = z;
4603
- v2 = w;
4604
-
4605
- dropped = x;
4606
- } else if (max === 1) {
4607
- //dropping y
4608
- v0 = x;
4609
- v1 = z;
4610
- v2 = w;
4611
-
4612
- dropped = y;
4613
- } else if (max === 2) {
4614
- //dropping z
4615
- v0 = x;
4616
- v1 = y;
4617
- v2 = w;
4618
-
4619
- dropped = z;
4620
- } else {
4621
- //dropping w
4622
- v0 = x;
4623
- v1 = y;
4624
- v2 = z;
4625
-
4626
- dropped = w;
4627
- }
4628
-
4629
- if (dropped < 0) {
4630
- //reconstructing dropped value is only possible if it is positive, so we invert the quaternion to make dropped value positive
4631
- v0 = -v0;
4632
- v1 = -v1;
4633
- v2 = -v2;
4634
- }
4635
-
4636
- const l = Math.sqrt(x * x + y * y + z * z + w * w);
4637
- const m = 1 / (l * K_CONST);
4638
-
4639
- //re-normalize the remaining components to 10 bit UINT value
4640
- const oV0 = Math.round((v0 * m + 1) * 511);
4641
- const oV1 = Math.round((v1 * m + 1) * 511);
4642
- const oV2 = Math.round((v2 * m + 1) * 511);
4643
-
4644
- assert.ok(oV0 <= 1023 && oV0 >= 0, `expected 0 <= ov0 <= 1023, instead was '${oV0}'`);
4645
- assert.ok(oV1 <= 1023 && oV1 >= 0, `expected 0 <= ov1 <= 1023, instead was '${oV1}'`);
4646
- assert.ok(oV2 <= 1023 && oV2 >= 0, `expected 0 <= ov2 <= 1023, instead was '${oV2}'`);
4647
-
4648
-
4649
- const result = (max & 0x3)
4650
- | ((oV0 & 0x3FF) << 2)
4651
- | ((oV1 & 0x3FF) << 12)
4652
- | ((oV2 & 0x3FF) << 22)
4653
- ;
4654
-
4655
- return result;
4701
+ return quat_encode_to_uint32(this.x, this.y, this.z, this.w);
4656
4702
  }
4657
4703
 
4658
4704
  /**
@@ -4839,13 +4885,7 @@ Quaternion$1.identity = Object.freeze(new Quaternion$1(0, 0, 0, 1));
4839
4885
  const axis = new Vector3$1();
4840
4886
 
4841
4887
 
4842
- const tempvec3 = new Vector3$1();
4843
-
4844
- /**
4845
- * Used in UINT32 packing
4846
- * @type {number}
4847
- */
4848
- const K_CONST = 0.70710678118; // 1/sqrt(2)
4888
+ const tempvec3 = new Vector3$1();
4849
4889
 
4850
4890
  /**
4851
4891
  * @readonly
@@ -5112,8 +5152,7 @@ class Transform {
5112
5152
  * @returns {boolean}
5113
5153
  */
5114
5154
  equals(other) {
5115
- return other.isTransform
5116
- && this.position.equals(other.position)
5155
+ return this.position.equals(other.position)
5117
5156
  && this.rotation.equals(other.rotation)
5118
5157
  && this.scale.equals(other.scale);
5119
5158
  }
@@ -48947,11 +48986,7 @@ class Vector2 {
48947
48986
  const x = computeHashFloat(this.x);
48948
48987
  const y = computeHashFloat(this.y);
48949
48988
 
48950
- let hash = ((x << 5) - x) + y;
48951
-
48952
- hash |= 0; //convert to 32bit int
48953
-
48954
- return hash;
48989
+ return ((x << 5) - x) + y;
48955
48990
  }
48956
48991
 
48957
48992
  /**
@@ -48962,8 +48997,11 @@ class Vector2 {
48962
48997
  const sin = Math.sin(angle);
48963
48998
  const cos = Math.cos(angle);
48964
48999
 
48965
- const x = this.x * cos - this.y * sin;
48966
- const y = this.x * sin + this.y * cos;
49000
+ const _x = this.x;
49001
+ const _y = this.y;
49002
+
49003
+ const x = _x * cos - _y * sin;
49004
+ const y = _x * sin + _y * cos;
48967
49005
 
48968
49006
  this.set(x, y);
48969
49007
  }
@@ -56786,6 +56824,39 @@ function mortonEncode_magicbits(x, y, z) {
56786
56824
  return x_bits | y_bits | z_bits;
56787
56825
  }
56788
56826
 
56827
+ /**
56828
+ * @param {number} x
56829
+ * @param {number} y
56830
+ * @param {number} z
56831
+ * @param {number[]} bounds
56832
+ * @returns {number}
56833
+ */
56834
+ function v3_morton_encode_bounded(x, y, z, bounds) {
56835
+
56836
+ const bounds_x0 = bounds[0];
56837
+ const bounds_y0 = bounds[1];
56838
+ const bounds_z0 = bounds[2];
56839
+
56840
+ const bounds_x1 = bounds[3];
56841
+ const bounds_y1 = bounds[4];
56842
+ const bounds_z1 = bounds[5];
56843
+
56844
+ const bounds_span_x = bounds_x1 - bounds_x0;
56845
+ const bounds_span_y = bounds_y1 - bounds_y0;
56846
+ const bounds_span_z = bounds_z1 - bounds_z0;
56847
+
56848
+ // scale to 10 bits
56849
+ const ndc_x = 1023 * (x - bounds_x0) / bounds_span_x;
56850
+ const ndc_y = 1023 * (y - bounds_y0) / bounds_span_y;
56851
+ const ndc_z = 1023 * (z - bounds_z0) / bounds_span_z;
56852
+
56853
+ return mortonEncode_magicbits(
56854
+ Math.round(ndc_x),
56855
+ Math.round(ndc_y),
56856
+ Math.round(ndc_z)
56857
+ );
56858
+ }
56859
+
56789
56860
  /**
56790
56861
  * Returns highest value out of 3 supplied
56791
56862
  * @param {number} a
@@ -56848,10 +56919,10 @@ function copy_box_zero_size(data, destination, source) {
56848
56919
  * Assumes data will be normalized to 0...1 value range
56849
56920
  * @param {Float32Array} data
56850
56921
  * @param {number} address
56851
- * @param {number[]} matrix
56922
+ * @param {number[]} bounds
56852
56923
  * @returns {number}
56853
56924
  */
56854
- function build_morton(data, address, matrix) {
56925
+ function build_morton(data, address, bounds) {
56855
56926
 
56856
56927
  const x0 = data[address];
56857
56928
  const y0 = data[address + 1];
@@ -56860,17 +56931,15 @@ function build_morton(data, address, matrix) {
56860
56931
  const y1 = data[address + 4];
56861
56932
  const z1 = data[address + 5];
56862
56933
 
56863
- const cx = (x0 + x1) / 2;
56864
- const cy = (y0 + y1) / 2;
56865
- const cz = (z0 + z1) / 2;
56934
+ const cx = (x0 + x1) * 0.5;
56935
+ const cy = (y0 + y1) * 0.5;
56936
+ const cz = (z0 + z1) * 0.5;
56866
56937
 
56867
- return mortonEncode_magicbits(cx, cy, cz);
56868
- // return v3_morton_encode_transformed(cx, cy, cz, matrix);
56938
+ return v3_morton_encode_bounded(cx, cy, cz, bounds);
56869
56939
 
56870
56940
  }
56871
56941
 
56872
- const scratch_box_0 = new Float32Array(18);
56873
- const stack$8 = [];
56942
+ const stack$8 = SCRATCH_UINT32_TRAVERSAL_STACK;
56874
56943
 
56875
56944
  class BinaryUint32BVH {
56876
56945
  /**
@@ -57101,17 +57170,15 @@ class BinaryUint32BVH {
57101
57170
  * @private
57102
57171
  */
57103
57172
  __compute_bounds_area_of_3_boxes(a, b, c) {
57104
- this.readBounds(a, scratch_box_0, 0);
57105
- this.readBounds(b, scratch_box_0, 6);
57106
- this.readBounds(c, scratch_box_0, 12);
57173
+ const float32 = this.__data_float32;
57107
57174
 
57108
- const x0 = min3(scratch_box_0[0], scratch_box_0[6], scratch_box_0[12]);
57109
- const y0 = min3(scratch_box_0[1], scratch_box_0[7], scratch_box_0[13]);
57110
- const z0 = min3(scratch_box_0[2], scratch_box_0[8], scratch_box_0[14]);
57175
+ const x0 = min3(float32[a + 0], float32[b + 0], float32[c + 0]);
57176
+ const y0 = min3(float32[a + 1], float32[b + 1], float32[c + 1]);
57177
+ const z0 = min3(float32[a + 2], float32[b + 2], float32[c + 2]);
57111
57178
 
57112
- const x1 = max3(scratch_box_0[3], scratch_box_0[9], scratch_box_0[15]);
57113
- const y1 = max3(scratch_box_0[4], scratch_box_0[10], scratch_box_0[16]);
57114
- const z1 = max3(scratch_box_0[5], scratch_box_0[11], scratch_box_0[17]);
57179
+ const x1 = max3(float32[a + 3], float32[b + 3], float32[c + 3]);
57180
+ const y1 = max3(float32[a + 4], float32[b + 4], float32[c + 4]);
57181
+ const z1 = max3(float32[a + 5], float32[b + 5], float32[c + 5]);
57115
57182
 
57116
57183
  return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
57117
57184
  }
@@ -57163,9 +57230,9 @@ class BinaryUint32BVH {
57163
57230
 
57164
57231
  /**
57165
57232
  * Sort leaf nodes according to their morton codes
57166
- * @param {number[]} projection
57233
+ * @param {number[]} bounds
57167
57234
  */
57168
- sort_morton(projection) {
57235
+ sort_morton(bounds) {
57169
57236
 
57170
57237
  const leaf_block_address = this.__node_count_binary * BVH_BINARY_NODE_SIZE;
57171
57238
 
@@ -57195,15 +57262,15 @@ class BinaryUint32BVH {
57195
57262
 
57196
57263
  const pivot_address = pivotIndex * BVH_LEAF_NODE_SIZE + leaf_block_address;
57197
57264
 
57198
- const pivot = build_morton(data, pivot_address);
57265
+ const pivot = build_morton(data, pivot_address, bounds);
57199
57266
 
57200
57267
  /* partition */
57201
57268
  while (i <= j) {
57202
- while (build_morton(data, i * BVH_LEAF_NODE_SIZE + leaf_block_address) < pivot) {
57269
+ while (build_morton(data, i * BVH_LEAF_NODE_SIZE + leaf_block_address, bounds) < pivot) {
57203
57270
  i++;
57204
57271
  }
57205
57272
 
57206
- while (build_morton(data, j * BVH_LEAF_NODE_SIZE + leaf_block_address) > pivot) {
57273
+ while (build_morton(data, j * BVH_LEAF_NODE_SIZE + leaf_block_address, bounds) > pivot) {
57207
57274
  j--;
57208
57275
  }
57209
57276
 
@@ -65351,6 +65418,23 @@ const TaskSignal = {
65351
65418
  Yield: 3
65352
65419
  };
65353
65420
 
65421
+ /**
65422
+ * @template T
65423
+ * @param {T[]} array
65424
+ * @param {T} element
65425
+ * @return {boolean}
65426
+ */
65427
+ function array_push_if_unique(array, element) {
65428
+ const i = array.indexOf(element);
65429
+
65430
+ if (i === -1) {
65431
+ array.push(element);
65432
+ return true;
65433
+ }
65434
+
65435
+ return false;
65436
+ }
65437
+
65354
65438
  /**
65355
65439
  * Created by Alex on 22/05/2016.
65356
65440
  */
@@ -65373,8 +65457,44 @@ const TaskState = {
65373
65457
  * Created by Alex on 22/05/2016.
65374
65458
  */
65375
65459
 
65460
+ /**
65461
+ *
65462
+ * @type {number}
65463
+ */
65464
+ let id_counter$3 = 0;
65376
65465
 
65377
65466
  class Task {
65467
+ /**
65468
+ * @readonly
65469
+ * @type {number}
65470
+ */
65471
+ id = id_counter$3++;
65472
+
65473
+ on = {
65474
+ started: new Signal(),
65475
+ completed: new Signal(),
65476
+ failed: new Signal()
65477
+ };
65478
+
65479
+ /**
65480
+ *
65481
+ * @type {ObservedInteger}
65482
+ */
65483
+ state = new ObservedInteger(TaskState.INITIAL);
65484
+
65485
+ /**
65486
+ * amount of time spent running this task in milliseconds
65487
+ * @type {number}
65488
+ * @public
65489
+ */
65490
+ __executedCpuTime = 0;
65491
+ /**
65492
+ * number of time task's cycle function was executed
65493
+ * @type {number}
65494
+ * @public
65495
+ */
65496
+ __executedCycleCount = 0;
65497
+
65378
65498
  /**
65379
65499
  *
65380
65500
  * @param {string} [name] useful for identifying the task later on, for various UI and debug purposes
@@ -65399,9 +65519,16 @@ class Task {
65399
65519
  assert.isFunction(cycleFunction, 'cycleFunction');
65400
65520
  assert.isNumber(estimatedDuration, 'estimatedDuration');
65401
65521
 
65402
-
65522
+ /**
65523
+ *
65524
+ * @type {Task[]}
65525
+ */
65403
65526
  this.dependencies = dependencies;
65404
65527
 
65528
+ /**
65529
+ *
65530
+ * @type {number}
65531
+ */
65405
65532
  this.estimatedDuration = estimatedDuration;
65406
65533
 
65407
65534
  /**
@@ -65429,30 +65556,6 @@ class Task {
65429
65556
 
65430
65557
  }
65431
65558
 
65432
- this.on = {
65433
- started: new Signal(),
65434
- completed: new Signal(),
65435
- failed: new Signal()
65436
- };
65437
-
65438
- /**
65439
- *
65440
- * @type {ObservedInteger}
65441
- */
65442
- this.state = new ObservedInteger(TaskState.INITIAL);
65443
-
65444
- /**
65445
- * amount of time spent running this task in milliseconds
65446
- * @type {number}
65447
- * @public
65448
- */
65449
- this.__executedCpuTime = 0;
65450
- /**
65451
- * number of time task's cycle function was executed
65452
- * @type {number}
65453
- * @public
65454
- */
65455
- this.__executedCycleCount = 0;
65456
65559
  }
65457
65560
 
65458
65561
  computeProgress() {
@@ -65497,11 +65600,7 @@ class Task {
65497
65600
  } else if (task.isTask) {
65498
65601
 
65499
65602
  //check that the dependency is not registered yet
65500
- if (this.dependencies.indexOf(task) === -1) {
65501
-
65502
- this.dependencies.push(task);
65503
-
65504
- }
65603
+ array_push_if_unique(this.dependencies, task);
65505
65604
 
65506
65605
  } else {
65507
65606
  throw new Error('Expected a Task or a TaskGroup, got something else');
@@ -65515,11 +65614,14 @@ class Task {
65515
65614
  * @param {Array<(Task|TaskGroup)>} tasks
65516
65615
  */
65517
65616
  addDependencies(tasks) {
65518
- if (!Array.isArray(tasks)) {
65519
- throw new Error(`argument 'tasks' is not an Array`);
65520
- }
65617
+ assert.isArray(tasks, 'tasks');
65618
+
65619
+ const task_count = tasks.length;
65521
65620
 
65522
- tasks.forEach(t => this.addDependency(t));
65621
+ for (let i = 0; i < task_count; i++) {
65622
+ const task = tasks[i];
65623
+ this.addDependency(task);
65624
+ }
65523
65625
  }
65524
65626
 
65525
65627
  toString() {
@@ -69859,23 +69961,6 @@ function array_copy_unique(source, source_position, destination, destination_pos
69859
69961
  return j - destination_position;
69860
69962
  }
69861
69963
 
69862
- /**
69863
- * @template T
69864
- * @param {T[]} array
69865
- * @param {T} element
69866
- * @return {boolean}
69867
- */
69868
- function array_push_if_unique(array, element) {
69869
- const i = array.indexOf(element);
69870
-
69871
- if (i === -1) {
69872
- array.push(element);
69873
- return true;
69874
- }
69875
-
69876
- return false;
69877
- }
69878
-
69879
69964
  /**
69880
69965
  * Created by Alex on 01/04/2014.
69881
69966
  */
@@ -87802,7 +87887,7 @@ function computeStatisticalPartialMedian(values, start, end) {
87802
87887
 
87803
87888
  const range = end - start;
87804
87889
 
87805
- const position = (start + range / 2) | 0;
87890
+ const position = (start + range) >> 1;
87806
87891
 
87807
87892
  return copy[position];
87808
87893
  }
@@ -98709,13 +98794,6 @@ function playTrackRealTime(track, ecd) {
98709
98794
  return entity;
98710
98795
  }
98711
98796
 
98712
- /**
98713
- * Magic field that can be added to an individual component to control serialization on level of individual components
98714
- * @readonly
98715
- * @type {string}
98716
- */
98717
- const COMPONENT_SERIALIZATION_TRANSIENT_FIELD = '@serialization_transient';
98718
-
98719
98797
  /**
98720
98798
  * @template A,B
98721
98799
  * @param {A} a
@@ -98787,64 +98865,48 @@ const GUIElementFlag = {
98787
98865
  class GUIElement {
98788
98866
  /**
98789
98867
  *
98790
- * @param {View} [view] parameter is deprecated
98791
- * @constructor
98868
+ * @type {View}
98792
98869
  */
98793
- constructor(view) {
98794
- /**
98795
- *
98796
- * @type {View}
98797
- */
98798
- this.view = null;
98870
+ view = null;
98799
98871
 
98800
- /**
98801
- *
98802
- * @type {String}
98803
- */
98804
- this.klass = null;
98805
-
98806
- /**
98807
- *
98808
- * @type {Object}
98809
- */
98810
- this.parameters = {};
98811
-
98812
- /**
98813
- * ranges from 0..1 in both X and Y, controls anchor point of element positioning
98814
- * @type {Vector2}
98815
- */
98816
- this.anchor = new Vector2(0, 0);
98817
-
98818
- /**
98819
- * Used for visual grouping of elements, system will create and manage named containers to group elements together
98820
- * @readonly
98821
- * @type {String|null}
98822
- */
98823
- this.group = null;
98872
+ /**
98873
+ *
98874
+ * @type {String}
98875
+ */
98876
+ klass = null;
98824
98877
 
98825
- /**
98826
- * @private
98827
- * @type {number}
98828
- */
98829
- this.flags = GUIElementFlag.Managed;
98878
+ /**
98879
+ *
98880
+ * @type {Object}
98881
+ */
98882
+ parameters = {};
98830
98883
 
98884
+ /**
98885
+ * ranges from 0..1 in both X and Y, controls anchor point of element positioning
98886
+ * @type {Vector2}
98887
+ */
98888
+ anchor = new Vector2(0, 0);
98831
98889
 
98832
- /**
98833
- *
98834
- * @type {ObservedBoolean}
98835
- */
98836
- this.visible = new ObservedBoolean(true);
98890
+ /**
98891
+ * Used for visual grouping of elements, system will create and manage named containers to group elements together
98892
+ * @readonly
98893
+ * @type {String|null}
98894
+ */
98895
+ group = null;
98837
98896
 
98897
+ /**
98898
+ * @private
98899
+ * @type {number}
98900
+ */
98901
+ flags = GUIElementFlag.Managed;
98838
98902
 
98839
- if (view !== undefined) {
98840
- console.warn('constructor parameters are deprecated');
98841
- this.view = view;
98842
98903
 
98843
- //set non-serializable flag
98844
- this[COMPONENT_SERIALIZATION_TRANSIENT_FIELD] = true;
98845
- }
98904
+ /**
98905
+ *
98906
+ * @type {ObservedBoolean}
98907
+ */
98908
+ visible = new ObservedBoolean(true);
98846
98909
 
98847
- }
98848
98910
 
98849
98911
  /**
98850
98912
  *
@@ -99001,11 +99063,9 @@ GUIElement.serializable = true;
99001
99063
  class ViewportPosition {
99002
99064
  /**
99003
99065
  *
99004
- * @param {Vector2} [position]
99005
- * @param {Vector2} [offset]
99006
99066
  * @constructor
99007
99067
  */
99008
- constructor({ position, offset } = {}) {
99068
+ constructor(options) {
99009
99069
  /**
99010
99070
  * Clip-scale position, on-screen values are in range of 0 to 1
99011
99071
  * @type {Vector2}
@@ -99051,12 +99111,9 @@ class ViewportPosition {
99051
99111
  */
99052
99112
  this.enabled = new ObservedBoolean(true);
99053
99113
 
99054
- if (position !== void 0) {
99055
- this.position.copy(position);
99056
- }
99057
-
99058
- if (offset !== void 0) {
99059
- this.offset.copy(offset);
99114
+ if (options !== undefined) {
99115
+ console.warn("ViewportPosition constructor options is deprecated, please use static fromJSON method instead if you need similar functionality");
99116
+ this.fromJSON(options);
99060
99117
  }
99061
99118
  }
99062
99119
 
@@ -118645,6 +118702,18 @@ class Blackboard extends AbstractBlackboard {
118645
118702
 
118646
118703
  Blackboard.typeName = 'Blackboard';
118647
118704
 
118705
+ /**
118706
+ * just in case you need that function also
118707
+ * @param {Vector3} axis
118708
+ * @param {number} angle
118709
+ * @param {Quaternion} result
118710
+ */
118711
+ function quat3_createFromAxisAngle(axis, angle, result) {
118712
+ const halfAngle = angle * .5;
118713
+ const s = Math.sin(halfAngle);
118714
+ result.set(axis.x * s, axis.y * s, axis.z * s, Math.cos(halfAngle));
118715
+ }
118716
+
118648
118717
  exports.AmbientOcclusionPostProcessEffect = AmbientOcclusionPostProcessEffect;
118649
118718
  exports.Behavior = Behavior;
118650
118719
  exports.BehaviorStatus = BehaviorStatus;