@woosh/meep-engine 2.68.0 → 2.70.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.
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +1090 -1581
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +1090 -1581
- package/package.json +1 -1
- package/src/core/__module.js +1 -0
- package/src/core/binary/BinaryBuffer.js +37 -31
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +76 -52
- package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +5 -7
- package/src/core/bvh2/binary/2/bvh32_query_user_data_overlaps_clipping_volume.js +94 -0
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +17 -18
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +4 -2
- package/src/core/geom/3d/aabb/AABB3.js +14 -14
- package/src/core/geom/3d/aabb/aabb3_array_intersects_clipping_volume_array.js +30 -0
- package/src/core/geom/3d/aabb/aabb3_intersects_clipping_volume_array.js +51 -0
- package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +3 -2
- package/src/core/geom/3d/frustum/{read_frustum_planes_to_array.js → read_three_planes_to_array.js} +5 -3
- package/src/core/geom/3d/morton/v3_morton_encode_bounded.js +34 -0
- package/src/core/geom/3d/morton/v3_morton_encode_transformed.js +2 -1
- package/src/core/geom/3d/quaternion/quat3_createFromAxisAngle.js +11 -0
- package/src/core/geom/3d/quaternion/quat_decode_from_uint32.js +53 -0
- package/src/core/geom/3d/quaternion/quat_encode_to_uint32.js +106 -0
- package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +51 -0
- package/src/core/geom/Quaternion.js +8 -142
- package/src/core/geom/Vector2.js +6 -7
- package/src/core/geom/Vector3.js +15 -82
- package/src/core/geom/vec3/v3_binary_equality_decode.js +44 -0
- package/src/core/geom/vec3/v3_binary_equality_encode.js +47 -0
- package/src/core/primitives/numbers/computeHashFloat.js +2 -2
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +2 -2
- package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +9 -46
- package/src/engine/ecs/transform/Transform.js +8 -9
- package/src/engine/ecs/transform/TransformSerializationAdapter.js +18 -7
- package/src/engine/graphics/ecs/mesh/Mesh.js +11 -11
- package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.d.ts +2 -2
- package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +79 -36
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_overlap_clipping_volume.js +88 -0
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +108 -0
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +4 -30
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.js +30 -0
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_set_leaf_from_triangle.js +41 -0
- package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
- package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +2 -2
- package/src/engine/graphics/render/view/CameraView.js +8 -8
- package/src/core/bvh2/binary/BinaryBVH.js +0 -281
- package/src/core/bvh2/binary/IndexedBinaryBVH.js +0 -407
- package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +0 -27
- package/src/core/bvh2/binary/IndexedBinaryBVHVisitor.js +0 -11
- package/src/core/bvh2/binary/NodeType.js +0 -8
- package/src/core/bvh2/binary/RayLeafIntersectionVisitor.js +0 -59
- package/src/core/geom/3d/aabb/aabb3_array_intersects_frustum_array.js +0 -20
- package/src/core/geom/3d/aabb/aabb3_intersects_frustum_array.js +0 -35
- package/src/engine/graphics/geometry/buffered/query/ClippingPlaneContainmentComputingVisitor.js +0 -195
- package/src/engine/graphics/geometry/buffered/query/GeometryVisitor.js +0 -87
- package/src/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +0 -206
- package/src/engine/graphics/geometry/bvh/buffered/BinaryBVHFromBufferGeometry.js +0 -123
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,191 @@ 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}
|
|
1812
|
+
* @returns {number}
|
|
1782
1813
|
*/
|
|
1783
|
-
function
|
|
1784
|
-
|
|
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 max = 0;
|
|
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
|
+
let v0, v1, v2, dropped;
|
|
1928
|
+
|
|
1929
|
+
//max will be dropped
|
|
1930
|
+
if (max === 0) {
|
|
1931
|
+
//dropping x
|
|
1932
|
+
v0 = y;
|
|
1933
|
+
v1 = z;
|
|
1934
|
+
v2 = w;
|
|
1935
|
+
|
|
1936
|
+
dropped = x;
|
|
1937
|
+
} else if (max === 1) {
|
|
1938
|
+
//dropping y
|
|
1939
|
+
v0 = x;
|
|
1940
|
+
v1 = z;
|
|
1941
|
+
v2 = w;
|
|
1942
|
+
|
|
1943
|
+
dropped = y;
|
|
1944
|
+
} else if (max === 2) {
|
|
1945
|
+
//dropping z
|
|
1946
|
+
v0 = x;
|
|
1947
|
+
v1 = y;
|
|
1948
|
+
v2 = w;
|
|
1949
|
+
|
|
1950
|
+
dropped = z;
|
|
1951
|
+
} else {
|
|
1952
|
+
//dropping w
|
|
1953
|
+
v0 = x;
|
|
1954
|
+
v1 = y;
|
|
1955
|
+
v2 = z;
|
|
1956
|
+
|
|
1957
|
+
dropped = w;
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
if (dropped < 0) {
|
|
1961
|
+
//reconstructing dropped value is only possible if it is positive, so we invert the quaternion to make dropped value positive
|
|
1962
|
+
v0 = -v0;
|
|
1963
|
+
v1 = -v1;
|
|
1964
|
+
v2 = -v2;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
const l = Math.sqrt(x * x + y * y + z * z + w * w);
|
|
1968
|
+
const m = 511 / (l * Math.SQRT1_2);
|
|
1969
|
+
|
|
1970
|
+
//re-normalize the remaining components to 10 bit UINT value
|
|
1971
|
+
const oV0 = Math.round(v0 * m + 511);
|
|
1972
|
+
const oV1 = Math.round(v1 * m + 511);
|
|
1973
|
+
const oV2 = Math.round(v2 * m + 511);
|
|
1974
|
+
|
|
1975
|
+
assert.ok(oV0 <= 1023 && oV0 >= 0, `expected 0 <= ov0 <= 1023, instead was '${oV0}'`);
|
|
1976
|
+
assert.ok(oV1 <= 1023 && oV1 >= 0, `expected 0 <= ov1 <= 1023, instead was '${oV1}'`);
|
|
1977
|
+
assert.ok(oV2 <= 1023 && oV2 >= 0, `expected 0 <= ov2 <= 1023, instead was '${oV2}'`);
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
return (max & 0x3)
|
|
1981
|
+
| ((oV0 & 0x3FF) << 2)
|
|
1982
|
+
| ((oV1 & 0x3FF) << 12)
|
|
1983
|
+
| ((oV2 & 0x3FF) << 22);
|
|
1785
1984
|
}
|
|
1786
1985
|
|
|
1787
1986
|
/**
|
|
@@ -1800,13 +1999,11 @@ function v3_dot(x0, y0, z0, x1, y1, z1) {
|
|
|
1800
1999
|
|
|
1801
2000
|
/**
|
|
1802
2001
|
*
|
|
1803
|
-
* @param {number}
|
|
1804
|
-
* @
|
|
1805
|
-
* @param {number} z
|
|
1806
|
-
* @return {number}
|
|
2002
|
+
* @param {number} v
|
|
2003
|
+
* @returns {number} +1 if v>0, 0 if v == 0, -1 if v<0
|
|
1807
2004
|
*/
|
|
1808
|
-
function
|
|
1809
|
-
return
|
|
2005
|
+
function sign$1(v) {
|
|
2006
|
+
return v > 0 ? 1 : (v < 0 ? -1 : 0);
|
|
1810
2007
|
}
|
|
1811
2008
|
|
|
1812
2009
|
/**
|
|
@@ -1862,6 +2059,110 @@ function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
|
|
|
1862
2059
|
return clamp$1(d / l, -1, 1);
|
|
1863
2060
|
}
|
|
1864
2061
|
|
|
2062
|
+
/**
|
|
2063
|
+
*
|
|
2064
|
+
* @param {BinaryBuffer} buffer
|
|
2065
|
+
* @param {number[]} result
|
|
2066
|
+
* @param {number} result_offset
|
|
2067
|
+
*/
|
|
2068
|
+
function v3_binary_equality_decode(buffer, result, result_offset) {
|
|
2069
|
+
const header = buffer.readUint8();
|
|
2070
|
+
|
|
2071
|
+
let x = 0;
|
|
2072
|
+
let y = 0;
|
|
2073
|
+
let z = 0;
|
|
2074
|
+
|
|
2075
|
+
if ((header & 7) === 7) {
|
|
2076
|
+
//all scale components are the same
|
|
2077
|
+
x = buffer.readFloat32();
|
|
2078
|
+
y = x;
|
|
2079
|
+
z = x;
|
|
2080
|
+
} else if ((header & 1) === 1) {
|
|
2081
|
+
//X and Y are the same, Z is different
|
|
2082
|
+
x = buffer.readFloat32();
|
|
2083
|
+
y = x;
|
|
2084
|
+
z = buffer.readFloat32();
|
|
2085
|
+
} else if ((header & 2) === 2) {
|
|
2086
|
+
//Y and Z are the same, X is different
|
|
2087
|
+
x = buffer.readFloat32();
|
|
2088
|
+
y = buffer.readFloat32();
|
|
2089
|
+
z = y;
|
|
2090
|
+
} else if ((header & 4) === 4) {
|
|
2091
|
+
//X and Z are the same, Y is different
|
|
2092
|
+
x = buffer.readFloat32();
|
|
2093
|
+
y = buffer.readFloat32();
|
|
2094
|
+
z = x;
|
|
2095
|
+
} else {
|
|
2096
|
+
//scale components are different
|
|
2097
|
+
x = buffer.readFloat32();
|
|
2098
|
+
y = buffer.readFloat32();
|
|
2099
|
+
z = buffer.readFloat32();
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
result[result_offset] = x;
|
|
2103
|
+
result[result_offset + 1] = y;
|
|
2104
|
+
result[result_offset + 2] = z;
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
/**
|
|
2108
|
+
*
|
|
2109
|
+
* @param {BinaryBuffer} buffer
|
|
2110
|
+
* @param {number} x
|
|
2111
|
+
* @param {number} y
|
|
2112
|
+
* @param {number} z
|
|
2113
|
+
*/
|
|
2114
|
+
function v3_binary_equality_encode(buffer, x, y, z){
|
|
2115
|
+
|
|
2116
|
+
let header = 0;
|
|
2117
|
+
|
|
2118
|
+
if (x === y) {
|
|
2119
|
+
header |= 1;
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
if (y === z) {
|
|
2123
|
+
header |= 2;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
if (x === z) {
|
|
2127
|
+
header |= 4;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
buffer.writeUint8(header);
|
|
2131
|
+
|
|
2132
|
+
if ((header & 7) === 7) {
|
|
2133
|
+
//all components are the same
|
|
2134
|
+
buffer.writeFloat32(x);
|
|
2135
|
+
} else if (header === 1) {
|
|
2136
|
+
//X and Y are the same, Z is different
|
|
2137
|
+
buffer.writeFloat32(x);
|
|
2138
|
+
buffer.writeFloat32(z);
|
|
2139
|
+
} else if (header === 2) {
|
|
2140
|
+
//Y and Z are the same, X is different
|
|
2141
|
+
buffer.writeFloat32(x);
|
|
2142
|
+
buffer.writeFloat32(y);
|
|
2143
|
+
} else if (header === 4) {
|
|
2144
|
+
//X and Z are the same, Y is different
|
|
2145
|
+
buffer.writeFloat32(x);
|
|
2146
|
+
buffer.writeFloat32(y);
|
|
2147
|
+
} else {
|
|
2148
|
+
//scale components are different
|
|
2149
|
+
buffer.writeFloat32(x);
|
|
2150
|
+
buffer.writeFloat32(y);
|
|
2151
|
+
buffer.writeFloat32(z);
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
/**
|
|
2156
|
+
*
|
|
2157
|
+
* @param {number} x
|
|
2158
|
+
* @param {number} y
|
|
2159
|
+
* @param {number} z
|
|
2160
|
+
* @return {number}
|
|
2161
|
+
*/
|
|
2162
|
+
function v3_length_sqr(x, y, z) {
|
|
2163
|
+
return x * x + y * y + z * z;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
1865
2166
|
/**
|
|
1866
2167
|
*
|
|
1867
2168
|
* @param {Vector3} result
|
|
@@ -1933,45 +2234,6 @@ function v3_slerp(
|
|
|
1933
2234
|
result.set(x, y, z);
|
|
1934
2235
|
}
|
|
1935
2236
|
|
|
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
2237
|
/**
|
|
1976
2238
|
* @author Alex Goldring
|
|
1977
2239
|
* @copyright Alex Goldring 2015
|
|
@@ -2816,100 +3078,31 @@ let Vector3$1 = class Vector3 {
|
|
|
2816
3078
|
/**
|
|
2817
3079
|
*
|
|
2818
3080
|
* @param {BinaryBuffer} buffer
|
|
3081
|
+
* @deprecated use dedicated method directly instead
|
|
2819
3082
|
*/
|
|
2820
3083
|
toBinaryBufferFloat32_EqualityEncoded(buffer) {
|
|
2821
3084
|
const x = this.x;
|
|
2822
3085
|
const y = this.y;
|
|
2823
3086
|
const z = this.z;
|
|
2824
3087
|
|
|
2825
|
-
|
|
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
|
-
}
|
|
3088
|
+
v3_binary_equality_encode(buffer, x, y, z);
|
|
2862
3089
|
}
|
|
2863
3090
|
|
|
2864
3091
|
/**
|
|
2865
3092
|
* 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
3093
|
* @param {BinaryBuffer} buffer
|
|
3094
|
+
* @deprecated use dedicated method directly instead
|
|
2867
3095
|
*/
|
|
2868
3096
|
fromBinaryBufferFloat32_EqualityEncoded(buffer) {
|
|
2869
|
-
|
|
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);
|
|
3097
|
+
v3_binary_equality_decode(buffer, this, 0);
|
|
2903
3098
|
}
|
|
2904
3099
|
|
|
2905
3100
|
hash() {
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
hash = ((hash << 5) - hash) + computeHashFloat(this.z);
|
|
3101
|
+
const x = computeHashFloat(this.x);
|
|
3102
|
+
const y = computeHashFloat(this.y);
|
|
3103
|
+
const z = computeHashFloat(this.z);
|
|
2911
3104
|
|
|
2912
|
-
return
|
|
3105
|
+
return x ^ (y << 1) ^ (z << 2);
|
|
2913
3106
|
}
|
|
2914
3107
|
|
|
2915
3108
|
|
|
@@ -3067,16 +3260,6 @@ Vector3$1.typeName = "Vector3";
|
|
|
3067
3260
|
*/
|
|
3068
3261
|
Vector3$1._dot = v3_dot;
|
|
3069
3262
|
|
|
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
3263
|
/**
|
|
3081
3264
|
* Created by Alex on 10/03/14.
|
|
3082
3265
|
*/
|
|
@@ -3086,18 +3269,6 @@ const forward = new Vector3$1();
|
|
|
3086
3269
|
const up = new Vector3$1();
|
|
3087
3270
|
const right = new Vector3$1();
|
|
3088
3271
|
|
|
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
3272
|
let Quaternion$1 = class Quaternion {
|
|
3102
3273
|
/**
|
|
3103
3274
|
*
|
|
@@ -4520,31 +4691,7 @@ let Quaternion$1 = class Quaternion {
|
|
|
4520
4691
|
* @param {number} value
|
|
4521
4692
|
*/
|
|
4522
4693
|
decodeFromUint32(value) {
|
|
4523
|
-
|
|
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
|
-
}
|
|
4694
|
+
quat_decode_from_uint32(this, 0, value);
|
|
4548
4695
|
}
|
|
4549
4696
|
|
|
4550
4697
|
/**
|
|
@@ -4552,107 +4699,7 @@ let Quaternion$1 = class Quaternion {
|
|
|
4552
4699
|
* @returns {number}
|
|
4553
4700
|
*/
|
|
4554
4701
|
encodeToUint32() {
|
|
4555
|
-
|
|
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;
|
|
4702
|
+
return quat_encode_to_uint32(this.x, this.y, this.z, this.w);
|
|
4656
4703
|
}
|
|
4657
4704
|
|
|
4658
4705
|
/**
|
|
@@ -4839,13 +4886,7 @@ Quaternion$1.identity = Object.freeze(new Quaternion$1(0, 0, 0, 1));
|
|
|
4839
4886
|
const axis = new Vector3$1();
|
|
4840
4887
|
|
|
4841
4888
|
|
|
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)
|
|
4889
|
+
const tempvec3 = new Vector3$1();
|
|
4849
4890
|
|
|
4850
4891
|
/**
|
|
4851
4892
|
* @readonly
|
|
@@ -5112,8 +5153,7 @@ class Transform {
|
|
|
5112
5153
|
* @returns {boolean}
|
|
5113
5154
|
*/
|
|
5114
5155
|
equals(other) {
|
|
5115
|
-
return other.
|
|
5116
|
-
&& this.position.equals(other.position)
|
|
5156
|
+
return this.position.equals(other.position)
|
|
5117
5157
|
&& this.rotation.equals(other.rotation)
|
|
5118
5158
|
&& this.scale.equals(other.scale);
|
|
5119
5159
|
}
|
|
@@ -48947,11 +48987,7 @@ class Vector2 {
|
|
|
48947
48987
|
const x = computeHashFloat(this.x);
|
|
48948
48988
|
const y = computeHashFloat(this.y);
|
|
48949
48989
|
|
|
48950
|
-
|
|
48951
|
-
|
|
48952
|
-
hash |= 0; //convert to 32bit int
|
|
48953
|
-
|
|
48954
|
-
return hash;
|
|
48990
|
+
return ((x << 5) - x) + y;
|
|
48955
48991
|
}
|
|
48956
48992
|
|
|
48957
48993
|
/**
|
|
@@ -48962,8 +48998,11 @@ class Vector2 {
|
|
|
48962
48998
|
const sin = Math.sin(angle);
|
|
48963
48999
|
const cos = Math.cos(angle);
|
|
48964
49000
|
|
|
48965
|
-
const
|
|
48966
|
-
const
|
|
49001
|
+
const _x = this.x;
|
|
49002
|
+
const _y = this.y;
|
|
49003
|
+
|
|
49004
|
+
const x = _x * cos - _y * sin;
|
|
49005
|
+
const y = _x * sin + _y * cos;
|
|
48967
49006
|
|
|
48968
49007
|
this.set(x, y);
|
|
48969
49008
|
}
|
|
@@ -56786,6 +56825,39 @@ function mortonEncode_magicbits(x, y, z) {
|
|
|
56786
56825
|
return x_bits | y_bits | z_bits;
|
|
56787
56826
|
}
|
|
56788
56827
|
|
|
56828
|
+
/**
|
|
56829
|
+
* @param {number} x
|
|
56830
|
+
* @param {number} y
|
|
56831
|
+
* @param {number} z
|
|
56832
|
+
* @param {number[]} bounds
|
|
56833
|
+
* @returns {number}
|
|
56834
|
+
*/
|
|
56835
|
+
function v3_morton_encode_bounded(x, y, z, bounds) {
|
|
56836
|
+
|
|
56837
|
+
const bounds_x0 = bounds[0];
|
|
56838
|
+
const bounds_y0 = bounds[1];
|
|
56839
|
+
const bounds_z0 = bounds[2];
|
|
56840
|
+
|
|
56841
|
+
const bounds_x1 = bounds[3];
|
|
56842
|
+
const bounds_y1 = bounds[4];
|
|
56843
|
+
const bounds_z1 = bounds[5];
|
|
56844
|
+
|
|
56845
|
+
const bounds_span_x = bounds_x1 - bounds_x0;
|
|
56846
|
+
const bounds_span_y = bounds_y1 - bounds_y0;
|
|
56847
|
+
const bounds_span_z = bounds_z1 - bounds_z0;
|
|
56848
|
+
|
|
56849
|
+
// scale to 10 bits
|
|
56850
|
+
const ndc_x = 1023 * (x - bounds_x0) / bounds_span_x;
|
|
56851
|
+
const ndc_y = 1023 * (y - bounds_y0) / bounds_span_y;
|
|
56852
|
+
const ndc_z = 1023 * (z - bounds_z0) / bounds_span_z;
|
|
56853
|
+
|
|
56854
|
+
return mortonEncode_magicbits(
|
|
56855
|
+
Math.round(ndc_x),
|
|
56856
|
+
Math.round(ndc_y),
|
|
56857
|
+
Math.round(ndc_z)
|
|
56858
|
+
);
|
|
56859
|
+
}
|
|
56860
|
+
|
|
56789
56861
|
/**
|
|
56790
56862
|
* Returns highest value out of 3 supplied
|
|
56791
56863
|
* @param {number} a
|
|
@@ -56848,10 +56920,10 @@ function copy_box_zero_size(data, destination, source) {
|
|
|
56848
56920
|
* Assumes data will be normalized to 0...1 value range
|
|
56849
56921
|
* @param {Float32Array} data
|
|
56850
56922
|
* @param {number} address
|
|
56851
|
-
* @param {number[]}
|
|
56923
|
+
* @param {number[]} bounds
|
|
56852
56924
|
* @returns {number}
|
|
56853
56925
|
*/
|
|
56854
|
-
function build_morton(data, address,
|
|
56926
|
+
function build_morton(data, address, bounds) {
|
|
56855
56927
|
|
|
56856
56928
|
const x0 = data[address];
|
|
56857
56929
|
const y0 = data[address + 1];
|
|
@@ -56860,17 +56932,15 @@ function build_morton(data, address, matrix) {
|
|
|
56860
56932
|
const y1 = data[address + 4];
|
|
56861
56933
|
const z1 = data[address + 5];
|
|
56862
56934
|
|
|
56863
|
-
const cx = (x0 + x1)
|
|
56864
|
-
const cy = (y0 + y1)
|
|
56865
|
-
const cz = (z0 + z1)
|
|
56935
|
+
const cx = (x0 + x1) * 0.5;
|
|
56936
|
+
const cy = (y0 + y1) * 0.5;
|
|
56937
|
+
const cz = (z0 + z1) * 0.5;
|
|
56866
56938
|
|
|
56867
|
-
return
|
|
56868
|
-
// return v3_morton_encode_transformed(cx, cy, cz, matrix);
|
|
56939
|
+
return v3_morton_encode_bounded(cx, cy, cz, bounds);
|
|
56869
56940
|
|
|
56870
56941
|
}
|
|
56871
56942
|
|
|
56872
|
-
const
|
|
56873
|
-
const stack$8 = [];
|
|
56943
|
+
const stack$8 = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
56874
56944
|
|
|
56875
56945
|
class BinaryUint32BVH {
|
|
56876
56946
|
/**
|
|
@@ -56894,34 +56964,41 @@ class BinaryUint32BVH {
|
|
|
56894
56964
|
*/
|
|
56895
56965
|
__data_uint32;
|
|
56896
56966
|
|
|
56897
|
-
|
|
56898
|
-
|
|
56899
|
-
|
|
56900
|
-
|
|
56901
|
-
|
|
56902
|
-
|
|
56903
|
-
*/
|
|
56904
|
-
this.__node_count_binary = 0;
|
|
56967
|
+
/**
|
|
56968
|
+
*
|
|
56969
|
+
* @type {number}
|
|
56970
|
+
* @private
|
|
56971
|
+
*/
|
|
56972
|
+
__node_count_binary = 0;
|
|
56905
56973
|
|
|
56906
|
-
|
|
56907
|
-
|
|
56908
|
-
|
|
56909
|
-
|
|
56910
|
-
|
|
56911
|
-
|
|
56974
|
+
/**
|
|
56975
|
+
*
|
|
56976
|
+
* @type {number}
|
|
56977
|
+
* @private
|
|
56978
|
+
*/
|
|
56979
|
+
__node_count_leaf = 0;
|
|
56912
56980
|
|
|
56981
|
+
constructor() {
|
|
56913
56982
|
this.data = new ArrayBuffer(320);
|
|
56914
56983
|
}
|
|
56915
56984
|
|
|
56985
|
+
/**
|
|
56986
|
+
* In bytes
|
|
56987
|
+
* @returns {number}
|
|
56988
|
+
*/
|
|
56989
|
+
estimateByteSize() {
|
|
56990
|
+
return this.data.byteLength + 248;
|
|
56991
|
+
}
|
|
56992
|
+
|
|
56916
56993
|
getTotalBoxCount() {
|
|
56917
56994
|
return this.__node_count_binary + this.__node_count_leaf;
|
|
56918
56995
|
}
|
|
56919
56996
|
|
|
56920
|
-
|
|
56997
|
+
get binary_node_count() {
|
|
56921
56998
|
return this.__node_count_binary;
|
|
56922
56999
|
}
|
|
56923
57000
|
|
|
56924
|
-
|
|
57001
|
+
get leaf_node_count() {
|
|
56925
57002
|
return this.__node_count_leaf;
|
|
56926
57003
|
}
|
|
56927
57004
|
|
|
@@ -56943,10 +57020,12 @@ class BinaryUint32BVH {
|
|
|
56943
57020
|
|
|
56944
57021
|
/**
|
|
56945
57022
|
*
|
|
56946
|
-
* @param {ArrayBuffer}
|
|
57023
|
+
* @param {ArrayBuffer} buffer
|
|
56947
57024
|
*/
|
|
56948
|
-
set data(
|
|
56949
|
-
|
|
57025
|
+
set data(buffer) {
|
|
57026
|
+
assert.defined(buffer, 'buffer');
|
|
57027
|
+
|
|
57028
|
+
this.__data_buffer = buffer;
|
|
56950
57029
|
|
|
56951
57030
|
this.__data_float32 = new Float32Array(this.__data_buffer);
|
|
56952
57031
|
this.__data_uint32 = new Uint32Array(this.__data_buffer);
|
|
@@ -56956,6 +57035,24 @@ class BinaryUint32BVH {
|
|
|
56956
57035
|
return this.__data_buffer;
|
|
56957
57036
|
}
|
|
56958
57037
|
|
|
57038
|
+
/**
|
|
57039
|
+
* Resolve index of the node to address where the node data starts, this is required to know where AABB is stored in memory
|
|
57040
|
+
* @param {number} node_index
|
|
57041
|
+
* @returns {number}
|
|
57042
|
+
*/
|
|
57043
|
+
getNodeAddress(node_index) {
|
|
57044
|
+
const binary_node_count = this.__node_count_binary;
|
|
57045
|
+
const leaf_node_index = node_index - binary_node_count;
|
|
57046
|
+
|
|
57047
|
+
if (leaf_node_index < 0) {
|
|
57048
|
+
// binary node
|
|
57049
|
+
return node_index * BVH_BINARY_NODE_SIZE;
|
|
57050
|
+
} else {
|
|
57051
|
+
// leaf node
|
|
57052
|
+
return binary_node_count * BVH_BINARY_NODE_SIZE + leaf_node_index * BVH_LEAF_NODE_SIZE;
|
|
57053
|
+
}
|
|
57054
|
+
}
|
|
57055
|
+
|
|
56959
57056
|
initialize_structure() {
|
|
56960
57057
|
// compute memory requirements
|
|
56961
57058
|
const word_count = this.__node_count_binary * BVH_BINARY_NODE_SIZE + this.__node_count_leaf * BVH_LEAF_NODE_SIZE;
|
|
@@ -57074,17 +57171,15 @@ class BinaryUint32BVH {
|
|
|
57074
57171
|
* @private
|
|
57075
57172
|
*/
|
|
57076
57173
|
__compute_bounds_area_of_3_boxes(a, b, c) {
|
|
57077
|
-
this.
|
|
57078
|
-
this.readBounds(b, scratch_box_0, 6);
|
|
57079
|
-
this.readBounds(c, scratch_box_0, 12);
|
|
57174
|
+
const float32 = this.__data_float32;
|
|
57080
57175
|
|
|
57081
|
-
const x0 = min3(
|
|
57082
|
-
const y0 = min3(
|
|
57083
|
-
const z0 = min3(
|
|
57176
|
+
const x0 = min3(float32[a + 0], float32[b + 0], float32[c + 0]);
|
|
57177
|
+
const y0 = min3(float32[a + 1], float32[b + 1], float32[c + 1]);
|
|
57178
|
+
const z0 = min3(float32[a + 2], float32[b + 2], float32[c + 2]);
|
|
57084
57179
|
|
|
57085
|
-
const x1 = max3(
|
|
57086
|
-
const y1 = max3(
|
|
57087
|
-
const z1 = max3(
|
|
57180
|
+
const x1 = max3(float32[a + 3], float32[b + 3], float32[c + 3]);
|
|
57181
|
+
const y1 = max3(float32[a + 4], float32[b + 4], float32[c + 4]);
|
|
57182
|
+
const z1 = max3(float32[a + 5], float32[b + 5], float32[c + 5]);
|
|
57088
57183
|
|
|
57089
57184
|
return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
|
|
57090
57185
|
}
|
|
@@ -57136,9 +57231,9 @@ class BinaryUint32BVH {
|
|
|
57136
57231
|
|
|
57137
57232
|
/**
|
|
57138
57233
|
* Sort leaf nodes according to their morton codes
|
|
57139
|
-
* @param {number[]}
|
|
57234
|
+
* @param {number[]} bounds
|
|
57140
57235
|
*/
|
|
57141
|
-
sort_morton(
|
|
57236
|
+
sort_morton(bounds) {
|
|
57142
57237
|
|
|
57143
57238
|
const leaf_block_address = this.__node_count_binary * BVH_BINARY_NODE_SIZE;
|
|
57144
57239
|
|
|
@@ -57168,15 +57263,15 @@ class BinaryUint32BVH {
|
|
|
57168
57263
|
|
|
57169
57264
|
const pivot_address = pivotIndex * BVH_LEAF_NODE_SIZE + leaf_block_address;
|
|
57170
57265
|
|
|
57171
|
-
const pivot = build_morton(data, pivot_address);
|
|
57266
|
+
const pivot = build_morton(data, pivot_address, bounds);
|
|
57172
57267
|
|
|
57173
57268
|
/* partition */
|
|
57174
57269
|
while (i <= j) {
|
|
57175
|
-
while (build_morton(data, i * BVH_LEAF_NODE_SIZE + leaf_block_address) < pivot) {
|
|
57270
|
+
while (build_morton(data, i * BVH_LEAF_NODE_SIZE + leaf_block_address, bounds) < pivot) {
|
|
57176
57271
|
i++;
|
|
57177
57272
|
}
|
|
57178
57273
|
|
|
57179
|
-
while (build_morton(data, j * BVH_LEAF_NODE_SIZE + leaf_block_address) > pivot) {
|
|
57274
|
+
while (build_morton(data, j * BVH_LEAF_NODE_SIZE + leaf_block_address, bounds) > pivot) {
|
|
57180
57275
|
j--;
|
|
57181
57276
|
}
|
|
57182
57277
|
|
|
@@ -57246,22 +57341,22 @@ class BinaryUint32BVH {
|
|
|
57246
57341
|
|
|
57247
57342
|
// build bottom-most level, just above the leaves
|
|
57248
57343
|
for (i = 0; i < level_node_count; i++) {
|
|
57249
|
-
const
|
|
57250
|
-
const
|
|
57344
|
+
const leaf_index_0 = i * 2;
|
|
57345
|
+
const leaf_index_1 = leaf_index_0 + 1;
|
|
57251
57346
|
|
|
57252
|
-
const
|
|
57253
|
-
const
|
|
57347
|
+
const leaf_offset_0 = leaf_node_block_address + leaf_index_0 * BVH_LEAF_NODE_SIZE;
|
|
57348
|
+
const leaf_offset_1 = leaf_node_block_address + leaf_index_1 * BVH_LEAF_NODE_SIZE;
|
|
57254
57349
|
|
|
57255
|
-
if (
|
|
57350
|
+
if (leaf_index_1 < node_count_leaf) {
|
|
57256
57351
|
// both children nodes are valid
|
|
57257
57352
|
aabb3_array_combine(
|
|
57258
57353
|
float32, offset,
|
|
57259
|
-
float32,
|
|
57260
|
-
float32,
|
|
57354
|
+
float32, leaf_offset_0,
|
|
57355
|
+
float32, leaf_offset_1
|
|
57261
57356
|
);
|
|
57262
|
-
} else if (
|
|
57357
|
+
} else if (leaf_index_0 < node_count_leaf) {
|
|
57263
57358
|
// only left child node is valid
|
|
57264
|
-
array_copy(float32,
|
|
57359
|
+
array_copy(float32, leaf_offset_0, float32, offset, 6);
|
|
57265
57360
|
} else {
|
|
57266
57361
|
//initialize to 0-size box same position as previous node
|
|
57267
57362
|
copy_box_zero_size(this.__data_float32, offset, (offset - BVH_BINARY_NODE_SIZE));
|
|
@@ -57301,127 +57396,6 @@ class BinaryUint32BVH {
|
|
|
57301
57396
|
|
|
57302
57397
|
//
|
|
57303
57398
|
|
|
57304
|
-
/**
|
|
57305
|
-
*
|
|
57306
|
-
* @param {ArrayLike<number>|number[]|Float32Array} aabb bounding box, order: x0,y0,z0,x1,y1,z1
|
|
57307
|
-
* @param {number} aabb_offset
|
|
57308
|
-
* @param {number} origin_x
|
|
57309
|
-
* @param {number} origin_y
|
|
57310
|
-
* @param {number} origin_z
|
|
57311
|
-
* @param {number} direction_x
|
|
57312
|
-
* @param {number} direction_y
|
|
57313
|
-
* @param {number} direction_z
|
|
57314
|
-
*/
|
|
57315
|
-
function aabb3_array_intersects_ray(
|
|
57316
|
-
aabb, aabb_offset,
|
|
57317
|
-
origin_x, origin_y, origin_z,
|
|
57318
|
-
direction_x, direction_y, direction_z
|
|
57319
|
-
) {
|
|
57320
|
-
return aabb3_intersects_ray(
|
|
57321
|
-
aabb[aabb_offset], aabb[aabb_offset+1], aabb[aabb_offset+2],
|
|
57322
|
-
aabb[aabb_offset+3], aabb[aabb_offset+4], aabb[aabb_offset+5],
|
|
57323
|
-
origin_x, origin_y, origin_z,
|
|
57324
|
-
direction_x, direction_y, direction_z
|
|
57325
|
-
);
|
|
57326
|
-
}
|
|
57327
|
-
|
|
57328
|
-
const stack$7 = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
57329
|
-
|
|
57330
|
-
/**
|
|
57331
|
-
*
|
|
57332
|
-
* @param {BinaryUint32BVH} bvh
|
|
57333
|
-
* @param {number[]} result
|
|
57334
|
-
* @param {number} result_offset
|
|
57335
|
-
* @param {number} origin_x
|
|
57336
|
-
* @param {number} origin_y
|
|
57337
|
-
* @param {number} origin_z
|
|
57338
|
-
* @param {number} direction_x
|
|
57339
|
-
* @param {number} direction_y
|
|
57340
|
-
* @param {number} direction_z
|
|
57341
|
-
* @returns {number}
|
|
57342
|
-
*/
|
|
57343
|
-
function bvh32_query_user_data_ray(
|
|
57344
|
-
bvh,
|
|
57345
|
-
result, result_offset,
|
|
57346
|
-
origin_x, origin_y, origin_z,
|
|
57347
|
-
direction_x, direction_y, direction_z
|
|
57348
|
-
) {
|
|
57349
|
-
let hit_count = 0;
|
|
57350
|
-
|
|
57351
|
-
const binary_node_count = bvh.getBinaryNodeCount();
|
|
57352
|
-
|
|
57353
|
-
if (binary_node_count <= 0) {
|
|
57354
|
-
// this should not happen
|
|
57355
|
-
return 0;
|
|
57356
|
-
}
|
|
57357
|
-
|
|
57358
|
-
/**
|
|
57359
|
-
*
|
|
57360
|
-
* @type {number}
|
|
57361
|
-
*/
|
|
57362
|
-
const stack_top = stack$7.pointer++;
|
|
57363
|
-
|
|
57364
|
-
/**
|
|
57365
|
-
* After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
|
|
57366
|
-
* @type {number}
|
|
57367
|
-
*/
|
|
57368
|
-
stack$7[stack_top] = 0;
|
|
57369
|
-
|
|
57370
|
-
const last_valid_index = binary_node_count + bvh.getLeafNodeCount();
|
|
57371
|
-
|
|
57372
|
-
const float32 = bvh.float32;
|
|
57373
|
-
const uint32 = bvh.uint32;
|
|
57374
|
-
|
|
57375
|
-
do {
|
|
57376
|
-
stack$7.pointer--;
|
|
57377
|
-
|
|
57378
|
-
// query_bvh_frustum_from_objects.iteration_count++;
|
|
57379
|
-
const node_index = stack$7[stack$7.pointer];
|
|
57380
|
-
|
|
57381
|
-
if (node_index < binary_node_count) {
|
|
57382
|
-
// is intermediate node
|
|
57383
|
-
const node_address = node_index * BVH_BINARY_NODE_SIZE;
|
|
57384
|
-
|
|
57385
|
-
if (!aabb3_array_intersects_ray(
|
|
57386
|
-
float32, node_address,
|
|
57387
|
-
origin_x, origin_y, origin_z,
|
|
57388
|
-
direction_x, direction_y, direction_z
|
|
57389
|
-
)) {
|
|
57390
|
-
continue;
|
|
57391
|
-
}
|
|
57392
|
-
|
|
57393
|
-
const left_index = (node_index << 1) + 1;
|
|
57394
|
-
const right_index = left_index + 1;
|
|
57395
|
-
|
|
57396
|
-
// left node ends up on top of the stack, which aligns with the desired access sequence
|
|
57397
|
-
if (right_index < last_valid_index) {
|
|
57398
|
-
stack$7[stack$7.pointer++] = right_index;
|
|
57399
|
-
// micro-optimization, since we know that right node is valid and left appears before that, left is valid too
|
|
57400
|
-
stack$7[stack$7.pointer++] = left_index;
|
|
57401
|
-
} else if (left_index < last_valid_index) {
|
|
57402
|
-
stack$7[stack$7.pointer++] = left_index;
|
|
57403
|
-
}
|
|
57404
|
-
|
|
57405
|
-
|
|
57406
|
-
} else {
|
|
57407
|
-
// leaf node
|
|
57408
|
-
const leaf_index = node_index - binary_node_count;
|
|
57409
|
-
|
|
57410
|
-
const node_address = leaf_index * BVH_LEAF_NODE_SIZE + binary_node_count * BVH_BINARY_NODE_SIZE;
|
|
57411
|
-
|
|
57412
|
-
// write to output
|
|
57413
|
-
result[result_offset + hit_count] = uint32[node_address + 6];
|
|
57414
|
-
|
|
57415
|
-
hit_count++;
|
|
57416
|
-
}
|
|
57417
|
-
|
|
57418
|
-
} while (stack$7.pointer > stack_top)
|
|
57419
|
-
|
|
57420
|
-
return hit_count;
|
|
57421
|
-
}
|
|
57422
|
-
|
|
57423
|
-
//
|
|
57424
|
-
|
|
57425
57399
|
/**
|
|
57426
57400
|
*
|
|
57427
57401
|
* @param {ArrayLike<number>|number[]|AABB3} aabb
|
|
@@ -57600,23 +57574,37 @@ function aabb3_compute_plane_side(
|
|
|
57600
57574
|
}
|
|
57601
57575
|
|
|
57602
57576
|
/**
|
|
57603
|
-
*
|
|
57577
|
+
* Tests whether AABB intersects a clipping volume defined by a set of planes
|
|
57578
|
+
* Mainly useful for frustum checks
|
|
57604
57579
|
* @param {number} x0
|
|
57605
57580
|
* @param {number} y0
|
|
57606
57581
|
* @param {number} z0
|
|
57607
57582
|
* @param {number} x1
|
|
57608
57583
|
* @param {number} y1
|
|
57609
57584
|
* @param {number} z1
|
|
57610
|
-
* @param {ArrayLike<number>|number[]|Float32Array|Float64Array}
|
|
57585
|
+
* @param {ArrayLike<number>|number[]|Float32Array|Float64Array} planes
|
|
57586
|
+
* @param {number} planes_offset
|
|
57587
|
+
* @param {number} plane_count
|
|
57611
57588
|
* @return {boolean}
|
|
57612
57589
|
*/
|
|
57613
|
-
function
|
|
57614
|
-
|
|
57590
|
+
function aabb3_intersects_clipping_volume_array(
|
|
57591
|
+
x0, y0, z0,
|
|
57592
|
+
x1, y1, z1,
|
|
57593
|
+
planes, planes_offset, plane_count
|
|
57594
|
+
) {
|
|
57595
|
+
|
|
57596
|
+
assert.isNonNegativeInteger(planes_offset, 'frustum_offset');
|
|
57597
|
+
|
|
57598
|
+
const limit = plane_count * 4;
|
|
57599
|
+
|
|
57600
|
+
for (let i = 0; i < limit; i += 4) {
|
|
57601
|
+
|
|
57602
|
+
const offset = planes_offset + i;
|
|
57615
57603
|
|
|
57616
|
-
const plane_x =
|
|
57617
|
-
const plane_y =
|
|
57618
|
-
const plane_z =
|
|
57619
|
-
const plane_w =
|
|
57604
|
+
const plane_x = planes[offset];
|
|
57605
|
+
const plane_y = planes[offset + 1];
|
|
57606
|
+
const plane_z = planes[offset + 2];
|
|
57607
|
+
const plane_w = planes[offset + 3];
|
|
57620
57608
|
|
|
57621
57609
|
const plane_distance = aabb3_compute_distance_above_plane_max(
|
|
57622
57610
|
plane_x, plane_y, plane_z, plane_w,
|
|
@@ -57631,6 +57619,7 @@ function aabb3_intersects_frustum_array(x0, y0, z0, x1, y1, z1, frustum) {
|
|
|
57631
57619
|
}
|
|
57632
57620
|
|
|
57633
57621
|
return true;
|
|
57622
|
+
|
|
57634
57623
|
}
|
|
57635
57624
|
|
|
57636
57625
|
//
|
|
@@ -58710,7 +58699,7 @@ class AABB3 {
|
|
|
58710
58699
|
const y1 = this.y1;
|
|
58711
58700
|
const z1 = this.z1;
|
|
58712
58701
|
|
|
58713
|
-
return
|
|
58702
|
+
return aabb3_intersects_clipping_volume_array(x0, y0, z0, x1, y1, z1, frustum, 0, 6);
|
|
58714
58703
|
}
|
|
58715
58704
|
|
|
58716
58705
|
/**
|
|
@@ -58845,6 +58834,127 @@ function ray3_array_compose(output, origin_x, origin_y, origin_z, direction_x, d
|
|
|
58845
58834
|
output[5] = direction_z;
|
|
58846
58835
|
}
|
|
58847
58836
|
|
|
58837
|
+
//
|
|
58838
|
+
|
|
58839
|
+
/**
|
|
58840
|
+
*
|
|
58841
|
+
* @param {ArrayLike<number>|number[]|Float32Array} aabb bounding box, order: x0,y0,z0,x1,y1,z1
|
|
58842
|
+
* @param {number} aabb_offset
|
|
58843
|
+
* @param {number} origin_x
|
|
58844
|
+
* @param {number} origin_y
|
|
58845
|
+
* @param {number} origin_z
|
|
58846
|
+
* @param {number} direction_x
|
|
58847
|
+
* @param {number} direction_y
|
|
58848
|
+
* @param {number} direction_z
|
|
58849
|
+
*/
|
|
58850
|
+
function aabb3_array_intersects_ray(
|
|
58851
|
+
aabb, aabb_offset,
|
|
58852
|
+
origin_x, origin_y, origin_z,
|
|
58853
|
+
direction_x, direction_y, direction_z
|
|
58854
|
+
) {
|
|
58855
|
+
return aabb3_intersects_ray(
|
|
58856
|
+
aabb[aabb_offset], aabb[aabb_offset+1], aabb[aabb_offset+2],
|
|
58857
|
+
aabb[aabb_offset+3], aabb[aabb_offset+4], aabb[aabb_offset+5],
|
|
58858
|
+
origin_x, origin_y, origin_z,
|
|
58859
|
+
direction_x, direction_y, direction_z
|
|
58860
|
+
);
|
|
58861
|
+
}
|
|
58862
|
+
|
|
58863
|
+
const stack$7 = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
58864
|
+
|
|
58865
|
+
/**
|
|
58866
|
+
*
|
|
58867
|
+
* @param {number[]} result
|
|
58868
|
+
* @param {number} result_offset
|
|
58869
|
+
* @param {BinaryUint32BVH} bvh
|
|
58870
|
+
* @param {number} origin_x
|
|
58871
|
+
* @param {number} origin_y
|
|
58872
|
+
* @param {number} origin_z
|
|
58873
|
+
* @param {number} direction_x
|
|
58874
|
+
* @param {number} direction_y
|
|
58875
|
+
* @param {number} direction_z
|
|
58876
|
+
* @returns {number}
|
|
58877
|
+
*/
|
|
58878
|
+
function bvh32_query_user_data_ray(
|
|
58879
|
+
result, result_offset,
|
|
58880
|
+
bvh,
|
|
58881
|
+
origin_x, origin_y, origin_z,
|
|
58882
|
+
direction_x, direction_y, direction_z
|
|
58883
|
+
) {
|
|
58884
|
+
let hit_count = 0;
|
|
58885
|
+
|
|
58886
|
+
const binary_node_count = bvh.binary_node_count;
|
|
58887
|
+
|
|
58888
|
+
if (binary_node_count <= 0) {
|
|
58889
|
+
// this should not happen
|
|
58890
|
+
return 0;
|
|
58891
|
+
}
|
|
58892
|
+
|
|
58893
|
+
/**
|
|
58894
|
+
*
|
|
58895
|
+
* @type {number}
|
|
58896
|
+
*/
|
|
58897
|
+
const stack_top = stack$7.pointer++;
|
|
58898
|
+
|
|
58899
|
+
/**
|
|
58900
|
+
* After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
|
|
58901
|
+
* @type {number}
|
|
58902
|
+
*/
|
|
58903
|
+
stack$7[stack_top] = 0;
|
|
58904
|
+
|
|
58905
|
+
const last_valid_index = binary_node_count + bvh.leaf_node_count;
|
|
58906
|
+
|
|
58907
|
+
const float32 = bvh.float32;
|
|
58908
|
+
const uint32 = bvh.uint32;
|
|
58909
|
+
|
|
58910
|
+
do {
|
|
58911
|
+
stack$7.pointer--;
|
|
58912
|
+
|
|
58913
|
+
// query_bvh_frustum_from_objects.iteration_count++;
|
|
58914
|
+
const node_index = stack$7[stack$7.pointer];
|
|
58915
|
+
|
|
58916
|
+
const node_address = bvh.getNodeAddress(node_index);
|
|
58917
|
+
|
|
58918
|
+
if (!aabb3_array_intersects_ray(
|
|
58919
|
+
float32, node_address,
|
|
58920
|
+
origin_x, origin_y, origin_z,
|
|
58921
|
+
direction_x, direction_y, direction_z
|
|
58922
|
+
)) {
|
|
58923
|
+
continue;
|
|
58924
|
+
}
|
|
58925
|
+
|
|
58926
|
+
const is_intermediate_node = node_index < binary_node_count;
|
|
58927
|
+
|
|
58928
|
+
if (is_intermediate_node) {
|
|
58929
|
+
// is intermediate node
|
|
58930
|
+
|
|
58931
|
+
const left_index = (node_index << 1) + 1;
|
|
58932
|
+
const right_index = left_index + 1;
|
|
58933
|
+
|
|
58934
|
+
// left node ends up on top of the stack, which aligns with the desired access sequence
|
|
58935
|
+
if (right_index < last_valid_index) {
|
|
58936
|
+
stack$7[stack$7.pointer++] = right_index;
|
|
58937
|
+
// micro-optimization, since we know that right node is valid and left appears before that, left is valid too
|
|
58938
|
+
stack$7[stack$7.pointer++] = left_index;
|
|
58939
|
+
} else if (left_index < last_valid_index) {
|
|
58940
|
+
stack$7[stack$7.pointer++] = left_index;
|
|
58941
|
+
}
|
|
58942
|
+
|
|
58943
|
+
|
|
58944
|
+
} else {
|
|
58945
|
+
// leaf node
|
|
58946
|
+
|
|
58947
|
+
// write to output
|
|
58948
|
+
result[result_offset + hit_count] = uint32[node_address + 6];
|
|
58949
|
+
|
|
58950
|
+
hit_count++;
|
|
58951
|
+
}
|
|
58952
|
+
|
|
58953
|
+
} while (stack$7.pointer > stack_top)
|
|
58954
|
+
|
|
58955
|
+
return hit_count;
|
|
58956
|
+
}
|
|
58957
|
+
|
|
58848
58958
|
/**
|
|
58849
58959
|
* NOTE: adapted from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
|
|
58850
58960
|
* @source https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm (Möller and Trumbore, « Fast, Minimum Storage Ray-Triangle Intersection », Journal of Graphics Tools, vol. 2, 1997, p. 21–28)
|
|
@@ -59002,6 +59112,110 @@ function computeTriangleRayIntersection(
|
|
|
59002
59112
|
return true;
|
|
59003
59113
|
}
|
|
59004
59114
|
|
|
59115
|
+
const scratch_array$4 = [];
|
|
59116
|
+
const scratch_hit = new SurfacePoint3();
|
|
59117
|
+
|
|
59118
|
+
/**
|
|
59119
|
+
*
|
|
59120
|
+
* @param {SurfacePoint3} result
|
|
59121
|
+
* @param {BinaryUint32BVH} bvh
|
|
59122
|
+
* @param {number[]|ArrayLike<number>} vertices
|
|
59123
|
+
* @param {number} vertex_offset Unless you're using an interleaved buffer of some kind, this will be 0
|
|
59124
|
+
* @param {number} vertex_stride Unless you're using an interleaved buffer, this should be 3
|
|
59125
|
+
* @param {number[]|ArrayLike<number>|undefined} indices if this is set to undefined - implicit indexing will be used
|
|
59126
|
+
* @param {number} originX
|
|
59127
|
+
* @param {number} originY
|
|
59128
|
+
* @param {number} originZ
|
|
59129
|
+
* @param {number} directionX
|
|
59130
|
+
* @param {number} directionY
|
|
59131
|
+
* @param {number} directionZ
|
|
59132
|
+
* @returns {boolean}
|
|
59133
|
+
*/
|
|
59134
|
+
function bvh32_geometry_raycast(
|
|
59135
|
+
result,
|
|
59136
|
+
bvh,
|
|
59137
|
+
vertices, vertex_offset, vertex_stride,
|
|
59138
|
+
indices,
|
|
59139
|
+
originX, originY, originZ,
|
|
59140
|
+
directionX, directionY, directionZ
|
|
59141
|
+
) {
|
|
59142
|
+
let hit_found = false;
|
|
59143
|
+
|
|
59144
|
+
const hit_count = bvh32_query_user_data_ray(
|
|
59145
|
+
scratch_array$4, 0,
|
|
59146
|
+
bvh,
|
|
59147
|
+
originX, originY, originZ,
|
|
59148
|
+
directionX, directionY, directionZ
|
|
59149
|
+
);
|
|
59150
|
+
|
|
59151
|
+
let best_distance = Infinity;
|
|
59152
|
+
|
|
59153
|
+
let a, b, c;
|
|
59154
|
+
|
|
59155
|
+
for (let i = 0; i < hit_count; i++) {
|
|
59156
|
+
const triangle_index = scratch_array$4[i];
|
|
59157
|
+
|
|
59158
|
+
const index3 = triangle_index * 3;
|
|
59159
|
+
|
|
59160
|
+
if (indices !== undefined) {
|
|
59161
|
+
assert.lessThan(index3 + 2, indices.length, 'triangle index overflow, possibly geometry changed but tree was not rebuilt?');
|
|
59162
|
+
|
|
59163
|
+
a = indices[index3];
|
|
59164
|
+
b = indices[index3 + 1];
|
|
59165
|
+
c = indices[index3 + 2];
|
|
59166
|
+
} else {
|
|
59167
|
+
// implicit indices
|
|
59168
|
+
a = index3;
|
|
59169
|
+
b = index3 + 1;
|
|
59170
|
+
c = index3 + 2;
|
|
59171
|
+
}
|
|
59172
|
+
|
|
59173
|
+
const a_address = a * vertex_stride + vertex_offset;
|
|
59174
|
+
const b_address = b * vertex_stride + vertex_offset;
|
|
59175
|
+
const c_address = c * vertex_stride + vertex_offset;
|
|
59176
|
+
|
|
59177
|
+
assert.lessThan(a_address + 2, vertices.length, 'a-vertex overflow');
|
|
59178
|
+
assert.lessThan(b_address + 2, vertices.length, 'b-vertex overflow');
|
|
59179
|
+
assert.lessThan(c_address + 2, vertices.length, 'c-vertex overflow');
|
|
59180
|
+
|
|
59181
|
+
const ax = vertices[a_address];
|
|
59182
|
+
const ay = vertices[a_address + 1];
|
|
59183
|
+
const az = vertices[a_address + 2];
|
|
59184
|
+
|
|
59185
|
+
const bx = vertices[b_address];
|
|
59186
|
+
const by = vertices[b_address + 1];
|
|
59187
|
+
const bz = vertices[b_address + 2];
|
|
59188
|
+
|
|
59189
|
+
const cx = vertices[c_address];
|
|
59190
|
+
const cy = vertices[c_address + 1];
|
|
59191
|
+
const cz = vertices[c_address + 2];
|
|
59192
|
+
|
|
59193
|
+
const triangle_hit_found = computeTriangleRayIntersection(
|
|
59194
|
+
scratch_hit,
|
|
59195
|
+
originX, originY, originZ,
|
|
59196
|
+
directionX, directionY, directionZ,
|
|
59197
|
+
ax, ay, az,
|
|
59198
|
+
bx, by, bz,
|
|
59199
|
+
cx, cy, cz
|
|
59200
|
+
);
|
|
59201
|
+
|
|
59202
|
+
if (!triangle_hit_found) {
|
|
59203
|
+
continue;
|
|
59204
|
+
}
|
|
59205
|
+
|
|
59206
|
+
hit_found = true;
|
|
59207
|
+
|
|
59208
|
+
const distance_sqr = scratch_hit.position._distanceSqrTo(originX, originY, originZ);
|
|
59209
|
+
|
|
59210
|
+
if (distance_sqr < best_distance) {
|
|
59211
|
+
best_distance = distance_sqr;
|
|
59212
|
+
result.copy(scratch_hit);
|
|
59213
|
+
}
|
|
59214
|
+
}
|
|
59215
|
+
|
|
59216
|
+
return hit_found;
|
|
59217
|
+
}
|
|
59218
|
+
|
|
59005
59219
|
/**
|
|
59006
59220
|
* Created by Alex on 28/01/2017.
|
|
59007
59221
|
*/
|
|
@@ -59083,9 +59297,6 @@ var ThreeFactory = {
|
|
|
59083
59297
|
const EMPTY_GEOMETRY = new BufferGeometry();
|
|
59084
59298
|
const DEFAULT_MATERIAL = new MeshBasicMaterial();
|
|
59085
59299
|
|
|
59086
|
-
const scratch_array$3 = [];
|
|
59087
|
-
const scratch_hit = new SurfacePoint3();
|
|
59088
|
-
|
|
59089
59300
|
const ray_tmp = [];
|
|
59090
59301
|
const m4_tmp = [];
|
|
59091
59302
|
|
|
@@ -59241,52 +59452,19 @@ class TerrainTile {
|
|
|
59241
59452
|
const _directionY = ray_tmp[4];
|
|
59242
59453
|
const _directionZ = ray_tmp[5];
|
|
59243
59454
|
|
|
59244
|
-
const hit_count = bvh32_query_user_data_ray(
|
|
59245
|
-
this.bvh,
|
|
59246
|
-
scratch_array$3, 0,
|
|
59247
|
-
_originX, _originY, _originZ,
|
|
59248
|
-
_directionX, _directionY, _directionZ
|
|
59249
|
-
);
|
|
59250
|
-
|
|
59251
|
-
let best_distance = Infinity;
|
|
59252
|
-
let hit_found = false;
|
|
59253
|
-
|
|
59254
59455
|
const geometry = this.geometry;
|
|
59255
59456
|
|
|
59256
59457
|
const geometryIndices = geometry.getIndex().array;
|
|
59257
59458
|
const geometryPositions = geometry.getAttribute('position').array;
|
|
59258
59459
|
|
|
59259
|
-
|
|
59260
|
-
|
|
59261
|
-
|
|
59262
|
-
|
|
59263
|
-
|
|
59264
|
-
|
|
59265
|
-
|
|
59266
|
-
|
|
59267
|
-
|
|
59268
|
-
const triangle_hit_found = computeTriangleRayIntersection(
|
|
59269
|
-
scratch_hit,
|
|
59270
|
-
_originX, _originY, _originZ,
|
|
59271
|
-
_directionX, _directionY, _directionZ,
|
|
59272
|
-
geometryPositions[a], geometryPositions[a + 1], geometryPositions[a + 2],
|
|
59273
|
-
geometryPositions[b], geometryPositions[b + 1], geometryPositions[b + 2],
|
|
59274
|
-
geometryPositions[c], geometryPositions[c + 1], geometryPositions[c + 2],
|
|
59275
|
-
);
|
|
59276
|
-
|
|
59277
|
-
if (!triangle_hit_found) {
|
|
59278
|
-
continue;
|
|
59279
|
-
}
|
|
59280
|
-
|
|
59281
|
-
hit_found = true;
|
|
59282
|
-
|
|
59283
|
-
const distance_sqr = scratch_hit.position._distanceSqrTo(_originX, _originY, _originZ);
|
|
59284
|
-
|
|
59285
|
-
if (distance_sqr < best_distance) {
|
|
59286
|
-
best_distance = distance_sqr;
|
|
59287
|
-
result.copy(scratch_hit);
|
|
59288
|
-
}
|
|
59289
|
-
}
|
|
59460
|
+
let hit_found = bvh32_geometry_raycast(
|
|
59461
|
+
result,
|
|
59462
|
+
this.bvh,
|
|
59463
|
+
geometryPositions, 0, 3,
|
|
59464
|
+
geometryIndices,
|
|
59465
|
+
_originX, _originY, _originZ,
|
|
59466
|
+
_directionX, _directionY, _directionZ
|
|
59467
|
+
);
|
|
59290
59468
|
|
|
59291
59469
|
if (hit_found) {
|
|
59292
59470
|
result.applyMatrix4(m4);
|
|
@@ -59708,7 +59886,7 @@ class TerrainTile {
|
|
|
59708
59886
|
*
|
|
59709
59887
|
* @type {number[]}
|
|
59710
59888
|
*/
|
|
59711
|
-
const scratch_array$
|
|
59889
|
+
const scratch_array$3 = [];
|
|
59712
59890
|
const scratch_contact = new SurfacePoint3();
|
|
59713
59891
|
|
|
59714
59892
|
class TerrainTileManager {
|
|
@@ -60284,7 +60462,7 @@ class TerrainTileManager {
|
|
|
60284
60462
|
const hit_count = bvh_query_leaves_ray(
|
|
60285
60463
|
this.bvh,
|
|
60286
60464
|
this.bvh.root,
|
|
60287
|
-
scratch_array$
|
|
60465
|
+
scratch_array$3, 0,
|
|
60288
60466
|
originX, originY, originZ,
|
|
60289
60467
|
directionX, directionY, directionZ
|
|
60290
60468
|
);
|
|
@@ -60293,7 +60471,7 @@ class TerrainTileManager {
|
|
|
60293
60471
|
let hit_found = false;
|
|
60294
60472
|
|
|
60295
60473
|
for (let i = 0; i < hit_count; i++) {
|
|
60296
|
-
const node_id = scratch_array$
|
|
60474
|
+
const node_id = scratch_array$3[i];
|
|
60297
60475
|
|
|
60298
60476
|
const tile_index = this.bvh.node_get_user_data(node_id);
|
|
60299
60477
|
|
|
@@ -65201,7 +65379,7 @@ function makeTerrainWorkerProxy() {
|
|
|
65201
65379
|
resolve({
|
|
65202
65380
|
geometry: geometry,
|
|
65203
65381
|
bvh: {
|
|
65204
|
-
leaf_count: bvh.
|
|
65382
|
+
leaf_count: bvh.leaf_node_count,
|
|
65205
65383
|
data: bvh.data
|
|
65206
65384
|
}
|
|
65207
65385
|
});
|
|
@@ -67185,598 +67363,283 @@ function aabb3_from_threejs_geometry(result, geometry) {
|
|
|
67185
67363
|
aabb3_from_min_max(result, min, max);
|
|
67186
67364
|
}
|
|
67187
67365
|
|
|
67188
|
-
class IndexedBinaryBVHVisitor {
|
|
67189
|
-
/**
|
|
67190
|
-
*
|
|
67191
|
-
* @param {number} address
|
|
67192
|
-
* @param {NodeType} type
|
|
67193
|
-
* @returns {boolean}
|
|
67194
|
-
*/
|
|
67195
|
-
visit(address, type) {
|
|
67196
|
-
|
|
67197
|
-
}
|
|
67198
|
-
}
|
|
67199
|
-
|
|
67200
67366
|
/**
|
|
67201
67367
|
*
|
|
67202
|
-
* @
|
|
67368
|
+
* @param {Plane[]} planes
|
|
67369
|
+
* @param {ArrayLike<number>|number[]|Float32Array|Float64Array} array
|
|
67203
67370
|
*/
|
|
67204
|
-
|
|
67205
|
-
|
|
67206
|
-
BINARY: 1
|
|
67207
|
-
};
|
|
67208
|
-
|
|
67209
|
-
class RayLeafIntersectionVisitor extends IndexedBinaryBVHVisitor {
|
|
67210
|
-
constructor() {
|
|
67211
|
-
super();
|
|
67212
|
-
this.callback = noop;
|
|
67213
|
-
this.callbackThisArg = null;
|
|
67214
|
-
|
|
67215
|
-
this.originX = 0;
|
|
67216
|
-
this.originY = 0;
|
|
67217
|
-
this.originZ = 0;
|
|
67371
|
+
function read_three_planes_to_array(planes, array) {
|
|
67372
|
+
const plane_count = planes.length;
|
|
67218
67373
|
|
|
67219
|
-
|
|
67220
|
-
this.directionY = 0;
|
|
67221
|
-
this.directionZ = 0;
|
|
67374
|
+
assert.greaterThanOrEqual(array.length, plane_count * 4, 'target array is too small');
|
|
67222
67375
|
|
|
67223
|
-
|
|
67224
|
-
|
|
67225
|
-
* @type {IndexedBinaryBVH}
|
|
67226
|
-
*/
|
|
67227
|
-
this.root = null;
|
|
67228
|
-
}
|
|
67229
|
-
|
|
67230
|
-
visit(address, type) {
|
|
67231
|
-
const root = this.root;
|
|
67232
|
-
|
|
67233
|
-
const data = root.data;
|
|
67234
|
-
const binaryNodeCount = root.binaryNodeCount;
|
|
67235
|
-
|
|
67236
|
-
const x0 = data[address];
|
|
67237
|
-
const y0 = data[address + 1];
|
|
67238
|
-
const z0 = data[address + 2];
|
|
67239
|
-
const x1 = data[address + 3];
|
|
67240
|
-
const y1 = data[address + 4];
|
|
67241
|
-
const z1 = data[address + 5];
|
|
67242
|
-
|
|
67243
|
-
const intersectionFound = aabb3_intersects_ray(x0, y0, z0, x1, y1, z1,
|
|
67244
|
-
this.originX, this.originY, this.originZ,
|
|
67245
|
-
this.directionX, this.directionY, this.directionZ
|
|
67246
|
-
);
|
|
67376
|
+
for (let i = 0; i < plane_count; i++) {
|
|
67377
|
+
const plane = planes[i];
|
|
67247
67378
|
|
|
67248
|
-
|
|
67249
|
-
return false;
|
|
67250
|
-
}
|
|
67379
|
+
const offset = i * 4;
|
|
67251
67380
|
|
|
67252
|
-
|
|
67253
|
-
const value = address / 6 - binaryNodeCount;
|
|
67381
|
+
const normal = plane.normal;
|
|
67254
67382
|
|
|
67255
|
-
|
|
67383
|
+
array[offset] = normal.x;
|
|
67384
|
+
array[offset + 1] = normal.y;
|
|
67385
|
+
array[offset + 2] = normal.z;
|
|
67256
67386
|
|
|
67257
|
-
|
|
67258
|
-
} else {
|
|
67259
|
-
return true;
|
|
67260
|
-
}
|
|
67387
|
+
array[offset + 3] = plane.constant;
|
|
67261
67388
|
}
|
|
67262
67389
|
}
|
|
67263
67390
|
|
|
67264
|
-
/**
|
|
67265
|
-
* Created by Alex on 29/05/2016.
|
|
67266
|
-
*/
|
|
67267
|
-
|
|
67268
|
-
|
|
67269
67391
|
/**
|
|
67270
67392
|
*
|
|
67271
|
-
* @
|
|
67393
|
+
* @param {BinaryUint32BVH} bvh
|
|
67394
|
+
* @param {number} triangle_index
|
|
67395
|
+
* @param {number[]|Float32Array} vertices
|
|
67396
|
+
* @param {number} a_index
|
|
67397
|
+
* @param {number} b_index
|
|
67398
|
+
* @param {number} c_index
|
|
67272
67399
|
*/
|
|
67273
|
-
|
|
67274
|
-
|
|
67275
|
-
|
|
67276
|
-
|
|
67277
|
-
/**
|
|
67278
|
-
*
|
|
67279
|
-
* @constructor
|
|
67280
|
-
*/
|
|
67281
|
-
constructor() {
|
|
67282
|
-
/**
|
|
67283
|
-
*
|
|
67284
|
-
* @type {number}
|
|
67285
|
-
*/
|
|
67286
|
-
this.leafNodeCount = 0;
|
|
67287
|
-
|
|
67288
|
-
/**
|
|
67289
|
-
*
|
|
67290
|
-
* @type {number}
|
|
67291
|
-
*/
|
|
67292
|
-
this.binaryNodeCount = 0;
|
|
67293
|
-
|
|
67294
|
-
/**
|
|
67295
|
-
* Total number of boxes contained in the tree, some might be unused
|
|
67296
|
-
* @type {number}
|
|
67297
|
-
*/
|
|
67298
|
-
this.boxCount = 0;
|
|
67299
|
-
|
|
67300
|
-
/**
|
|
67301
|
-
*
|
|
67302
|
-
* @type {Float32Array|number[]}
|
|
67303
|
-
*/
|
|
67304
|
-
this.data = new Float32Array(16);
|
|
67305
|
-
}
|
|
67306
|
-
|
|
67307
|
-
/**
|
|
67308
|
-
*
|
|
67309
|
-
* @returns {number}
|
|
67310
|
-
*/
|
|
67311
|
-
estimateByteSize(){
|
|
67312
|
-
return this.data.buffer.byteLength + 248;
|
|
67313
|
-
}
|
|
67314
|
-
|
|
67315
|
-
/**
|
|
67316
|
-
*
|
|
67317
|
-
* @param {int} leafCount
|
|
67318
|
-
*/
|
|
67319
|
-
initialize(leafCount) {
|
|
67320
|
-
|
|
67321
|
-
const twoLog = Math.log(leafCount) / Math.log(2);
|
|
67322
|
-
|
|
67323
|
-
const twoLeafLimit = Math.pow(2, Math.ceil(twoLog));
|
|
67324
|
-
const binaryNodeCount = twoLeafLimit - 1;
|
|
67325
|
-
|
|
67326
|
-
this.leafNodeCount = leafCount;
|
|
67327
|
-
|
|
67328
|
-
this.binaryNodeCount = binaryNodeCount;
|
|
67329
|
-
|
|
67330
|
-
this.boxCount = this.leafNodeCount + this.binaryNodeCount;
|
|
67331
|
-
|
|
67332
|
-
// possibly resize the storage
|
|
67333
|
-
const storage_size = this.boxCount * 6;
|
|
67334
|
-
|
|
67335
|
-
if (this.data.length < storage_size) {
|
|
67336
|
-
this.data = new Float32Array(storage_size);
|
|
67337
|
-
} else {
|
|
67338
|
-
this.data.fill(0);
|
|
67339
|
-
}
|
|
67340
|
-
}
|
|
67341
|
-
|
|
67342
|
-
unsortedBuiltIntermediate() {
|
|
67343
|
-
const data = this.data;
|
|
67344
|
-
|
|
67345
|
-
const nodeCount = this.binaryNodeCount;
|
|
67346
|
-
|
|
67347
|
-
const leafNodesOffset = this.binaryNodeCount * 6;
|
|
67348
|
-
|
|
67349
|
-
let level = Math.floor(Math.log(nodeCount) / Math.log(2));
|
|
67350
|
-
|
|
67351
|
-
let i, offset, levelNodeCount;
|
|
67352
|
-
//NOTE: building first level separately allows to avoid some switching logic needed to determine what is the type of lower level node
|
|
67353
|
-
//build one level above leaf nodes
|
|
67354
|
-
levelNodeCount = Math.pow(2, level);
|
|
67355
|
-
offset = (levelNodeCount - 1) * 6;
|
|
67356
|
-
|
|
67357
|
-
let parentIndex, childIndex0, childIndex1;
|
|
67358
|
-
|
|
67359
|
-
for (i = 0; i < levelNodeCount; i++) {
|
|
67360
|
-
const leafIndex0 = i * 2;
|
|
67361
|
-
const leafIndex1 = leafIndex0 + 1;
|
|
67362
|
-
|
|
67363
|
-
const leafOffset0 = leafNodesOffset + leafIndex0 * 6;
|
|
67364
|
-
const leafOffset1 = leafNodesOffset + leafIndex1 * 6;
|
|
67365
|
-
|
|
67366
|
-
if (leafIndex1 < this.leafNodeCount) {
|
|
67367
|
-
binaryNodeRefit(data, offset, leafOffset0, leafOffset1);
|
|
67368
|
-
} else if (leafIndex0 < this.leafNodeCount) {
|
|
67369
|
-
copyBox(leafOffset0, offset, data);
|
|
67370
|
-
} else {
|
|
67371
|
-
//initialize to 0-size box same position as previous node
|
|
67372
|
-
copyBoxZeroSize(offset - 6, offset, data);
|
|
67373
|
-
}
|
|
67374
|
-
|
|
67375
|
-
offset += 6;
|
|
67376
|
-
}
|
|
67377
|
-
|
|
67378
|
-
level--;
|
|
67379
|
-
|
|
67380
|
-
//build intermediate nodes
|
|
67381
|
-
for (; level >= 0; level--) {
|
|
67382
|
-
levelNodeCount = Math.pow(2, level);
|
|
67383
|
-
parentIndex = (levelNodeCount - 1);
|
|
67384
|
-
|
|
67385
|
-
for (i = 0; i < levelNodeCount; i++) {
|
|
67386
|
-
|
|
67387
|
-
childIndex0 = (parentIndex << 1) + 1;
|
|
67388
|
-
childIndex1 = childIndex0 + 1;
|
|
67389
|
-
|
|
67390
|
-
binaryNodeRefit(data, parentIndex * 6, childIndex0 * 6, childIndex1 * 6);
|
|
67391
|
-
|
|
67392
|
-
parentIndex++;
|
|
67393
|
-
}
|
|
67394
|
-
}
|
|
67395
|
-
|
|
67396
|
-
//set bounds of the bvh
|
|
67397
|
-
array_copy(data, 0, scratch_aabb_0, 0, 6);
|
|
67398
|
-
|
|
67399
|
-
this.x0 = scratch_aabb_0[0];
|
|
67400
|
-
this.y0 = scratch_aabb_0[1];
|
|
67401
|
-
this.z0 = scratch_aabb_0[2];
|
|
67402
|
-
this.x1 = scratch_aabb_0[3];
|
|
67403
|
-
this.y1 = scratch_aabb_0[4];
|
|
67404
|
-
this.z1 = scratch_aabb_0[5];
|
|
67405
|
-
}
|
|
67406
|
-
|
|
67407
|
-
/**
|
|
67408
|
-
* Sets bounds of a given leaf
|
|
67409
|
-
* NOTE: to build tree, must call {@link #unsortedBuiltIntermediate} after all leaves are set
|
|
67410
|
-
* @param {number} leaf_index
|
|
67411
|
-
* @param {number} x0
|
|
67412
|
-
* @param {number} y0
|
|
67413
|
-
* @param {number} z0
|
|
67414
|
-
* @param {number} x1
|
|
67415
|
-
* @param {number} y1
|
|
67416
|
-
* @param {number} z1
|
|
67417
|
-
*/
|
|
67418
|
-
writeLeaf(leaf_index, x0, y0, z0, x1, y1, z1) {
|
|
67419
|
-
const offset = this.binaryNodeCount * 6 + leaf_index * 6;
|
|
67420
|
-
writeBox(this.data, offset, x0, y0, z0, x1, y1, z1);
|
|
67421
|
-
}
|
|
67422
|
-
|
|
67423
|
-
/**
|
|
67424
|
-
* @template T
|
|
67425
|
-
* @deprecated use {@link #writeLeaf} instead followed by {@link #unsortedBuiltIntermediate}
|
|
67426
|
-
* @param {function(index:number,offset:number,data:T, writeBox:function):void} visitor
|
|
67427
|
-
*/
|
|
67428
|
-
setLeafs(visitor) {
|
|
67429
|
-
let offset = this.binaryNodeCount * 6;
|
|
67430
|
-
|
|
67431
|
-
const data = this.data;
|
|
67400
|
+
function bvh32_set_leaf_from_triangle(bvh, triangle_index, vertices, a_index, b_index, c_index) {
|
|
67401
|
+
const a = a_index * 3;
|
|
67402
|
+
const b = b_index * 3;
|
|
67403
|
+
const c = c_index * 3;
|
|
67432
67404
|
|
|
67433
|
-
|
|
67434
|
-
|
|
67435
|
-
|
|
67436
|
-
|
|
67405
|
+
// read actual positions of each vertex
|
|
67406
|
+
const aX = vertices[a];
|
|
67407
|
+
const aY = vertices[a + 1];
|
|
67408
|
+
const aZ = vertices[a + 2];
|
|
67437
67409
|
|
|
67438
|
-
|
|
67439
|
-
|
|
67440
|
-
|
|
67441
|
-
}
|
|
67410
|
+
const bX = vertices[b];
|
|
67411
|
+
const bY = vertices[b + 1];
|
|
67412
|
+
const bZ = vertices[b + 2];
|
|
67442
67413
|
|
|
67443
|
-
|
|
67444
|
-
|
|
67445
|
-
|
|
67446
|
-
* @param {Number} startIndex
|
|
67447
|
-
*/
|
|
67448
|
-
traversePreOrderStack(visitor, startIndex) {
|
|
67414
|
+
const cX = vertices[c];
|
|
67415
|
+
const cY = vertices[c + 1];
|
|
67416
|
+
const cZ = vertices[c + 2];
|
|
67449
67417
|
|
|
67450
|
-
|
|
67418
|
+
// compute bounds of the triangle
|
|
67419
|
+
const x0 = min3(aX, bX, cX);
|
|
67420
|
+
const y0 = min3(aY, bY, cY);
|
|
67421
|
+
const z0 = min3(aZ, bZ, cZ);
|
|
67451
67422
|
|
|
67452
|
-
|
|
67423
|
+
const x1 = max3(aX, bX, cX);
|
|
67424
|
+
const y1 = max3(aY, bY, cY);
|
|
67425
|
+
const z1 = max3(aZ, bZ, cZ);
|
|
67453
67426
|
|
|
67454
|
-
|
|
67455
|
-
|
|
67456
|
-
|
|
67457
|
-
|
|
67458
|
-
|
|
67459
|
-
|
|
67460
|
-
|
|
67461
|
-
|
|
67427
|
+
bvh.setLeafData(triangle_index, triangle_index, x0, y0, z0, x1, y1, z1);
|
|
67428
|
+
}
|
|
67429
|
+
|
|
67430
|
+
/**
|
|
67431
|
+
*
|
|
67432
|
+
* @param {BinaryUint32BVH} bvh
|
|
67433
|
+
* @param {Float32Array} vertices
|
|
67434
|
+
* @param {Uint32Array} indices
|
|
67435
|
+
*/
|
|
67436
|
+
function bvh32_from_indexed_geometry(bvh, vertices, indices) {
|
|
67462
67437
|
|
|
67463
|
-
|
|
67464
|
-
if (split) {
|
|
67438
|
+
const triangle_count = indices.length / 3;
|
|
67465
67439
|
|
|
67466
|
-
|
|
67467
|
-
|
|
67440
|
+
bvh.setLeafCount(triangle_count);
|
|
67441
|
+
bvh.initialize_structure();
|
|
67468
67442
|
|
|
67469
|
-
|
|
67470
|
-
const rightAddress = rightIndex * 6;
|
|
67443
|
+
for (let i = 0; i < triangle_count; i++) {
|
|
67471
67444
|
|
|
67472
|
-
|
|
67473
|
-
if (rightAddress < endAddress) {
|
|
67474
|
-
if (rightAddress < nodeThreshold) {
|
|
67475
|
-
stack$6[stackPointer++] = rightIndex;
|
|
67476
|
-
} else {
|
|
67477
|
-
visitor.visit(rightAddress, NodeType.LEAF);
|
|
67478
|
-
}
|
|
67479
|
-
}
|
|
67445
|
+
const index3 = i * 3;
|
|
67480
67446
|
|
|
67481
|
-
|
|
67482
|
-
|
|
67483
|
-
|
|
67484
|
-
|
|
67485
|
-
} else {
|
|
67486
|
-
visitor.visit(leftAddress, NodeType.LEAF);
|
|
67487
|
-
}
|
|
67488
|
-
}
|
|
67489
|
-
}
|
|
67490
|
-
}
|
|
67447
|
+
// read triangle vertex indices
|
|
67448
|
+
const iA = indices[index3];
|
|
67449
|
+
const iB = indices[index3 + 1];
|
|
67450
|
+
const iC = indices[index3 + 2];
|
|
67491
67451
|
|
|
67492
|
-
|
|
67493
|
-
stackPointer = stackOffset;
|
|
67452
|
+
bvh32_set_leaf_from_triangle(bvh, i, vertices, iA, iB, iC);
|
|
67494
67453
|
}
|
|
67495
67454
|
|
|
67496
|
-
|
|
67497
|
-
|
|
67498
|
-
|
|
67499
|
-
|
|
67500
|
-
|
|
67501
|
-
|
|
67502
|
-
|
|
67503
|
-
|
|
67504
|
-
|
|
67505
|
-
|
|
67506
|
-
|
|
67507
|
-
|
|
67508
|
-
if (carryOn !== false) {
|
|
67455
|
+
// finalize build
|
|
67456
|
+
// bvh.sort_morton(MATRIX_4_IDENTITY);
|
|
67457
|
+
bvh.build();
|
|
67458
|
+
}
|
|
67459
|
+
|
|
67460
|
+
/**
|
|
67461
|
+
*
|
|
67462
|
+
* @param {BinaryUint32BVH} bvh
|
|
67463
|
+
* @param {Float32Array} vertices
|
|
67464
|
+
*/
|
|
67465
|
+
function bvh32_from_unindexed_geometry(bvh, vertices) {
|
|
67509
67466
|
|
|
67510
|
-
|
|
67511
|
-
const rightIndex = leftIndex + 1;
|
|
67467
|
+
const triangle_count = indices.length / 3;
|
|
67512
67468
|
|
|
67513
|
-
|
|
67514
|
-
|
|
67515
|
-
//left
|
|
67516
|
-
if (leftAddress < endAddress) {
|
|
67517
|
-
if (leftAddress < nodeThreshold) {
|
|
67518
|
-
this.traversePreOrder(visitor, leftIndex, NodeType.BINARY);
|
|
67519
|
-
} else {
|
|
67520
|
-
visitor(leftAddress, NodeType.LEAF);
|
|
67521
|
-
}
|
|
67522
|
-
}
|
|
67523
|
-
//right
|
|
67524
|
-
if (rightAddress < endAddress) {
|
|
67525
|
-
if (rightAddress < nodeThreshold) {
|
|
67526
|
-
this.traversePreOrder(visitor, rightIndex, NodeType.BINARY);
|
|
67527
|
-
} else {
|
|
67528
|
-
visitor(rightAddress, NodeType.LEAF);
|
|
67529
|
-
}
|
|
67530
|
-
}
|
|
67531
|
-
}
|
|
67532
|
-
}
|
|
67469
|
+
bvh.setLeafCount(triangle_count);
|
|
67470
|
+
bvh.initialize_structure();
|
|
67533
67471
|
|
|
67534
|
-
|
|
67535
|
-
* @deprecated use a visitor object instead
|
|
67536
|
-
* @param {number} startX
|
|
67537
|
-
* @param {number} startY
|
|
67538
|
-
* @param {number} startZ
|
|
67539
|
-
* @param {number} directionX
|
|
67540
|
-
* @param {number} directionY
|
|
67541
|
-
* @param {number} directionZ
|
|
67542
|
-
* @param {function} visitor
|
|
67543
|
-
* @param {*} [thisArg]
|
|
67544
|
-
*/
|
|
67545
|
-
traverseRayLeafIntersections(startX, startY, startZ, directionX, directionY, directionZ, visitor, thisArg) {
|
|
67546
|
-
rayLeafIntersectionVisitor.originX = startX;
|
|
67547
|
-
rayLeafIntersectionVisitor.originY = startY;
|
|
67548
|
-
rayLeafIntersectionVisitor.originZ = startZ;
|
|
67472
|
+
for (let i = 0; i < triangle_count; i++) {
|
|
67549
67473
|
|
|
67550
|
-
|
|
67551
|
-
rayLeafIntersectionVisitor.directionY = directionY;
|
|
67552
|
-
rayLeafIntersectionVisitor.directionZ = directionZ;
|
|
67474
|
+
const index3 = i * 3;
|
|
67553
67475
|
|
|
67554
|
-
|
|
67555
|
-
|
|
67556
|
-
|
|
67476
|
+
// generate triangle vertex indices
|
|
67477
|
+
const iA = index3;
|
|
67478
|
+
const iB = index3 + 1;
|
|
67479
|
+
const iC = index3 + 2;
|
|
67557
67480
|
|
|
67558
|
-
|
|
67481
|
+
bvh32_set_leaf_from_triangle(bvh, i, vertices, iA, iB, iC);
|
|
67559
67482
|
}
|
|
67560
|
-
}
|
|
67561
67483
|
|
|
67484
|
+
// finalize build
|
|
67485
|
+
// bvh.sort_morton(MATRIX_4_IDENTITY);
|
|
67486
|
+
bvh.build();
|
|
67487
|
+
}
|
|
67488
|
+
|
|
67562
67489
|
/**
|
|
67563
67490
|
*
|
|
67564
|
-
* @param {
|
|
67565
|
-
* @
|
|
67566
|
-
* @param {number} source_address_1
|
|
67567
|
-
* @param {number[]|Float32Array} destination
|
|
67568
|
-
* @param {number} destination_offset
|
|
67491
|
+
* @param {THREE.InterleavedBufferAttribute|THREE.BufferAttribute} source_attribute
|
|
67492
|
+
* @returns {THREE.BufferAttribute}
|
|
67569
67493
|
*/
|
|
67570
|
-
function
|
|
67571
|
-
|
|
67572
|
-
|
|
67573
|
-
|
|
67574
|
-
const az0 = source[source_address_0 + 2];
|
|
67575
|
-
const ax1 = source[source_address_0 + 3];
|
|
67576
|
-
const ay1 = source[source_address_0 + 4];
|
|
67577
|
-
const az1 = source[source_address_0 + 5];
|
|
67578
|
-
|
|
67579
|
-
const bx0 = source[source_address_1];
|
|
67580
|
-
const by0 = source[source_address_1 + 1];
|
|
67581
|
-
const bz0 = source[source_address_1 + 2];
|
|
67582
|
-
const bx1 = source[source_address_1 + 3];
|
|
67583
|
-
const by1 = source[source_address_1 + 4];
|
|
67584
|
-
const bz1 = source[source_address_1 + 5];
|
|
67585
|
-
|
|
67586
|
-
const x0 = min2(ax0, bx0);
|
|
67587
|
-
const y0 = min2(ay0, by0);
|
|
67588
|
-
const z0 = min2(az0, bz0);
|
|
67494
|
+
function deinterleaveBufferAttribute(source_attribute) {
|
|
67495
|
+
if (source_attribute.isInterleavedBufferAttribute !== true && source_attribute.isBufferAttribute) {
|
|
67496
|
+
return source_attribute;
|
|
67497
|
+
}
|
|
67589
67498
|
|
|
67590
|
-
const
|
|
67591
|
-
const
|
|
67592
|
-
const
|
|
67499
|
+
const source_data = source_attribute.data;
|
|
67500
|
+
const source_data_array = source_data.array;
|
|
67501
|
+
const stride = source_data.stride;
|
|
67593
67502
|
|
|
67594
|
-
|
|
67595
|
-
|
|
67596
|
-
|
|
67597
|
-
destination[destination_offset + 3] = x1;
|
|
67598
|
-
destination[destination_offset + 4] = y1;
|
|
67599
|
-
destination[destination_offset + 5] = z1;
|
|
67600
|
-
}
|
|
67503
|
+
const item_count = source_attribute.count;
|
|
67504
|
+
const itemSize = source_attribute.itemSize;
|
|
67505
|
+
const array_size = item_count * itemSize;
|
|
67601
67506
|
|
|
67602
|
-
|
|
67603
|
-
*
|
|
67604
|
-
* @param {Float32Array} array
|
|
67605
|
-
* @param {number} address
|
|
67606
|
-
* @param {number} x0
|
|
67607
|
-
* @param {number} y0
|
|
67608
|
-
* @param {number} z0
|
|
67609
|
-
* @param {number} x1
|
|
67610
|
-
* @param {number} y1
|
|
67611
|
-
* @param {number} z1
|
|
67612
|
-
*/
|
|
67613
|
-
function writeBox(array, address, x0, y0, z0, x1, y1, z1) {
|
|
67614
|
-
array[address] = x0;
|
|
67615
|
-
array[address + 1] = y0;
|
|
67616
|
-
array[address + 2] = z0;
|
|
67617
|
-
array[address + 3] = x1;
|
|
67618
|
-
array[address + 4] = y1;
|
|
67619
|
-
array[address + 5] = z1;
|
|
67620
|
-
}
|
|
67507
|
+
const offset = source_attribute.offset;
|
|
67621
67508
|
|
|
67622
|
-
|
|
67623
|
-
*
|
|
67624
|
-
* @param {number} from
|
|
67625
|
-
* @param {number} to
|
|
67626
|
-
* @param {Float32Array} array
|
|
67627
|
-
*/
|
|
67628
|
-
function copyBox(from, to, array) {
|
|
67629
|
-
array_copy(array, from, array, to, 6);
|
|
67630
|
-
}
|
|
67509
|
+
const destination_array = new source_data_array.constructor(array_size);
|
|
67631
67510
|
|
|
67632
|
-
|
|
67633
|
-
*
|
|
67634
|
-
* @param {number} from
|
|
67635
|
-
* @param {number} to
|
|
67636
|
-
* @param {Float32Array|number[]} array
|
|
67637
|
-
*/
|
|
67638
|
-
function copyBoxZeroSize(from, to, array) {
|
|
67639
|
-
array_copy(array, from, scratch_aabb_0, 0, 3);
|
|
67511
|
+
const attribute = new BufferAttribute(destination_array, itemSize);
|
|
67640
67512
|
|
|
67641
|
-
|
|
67642
|
-
|
|
67643
|
-
scratch_aabb_0[5] = scratch_aabb_0[2];
|
|
67513
|
+
attribute.normalized = source_attribute.normalized;
|
|
67514
|
+
attribute.name = source_attribute.name;
|
|
67644
67515
|
|
|
67645
|
-
|
|
67646
|
-
|
|
67516
|
+
let i = 0, j = 0;
|
|
67517
|
+
// copy data
|
|
67518
|
+
for (; i < item_count; i++) {
|
|
67519
|
+
for (j = 0; j < itemSize; j++) {
|
|
67520
|
+
destination_array[i * itemSize + j] = source_data_array[i * stride + offset + j];
|
|
67521
|
+
}
|
|
67522
|
+
}
|
|
67647
67523
|
|
|
67524
|
+
return attribute;
|
|
67525
|
+
}
|
|
67526
|
+
|
|
67648
67527
|
/**
|
|
67649
67528
|
*
|
|
67650
|
-
* @param {Float32Array}
|
|
67651
|
-
* @param {number}
|
|
67652
|
-
* @param {number}
|
|
67653
|
-
* @param {number}
|
|
67529
|
+
* @param {Float32Array|number[]} aabb
|
|
67530
|
+
* @param {number} aabb_offset
|
|
67531
|
+
* @param {Float32Array|number[]} planes
|
|
67532
|
+
* @param {number} planes_offset
|
|
67533
|
+
* @param {number} plane_count
|
|
67534
|
+
* @return {boolean}
|
|
67654
67535
|
*/
|
|
67655
|
-
function
|
|
67656
|
-
|
|
67657
|
-
|
|
67658
|
-
|
|
67536
|
+
function aabb3_array_intersects_clipping_volume_array(
|
|
67537
|
+
aabb, aabb_offset,
|
|
67538
|
+
planes, planes_offset, plane_count
|
|
67539
|
+
) {
|
|
67659
67540
|
|
|
67660
|
-
const
|
|
67661
|
-
|
|
67541
|
+
const x0 = aabb[aabb_offset + 0];
|
|
67542
|
+
const y0 = aabb[aabb_offset + 1];
|
|
67543
|
+
const z0 = aabb[aabb_offset + 2];
|
|
67544
|
+
const x1 = aabb[aabb_offset + 3];
|
|
67545
|
+
const y1 = aabb[aabb_offset + 4];
|
|
67546
|
+
const z1 = aabb[aabb_offset + 5];
|
|
67662
67547
|
|
|
67663
|
-
|
|
67548
|
+
return aabb3_intersects_clipping_volume_array(
|
|
67549
|
+
x0, y0, z0,
|
|
67550
|
+
x1, y1, z1,
|
|
67551
|
+
planes, planes_offset, plane_count
|
|
67552
|
+
);
|
|
67553
|
+
}
|
|
67664
67554
|
|
|
67665
|
-
|
|
67666
|
-
* Created by Alex on 29/05/2016.
|
|
67667
|
-
*/
|
|
67555
|
+
const stack$6 = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
67668
67556
|
|
|
67669
67557
|
/**
|
|
67670
67558
|
*
|
|
67671
|
-
* @param {
|
|
67672
|
-
* @param {
|
|
67673
|
-
* @
|
|
67559
|
+
* @param {number[]} result
|
|
67560
|
+
* @param {number} result_offset
|
|
67561
|
+
* @param {BinaryUint32BVH} bvh
|
|
67562
|
+
* @param {Float32Array|number[]} planes
|
|
67563
|
+
* @param {number} planes_offset
|
|
67564
|
+
* @param {number} plane_count
|
|
67565
|
+
* @returns {number}
|
|
67674
67566
|
*/
|
|
67675
|
-
function
|
|
67676
|
-
|
|
67677
|
-
|
|
67678
|
-
|
|
67679
|
-
|
|
67680
|
-
|
|
67681
|
-
|
|
67682
|
-
for (let i = 0; i < numNodes; i++) {
|
|
67683
|
-
|
|
67684
|
-
const index3 = i * 3;
|
|
67685
|
-
|
|
67686
|
-
// read triangle vertex indices
|
|
67687
|
-
const iA = indices[index3];
|
|
67688
|
-
const iB = indices[index3 + 1];
|
|
67689
|
-
const iC = indices[index3 + 2];
|
|
67690
|
-
|
|
67691
|
-
const a = iA * 3;
|
|
67692
|
-
const b = iB * 3;
|
|
67693
|
-
const c = iC * 3;
|
|
67694
|
-
|
|
67695
|
-
// read actual positions of each vertex
|
|
67696
|
-
const aX = vertices[a];
|
|
67697
|
-
const aY = vertices[a + 1];
|
|
67698
|
-
const aZ = vertices[a + 2];
|
|
67699
|
-
|
|
67700
|
-
const bX = vertices[b];
|
|
67701
|
-
const bY = vertices[b + 1];
|
|
67702
|
-
const bZ = vertices[b + 2];
|
|
67567
|
+
function bvh32_query_user_data_overlaps_clipping_volume(
|
|
67568
|
+
result, result_offset,
|
|
67569
|
+
bvh,
|
|
67570
|
+
planes, planes_offset, plane_count
|
|
67571
|
+
) {
|
|
67572
|
+
let hit_count = 0;
|
|
67703
67573
|
|
|
67704
|
-
|
|
67705
|
-
const cY = vertices[c + 1];
|
|
67706
|
-
const cZ = vertices[c + 2];
|
|
67574
|
+
const binary_node_count = bvh.binary_node_count;
|
|
67707
67575
|
|
|
67708
|
-
|
|
67709
|
-
|
|
67710
|
-
|
|
67711
|
-
|
|
67576
|
+
if (binary_node_count <= 0) {
|
|
67577
|
+
// this should not happen
|
|
67578
|
+
return 0;
|
|
67579
|
+
}
|
|
67712
67580
|
|
|
67713
|
-
|
|
67714
|
-
|
|
67715
|
-
|
|
67581
|
+
/**
|
|
67582
|
+
*
|
|
67583
|
+
* @type {number}
|
|
67584
|
+
*/
|
|
67585
|
+
const stack_top = stack$6.pointer++;
|
|
67716
67586
|
|
|
67717
|
-
|
|
67718
|
-
|
|
67587
|
+
/**
|
|
67588
|
+
* After performing empirical tests, stack-based depth-first traversal turns out faster than using a queue
|
|
67589
|
+
* @type {number}
|
|
67590
|
+
*/
|
|
67591
|
+
stack$6[stack_top] = 0;
|
|
67719
67592
|
|
|
67720
|
-
|
|
67721
|
-
tree.unsortedBuiltIntermediate();
|
|
67593
|
+
const last_valid_index = binary_node_count + bvh.leaf_node_count;
|
|
67722
67594
|
|
|
67723
|
-
|
|
67724
|
-
|
|
67595
|
+
const float32 = bvh.float32;
|
|
67596
|
+
const uint32 = bvh.uint32;
|
|
67725
67597
|
|
|
67726
|
-
|
|
67727
|
-
|
|
67728
|
-
* @param {Float32Array|Float64Array|Array.<Number>} vertices
|
|
67729
|
-
* @returns {IndexedBinaryBVH}
|
|
67730
|
-
*/
|
|
67731
|
-
function buildUnsortedUnindexed(vertices) {
|
|
67732
|
-
//
|
|
67733
|
-
const numNodes = vertices.length / 9;
|
|
67598
|
+
do {
|
|
67599
|
+
stack$6.pointer--;
|
|
67734
67600
|
|
|
67735
|
-
|
|
67736
|
-
|
|
67601
|
+
// query_bvh_frustum_from_objects.iteration_count++;
|
|
67602
|
+
const node_index = stack$6[stack$6.pointer];
|
|
67737
67603
|
|
|
67738
|
-
|
|
67604
|
+
const node_address = bvh.getNodeAddress(node_index);
|
|
67739
67605
|
|
|
67740
|
-
|
|
67606
|
+
if (!aabb3_array_intersects_clipping_volume_array(
|
|
67607
|
+
float32, node_address,
|
|
67608
|
+
planes, planes_offset, plane_count
|
|
67609
|
+
)) {
|
|
67610
|
+
continue;
|
|
67611
|
+
}
|
|
67741
67612
|
|
|
67742
|
-
|
|
67743
|
-
const iA = index3;
|
|
67744
|
-
const iB = index3 + 1;
|
|
67745
|
-
const iC = index3 + 2;
|
|
67613
|
+
const is_intermediate_node = node_index < binary_node_count;
|
|
67746
67614
|
|
|
67747
|
-
|
|
67748
|
-
|
|
67749
|
-
const c = iC * 3;
|
|
67615
|
+
if (is_intermediate_node) {
|
|
67616
|
+
// is intermediate node
|
|
67750
67617
|
|
|
67751
|
-
|
|
67752
|
-
|
|
67753
|
-
const aY = vertices[a + 1];
|
|
67754
|
-
const aZ = vertices[a + 2];
|
|
67618
|
+
const left_index = (node_index << 1) + 1;
|
|
67619
|
+
const right_index = left_index + 1;
|
|
67755
67620
|
|
|
67756
|
-
|
|
67757
|
-
|
|
67758
|
-
|
|
67621
|
+
// left node ends up on top of the stack, which aligns with the desired access sequence
|
|
67622
|
+
if (right_index < last_valid_index) {
|
|
67623
|
+
stack$6[stack$6.pointer++] = right_index;
|
|
67624
|
+
// micro-optimization, since we know that right node is valid and left appears before that, left is valid too
|
|
67625
|
+
stack$6[stack$6.pointer++] = left_index;
|
|
67626
|
+
} else if (left_index < last_valid_index) {
|
|
67627
|
+
stack$6[stack$6.pointer++] = left_index;
|
|
67628
|
+
}
|
|
67759
67629
|
|
|
67760
|
-
const cX = vertices[c];
|
|
67761
|
-
const cY = vertices[c + 1];
|
|
67762
|
-
const cZ = vertices[c + 2];
|
|
67763
67630
|
|
|
67764
|
-
|
|
67765
|
-
|
|
67766
|
-
const y0 = min3(aY, bY, cY);
|
|
67767
|
-
const z0 = min3(aZ, bZ, cZ);
|
|
67631
|
+
} else {
|
|
67632
|
+
// leaf node
|
|
67768
67633
|
|
|
67769
|
-
|
|
67770
|
-
|
|
67771
|
-
const z1 = max3(aZ, bZ, cZ);
|
|
67634
|
+
// write to output
|
|
67635
|
+
result[result_offset + hit_count] = uint32[node_address + 6];
|
|
67772
67636
|
|
|
67773
|
-
|
|
67774
|
-
|
|
67637
|
+
hit_count++;
|
|
67638
|
+
}
|
|
67775
67639
|
|
|
67776
|
-
|
|
67777
|
-
tree.unsortedBuiltIntermediate();
|
|
67640
|
+
} while (stack$6.pointer > stack_top)
|
|
67778
67641
|
|
|
67779
|
-
return
|
|
67642
|
+
return hit_count;
|
|
67780
67643
|
}
|
|
67781
67644
|
|
|
67782
67645
|
/**
|
|
@@ -67813,526 +67676,145 @@ function computeTrianglePlaneSide(
|
|
|
67813
67676
|
return result;
|
|
67814
67677
|
}
|
|
67815
67678
|
|
|
67816
|
-
|
|
67817
|
-
|
|
67818
|
-
|
|
67819
|
-
|
|
67820
|
-
|
|
67821
|
-
|
|
67822
|
-
|
|
67823
|
-
|
|
67824
|
-
|
|
67825
|
-
|
|
67826
|
-
|
|
67827
|
-
|
|
67828
|
-
|
|
67829
|
-
|
|
67830
|
-
|
|
67831
|
-
|
|
67832
|
-
|
|
67833
|
-
|
|
67834
|
-
|
|
67835
|
-
|
|
67836
|
-
|
|
67837
|
-
* @protected
|
|
67838
|
-
*/
|
|
67839
|
-
this.__buffer_vertices = null;
|
|
67840
|
-
|
|
67841
|
-
/**
|
|
67842
|
-
*
|
|
67843
|
-
* @type {number}
|
|
67844
|
-
* @protected
|
|
67845
|
-
*/
|
|
67846
|
-
this.__buffer_vertex_stride = 3;
|
|
67847
|
-
|
|
67848
|
-
/**
|
|
67849
|
-
*
|
|
67850
|
-
* @type {number}
|
|
67851
|
-
* @protected
|
|
67852
|
-
*/
|
|
67853
|
-
this.__buffer_position_offset = 0;
|
|
67854
|
-
|
|
67855
|
-
/**
|
|
67856
|
-
* @protected
|
|
67857
|
-
* @type {IndexedBinaryBVH}
|
|
67858
|
-
*/
|
|
67859
|
-
this.__root = null;
|
|
67860
|
-
}
|
|
67861
|
-
|
|
67862
|
-
/**
|
|
67863
|
-
* @param {IndexedBinaryBVH} root
|
|
67864
|
-
*/
|
|
67865
|
-
setRoot(root) {
|
|
67866
|
-
this.__root = root;
|
|
67867
|
-
}
|
|
67868
|
-
|
|
67869
|
-
|
|
67870
|
-
/**
|
|
67871
|
-
* @param {THREE.BufferGeometry} geometry
|
|
67872
|
-
*/
|
|
67873
|
-
setGeometry(geometry) {
|
|
67874
|
-
this.geometry = geometry;
|
|
67875
|
-
|
|
67876
|
-
const index_attribute = geometry.getIndex();
|
|
67877
|
-
|
|
67878
|
-
if (index_attribute) {
|
|
67879
|
-
this.__buffer_indices = index_attribute.array;
|
|
67880
|
-
} else {
|
|
67881
|
-
// no index attribute
|
|
67882
|
-
this.__buffer_indices = null;
|
|
67883
|
-
}
|
|
67884
|
-
|
|
67885
|
-
const position_attribute = geometry.getAttribute('position');
|
|
67886
|
-
|
|
67887
|
-
if (position_attribute.isInterleavedBufferAttribute) {
|
|
67888
|
-
const data = position_attribute.data;
|
|
67889
|
-
|
|
67890
|
-
this.__buffer_vertices = data.array;
|
|
67891
|
-
this.__buffer_vertex_stride = data.stride;
|
|
67892
|
-
this.__buffer_position_offset = position_attribute.offset;
|
|
67893
|
-
} else {
|
|
67894
|
-
this.__buffer_vertices = position_attribute.array;
|
|
67895
|
-
this.__buffer_vertex_stride = 3;
|
|
67896
|
-
this.__buffer_position_offset = 0;
|
|
67897
|
-
}
|
|
67898
|
-
}
|
|
67899
|
-
|
|
67900
|
-
}
|
|
67901
|
-
|
|
67902
|
-
class ClippingPlaneContainmentComputingVisitor extends GeometrySpatialAcceleratorVisitor {
|
|
67903
|
-
constructor() {
|
|
67904
|
-
super();
|
|
67905
|
-
|
|
67906
|
-
/**
|
|
67907
|
-
* @private
|
|
67908
|
-
* @type {Plane[]}
|
|
67909
|
-
*/
|
|
67910
|
-
this.planes = [];
|
|
67911
|
-
|
|
67912
|
-
/**
|
|
67913
|
-
*
|
|
67914
|
-
* @private
|
|
67915
|
-
* @type {number}
|
|
67916
|
-
*/
|
|
67917
|
-
this.plane_count = 0;
|
|
67918
|
-
|
|
67919
|
-
this.__hit_count_in = 0;
|
|
67920
|
-
this.__hit_count_out = 0;
|
|
67921
|
-
this.__hit_count_intersect = 0;
|
|
67922
|
-
}
|
|
67923
|
-
|
|
67924
|
-
reset() {
|
|
67925
|
-
this.__hit_count_in = 0;
|
|
67926
|
-
this.__hit_count_intersect = 0;
|
|
67927
|
-
this.__hit_count_out = 0;
|
|
67928
|
-
}
|
|
67929
|
-
|
|
67930
|
-
/**
|
|
67931
|
-
*
|
|
67932
|
-
* @returns {number}
|
|
67933
|
-
*/
|
|
67934
|
-
getContainment() {
|
|
67935
|
-
if (this.__hit_count_out === 0) {
|
|
67936
|
-
if (this.__hit_count_intersect > 0) {
|
|
67937
|
-
return 0;
|
|
67938
|
-
} else {
|
|
67939
|
-
// fully in
|
|
67940
|
-
return 1;
|
|
67941
|
-
}
|
|
67942
|
-
} else {
|
|
67943
|
-
if (this.__hit_count_intersect > 0 || this.__hit_count_in > 0) {
|
|
67944
|
-
return 0;
|
|
67945
|
-
} else {
|
|
67946
|
-
// fully out
|
|
67947
|
-
return -1;
|
|
67948
|
-
}
|
|
67949
|
-
}
|
|
67950
|
-
}
|
|
67951
|
-
|
|
67952
|
-
/**
|
|
67953
|
-
* @param {Plane[]} planes
|
|
67954
|
-
*/
|
|
67955
|
-
setPlanes(planes) {
|
|
67956
|
-
this.planes = planes;
|
|
67957
|
-
this.plane_count = planes.length;
|
|
67958
|
-
}
|
|
67959
|
-
|
|
67960
|
-
|
|
67961
|
-
visit(address, type) {
|
|
67962
|
-
const root = this.__root;
|
|
67963
|
-
|
|
67964
|
-
const data = root.data;
|
|
67965
|
-
const binaryNodeCount = root.binaryNodeCount;
|
|
67966
|
-
|
|
67967
|
-
const planes = this.planes;
|
|
67968
|
-
const plane_count = this.plane_count;
|
|
67969
|
-
|
|
67970
|
-
let intersect_flag = false;
|
|
67971
|
-
if (type === NodeType.LEAF) {
|
|
67972
|
-
// check triangle intersection
|
|
67973
|
-
|
|
67974
|
-
const index = address / 6 - binaryNodeCount;
|
|
67975
|
-
|
|
67976
|
-
const index3 = index * 3;
|
|
67977
|
-
|
|
67978
|
-
const indices = this.__buffer_indices;
|
|
67979
|
-
|
|
67980
|
-
const a = indices[index3];
|
|
67981
|
-
const b = indices[index3 + 1];
|
|
67982
|
-
const c = indices[index3 + 2];
|
|
67983
|
-
|
|
67984
|
-
const vertices = this.__buffer_vertices;
|
|
67985
|
-
|
|
67986
|
-
const stride = this.__buffer_vertex_stride;
|
|
67987
|
-
const offset = this.__buffer_position_offset;
|
|
67988
|
-
|
|
67989
|
-
const a_address = a * stride + offset;
|
|
67990
|
-
const b_address = b * stride + offset;
|
|
67991
|
-
const c_address = c * stride + offset;
|
|
67992
|
-
|
|
67993
|
-
const ax = vertices[a_address];
|
|
67994
|
-
const ay = vertices[a_address + 1];
|
|
67995
|
-
const az = vertices[a_address + 2];
|
|
67996
|
-
|
|
67997
|
-
const bx = vertices[b_address];
|
|
67998
|
-
const by = vertices[b_address + 1];
|
|
67999
|
-
const bz = vertices[b_address + 2];
|
|
68000
|
-
|
|
68001
|
-
const cx = vertices[c_address];
|
|
68002
|
-
const cy = vertices[c_address + 1];
|
|
68003
|
-
const cz = vertices[c_address + 2];
|
|
68004
|
-
|
|
68005
|
-
for (let i = 0; i < plane_count; i++) {
|
|
68006
|
-
const plane = planes[i];
|
|
68007
|
-
|
|
68008
|
-
const plane_normal_x = plane.normal.x;
|
|
68009
|
-
const plane_normal_y = plane.normal.y;
|
|
68010
|
-
const plane_normal_z = plane.normal.z;
|
|
68011
|
-
const plane_constant = plane.constant;
|
|
68012
|
-
|
|
68013
|
-
const side = computeTrianglePlaneSide(
|
|
68014
|
-
plane_normal_x,
|
|
68015
|
-
plane_normal_y,
|
|
68016
|
-
plane_normal_z,
|
|
68017
|
-
plane_constant,
|
|
68018
|
-
ax, ay, az,
|
|
68019
|
-
bx, by, bz,
|
|
68020
|
-
cx, cy, cz
|
|
68021
|
-
);
|
|
68022
|
-
|
|
68023
|
-
if (side === -3) {
|
|
68024
|
-
// fully outside
|
|
68025
|
-
this.__hit_count_out++;
|
|
68026
|
-
return false;
|
|
68027
|
-
} else if (side < 3) {
|
|
68028
|
-
intersect_flag = true;
|
|
68029
|
-
}
|
|
68030
|
-
}
|
|
68031
|
-
|
|
68032
|
-
if (intersect_flag) {
|
|
68033
|
-
this.__hit_count_intersect++;
|
|
68034
|
-
} else {
|
|
68035
|
-
this.__hit_count_in++;
|
|
68036
|
-
}
|
|
68037
|
-
|
|
68038
|
-
return false;
|
|
68039
|
-
} else {
|
|
68040
|
-
// this is an intermediate node (binary node)
|
|
68041
|
-
|
|
68042
|
-
// check AABB intersection
|
|
68043
|
-
|
|
68044
|
-
|
|
68045
|
-
const x0 = data[address];
|
|
68046
|
-
const y0 = data[address + 1];
|
|
68047
|
-
const z0 = data[address + 2];
|
|
68048
|
-
const x1 = data[address + 3];
|
|
68049
|
-
const y1 = data[address + 4];
|
|
68050
|
-
const z1 = data[address + 5];
|
|
68051
|
-
|
|
68052
|
-
|
|
68053
|
-
for (let i = 0; i < plane_count; i++) {
|
|
68054
|
-
const plane = planes[i];
|
|
68055
|
-
|
|
68056
|
-
const plane_normal_x = plane.normal.x;
|
|
68057
|
-
const plane_normal_y = plane.normal.y;
|
|
68058
|
-
const plane_normal_z = plane.normal.z;
|
|
68059
|
-
const plane_constant = plane.constant;
|
|
68060
|
-
|
|
68061
|
-
const side = aabb3_compute_plane_side(
|
|
68062
|
-
plane_normal_x,
|
|
68063
|
-
plane_normal_y,
|
|
68064
|
-
plane_normal_z,
|
|
68065
|
-
plane_constant,
|
|
68066
|
-
|
|
68067
|
-
x0, y0, z0,
|
|
68068
|
-
x1, y1, z1
|
|
68069
|
-
);
|
|
68070
|
-
|
|
68071
|
-
if (side === -2) {
|
|
68072
|
-
this.__hit_count_out++;
|
|
68073
|
-
|
|
68074
|
-
return false;
|
|
68075
|
-
} else if (side === 0) {
|
|
68076
|
-
intersect_flag = true;
|
|
68077
|
-
}
|
|
68078
|
-
}
|
|
68079
|
-
|
|
68080
|
-
if (intersect_flag) {
|
|
68081
|
-
return true;
|
|
68082
|
-
} else {
|
|
68083
|
-
// no need to traverse further down, the whole node is in
|
|
68084
|
-
this.__hit_count_in++;
|
|
68085
|
-
return false;
|
|
68086
|
-
}
|
|
68087
|
-
}
|
|
68088
|
-
|
|
68089
|
-
|
|
68090
|
-
}
|
|
68091
|
-
}
|
|
68092
|
-
|
|
68093
|
-
class RaycastNearestHitComputingVisitor extends GeometrySpatialAcceleratorVisitor {
|
|
68094
|
-
constructor() {
|
|
68095
|
-
super();
|
|
68096
|
-
|
|
68097
|
-
|
|
68098
|
-
/**
|
|
68099
|
-
*
|
|
68100
|
-
* @type {number}
|
|
68101
|
-
* @private
|
|
68102
|
-
*/
|
|
68103
|
-
this.__nearest_distance = Number.POSITIVE_INFINITY;
|
|
68104
|
-
|
|
68105
|
-
/**
|
|
68106
|
-
* @readonly
|
|
68107
|
-
* @type {SurfacePoint3}
|
|
68108
|
-
* @private
|
|
68109
|
-
*/
|
|
68110
|
-
this.__nearest_hit = new SurfacePoint3();
|
|
68111
|
-
|
|
68112
|
-
/**
|
|
68113
|
-
* @readonly
|
|
68114
|
-
* @type {SurfacePoint3}
|
|
68115
|
-
* @private
|
|
68116
|
-
*/
|
|
68117
|
-
this.__temp_hit = new SurfacePoint3();
|
|
68118
|
-
|
|
68119
|
-
/**
|
|
68120
|
-
*
|
|
68121
|
-
* @type {boolean}
|
|
68122
|
-
* @private
|
|
68123
|
-
*/
|
|
68124
|
-
this.__hit_found = false;
|
|
67679
|
+
/**
|
|
67680
|
+
* @param {number[]|Float32Array} planes
|
|
67681
|
+
* @param {number} planes_offset
|
|
67682
|
+
* @param {number} plane_count
|
|
67683
|
+
* @param {number} ax
|
|
67684
|
+
* @param {number} ay
|
|
67685
|
+
* @param {number} az
|
|
67686
|
+
* @param {number} bx
|
|
67687
|
+
* @param {number} by
|
|
67688
|
+
* @param {number} bz
|
|
67689
|
+
* @param {number} cx
|
|
67690
|
+
* @param {number} cy
|
|
67691
|
+
* @param {number} cz
|
|
67692
|
+
* @returns {boolean}
|
|
67693
|
+
*/
|
|
67694
|
+
function triangle_intersects_clipping_volume(
|
|
67695
|
+
planes, planes_offset, plane_count,
|
|
67696
|
+
ax, ay, az,
|
|
67697
|
+
bx, by, bz,
|
|
67698
|
+
cx, cy, cz
|
|
67699
|
+
) {
|
|
68125
67700
|
|
|
68126
|
-
|
|
68127
|
-
* @readonly
|
|
68128
|
-
* @type {Vector3}
|
|
68129
|
-
* @private
|
|
68130
|
-
*/
|
|
68131
|
-
this.__ray_origin = new Vector3$1();
|
|
67701
|
+
for (let j = 0; j < plane_count; j++) {
|
|
68132
67702
|
|
|
68133
|
-
|
|
68134
|
-
* @readonly
|
|
68135
|
-
* @type {Vector3}
|
|
68136
|
-
* @private
|
|
68137
|
-
*/
|
|
68138
|
-
this.__ray_direction = new Vector3$1();
|
|
68139
|
-
}
|
|
67703
|
+
const plane_address = planes_offset + j * 4;
|
|
68140
67704
|
|
|
68141
|
-
|
|
68142
|
-
|
|
68143
|
-
|
|
68144
|
-
|
|
68145
|
-
* @param {number} origin_z
|
|
68146
|
-
* @param {number} direction_x
|
|
68147
|
-
* @param {number} direction_y
|
|
68148
|
-
* @param {number} direction_z
|
|
68149
|
-
*/
|
|
68150
|
-
setRay(origin_x, origin_y, origin_z, direction_x, direction_y, direction_z) {
|
|
68151
|
-
this.__ray_origin.set(
|
|
68152
|
-
origin_x,
|
|
68153
|
-
origin_y,
|
|
68154
|
-
origin_z
|
|
68155
|
-
);
|
|
67705
|
+
const plane_normal_x = planes[plane_address];
|
|
67706
|
+
const plane_normal_y = planes[plane_address + 1];
|
|
67707
|
+
const plane_normal_z = planes[plane_address + 2];
|
|
67708
|
+
const plane_constant = planes[plane_address + 3];
|
|
68156
67709
|
|
|
68157
|
-
|
|
68158
|
-
|
|
68159
|
-
|
|
68160
|
-
|
|
67710
|
+
const side = computeTrianglePlaneSide(
|
|
67711
|
+
plane_normal_x,
|
|
67712
|
+
plane_normal_y,
|
|
67713
|
+
plane_normal_z,
|
|
67714
|
+
plane_constant,
|
|
67715
|
+
ax, ay, az,
|
|
67716
|
+
bx, by, bz,
|
|
67717
|
+
cx, cy, cz
|
|
68161
67718
|
);
|
|
68162
|
-
}
|
|
68163
|
-
|
|
68164
|
-
reset() {
|
|
68165
|
-
this.__nearest_distance = Number.POSITIVE_INFINITY;
|
|
68166
|
-
this.__hit_found = false;
|
|
68167
|
-
}
|
|
68168
|
-
|
|
68169
|
-
getNearestHit() {
|
|
68170
|
-
return this.__nearest_hit;
|
|
68171
|
-
}
|
|
68172
|
-
|
|
68173
|
-
isHitFound() {
|
|
68174
|
-
return this.__hit_found;
|
|
68175
|
-
}
|
|
68176
|
-
|
|
68177
|
-
|
|
68178
|
-
visit(address, type) {
|
|
68179
|
-
const root = this.__root;
|
|
68180
|
-
|
|
68181
|
-
const data = root.data;
|
|
68182
|
-
const binaryNodeCount = root.binaryNodeCount;
|
|
68183
|
-
|
|
68184
|
-
const rayOrigin = this.__ray_origin;
|
|
68185
|
-
const rayDirection = this.__ray_direction;
|
|
68186
|
-
|
|
68187
|
-
if (type === NodeType.LEAF) {
|
|
68188
|
-
// do triangle test
|
|
68189
|
-
|
|
68190
|
-
const index = address / 6 - binaryNodeCount;
|
|
68191
|
-
|
|
68192
|
-
const index3 = index * 3;
|
|
68193
|
-
|
|
68194
|
-
const indices = this.__buffer_indices;
|
|
68195
|
-
|
|
68196
|
-
let a, b, c;
|
|
68197
|
-
|
|
68198
|
-
if (indices !== null) {
|
|
68199
|
-
assert.lessThan(index3 + 2, indices.length, 'triangle index overflow, possibly geometry changed but tree was not rebuilt?');
|
|
68200
|
-
|
|
68201
|
-
a = indices[index3];
|
|
68202
|
-
b = indices[index3 + 1];
|
|
68203
|
-
c = indices[index3 + 2];
|
|
68204
|
-
} else {
|
|
68205
|
-
// implicit indices
|
|
68206
|
-
a = index3;
|
|
68207
|
-
b = index3 + 1;
|
|
68208
|
-
c = index3 + 2;
|
|
68209
|
-
}
|
|
68210
|
-
|
|
68211
|
-
const vertices = this.__buffer_vertices;
|
|
68212
|
-
|
|
68213
|
-
const stride = this.__buffer_vertex_stride;
|
|
68214
|
-
const offset = this.__buffer_position_offset;
|
|
68215
|
-
|
|
68216
|
-
const a_address = a * stride + offset;
|
|
68217
|
-
const b_address = b * stride + offset;
|
|
68218
|
-
const c_address = c * stride + offset;
|
|
68219
|
-
|
|
68220
|
-
assert.lessThan(a_address + 2, vertices.length, 'a-vertex overflow');
|
|
68221
|
-
assert.lessThan(b_address + 2, vertices.length, 'b-vertex overflow');
|
|
68222
|
-
assert.lessThan(c_address + 2, vertices.length, 'c-vertex overflow');
|
|
68223
|
-
|
|
68224
|
-
const ax = vertices[a_address];
|
|
68225
|
-
const ay = vertices[a_address + 1];
|
|
68226
|
-
const az = vertices[a_address + 2];
|
|
68227
|
-
|
|
68228
|
-
const bx = vertices[b_address];
|
|
68229
|
-
const by = vertices[b_address + 1];
|
|
68230
|
-
const bz = vertices[b_address + 2];
|
|
68231
|
-
|
|
68232
|
-
const cx = vertices[c_address];
|
|
68233
|
-
const cy = vertices[c_address + 1];
|
|
68234
|
-
const cz = vertices[c_address + 2];
|
|
68235
|
-
|
|
68236
|
-
const temp_hit = this.__temp_hit;
|
|
68237
|
-
|
|
68238
|
-
if (computeTriangleRayIntersection(
|
|
68239
|
-
temp_hit,
|
|
68240
|
-
rayOrigin.x,
|
|
68241
|
-
rayOrigin.y,
|
|
68242
|
-
rayOrigin.z,
|
|
68243
|
-
rayDirection.x,
|
|
68244
|
-
rayDirection.y,
|
|
68245
|
-
rayDirection.z,
|
|
68246
|
-
ax, ay, az,
|
|
68247
|
-
bx, by, bz,
|
|
68248
|
-
cx, cy, cz
|
|
68249
|
-
)) {
|
|
68250
|
-
const d = temp_hit.position.distanceSqrTo(rayOrigin);
|
|
68251
|
-
|
|
68252
|
-
if (d < this.__nearest_distance) {
|
|
68253
|
-
this.__nearest_hit.copy(temp_hit);
|
|
68254
|
-
this.__nearest_hit.index = index;
|
|
68255
|
-
|
|
68256
|
-
this.__nearest_distance = d;
|
|
68257
|
-
|
|
68258
|
-
this.__hit_found = true;
|
|
68259
|
-
}
|
|
68260
|
-
|
|
68261
|
-
}
|
|
68262
67719
|
|
|
67720
|
+
if (side === -3) {
|
|
67721
|
+
// fully outside
|
|
68263
67722
|
return false;
|
|
68264
|
-
|
|
68265
|
-
} else {
|
|
68266
|
-
// do AABB test
|
|
68267
|
-
|
|
68268
|
-
const x0 = data[address];
|
|
68269
|
-
const y0 = data[address + 1];
|
|
68270
|
-
const z0 = data[address + 2];
|
|
68271
|
-
const x1 = data[address + 3];
|
|
68272
|
-
const y1 = data[address + 4];
|
|
68273
|
-
const z1 = data[address + 5];
|
|
68274
|
-
|
|
68275
|
-
return aabb3_intersects_ray(
|
|
68276
|
-
x0, y0, z0,
|
|
68277
|
-
x1, y1, z1,
|
|
68278
|
-
|
|
68279
|
-
rayOrigin.x,
|
|
68280
|
-
rayOrigin.y,
|
|
68281
|
-
rayOrigin.z,
|
|
68282
|
-
|
|
68283
|
-
rayDirection.x,
|
|
68284
|
-
rayDirection.y,
|
|
68285
|
-
rayDirection.z
|
|
68286
|
-
);
|
|
68287
|
-
|
|
68288
67723
|
}
|
|
68289
67724
|
}
|
|
67725
|
+
|
|
67726
|
+
return true;
|
|
68290
67727
|
}
|
|
68291
67728
|
|
|
67729
|
+
const scratch_array$2 = [];
|
|
67730
|
+
|
|
68292
67731
|
/**
|
|
68293
67732
|
*
|
|
68294
|
-
* @param {
|
|
68295
|
-
* @
|
|
67733
|
+
* @param {BinaryUint32BVH} bvh
|
|
67734
|
+
* @param {number[]|ArrayLike<number>} vertices
|
|
67735
|
+
* @param {number} vertex_offset Unless you're using an interleaved buffer of some kind, this will be 0
|
|
67736
|
+
* @param {number} vertex_stride Unless you're using an interleaved buffer, this should be 3
|
|
67737
|
+
* @param {number[]|ArrayLike<number>|undefined} indices if this is set to undefined - implicit indexing will be used
|
|
67738
|
+
* @param {number[]|Float32Array} planes
|
|
67739
|
+
* @param {number} planes_offset
|
|
67740
|
+
* @param {number} plane_count
|
|
67741
|
+
* @returns {boolean}
|
|
68296
67742
|
*/
|
|
68297
|
-
function
|
|
68298
|
-
|
|
68299
|
-
|
|
68300
|
-
|
|
68301
|
-
|
|
68302
|
-
|
|
68303
|
-
const source_data_array = source_data.array;
|
|
68304
|
-
const stride = source_data.stride;
|
|
67743
|
+
function bvh32_geometry_overlap_clipping_volume(
|
|
67744
|
+
bvh,
|
|
67745
|
+
vertices, vertex_offset, vertex_stride,
|
|
67746
|
+
indices,
|
|
67747
|
+
planes, planes_offset, plane_count
|
|
67748
|
+
) {
|
|
68305
67749
|
|
|
68306
|
-
const
|
|
68307
|
-
|
|
68308
|
-
|
|
67750
|
+
const hit_count = bvh32_query_user_data_overlaps_clipping_volume(
|
|
67751
|
+
scratch_array$2, 0,
|
|
67752
|
+
bvh,
|
|
67753
|
+
planes, planes_offset, plane_count
|
|
67754
|
+
);
|
|
68309
67755
|
|
|
68310
|
-
|
|
67756
|
+
let a, b, c;
|
|
68311
67757
|
|
|
68312
|
-
|
|
67758
|
+
for (let i = 0; i < hit_count; i++) {
|
|
67759
|
+
const triangle_index = scratch_array$2[i];
|
|
68313
67760
|
|
|
68314
|
-
|
|
67761
|
+
const index3 = triangle_index * 3;
|
|
68315
67762
|
|
|
68316
|
-
|
|
68317
|
-
|
|
67763
|
+
if (indices !== undefined) {
|
|
67764
|
+
assert.lessThan(index3 + 2, indices.length, 'triangle index overflow, possibly geometry changed but tree was not rebuilt?');
|
|
68318
67765
|
|
|
68319
|
-
|
|
68320
|
-
|
|
68321
|
-
|
|
68322
|
-
|
|
68323
|
-
|
|
67766
|
+
a = indices[index3];
|
|
67767
|
+
b = indices[index3 + 1];
|
|
67768
|
+
c = indices[index3 + 2];
|
|
67769
|
+
} else {
|
|
67770
|
+
// implicit indices
|
|
67771
|
+
a = index3;
|
|
67772
|
+
b = index3 + 1;
|
|
67773
|
+
c = index3 + 2;
|
|
67774
|
+
}
|
|
67775
|
+
|
|
67776
|
+
const a_address = a * vertex_stride + vertex_offset;
|
|
67777
|
+
const b_address = b * vertex_stride + vertex_offset;
|
|
67778
|
+
const c_address = c * vertex_stride + vertex_offset;
|
|
67779
|
+
|
|
67780
|
+
assert.lessThan(a_address + 2, vertices.length, 'a-vertex overflow');
|
|
67781
|
+
assert.lessThan(b_address + 2, vertices.length, 'b-vertex overflow');
|
|
67782
|
+
assert.lessThan(c_address + 2, vertices.length, 'c-vertex overflow');
|
|
67783
|
+
|
|
67784
|
+
const ax = vertices[a_address];
|
|
67785
|
+
const ay = vertices[a_address + 1];
|
|
67786
|
+
const az = vertices[a_address + 2];
|
|
67787
|
+
|
|
67788
|
+
const bx = vertices[b_address];
|
|
67789
|
+
const by = vertices[b_address + 1];
|
|
67790
|
+
const bz = vertices[b_address + 2];
|
|
67791
|
+
|
|
67792
|
+
const cx = vertices[c_address];
|
|
67793
|
+
const cy = vertices[c_address + 1];
|
|
67794
|
+
const cz = vertices[c_address + 2];
|
|
67795
|
+
|
|
67796
|
+
if (triangle_intersects_clipping_volume(
|
|
67797
|
+
planes, planes_offset, plane_count,
|
|
67798
|
+
ax, ay, az,
|
|
67799
|
+
bx, by, bz,
|
|
67800
|
+
cx, cy, cz
|
|
67801
|
+
)) {
|
|
67802
|
+
return true;
|
|
68324
67803
|
}
|
|
67804
|
+
|
|
68325
67805
|
}
|
|
68326
67806
|
|
|
68327
|
-
return
|
|
67807
|
+
return false;
|
|
68328
67808
|
}
|
|
68329
67809
|
|
|
67810
|
+
const scratch_planes = [];
|
|
67811
|
+
|
|
68330
67812
|
class GeometrySpatialQueryAccelerator {
|
|
68331
67813
|
constructor(cache_size = 100 * 1024 * 1024) {
|
|
68332
67814
|
|
|
68333
67815
|
/**
|
|
68334
67816
|
*
|
|
68335
|
-
* @type {Cache<THREE.BufferGeometry,
|
|
67817
|
+
* @type {Cache<THREE.BufferGeometry, BinaryUint32BVH>}
|
|
68336
67818
|
*/
|
|
68337
67819
|
this.cache = new Cache({
|
|
68338
67820
|
maxWeight: cache_size,
|
|
@@ -68344,15 +67826,13 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68344
67826
|
},
|
|
68345
67827
|
/**
|
|
68346
67828
|
*
|
|
68347
|
-
* @param {
|
|
67829
|
+
* @param {BinaryUint32BVH} tree
|
|
68348
67830
|
*/
|
|
68349
67831
|
valueWeigher(tree) {
|
|
68350
67832
|
return tree.estimateByteSize();
|
|
68351
67833
|
}
|
|
68352
67834
|
});
|
|
68353
67835
|
|
|
68354
|
-
this.__visitor_clip = new ClippingPlaneContainmentComputingVisitor();
|
|
68355
|
-
this.__visitor_raycast = new RaycastNearestHitComputingVisitor();
|
|
68356
67836
|
}
|
|
68357
67837
|
|
|
68358
67838
|
/**
|
|
@@ -68375,23 +67855,46 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68375
67855
|
*
|
|
68376
67856
|
* @param {THREE.BufferGeometry} geometry
|
|
68377
67857
|
* @param {Plane[]} planes
|
|
68378
|
-
* @returns {
|
|
67858
|
+
* @returns {boolean} true means some overlap exists, false otherwise
|
|
68379
67859
|
*/
|
|
68380
67860
|
queryContainmentViaClippingPlanes(geometry, planes) {
|
|
68381
67861
|
assert.notNull(geometry, 'geometry');
|
|
68382
67862
|
assert.defined(geometry, 'geometry');
|
|
68383
67863
|
|
|
67864
|
+
|
|
68384
67865
|
const bvh = this.__acquireBVH(geometry);
|
|
68385
67866
|
|
|
68386
|
-
|
|
67867
|
+
read_three_planes_to_array(planes, scratch_planes);
|
|
68387
67868
|
|
|
68388
|
-
|
|
68389
|
-
|
|
68390
|
-
|
|
67869
|
+
const geometryIndices = geometry.getIndex()?.array;
|
|
67870
|
+
const position_attribute = geometry.getAttribute('position');
|
|
67871
|
+
|
|
67872
|
+
let position_data;
|
|
67873
|
+
let stride = 3;
|
|
67874
|
+
let position_data_offset = 0;
|
|
67875
|
+
|
|
67876
|
+
if (position_attribute.isInterleavedBufferAttribute) {
|
|
67877
|
+
|
|
67878
|
+
position_data = position_attribute.data.array;
|
|
67879
|
+
|
|
67880
|
+
stride = position_attribute.data.stride;
|
|
67881
|
+
position_data_offset = position_attribute.offset;
|
|
68391
67882
|
|
|
68392
|
-
|
|
67883
|
+
} else {
|
|
67884
|
+
|
|
67885
|
+
position_data = position_attribute.array;
|
|
67886
|
+
|
|
67887
|
+
stride = 3;
|
|
67888
|
+
position_data_offset = 0;
|
|
68393
67889
|
|
|
68394
|
-
|
|
67890
|
+
}
|
|
67891
|
+
|
|
67892
|
+
return bvh32_geometry_overlap_clipping_volume(
|
|
67893
|
+
bvh,
|
|
67894
|
+
position_data, position_data_offset, stride,
|
|
67895
|
+
geometryIndices,
|
|
67896
|
+
scratch_planes, 0, planes.length
|
|
67897
|
+
);
|
|
68395
67898
|
}
|
|
68396
67899
|
|
|
68397
67900
|
/**
|
|
@@ -68441,11 +67944,33 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68441
67944
|
return false;
|
|
68442
67945
|
}
|
|
68443
67946
|
|
|
68444
|
-
|
|
67947
|
+
const geometryIndices = geometry.getIndex()?.array;
|
|
67948
|
+
const position_attribute = geometry.getAttribute('position');
|
|
67949
|
+
|
|
67950
|
+
let position_data;
|
|
67951
|
+
let stride = 3;
|
|
67952
|
+
let position_data_offset = 0;
|
|
67953
|
+
|
|
67954
|
+
if (position_attribute.isInterleavedBufferAttribute) {
|
|
67955
|
+
|
|
67956
|
+
position_data = position_attribute.data.array;
|
|
67957
|
+
|
|
67958
|
+
stride = position_attribute.data.stride;
|
|
67959
|
+
position_data_offset = position_attribute.offset;
|
|
68445
67960
|
|
|
68446
|
-
|
|
68447
|
-
|
|
68448
|
-
|
|
67961
|
+
} else {
|
|
67962
|
+
|
|
67963
|
+
position_data = position_attribute.array;
|
|
67964
|
+
|
|
67965
|
+
stride = 3;
|
|
67966
|
+
position_data_offset = 0;
|
|
67967
|
+
|
|
67968
|
+
}
|
|
67969
|
+
|
|
67970
|
+
return bvh32_geometry_raycast(
|
|
67971
|
+
destination, bvh,
|
|
67972
|
+
position_data, position_data_offset, stride,
|
|
67973
|
+
geometryIndices,
|
|
68449
67974
|
ray_origin_x,
|
|
68450
67975
|
ray_origin_y,
|
|
68451
67976
|
ray_origin_z,
|
|
@@ -68454,16 +67979,6 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68454
67979
|
ray_direction_z
|
|
68455
67980
|
);
|
|
68456
67981
|
|
|
68457
|
-
bvh.traversePreOrderStack(this.__visitor_raycast, 0);
|
|
68458
|
-
|
|
68459
|
-
if (this.__visitor_raycast.isHitFound()) {
|
|
68460
|
-
|
|
68461
|
-
destination.copy(this.__visitor_raycast.getNearestHit());
|
|
68462
|
-
|
|
68463
|
-
return true;
|
|
68464
|
-
} else {
|
|
68465
|
-
return false;
|
|
68466
|
-
}
|
|
68467
67982
|
}
|
|
68468
67983
|
|
|
68469
67984
|
/**
|
|
@@ -68491,7 +68006,7 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68491
68006
|
/**
|
|
68492
68007
|
* @private
|
|
68493
68008
|
* @param {THREE.BufferGeometry} geometry
|
|
68494
|
-
* @returns {
|
|
68009
|
+
* @returns {BinaryUint32BVH}
|
|
68495
68010
|
*/
|
|
68496
68011
|
__acquireBVH(geometry) {
|
|
68497
68012
|
assert.notNull(geometry, 'geometry');
|
|
@@ -68513,7 +68028,7 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68513
68028
|
/**
|
|
68514
68029
|
* @private
|
|
68515
68030
|
* @param {THREE.BufferGeometry} geometry
|
|
68516
|
-
* @returns {
|
|
68031
|
+
* @returns {BinaryUint32BVH}
|
|
68517
68032
|
*/
|
|
68518
68033
|
__buildBVH(geometry) {
|
|
68519
68034
|
const position_attribute = geometry.getAttribute('position');
|
|
@@ -68522,14 +68037,19 @@ class GeometrySpatialQueryAccelerator {
|
|
|
68522
68037
|
const de_interleaved_position_attribute = deinterleaveBufferAttribute(position_attribute);
|
|
68523
68038
|
const vertices = de_interleaved_position_attribute.array;
|
|
68524
68039
|
|
|
68040
|
+
const bvh = new BinaryUint32BVH();
|
|
68041
|
+
|
|
68525
68042
|
if (index_attribute === undefined || index_attribute === null) {
|
|
68526
|
-
|
|
68527
|
-
}
|
|
68043
|
+
bvh32_from_unindexed_geometry(bvh, vertices);
|
|
68044
|
+
} else {
|
|
68528
68045
|
|
|
68529
|
-
|
|
68530
|
-
|
|
68046
|
+
const de_interleaved_index_attribute = deinterleaveBufferAttribute(index_attribute);
|
|
68047
|
+
const indices = de_interleaved_index_attribute.array;
|
|
68531
68048
|
|
|
68532
|
-
|
|
68049
|
+
bvh32_from_indexed_geometry(bvh, vertices, indices);
|
|
68050
|
+
}
|
|
68051
|
+
|
|
68052
|
+
return bvh;
|
|
68533
68053
|
}
|
|
68534
68054
|
|
|
68535
68055
|
}
|
|
@@ -69348,29 +68868,6 @@ function bvh_query_user_data_overlaps_frustum(
|
|
|
69348
68868
|
return result_cursor - result_offset;
|
|
69349
68869
|
}
|
|
69350
68870
|
|
|
69351
|
-
/**
|
|
69352
|
-
*
|
|
69353
|
-
* @param {Plane[]} planes
|
|
69354
|
-
* @param {ArrayLike<number>|number[]|Float32Array|Float64Array} array
|
|
69355
|
-
*/
|
|
69356
|
-
function read_frustum_planes_to_array(planes, array) {
|
|
69357
|
-
assert.greaterThanOrEqual(array.length, 24, 'target array is too small');
|
|
69358
|
-
|
|
69359
|
-
for (let i = 0; i < 6; i++) {
|
|
69360
|
-
const plane = planes[i];
|
|
69361
|
-
|
|
69362
|
-
const offset = i * 4;
|
|
69363
|
-
|
|
69364
|
-
const normal = plane.normal;
|
|
69365
|
-
|
|
69366
|
-
array[offset] = normal.x;
|
|
69367
|
-
array[offset + 1] = normal.y;
|
|
69368
|
-
array[offset + 2] = normal.z;
|
|
69369
|
-
|
|
69370
|
-
array[offset + 3] = plane.constant;
|
|
69371
|
-
}
|
|
69372
|
-
}
|
|
69373
|
-
|
|
69374
68871
|
/**
|
|
69375
68872
|
* @template CTX
|
|
69376
68873
|
* @template Asset
|
|
@@ -71961,7 +71458,7 @@ class TerrainSystem extends System {
|
|
|
71961
71458
|
|
|
71962
71459
|
for (let i = 0; i < frustums.length; i++) {
|
|
71963
71460
|
|
|
71964
|
-
|
|
71461
|
+
read_three_planes_to_array(frustums[i].planes, frustum);
|
|
71965
71462
|
|
|
71966
71463
|
found_tiles += bvh_query_user_data_overlaps_frustum(tiles, tile_count, tileManager.bvh, frustum);
|
|
71967
71464
|
}
|
|
@@ -91558,7 +91055,7 @@ class CameraView {
|
|
|
91558
91055
|
frustum_from_camera(camera, scratch_frustum, false);
|
|
91559
91056
|
|
|
91560
91057
|
// update view definition
|
|
91561
|
-
|
|
91058
|
+
read_three_planes_to_array(scratch_frustum.planes, this.frustum);
|
|
91562
91059
|
|
|
91563
91060
|
// read projection matrix
|
|
91564
91061
|
// TODO
|
|
@@ -111244,7 +110741,7 @@ function query_bvh_frustum_from_texture(
|
|
|
111244
110741
|
) {
|
|
111245
110742
|
let result = 0;
|
|
111246
110743
|
|
|
111247
|
-
const binary_node_count = bvh.
|
|
110744
|
+
const binary_node_count = bvh.binary_node_count;
|
|
111248
110745
|
|
|
111249
110746
|
if (binary_node_count <= 0) {
|
|
111250
110747
|
// this should not happen
|
|
@@ -111263,7 +110760,7 @@ function query_bvh_frustum_from_texture(
|
|
|
111263
110760
|
*/
|
|
111264
110761
|
stack[stack_top] = 0;
|
|
111265
110762
|
|
|
111266
|
-
const last_valid_index = binary_node_count + bvh.
|
|
110763
|
+
const last_valid_index = binary_node_count + bvh.leaf_node_count;
|
|
111267
110764
|
|
|
111268
110765
|
const float32 = bvh.float32;
|
|
111269
110766
|
const uint32 = bvh.uint32;
|
|
@@ -112819,7 +112316,7 @@ class LightManager {
|
|
|
112819
112316
|
|
|
112820
112317
|
const nodes = [];
|
|
112821
112318
|
|
|
112822
|
-
|
|
112319
|
+
read_three_planes_to_array(this.__view_frustum.planes, scratch_frustum_planes);
|
|
112823
112320
|
|
|
112824
112321
|
/*
|
|
112825
112322
|
Search is done in 2 phases:
|
|
@@ -119216,6 +118713,18 @@ class Blackboard extends AbstractBlackboard {
|
|
|
119216
118713
|
|
|
119217
118714
|
Blackboard.typeName = 'Blackboard';
|
|
119218
118715
|
|
|
118716
|
+
/**
|
|
118717
|
+
* just in case you need that function also
|
|
118718
|
+
* @param {Vector3} axis
|
|
118719
|
+
* @param {number} angle
|
|
118720
|
+
* @param {Quaternion} result
|
|
118721
|
+
*/
|
|
118722
|
+
function quat3_createFromAxisAngle(axis, angle, result) {
|
|
118723
|
+
const halfAngle = angle * .5;
|
|
118724
|
+
const s = Math.sin(halfAngle);
|
|
118725
|
+
result.set(axis.x * s, axis.y * s, axis.z * s, Math.cos(halfAngle));
|
|
118726
|
+
}
|
|
118727
|
+
|
|
119219
118728
|
exports.AmbientOcclusionPostProcessEffect = AmbientOcclusionPostProcessEffect;
|
|
119220
118729
|
exports.Behavior = Behavior;
|
|
119221
118730
|
exports.BehaviorStatus = BehaviorStatus;
|