@perceptimagery/dita-configurator-staging 0.1.6300 → 0.1.7000

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +4247 -71
  2. package/package.json +4 -3
package/dist/index.js CHANGED
@@ -111,7 +111,7 @@ var __publicField = (obj, key, value) => {
111
111
  host: "https://api.sprie.io"
112
112
  };
113
113
  const config = Object.freeze(Config$1);
114
- const version = "0.1.6300";
114
+ const version$1 = "0.1.7000";
115
115
  function modifyLensArr(arr, element) {
116
116
  const index = arr.findIndex((e) => e["sku"] === element["sku"]);
117
117
  if (index !== -1) {
@@ -6721,17 +6721,17 @@ var __publicField = (obj, key, value) => {
6721
6721
  function BlowFish_Encrypt(ctx, left, right) {
6722
6722
  let Xl = left;
6723
6723
  let Xr = right;
6724
- let temp;
6724
+ let temp5;
6725
6725
  for (let i = 0; i < N; ++i) {
6726
6726
  Xl = Xl ^ ctx.pbox[i];
6727
6727
  Xr = F2(ctx, Xl) ^ Xr;
6728
- temp = Xl;
6728
+ temp5 = Xl;
6729
6729
  Xl = Xr;
6730
- Xr = temp;
6730
+ Xr = temp5;
6731
6731
  }
6732
- temp = Xl;
6732
+ temp5 = Xl;
6733
6733
  Xl = Xr;
6734
- Xr = temp;
6734
+ Xr = temp5;
6735
6735
  Xr = Xr ^ ctx.pbox[N];
6736
6736
  Xl = Xl ^ ctx.pbox[N + 1];
6737
6737
  return { left: Xl, right: Xr };
@@ -6739,17 +6739,17 @@ var __publicField = (obj, key, value) => {
6739
6739
  function BlowFish_Decrypt(ctx, left, right) {
6740
6740
  let Xl = left;
6741
6741
  let Xr = right;
6742
- let temp;
6742
+ let temp5;
6743
6743
  for (let i = N + 1; i > 1; --i) {
6744
6744
  Xl = Xl ^ ctx.pbox[i];
6745
6745
  Xr = F2(ctx, Xl) ^ Xr;
6746
- temp = Xl;
6746
+ temp5 = Xl;
6747
6747
  Xl = Xr;
6748
- Xr = temp;
6748
+ Xr = temp5;
6749
6749
  }
6750
- temp = Xl;
6750
+ temp5 = Xl;
6751
6751
  Xl = Xr;
6752
- Xr = temp;
6752
+ Xr = temp5;
6753
6753
  Xr = Xr ^ ctx.pbox[1];
6754
6754
  Xl = Xl ^ ctx.pbox[0];
6755
6755
  return { left: Xl, right: Xr };
@@ -13891,15 +13891,15 @@ var __publicField = (obj, key, value) => {
13891
13891
  }
13892
13892
  return min <= -plane.constant && max >= -plane.constant;
13893
13893
  }
13894
- intersectsTriangle(triangle) {
13894
+ intersectsTriangle(triangle3) {
13895
13895
  if (this.isEmpty()) {
13896
13896
  return false;
13897
13897
  }
13898
13898
  this.getCenter(_center);
13899
13899
  _extents.subVectors(this.max, _center);
13900
- _v0$2.subVectors(triangle.a, _center);
13901
- _v1$7.subVectors(triangle.b, _center);
13902
- _v2$4.subVectors(triangle.c, _center);
13900
+ _v0$2.subVectors(triangle3.a, _center);
13901
+ _v1$7.subVectors(triangle3.b, _center);
13902
+ _v2$4.subVectors(triangle3.c, _center);
13903
13903
  _f0.subVectors(_v1$7, _v0$2);
13904
13904
  _f1.subVectors(_v2$4, _v1$7);
13905
13905
  _f2.subVectors(_v0$2, _v2$4);
@@ -16006,10 +16006,10 @@ var __publicField = (obj, key, value) => {
16006
16006
  clone() {
16007
16007
  return new this.constructor().copy(this);
16008
16008
  }
16009
- copy(triangle) {
16010
- this.a.copy(triangle.a);
16011
- this.b.copy(triangle.b);
16012
- this.c.copy(triangle.c);
16009
+ copy(triangle3) {
16010
+ this.a.copy(triangle3.a);
16011
+ this.b.copy(triangle3.b);
16012
+ this.c.copy(triangle3.c);
16013
16013
  return this;
16014
16014
  }
16015
16015
  getArea() {
@@ -16092,8 +16092,8 @@ var __publicField = (obj, key, value) => {
16092
16092
  w2 = vc * denom;
16093
16093
  return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w2);
16094
16094
  }
16095
- equals(triangle) {
16096
- return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c);
16095
+ equals(triangle3) {
16096
+ return triangle3.a.equals(this.a) && triangle3.b.equals(this.b) && triangle3.c.equals(this.c);
16097
16097
  }
16098
16098
  }
16099
16099
  const _colorKeywords = {
@@ -17919,9 +17919,9 @@ var __publicField = (obj, key, value) => {
17919
17919
  const group = groups[i];
17920
17920
  this.addGroup(group.start, group.count, group.materialIndex);
17921
17921
  }
17922
- const boundingBox = source.boundingBox;
17923
- if (boundingBox !== null) {
17924
- this.boundingBox = boundingBox.clone();
17922
+ const boundingBox2 = source.boundingBox;
17923
+ if (boundingBox2 !== null) {
17924
+ this.boundingBox = boundingBox2.clone();
17925
17925
  }
17926
17926
  const boundingSphere = source.boundingSphere;
17927
17927
  if (boundingSphere !== null) {
@@ -17948,10 +17948,10 @@ var __publicField = (obj, key, value) => {
17948
17948
  const _uvA$1 = /* @__PURE__ */ new Vector2();
17949
17949
  const _uvB$1 = /* @__PURE__ */ new Vector2();
17950
17950
  const _uvC$1 = /* @__PURE__ */ new Vector2();
17951
- const _normalA = /* @__PURE__ */ new Vector3();
17952
- const _normalB = /* @__PURE__ */ new Vector3();
17953
- const _normalC = /* @__PURE__ */ new Vector3();
17954
- const _intersectionPoint = /* @__PURE__ */ new Vector3();
17951
+ const _normalA$1 = /* @__PURE__ */ new Vector3();
17952
+ const _normalB$1 = /* @__PURE__ */ new Vector3();
17953
+ const _normalC$1 = /* @__PURE__ */ new Vector3();
17954
+ const _intersectionPoint$1 = /* @__PURE__ */ new Vector3();
17955
17955
  const _intersectionPointWorld = /* @__PURE__ */ new Vector3();
17956
17956
  class Mesh extends Object3D {
17957
17957
  constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) {
@@ -18121,7 +18121,7 @@ var __publicField = (obj, key, value) => {
18121
18121
  }
18122
18122
  }
18123
18123
  }
18124
- function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) {
18124
+ function checkIntersection$1(object, material, raycaster, ray, pA, pB, pC, point) {
18125
18125
  let intersect;
18126
18126
  if (material.side === BackSide) {
18127
18127
  intersect = ray.intersectTriangle(pC, pB, pA, true, point);
@@ -18145,26 +18145,26 @@ var __publicField = (obj, key, value) => {
18145
18145
  object.getVertexPosition(a, _vA$1);
18146
18146
  object.getVertexPosition(b, _vB$1);
18147
18147
  object.getVertexPosition(c2, _vC$1);
18148
- const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint);
18148
+ const intersection = checkIntersection$1(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint$1);
18149
18149
  if (intersection) {
18150
18150
  if (uv) {
18151
18151
  _uvA$1.fromBufferAttribute(uv, a);
18152
18152
  _uvB$1.fromBufferAttribute(uv, b);
18153
18153
  _uvC$1.fromBufferAttribute(uv, c2);
18154
- intersection.uv = Triangle.getInterpolation(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
18154
+ intersection.uv = Triangle.getInterpolation(_intersectionPoint$1, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
18155
18155
  }
18156
18156
  if (uv1) {
18157
18157
  _uvA$1.fromBufferAttribute(uv1, a);
18158
18158
  _uvB$1.fromBufferAttribute(uv1, b);
18159
18159
  _uvC$1.fromBufferAttribute(uv1, c2);
18160
- intersection.uv1 = Triangle.getInterpolation(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
18160
+ intersection.uv1 = Triangle.getInterpolation(_intersectionPoint$1, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
18161
18161
  intersection.uv2 = intersection.uv1;
18162
18162
  }
18163
18163
  if (normal) {
18164
- _normalA.fromBufferAttribute(normal, a);
18165
- _normalB.fromBufferAttribute(normal, b);
18166
- _normalC.fromBufferAttribute(normal, c2);
18167
- intersection.normal = Triangle.getInterpolation(_intersectionPoint, _vA$1, _vB$1, _vC$1, _normalA, _normalB, _normalC, new Vector3());
18164
+ _normalA$1.fromBufferAttribute(normal, a);
18165
+ _normalB$1.fromBufferAttribute(normal, b);
18166
+ _normalC$1.fromBufferAttribute(normal, c2);
18167
+ intersection.normal = Triangle.getInterpolation(_intersectionPoint$1, _vA$1, _vB$1, _vC$1, _normalA$1, _normalB$1, _normalC$1, new Vector3());
18168
18168
  if (intersection.normal.dot(ray.direction) > 0) {
18169
18169
  intersection.normal.multiplyScalar(-1);
18170
18170
  }
@@ -21194,7 +21194,7 @@ var __publicField = (obj, key, value) => {
21194
21194
  function _getBlurShader(lodMax, width, height) {
21195
21195
  const weights = new Float32Array(MAX_SAMPLES);
21196
21196
  const poleAxis = new Vector3(0, 1, 0);
21197
- const shaderMaterial = new ShaderMaterial({
21197
+ const shaderMaterial2 = new ShaderMaterial({
21198
21198
  name: "SphericalGaussianBlur",
21199
21199
  defines: {
21200
21200
  "n": MAX_SAMPLES,
@@ -21280,7 +21280,7 @@ var __publicField = (obj, key, value) => {
21280
21280
  depthTest: false,
21281
21281
  depthWrite: false
21282
21282
  });
21283
- return shaderMaterial;
21283
+ return shaderMaterial2;
21284
21284
  }
21285
21285
  function _getEquirectMaterial() {
21286
21286
  return new ShaderMaterial({
@@ -23284,8 +23284,8 @@ var __publicField = (obj, key, value) => {
23284
23284
  const fog = scene.fog;
23285
23285
  const geometry = object.geometry;
23286
23286
  const environment = material.isMeshStandardMaterial ? scene.environment : null;
23287
- const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
23288
- const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null;
23287
+ const envMap2 = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
23288
+ const envMapCubeUVHeight = !!envMap2 && envMap2.mapping === CubeUVReflectionMapping ? envMap2.image.height : null;
23289
23289
  const shaderID = shaderIDs[material.type];
23290
23290
  if (material.precision !== null) {
23291
23291
  precision = capabilities.getMaxPrecision(material.precision);
@@ -23319,7 +23319,7 @@ var __publicField = (obj, key, value) => {
23319
23319
  const IS_INSTANCEDMESH = object.isInstancedMesh === true;
23320
23320
  const HAS_MAP = !!material.map;
23321
23321
  const HAS_MATCAP = !!material.matcap;
23322
- const HAS_ENVMAP = !!envMap;
23322
+ const HAS_ENVMAP = !!envMap2;
23323
23323
  const HAS_AOMAP = !!material.aoMap;
23324
23324
  const HAS_LIGHTMAP = !!material.lightMap;
23325
23325
  const HAS_BUMPMAP = !!material.bumpMap;
@@ -23380,7 +23380,7 @@ var __publicField = (obj, key, value) => {
23380
23380
  map: HAS_MAP,
23381
23381
  matcap: HAS_MATCAP,
23382
23382
  envMap: HAS_ENVMAP,
23383
- envMapMode: HAS_ENVMAP && envMap.mapping,
23383
+ envMapMode: HAS_ENVMAP && envMap2.mapping,
23384
23384
  envMapCubeUVHeight,
23385
23385
  aoMap: HAS_AOMAP,
23386
23386
  lightMap: HAS_LIGHTMAP,
@@ -27403,10 +27403,10 @@ var __publicField = (obj, key, value) => {
27403
27403
  if (material.alphaTest > 0) {
27404
27404
  uniforms.alphaTest.value = material.alphaTest;
27405
27405
  }
27406
- const envMap = properties.get(material).envMap;
27407
- if (envMap) {
27408
- uniforms.envMap.value = envMap;
27409
- uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1;
27406
+ const envMap2 = properties.get(material).envMap;
27407
+ if (envMap2) {
27408
+ uniforms.envMap.value = envMap2;
27409
+ uniforms.flipEnvMap.value = envMap2.isCubeTexture && envMap2.isRenderTargetTexture === false ? -1 : 1;
27410
27410
  uniforms.reflectivity.value = material.reflectivity;
27411
27411
  uniforms.ior.value = material.ior;
27412
27412
  uniforms.refractionRatio.value = material.refractionRatio;
@@ -27489,8 +27489,8 @@ var __publicField = (obj, key, value) => {
27489
27489
  uniforms.roughnessMap.value = material.roughnessMap;
27490
27490
  refreshTransformUniform(material.roughnessMap, uniforms.roughnessMapTransform);
27491
27491
  }
27492
- const envMap = properties.get(material).envMap;
27493
- if (envMap) {
27492
+ const envMap2 = properties.get(material).envMap;
27493
+ if (envMap2) {
27494
27494
  uniforms.envMapIntensity.value = material.envMapIntensity;
27495
27495
  }
27496
27496
  }
@@ -28721,7 +28721,7 @@ var __publicField = (obj, key, value) => {
28721
28721
  const fog = scene.fog;
28722
28722
  const environment = material.isMeshStandardMaterial ? scene.environment : null;
28723
28723
  const colorSpace = _currentRenderTarget === null ? _this.outputColorSpace : _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace;
28724
- const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
28724
+ const envMap2 = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
28725
28725
  const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4;
28726
28726
  const vertexTangents = !!geometry.attributes.tangent && (!!material.normalMap || material.anisotropy > 0);
28727
28727
  const morphTargets = !!geometry.morphAttributes.position;
@@ -28761,7 +28761,7 @@ var __publicField = (obj, key, value) => {
28761
28761
  needsProgramChange = true;
28762
28762
  } else if (object.isInstancedMesh && materialProperties.instancingColor === false && object.instanceColor !== null) {
28763
28763
  needsProgramChange = true;
28764
- } else if (materialProperties.envMap !== envMap) {
28764
+ } else if (materialProperties.envMap !== envMap2) {
28765
28765
  needsProgramChange = true;
28766
28766
  } else if (material.fog === true && materialProperties.fog !== fog) {
28767
28767
  needsProgramChange = true;
@@ -28850,8 +28850,8 @@ var __publicField = (obj, key, value) => {
28850
28850
  p_uniforms.setValue(_gl, "receiveShadow", object.receiveShadow);
28851
28851
  }
28852
28852
  if (material.isMeshGouraudMaterial && material.envMap !== null) {
28853
- m_uniforms.envMap.value = envMap;
28854
- m_uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1;
28853
+ m_uniforms.envMap.value = envMap2;
28854
+ m_uniforms.flipEnvMap.value = envMap2.isCubeTexture && envMap2.isRenderTargetTexture === false ? -1 : 1;
28855
28855
  }
28856
28856
  if (refreshMaterial) {
28857
28857
  p_uniforms.setValue(_gl, "toneMappingExposure", _this.toneMappingExposure);
@@ -32526,6 +32526,65 @@ var __publicField = (obj, key, value) => {
32526
32526
  return new this.constructor().copy(this);
32527
32527
  }
32528
32528
  }
32529
+ const _startP = /* @__PURE__ */ new Vector3();
32530
+ const _startEnd = /* @__PURE__ */ new Vector3();
32531
+ class Line3 {
32532
+ constructor(start = new Vector3(), end = new Vector3()) {
32533
+ this.start = start;
32534
+ this.end = end;
32535
+ }
32536
+ set(start, end) {
32537
+ this.start.copy(start);
32538
+ this.end.copy(end);
32539
+ return this;
32540
+ }
32541
+ copy(line) {
32542
+ this.start.copy(line.start);
32543
+ this.end.copy(line.end);
32544
+ return this;
32545
+ }
32546
+ getCenter(target) {
32547
+ return target.addVectors(this.start, this.end).multiplyScalar(0.5);
32548
+ }
32549
+ delta(target) {
32550
+ return target.subVectors(this.end, this.start);
32551
+ }
32552
+ distanceSq() {
32553
+ return this.start.distanceToSquared(this.end);
32554
+ }
32555
+ distance() {
32556
+ return this.start.distanceTo(this.end);
32557
+ }
32558
+ at(t2, target) {
32559
+ return this.delta(target).multiplyScalar(t2).add(this.start);
32560
+ }
32561
+ closestPointToPointParameter(point, clampToLine) {
32562
+ _startP.subVectors(point, this.start);
32563
+ _startEnd.subVectors(this.end, this.start);
32564
+ const startEnd2 = _startEnd.dot(_startEnd);
32565
+ const startEnd_startP = _startEnd.dot(_startP);
32566
+ let t2 = startEnd_startP / startEnd2;
32567
+ if (clampToLine) {
32568
+ t2 = clamp(t2, 0, 1);
32569
+ }
32570
+ return t2;
32571
+ }
32572
+ closestPointToPoint(point, clampToLine, target) {
32573
+ const t2 = this.closestPointToPointParameter(point, clampToLine);
32574
+ return this.delta(target).multiplyScalar(t2).add(this.start);
32575
+ }
32576
+ applyMatrix4(matrix) {
32577
+ this.start.applyMatrix4(matrix);
32578
+ this.end.applyMatrix4(matrix);
32579
+ return this;
32580
+ }
32581
+ equals(line) {
32582
+ return line.start.equals(this.start) && line.end.equals(this.end);
32583
+ }
32584
+ clone() {
32585
+ return new this.constructor().copy(this);
32586
+ }
32587
+ }
32529
32588
  if (typeof __THREE_DEVTOOLS__ !== "undefined") {
32530
32589
  __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register", { detail: {
32531
32590
  revision: REVISION
@@ -37282,7 +37341,4085 @@ var __publicField = (obj, key, value) => {
37282
37341
  }`
37283
37342
  )
37284
37343
  };
37344
+ const CENTER = 0;
37345
+ const AVERAGE = 1;
37346
+ const SAH = 2;
37347
+ const CONTAINED = 2;
37348
+ const TRIANGLE_INTERSECT_COST = 1.25;
37349
+ const TRAVERSAL_COST = 1;
37350
+ const BYTES_PER_NODE = 6 * 4 + 4 + 4;
37351
+ const IS_LEAFNODE_FLAG = 65535;
37352
+ const FLOAT32_EPSILON = Math.pow(2, -24);
37353
+ const SKIP_GENERATION = Symbol("SKIP_GENERATION");
37354
+ function getVertexCount(geo) {
37355
+ return geo.index ? geo.index.count : geo.attributes.position.count;
37356
+ }
37357
+ function getTriCount(geo) {
37358
+ return getVertexCount(geo) / 3;
37359
+ }
37360
+ function getIndexArray(vertexCount, BufferConstructor = ArrayBuffer) {
37361
+ if (vertexCount > 65535) {
37362
+ return new Uint32Array(new BufferConstructor(4 * vertexCount));
37363
+ } else {
37364
+ return new Uint16Array(new BufferConstructor(2 * vertexCount));
37365
+ }
37366
+ }
37367
+ function ensureIndex(geo, options) {
37368
+ if (!geo.index) {
37369
+ const vertexCount = geo.attributes.position.count;
37370
+ const BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;
37371
+ const index = getIndexArray(vertexCount, BufferConstructor);
37372
+ geo.setIndex(new BufferAttribute(index, 1));
37373
+ for (let i = 0; i < vertexCount; i++) {
37374
+ index[i] = i;
37375
+ }
37376
+ }
37377
+ }
37378
+ function getFullGeometryRange(geo) {
37379
+ const triCount = getTriCount(geo);
37380
+ const drawRange = geo.drawRange;
37381
+ const start = drawRange.start / 3;
37382
+ const end = (drawRange.start + drawRange.count) / 3;
37383
+ const offset = Math.max(0, start);
37384
+ const count = Math.min(triCount, end) - offset;
37385
+ return [{
37386
+ offset: Math.floor(offset),
37387
+ count: Math.floor(count)
37388
+ }];
37389
+ }
37390
+ function getRootIndexRanges(geo) {
37391
+ if (!geo.groups || !geo.groups.length) {
37392
+ return getFullGeometryRange(geo);
37393
+ }
37394
+ const ranges = [];
37395
+ const rangeBoundaries = /* @__PURE__ */ new Set();
37396
+ const drawRange = geo.drawRange;
37397
+ const drawRangeStart = drawRange.start / 3;
37398
+ const drawRangeEnd = (drawRange.start + drawRange.count) / 3;
37399
+ for (const group of geo.groups) {
37400
+ const groupStart = group.start / 3;
37401
+ const groupEnd = (group.start + group.count) / 3;
37402
+ rangeBoundaries.add(Math.max(drawRangeStart, groupStart));
37403
+ rangeBoundaries.add(Math.min(drawRangeEnd, groupEnd));
37404
+ }
37405
+ const sortedBoundaries = Array.from(rangeBoundaries.values()).sort((a, b) => a - b);
37406
+ for (let i = 0; i < sortedBoundaries.length - 1; i++) {
37407
+ const start = sortedBoundaries[i];
37408
+ const end = sortedBoundaries[i + 1];
37409
+ ranges.push({
37410
+ offset: Math.floor(start),
37411
+ count: Math.floor(end - start)
37412
+ });
37413
+ }
37414
+ return ranges;
37415
+ }
37416
+ function hasGroupGaps(geometry) {
37417
+ if (geometry.groups.length === 0) {
37418
+ return false;
37419
+ }
37420
+ const vertexCount = getTriCount(geometry);
37421
+ const groups = getRootIndexRanges(geometry).sort((a, b) => a.offset - b.offset);
37422
+ const finalGroup = groups[groups.length - 1];
37423
+ finalGroup.count = Math.min(vertexCount - finalGroup.offset, finalGroup.count);
37424
+ let total = 0;
37425
+ groups.forEach(({ count }) => total += count);
37426
+ return vertexCount !== total;
37427
+ }
37428
+ function arrayToBox(nodeIndex32, array, target) {
37429
+ target.min.x = array[nodeIndex32];
37430
+ target.min.y = array[nodeIndex32 + 1];
37431
+ target.min.z = array[nodeIndex32 + 2];
37432
+ target.max.x = array[nodeIndex32 + 3];
37433
+ target.max.y = array[nodeIndex32 + 4];
37434
+ target.max.z = array[nodeIndex32 + 5];
37435
+ return target;
37436
+ }
37437
+ function makeEmptyBounds(target) {
37438
+ target[0] = target[1] = target[2] = Infinity;
37439
+ target[3] = target[4] = target[5] = -Infinity;
37440
+ }
37441
+ function getLongestEdgeIndex(bounds) {
37442
+ let splitDimIdx = -1;
37443
+ let splitDist = -Infinity;
37444
+ for (let i = 0; i < 3; i++) {
37445
+ const dist = bounds[i + 3] - bounds[i];
37446
+ if (dist > splitDist) {
37447
+ splitDist = dist;
37448
+ splitDimIdx = i;
37449
+ }
37450
+ }
37451
+ return splitDimIdx;
37452
+ }
37453
+ function copyBounds(source, target) {
37454
+ target.set(source);
37455
+ }
37456
+ function unionBounds(a, b, target) {
37457
+ let aVal, bVal;
37458
+ for (let d = 0; d < 3; d++) {
37459
+ const d3 = d + 3;
37460
+ aVal = a[d];
37461
+ bVal = b[d];
37462
+ target[d] = aVal < bVal ? aVal : bVal;
37463
+ aVal = a[d3];
37464
+ bVal = b[d3];
37465
+ target[d3] = aVal > bVal ? aVal : bVal;
37466
+ }
37467
+ }
37468
+ function expandByTriangleBounds(startIndex, triangleBounds, bounds) {
37469
+ for (let d = 0; d < 3; d++) {
37470
+ const tCenter = triangleBounds[startIndex + 2 * d];
37471
+ const tHalf = triangleBounds[startIndex + 2 * d + 1];
37472
+ const tMin = tCenter - tHalf;
37473
+ const tMax = tCenter + tHalf;
37474
+ if (tMin < bounds[d]) {
37475
+ bounds[d] = tMin;
37476
+ }
37477
+ if (tMax > bounds[d + 3]) {
37478
+ bounds[d + 3] = tMax;
37479
+ }
37480
+ }
37481
+ }
37482
+ function computeSurfaceArea(bounds) {
37483
+ const d0 = bounds[3] - bounds[0];
37484
+ const d1 = bounds[4] - bounds[1];
37485
+ const d2 = bounds[5] - bounds[2];
37486
+ return 2 * (d0 * d1 + d1 * d2 + d2 * d0);
37487
+ }
37488
+ function getBounds(triangleBounds, offset, count, target, centroidTarget = null) {
37489
+ let minx = Infinity;
37490
+ let miny = Infinity;
37491
+ let minz = Infinity;
37492
+ let maxx = -Infinity;
37493
+ let maxy = -Infinity;
37494
+ let maxz = -Infinity;
37495
+ let cminx = Infinity;
37496
+ let cminy = Infinity;
37497
+ let cminz = Infinity;
37498
+ let cmaxx = -Infinity;
37499
+ let cmaxy = -Infinity;
37500
+ let cmaxz = -Infinity;
37501
+ const includeCentroid = centroidTarget !== null;
37502
+ for (let i = offset * 6, end = (offset + count) * 6; i < end; i += 6) {
37503
+ const cx = triangleBounds[i + 0];
37504
+ const hx = triangleBounds[i + 1];
37505
+ const lx = cx - hx;
37506
+ const rx = cx + hx;
37507
+ if (lx < minx)
37508
+ minx = lx;
37509
+ if (rx > maxx)
37510
+ maxx = rx;
37511
+ if (includeCentroid && cx < cminx)
37512
+ cminx = cx;
37513
+ if (includeCentroid && cx > cmaxx)
37514
+ cmaxx = cx;
37515
+ const cy = triangleBounds[i + 2];
37516
+ const hy = triangleBounds[i + 3];
37517
+ const ly = cy - hy;
37518
+ const ry = cy + hy;
37519
+ if (ly < miny)
37520
+ miny = ly;
37521
+ if (ry > maxy)
37522
+ maxy = ry;
37523
+ if (includeCentroid && cy < cminy)
37524
+ cminy = cy;
37525
+ if (includeCentroid && cy > cmaxy)
37526
+ cmaxy = cy;
37527
+ const cz = triangleBounds[i + 4];
37528
+ const hz = triangleBounds[i + 5];
37529
+ const lz = cz - hz;
37530
+ const rz = cz + hz;
37531
+ if (lz < minz)
37532
+ minz = lz;
37533
+ if (rz > maxz)
37534
+ maxz = rz;
37535
+ if (includeCentroid && cz < cminz)
37536
+ cminz = cz;
37537
+ if (includeCentroid && cz > cmaxz)
37538
+ cmaxz = cz;
37539
+ }
37540
+ target[0] = minx;
37541
+ target[1] = miny;
37542
+ target[2] = minz;
37543
+ target[3] = maxx;
37544
+ target[4] = maxy;
37545
+ target[5] = maxz;
37546
+ if (includeCentroid) {
37547
+ centroidTarget[0] = cminx;
37548
+ centroidTarget[1] = cminy;
37549
+ centroidTarget[2] = cminz;
37550
+ centroidTarget[3] = cmaxx;
37551
+ centroidTarget[4] = cmaxy;
37552
+ centroidTarget[5] = cmaxz;
37553
+ }
37554
+ }
37555
+ function getCentroidBounds(triangleBounds, offset, count, centroidTarget) {
37556
+ let cminx = Infinity;
37557
+ let cminy = Infinity;
37558
+ let cminz = Infinity;
37559
+ let cmaxx = -Infinity;
37560
+ let cmaxy = -Infinity;
37561
+ let cmaxz = -Infinity;
37562
+ for (let i = offset * 6, end = (offset + count) * 6; i < end; i += 6) {
37563
+ const cx = triangleBounds[i + 0];
37564
+ if (cx < cminx)
37565
+ cminx = cx;
37566
+ if (cx > cmaxx)
37567
+ cmaxx = cx;
37568
+ const cy = triangleBounds[i + 2];
37569
+ if (cy < cminy)
37570
+ cminy = cy;
37571
+ if (cy > cmaxy)
37572
+ cmaxy = cy;
37573
+ const cz = triangleBounds[i + 4];
37574
+ if (cz < cminz)
37575
+ cminz = cz;
37576
+ if (cz > cmaxz)
37577
+ cmaxz = cz;
37578
+ }
37579
+ centroidTarget[0] = cminx;
37580
+ centroidTarget[1] = cminy;
37581
+ centroidTarget[2] = cminz;
37582
+ centroidTarget[3] = cmaxx;
37583
+ centroidTarget[4] = cmaxy;
37584
+ centroidTarget[5] = cmaxz;
37585
+ }
37586
+ function computeTriangleBounds(geo, fullBounds) {
37587
+ makeEmptyBounds(fullBounds);
37588
+ const posAttr = geo.attributes.position;
37589
+ const index = geo.index ? geo.index.array : null;
37590
+ const triCount = getTriCount(geo);
37591
+ const triangleBounds = new Float32Array(triCount * 6);
37592
+ const normalized = posAttr.normalized;
37593
+ const posArr = posAttr.array;
37594
+ const bufferOffset = posAttr.offset || 0;
37595
+ let stride = 3;
37596
+ if (posAttr.isInterleavedBufferAttribute) {
37597
+ stride = posAttr.data.stride;
37598
+ }
37599
+ const getters = ["getX", "getY", "getZ"];
37600
+ for (let tri = 0; tri < triCount; tri++) {
37601
+ const tri3 = tri * 3;
37602
+ const tri6 = tri * 6;
37603
+ let ai = tri3 + 0;
37604
+ let bi = tri3 + 1;
37605
+ let ci = tri3 + 2;
37606
+ if (index) {
37607
+ ai = index[ai];
37608
+ bi = index[bi];
37609
+ ci = index[ci];
37610
+ }
37611
+ if (!normalized) {
37612
+ ai = ai * stride + bufferOffset;
37613
+ bi = bi * stride + bufferOffset;
37614
+ ci = ci * stride + bufferOffset;
37615
+ }
37616
+ for (let el = 0; el < 3; el++) {
37617
+ let a, b, c2;
37618
+ if (normalized) {
37619
+ a = posAttr[getters[el]](ai);
37620
+ b = posAttr[getters[el]](bi);
37621
+ c2 = posAttr[getters[el]](ci);
37622
+ } else {
37623
+ a = posArr[ai + el];
37624
+ b = posArr[bi + el];
37625
+ c2 = posArr[ci + el];
37626
+ }
37627
+ let min = a;
37628
+ if (b < min)
37629
+ min = b;
37630
+ if (c2 < min)
37631
+ min = c2;
37632
+ let max = a;
37633
+ if (b > max)
37634
+ max = b;
37635
+ if (c2 > max)
37636
+ max = c2;
37637
+ const halfExtents = (max - min) / 2;
37638
+ const el2 = el * 2;
37639
+ triangleBounds[tri6 + el2 + 0] = min + halfExtents;
37640
+ triangleBounds[tri6 + el2 + 1] = halfExtents + (Math.abs(min) + halfExtents) * FLOAT32_EPSILON;
37641
+ if (min < fullBounds[el])
37642
+ fullBounds[el] = min;
37643
+ if (max > fullBounds[el + 3])
37644
+ fullBounds[el + 3] = max;
37645
+ }
37646
+ }
37647
+ return triangleBounds;
37648
+ }
37649
+ const BIN_COUNT = 32;
37650
+ const binsSort = (a, b) => a.candidate - b.candidate;
37651
+ const sahBins = new Array(BIN_COUNT).fill().map(() => {
37652
+ return {
37653
+ count: 0,
37654
+ bounds: new Float32Array(6),
37655
+ rightCacheBounds: new Float32Array(6),
37656
+ leftCacheBounds: new Float32Array(6),
37657
+ candidate: 0
37658
+ };
37659
+ });
37660
+ const leftBounds = new Float32Array(6);
37661
+ function getOptimalSplit(nodeBoundingData, centroidBoundingData, triangleBounds, offset, count, strategy) {
37662
+ let axis = -1;
37663
+ let pos = 0;
37664
+ if (strategy === CENTER) {
37665
+ axis = getLongestEdgeIndex(centroidBoundingData);
37666
+ if (axis !== -1) {
37667
+ pos = (centroidBoundingData[axis] + centroidBoundingData[axis + 3]) / 2;
37668
+ }
37669
+ } else if (strategy === AVERAGE) {
37670
+ axis = getLongestEdgeIndex(nodeBoundingData);
37671
+ if (axis !== -1) {
37672
+ pos = getAverage(triangleBounds, offset, count, axis);
37673
+ }
37674
+ } else if (strategy === SAH) {
37675
+ const rootSurfaceArea = computeSurfaceArea(nodeBoundingData);
37676
+ let bestCost = TRIANGLE_INTERSECT_COST * count;
37677
+ const cStart = offset * 6;
37678
+ const cEnd = (offset + count) * 6;
37679
+ for (let a = 0; a < 3; a++) {
37680
+ const axisLeft = centroidBoundingData[a];
37681
+ const axisRight = centroidBoundingData[a + 3];
37682
+ const axisLength = axisRight - axisLeft;
37683
+ const binWidth = axisLength / BIN_COUNT;
37684
+ if (count < BIN_COUNT / 4) {
37685
+ const truncatedBins = [...sahBins];
37686
+ truncatedBins.length = count;
37687
+ let b = 0;
37688
+ for (let c2 = cStart; c2 < cEnd; c2 += 6, b++) {
37689
+ const bin = truncatedBins[b];
37690
+ bin.candidate = triangleBounds[c2 + 2 * a];
37691
+ bin.count = 0;
37692
+ const {
37693
+ bounds,
37694
+ leftCacheBounds,
37695
+ rightCacheBounds
37696
+ } = bin;
37697
+ for (let d = 0; d < 3; d++) {
37698
+ rightCacheBounds[d] = Infinity;
37699
+ rightCacheBounds[d + 3] = -Infinity;
37700
+ leftCacheBounds[d] = Infinity;
37701
+ leftCacheBounds[d + 3] = -Infinity;
37702
+ bounds[d] = Infinity;
37703
+ bounds[d + 3] = -Infinity;
37704
+ }
37705
+ expandByTriangleBounds(c2, triangleBounds, bounds);
37706
+ }
37707
+ truncatedBins.sort(binsSort);
37708
+ let splitCount = count;
37709
+ for (let bi = 0; bi < splitCount; bi++) {
37710
+ const bin = truncatedBins[bi];
37711
+ while (bi + 1 < splitCount && truncatedBins[bi + 1].candidate === bin.candidate) {
37712
+ truncatedBins.splice(bi + 1, 1);
37713
+ splitCount--;
37714
+ }
37715
+ }
37716
+ for (let c2 = cStart; c2 < cEnd; c2 += 6) {
37717
+ const center = triangleBounds[c2 + 2 * a];
37718
+ for (let bi = 0; bi < splitCount; bi++) {
37719
+ const bin = truncatedBins[bi];
37720
+ if (center >= bin.candidate) {
37721
+ expandByTriangleBounds(c2, triangleBounds, bin.rightCacheBounds);
37722
+ } else {
37723
+ expandByTriangleBounds(c2, triangleBounds, bin.leftCacheBounds);
37724
+ bin.count++;
37725
+ }
37726
+ }
37727
+ }
37728
+ for (let bi = 0; bi < splitCount; bi++) {
37729
+ const bin = truncatedBins[bi];
37730
+ const leftCount = bin.count;
37731
+ const rightCount = count - bin.count;
37732
+ const leftBounds2 = bin.leftCacheBounds;
37733
+ const rightBounds = bin.rightCacheBounds;
37734
+ let leftProb = 0;
37735
+ if (leftCount !== 0) {
37736
+ leftProb = computeSurfaceArea(leftBounds2) / rootSurfaceArea;
37737
+ }
37738
+ let rightProb = 0;
37739
+ if (rightCount !== 0) {
37740
+ rightProb = computeSurfaceArea(rightBounds) / rootSurfaceArea;
37741
+ }
37742
+ const cost = TRAVERSAL_COST + TRIANGLE_INTERSECT_COST * (leftProb * leftCount + rightProb * rightCount);
37743
+ if (cost < bestCost) {
37744
+ axis = a;
37745
+ bestCost = cost;
37746
+ pos = bin.candidate;
37747
+ }
37748
+ }
37749
+ } else {
37750
+ for (let i = 0; i < BIN_COUNT; i++) {
37751
+ const bin = sahBins[i];
37752
+ bin.count = 0;
37753
+ bin.candidate = axisLeft + binWidth + i * binWidth;
37754
+ const bounds = bin.bounds;
37755
+ for (let d = 0; d < 3; d++) {
37756
+ bounds[d] = Infinity;
37757
+ bounds[d + 3] = -Infinity;
37758
+ }
37759
+ }
37760
+ for (let c2 = cStart; c2 < cEnd; c2 += 6) {
37761
+ const triCenter = triangleBounds[c2 + 2 * a];
37762
+ const relativeCenter = triCenter - axisLeft;
37763
+ let binIndex = ~~(relativeCenter / binWidth);
37764
+ if (binIndex >= BIN_COUNT)
37765
+ binIndex = BIN_COUNT - 1;
37766
+ const bin = sahBins[binIndex];
37767
+ bin.count++;
37768
+ expandByTriangleBounds(c2, triangleBounds, bin.bounds);
37769
+ }
37770
+ const lastBin = sahBins[BIN_COUNT - 1];
37771
+ copyBounds(lastBin.bounds, lastBin.rightCacheBounds);
37772
+ for (let i = BIN_COUNT - 2; i >= 0; i--) {
37773
+ const bin = sahBins[i];
37774
+ const nextBin = sahBins[i + 1];
37775
+ unionBounds(bin.bounds, nextBin.rightCacheBounds, bin.rightCacheBounds);
37776
+ }
37777
+ let leftCount = 0;
37778
+ for (let i = 0; i < BIN_COUNT - 1; i++) {
37779
+ const bin = sahBins[i];
37780
+ const binCount = bin.count;
37781
+ const bounds = bin.bounds;
37782
+ const nextBin = sahBins[i + 1];
37783
+ const rightBounds = nextBin.rightCacheBounds;
37784
+ if (binCount !== 0) {
37785
+ if (leftCount === 0) {
37786
+ copyBounds(bounds, leftBounds);
37787
+ } else {
37788
+ unionBounds(bounds, leftBounds, leftBounds);
37789
+ }
37790
+ }
37791
+ leftCount += binCount;
37792
+ let leftProb = 0;
37793
+ let rightProb = 0;
37794
+ if (leftCount !== 0) {
37795
+ leftProb = computeSurfaceArea(leftBounds) / rootSurfaceArea;
37796
+ }
37797
+ const rightCount = count - leftCount;
37798
+ if (rightCount !== 0) {
37799
+ rightProb = computeSurfaceArea(rightBounds) / rootSurfaceArea;
37800
+ }
37801
+ const cost = TRAVERSAL_COST + TRIANGLE_INTERSECT_COST * (leftProb * leftCount + rightProb * rightCount);
37802
+ if (cost < bestCost) {
37803
+ axis = a;
37804
+ bestCost = cost;
37805
+ pos = bin.candidate;
37806
+ }
37807
+ }
37808
+ }
37809
+ }
37810
+ } else {
37811
+ console.warn(`MeshBVH: Invalid build strategy value ${strategy} used.`);
37812
+ }
37813
+ return { axis, pos };
37814
+ }
37815
+ function getAverage(triangleBounds, offset, count, axis) {
37816
+ let avg = 0;
37817
+ for (let i = offset, end = offset + count; i < end; i++) {
37818
+ avg += triangleBounds[i * 6 + axis * 2];
37819
+ }
37820
+ return avg / count;
37821
+ }
37822
+ class MeshBVHNode {
37823
+ constructor() {
37824
+ }
37825
+ }
37826
+ function partition(indirectBuffer, index, triangleBounds, offset, count, split) {
37827
+ let left = offset;
37828
+ let right = offset + count - 1;
37829
+ const pos = split.pos;
37830
+ const axisOffset = split.axis * 2;
37831
+ while (true) {
37832
+ while (left <= right && triangleBounds[left * 6 + axisOffset] < pos) {
37833
+ left++;
37834
+ }
37835
+ while (left <= right && triangleBounds[right * 6 + axisOffset] >= pos) {
37836
+ right--;
37837
+ }
37838
+ if (left < right) {
37839
+ for (let i = 0; i < 3; i++) {
37840
+ let t0 = index[left * 3 + i];
37841
+ index[left * 3 + i] = index[right * 3 + i];
37842
+ index[right * 3 + i] = t0;
37843
+ }
37844
+ for (let i = 0; i < 6; i++) {
37845
+ let tb = triangleBounds[left * 6 + i];
37846
+ triangleBounds[left * 6 + i] = triangleBounds[right * 6 + i];
37847
+ triangleBounds[right * 6 + i] = tb;
37848
+ }
37849
+ left++;
37850
+ right--;
37851
+ } else {
37852
+ return left;
37853
+ }
37854
+ }
37855
+ }
37856
+ function partition_indirect(indirectBuffer, index, triangleBounds, offset, count, split) {
37857
+ let left = offset;
37858
+ let right = offset + count - 1;
37859
+ const pos = split.pos;
37860
+ const axisOffset = split.axis * 2;
37861
+ while (true) {
37862
+ while (left <= right && triangleBounds[left * 6 + axisOffset] < pos) {
37863
+ left++;
37864
+ }
37865
+ while (left <= right && triangleBounds[right * 6 + axisOffset] >= pos) {
37866
+ right--;
37867
+ }
37868
+ if (left < right) {
37869
+ let t2 = indirectBuffer[left];
37870
+ indirectBuffer[left] = indirectBuffer[right];
37871
+ indirectBuffer[right] = t2;
37872
+ for (let i = 0; i < 6; i++) {
37873
+ let tb = triangleBounds[left * 6 + i];
37874
+ triangleBounds[left * 6 + i] = triangleBounds[right * 6 + i];
37875
+ triangleBounds[right * 6 + i] = tb;
37876
+ }
37877
+ left++;
37878
+ right--;
37879
+ } else {
37880
+ return left;
37881
+ }
37882
+ }
37883
+ }
37884
+ function generateIndirectBuffer(geometry, useSharedArrayBuffer) {
37885
+ const triCount = (geometry.index ? geometry.index.count : geometry.attributes.position.count) / 3;
37886
+ const useUint32 = triCount > 2 ** 16;
37887
+ const byteCount = useUint32 ? 4 : 2;
37888
+ const buffer = useSharedArrayBuffer ? new SharedArrayBuffer(triCount * byteCount) : new ArrayBuffer(triCount * byteCount);
37889
+ const indirectBuffer = useUint32 ? new Uint32Array(buffer) : new Uint16Array(buffer);
37890
+ for (let i = 0, l = indirectBuffer.length; i < l; i++) {
37891
+ indirectBuffer[i] = i;
37892
+ }
37893
+ return indirectBuffer;
37894
+ }
37895
+ function buildTree(bvh, options) {
37896
+ const geometry = bvh.geometry;
37897
+ const indexArray = geometry.index ? geometry.index.array : null;
37898
+ const maxDepth = options.maxDepth;
37899
+ const verbose = options.verbose;
37900
+ const maxLeafTris = options.maxLeafTris;
37901
+ const strategy = options.strategy;
37902
+ const onProgress = options.onProgress;
37903
+ const totalTriangles = getTriCount(geometry);
37904
+ const indirectBuffer = bvh._indirectBuffer;
37905
+ let reachedMaxDepth = false;
37906
+ const fullBounds = new Float32Array(6);
37907
+ const cacheCentroidBoundingData = new Float32Array(6);
37908
+ const triangleBounds = computeTriangleBounds(geometry, fullBounds);
37909
+ const partionFunc = options.indirect ? partition_indirect : partition;
37910
+ const roots = [];
37911
+ const ranges = options.indirect ? getFullGeometryRange(geometry) : getRootIndexRanges(geometry);
37912
+ if (ranges.length === 1) {
37913
+ const range = ranges[0];
37914
+ const root = new MeshBVHNode();
37915
+ root.boundingData = fullBounds;
37916
+ getCentroidBounds(triangleBounds, range.offset, range.count, cacheCentroidBoundingData);
37917
+ splitNode(root, range.offset, range.count, cacheCentroidBoundingData);
37918
+ roots.push(root);
37919
+ } else {
37920
+ for (let range of ranges) {
37921
+ const root = new MeshBVHNode();
37922
+ root.boundingData = new Float32Array(6);
37923
+ getBounds(triangleBounds, range.offset, range.count, root.boundingData, cacheCentroidBoundingData);
37924
+ splitNode(root, range.offset, range.count, cacheCentroidBoundingData);
37925
+ roots.push(root);
37926
+ }
37927
+ }
37928
+ return roots;
37929
+ function triggerProgress(trianglesProcessed) {
37930
+ if (onProgress) {
37931
+ onProgress(trianglesProcessed / totalTriangles);
37932
+ }
37933
+ }
37934
+ function splitNode(node, offset, count, centroidBoundingData = null, depth = 0) {
37935
+ if (!reachedMaxDepth && depth >= maxDepth) {
37936
+ reachedMaxDepth = true;
37937
+ if (verbose) {
37938
+ console.warn(`MeshBVH: Max depth of ${maxDepth} reached when generating BVH. Consider increasing maxDepth.`);
37939
+ console.warn(geometry);
37940
+ }
37941
+ }
37942
+ if (count <= maxLeafTris || depth >= maxDepth) {
37943
+ triggerProgress(offset + count);
37944
+ node.offset = offset;
37945
+ node.count = count;
37946
+ return node;
37947
+ }
37948
+ const split = getOptimalSplit(node.boundingData, centroidBoundingData, triangleBounds, offset, count, strategy);
37949
+ if (split.axis === -1) {
37950
+ triggerProgress(offset + count);
37951
+ node.offset = offset;
37952
+ node.count = count;
37953
+ return node;
37954
+ }
37955
+ const splitOffset = partionFunc(indirectBuffer, indexArray, triangleBounds, offset, count, split);
37956
+ if (splitOffset === offset || splitOffset === offset + count) {
37957
+ triggerProgress(offset + count);
37958
+ node.offset = offset;
37959
+ node.count = count;
37960
+ } else {
37961
+ node.splitAxis = split.axis;
37962
+ const left = new MeshBVHNode();
37963
+ const lstart = offset;
37964
+ const lcount = splitOffset - offset;
37965
+ node.left = left;
37966
+ left.boundingData = new Float32Array(6);
37967
+ getBounds(triangleBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData);
37968
+ splitNode(left, lstart, lcount, cacheCentroidBoundingData, depth + 1);
37969
+ const right = new MeshBVHNode();
37970
+ const rstart = splitOffset;
37971
+ const rcount = count - lcount;
37972
+ node.right = right;
37973
+ right.boundingData = new Float32Array(6);
37974
+ getBounds(triangleBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData);
37975
+ splitNode(right, rstart, rcount, cacheCentroidBoundingData, depth + 1);
37976
+ }
37977
+ return node;
37978
+ }
37979
+ }
37980
+ function buildPackedTree(bvh, options) {
37981
+ const geometry = bvh.geometry;
37982
+ if (options.indirect) {
37983
+ bvh._indirectBuffer = generateIndirectBuffer(geometry, options.useSharedArrayBuffer);
37984
+ if (hasGroupGaps(geometry) && !options.verbose) {
37985
+ console.warn(
37986
+ 'MeshBVH: Provided geometry contains groups that do not fully span the vertex contents while using the "indirect" option. BVH may incorrectly report intersections on unrendered portions of the geometry.'
37987
+ );
37988
+ }
37989
+ }
37990
+ if (!bvh._indirectBuffer) {
37991
+ ensureIndex(geometry, options);
37992
+ }
37993
+ const roots = buildTree(bvh, options);
37994
+ let float32Array;
37995
+ let uint32Array;
37996
+ let uint16Array;
37997
+ const packedRoots = [];
37998
+ const BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;
37999
+ for (let i = 0; i < roots.length; i++) {
38000
+ const root = roots[i];
38001
+ let nodeCount = countNodes(root);
38002
+ const buffer = new BufferConstructor(BYTES_PER_NODE * nodeCount);
38003
+ float32Array = new Float32Array(buffer);
38004
+ uint32Array = new Uint32Array(buffer);
38005
+ uint16Array = new Uint16Array(buffer);
38006
+ populateBuffer(0, root);
38007
+ packedRoots.push(buffer);
38008
+ }
38009
+ bvh._roots = packedRoots;
38010
+ return;
38011
+ function countNodes(node) {
38012
+ if (node.count) {
38013
+ return 1;
38014
+ } else {
38015
+ return 1 + countNodes(node.left) + countNodes(node.right);
38016
+ }
38017
+ }
38018
+ function populateBuffer(byteOffset, node) {
38019
+ const stride4Offset = byteOffset / 4;
38020
+ const stride2Offset = byteOffset / 2;
38021
+ const isLeaf = !!node.count;
38022
+ const boundingData = node.boundingData;
38023
+ for (let i = 0; i < 6; i++) {
38024
+ float32Array[stride4Offset + i] = boundingData[i];
38025
+ }
38026
+ if (isLeaf) {
38027
+ const offset = node.offset;
38028
+ const count = node.count;
38029
+ uint32Array[stride4Offset + 6] = offset;
38030
+ uint16Array[stride2Offset + 14] = count;
38031
+ uint16Array[stride2Offset + 15] = IS_LEAFNODE_FLAG;
38032
+ return byteOffset + BYTES_PER_NODE;
38033
+ } else {
38034
+ const left = node.left;
38035
+ const right = node.right;
38036
+ const splitAxis = node.splitAxis;
38037
+ let nextUnusedPointer;
38038
+ nextUnusedPointer = populateBuffer(byteOffset + BYTES_PER_NODE, left);
38039
+ if (nextUnusedPointer / 4 > Math.pow(2, 32)) {
38040
+ throw new Error("MeshBVH: Cannot store child pointer greater than 32 bits.");
38041
+ }
38042
+ uint32Array[stride4Offset + 6] = nextUnusedPointer / 4;
38043
+ nextUnusedPointer = populateBuffer(nextUnusedPointer, right);
38044
+ uint32Array[stride4Offset + 7] = splitAxis;
38045
+ return nextUnusedPointer;
38046
+ }
38047
+ }
38048
+ }
38049
+ class SeparatingAxisBounds {
38050
+ constructor() {
38051
+ this.min = Infinity;
38052
+ this.max = -Infinity;
38053
+ }
38054
+ setFromPointsField(points, field) {
38055
+ let min = Infinity;
38056
+ let max = -Infinity;
38057
+ for (let i = 0, l = points.length; i < l; i++) {
38058
+ const p2 = points[i];
38059
+ const val = p2[field];
38060
+ min = val < min ? val : min;
38061
+ max = val > max ? val : max;
38062
+ }
38063
+ this.min = min;
38064
+ this.max = max;
38065
+ }
38066
+ setFromPoints(axis, points) {
38067
+ let min = Infinity;
38068
+ let max = -Infinity;
38069
+ for (let i = 0, l = points.length; i < l; i++) {
38070
+ const p2 = points[i];
38071
+ const val = axis.dot(p2);
38072
+ min = val < min ? val : min;
38073
+ max = val > max ? val : max;
38074
+ }
38075
+ this.min = min;
38076
+ this.max = max;
38077
+ }
38078
+ isSeparated(other) {
38079
+ return this.min > other.max || other.min > this.max;
38080
+ }
38081
+ }
38082
+ SeparatingAxisBounds.prototype.setFromBox = function() {
38083
+ const p2 = new Vector3();
38084
+ return function setFromBox(axis, box) {
38085
+ const boxMin = box.min;
38086
+ const boxMax = box.max;
38087
+ let min = Infinity;
38088
+ let max = -Infinity;
38089
+ for (let x2 = 0; x2 <= 1; x2++) {
38090
+ for (let y = 0; y <= 1; y++) {
38091
+ for (let z = 0; z <= 1; z++) {
38092
+ p2.x = boxMin.x * x2 + boxMax.x * (1 - x2);
38093
+ p2.y = boxMin.y * y + boxMax.y * (1 - y);
38094
+ p2.z = boxMin.z * z + boxMax.z * (1 - z);
38095
+ const val = axis.dot(p2);
38096
+ min = Math.min(val, min);
38097
+ max = Math.max(val, max);
38098
+ }
38099
+ }
38100
+ }
38101
+ this.min = min;
38102
+ this.max = max;
38103
+ };
38104
+ }();
38105
+ const closestPointLineToLine = function() {
38106
+ const dir1 = new Vector3();
38107
+ const dir2 = new Vector3();
38108
+ const v02 = new Vector3();
38109
+ return function closestPointLineToLine2(l1, l2, result) {
38110
+ const v0 = l1.start;
38111
+ const v10 = dir1;
38112
+ const v2 = l2.start;
38113
+ const v32 = dir2;
38114
+ v02.subVectors(v0, v2);
38115
+ dir1.subVectors(l1.end, l1.start);
38116
+ dir2.subVectors(l2.end, l2.start);
38117
+ const d0232 = v02.dot(v32);
38118
+ const d3210 = v32.dot(v10);
38119
+ const d3232 = v32.dot(v32);
38120
+ const d0210 = v02.dot(v10);
38121
+ const d1010 = v10.dot(v10);
38122
+ const denom = d1010 * d3232 - d3210 * d3210;
38123
+ let d, d2;
38124
+ if (denom !== 0) {
38125
+ d = (d0232 * d3210 - d0210 * d3232) / denom;
38126
+ } else {
38127
+ d = 0;
38128
+ }
38129
+ d2 = (d0232 + d * d3210) / d3232;
38130
+ result.x = d;
38131
+ result.y = d2;
38132
+ };
38133
+ }();
38134
+ const closestPointsSegmentToSegment = function() {
38135
+ const paramResult = new Vector2();
38136
+ const temp12 = new Vector3();
38137
+ const temp22 = new Vector3();
38138
+ return function closestPointsSegmentToSegment2(l1, l2, target1, target2) {
38139
+ closestPointLineToLine(l1, l2, paramResult);
38140
+ let d = paramResult.x;
38141
+ let d2 = paramResult.y;
38142
+ if (d >= 0 && d <= 1 && d2 >= 0 && d2 <= 1) {
38143
+ l1.at(d, target1);
38144
+ l2.at(d2, target2);
38145
+ return;
38146
+ } else if (d >= 0 && d <= 1) {
38147
+ if (d2 < 0) {
38148
+ l2.at(0, target2);
38149
+ } else {
38150
+ l2.at(1, target2);
38151
+ }
38152
+ l1.closestPointToPoint(target2, true, target1);
38153
+ return;
38154
+ } else if (d2 >= 0 && d2 <= 1) {
38155
+ if (d < 0) {
38156
+ l1.at(0, target1);
38157
+ } else {
38158
+ l1.at(1, target1);
38159
+ }
38160
+ l2.closestPointToPoint(target1, true, target2);
38161
+ return;
38162
+ } else {
38163
+ let p2;
38164
+ if (d < 0) {
38165
+ p2 = l1.start;
38166
+ } else {
38167
+ p2 = l1.end;
38168
+ }
38169
+ let p22;
38170
+ if (d2 < 0) {
38171
+ p22 = l2.start;
38172
+ } else {
38173
+ p22 = l2.end;
38174
+ }
38175
+ const closestPoint = temp12;
38176
+ const closestPoint2 = temp22;
38177
+ l1.closestPointToPoint(p22, true, temp12);
38178
+ l2.closestPointToPoint(p2, true, temp22);
38179
+ if (closestPoint.distanceToSquared(p22) <= closestPoint2.distanceToSquared(p2)) {
38180
+ target1.copy(closestPoint);
38181
+ target2.copy(p22);
38182
+ return;
38183
+ } else {
38184
+ target1.copy(p2);
38185
+ target2.copy(closestPoint2);
38186
+ return;
38187
+ }
38188
+ }
38189
+ };
38190
+ }();
38191
+ const sphereIntersectTriangle = function() {
38192
+ const closestPointTemp = new Vector3();
38193
+ const projectedPointTemp = new Vector3();
38194
+ const planeTemp = new Plane();
38195
+ const lineTemp = new Line3();
38196
+ return function sphereIntersectTriangle2(sphere, triangle3) {
38197
+ const { radius, center } = sphere;
38198
+ const { a, b, c: c2 } = triangle3;
38199
+ lineTemp.start = a;
38200
+ lineTemp.end = b;
38201
+ const closestPoint1 = lineTemp.closestPointToPoint(center, true, closestPointTemp);
38202
+ if (closestPoint1.distanceTo(center) <= radius)
38203
+ return true;
38204
+ lineTemp.start = a;
38205
+ lineTemp.end = c2;
38206
+ const closestPoint2 = lineTemp.closestPointToPoint(center, true, closestPointTemp);
38207
+ if (closestPoint2.distanceTo(center) <= radius)
38208
+ return true;
38209
+ lineTemp.start = b;
38210
+ lineTemp.end = c2;
38211
+ const closestPoint3 = lineTemp.closestPointToPoint(center, true, closestPointTemp);
38212
+ if (closestPoint3.distanceTo(center) <= radius)
38213
+ return true;
38214
+ const plane = triangle3.getPlane(planeTemp);
38215
+ const dp = Math.abs(plane.distanceToPoint(center));
38216
+ if (dp <= radius) {
38217
+ const pp = plane.projectPoint(center, projectedPointTemp);
38218
+ const cp = triangle3.containsPoint(pp);
38219
+ if (cp)
38220
+ return true;
38221
+ }
38222
+ return false;
38223
+ };
38224
+ }();
38225
+ const ZERO_EPSILON = 1e-15;
38226
+ function isNearZero(value) {
38227
+ return Math.abs(value) < ZERO_EPSILON;
38228
+ }
38229
+ class ExtendedTriangle extends Triangle {
38230
+ constructor(...args) {
38231
+ super(...args);
38232
+ this.isExtendedTriangle = true;
38233
+ this.satAxes = new Array(4).fill().map(() => new Vector3());
38234
+ this.satBounds = new Array(4).fill().map(() => new SeparatingAxisBounds());
38235
+ this.points = [this.a, this.b, this.c];
38236
+ this.sphere = new Sphere();
38237
+ this.plane = new Plane();
38238
+ this.needsUpdate = true;
38239
+ }
38240
+ intersectsSphere(sphere) {
38241
+ return sphereIntersectTriangle(sphere, this);
38242
+ }
38243
+ update() {
38244
+ const a = this.a;
38245
+ const b = this.b;
38246
+ const c2 = this.c;
38247
+ const points = this.points;
38248
+ const satAxes = this.satAxes;
38249
+ const satBounds = this.satBounds;
38250
+ const axis0 = satAxes[0];
38251
+ const sab0 = satBounds[0];
38252
+ this.getNormal(axis0);
38253
+ sab0.setFromPoints(axis0, points);
38254
+ const axis1 = satAxes[1];
38255
+ const sab1 = satBounds[1];
38256
+ axis1.subVectors(a, b);
38257
+ sab1.setFromPoints(axis1, points);
38258
+ const axis2 = satAxes[2];
38259
+ const sab2 = satBounds[2];
38260
+ axis2.subVectors(b, c2);
38261
+ sab2.setFromPoints(axis2, points);
38262
+ const axis3 = satAxes[3];
38263
+ const sab3 = satBounds[3];
38264
+ axis3.subVectors(c2, a);
38265
+ sab3.setFromPoints(axis3, points);
38266
+ this.sphere.setFromPoints(this.points);
38267
+ this.plane.setFromNormalAndCoplanarPoint(axis0, a);
38268
+ this.needsUpdate = false;
38269
+ }
38270
+ }
38271
+ ExtendedTriangle.prototype.closestPointToSegment = function() {
38272
+ const point1 = new Vector3();
38273
+ const point2 = new Vector3();
38274
+ const edge = new Line3();
38275
+ return function distanceToSegment(segment, target1 = null, target2 = null) {
38276
+ const { start, end } = segment;
38277
+ const points = this.points;
38278
+ let distSq;
38279
+ let closestDistanceSq = Infinity;
38280
+ for (let i = 0; i < 3; i++) {
38281
+ const nexti = (i + 1) % 3;
38282
+ edge.start.copy(points[i]);
38283
+ edge.end.copy(points[nexti]);
38284
+ closestPointsSegmentToSegment(edge, segment, point1, point2);
38285
+ distSq = point1.distanceToSquared(point2);
38286
+ if (distSq < closestDistanceSq) {
38287
+ closestDistanceSq = distSq;
38288
+ if (target1)
38289
+ target1.copy(point1);
38290
+ if (target2)
38291
+ target2.copy(point2);
38292
+ }
38293
+ }
38294
+ this.closestPointToPoint(start, point1);
38295
+ distSq = start.distanceToSquared(point1);
38296
+ if (distSq < closestDistanceSq) {
38297
+ closestDistanceSq = distSq;
38298
+ if (target1)
38299
+ target1.copy(point1);
38300
+ if (target2)
38301
+ target2.copy(start);
38302
+ }
38303
+ this.closestPointToPoint(end, point1);
38304
+ distSq = end.distanceToSquared(point1);
38305
+ if (distSq < closestDistanceSq) {
38306
+ closestDistanceSq = distSq;
38307
+ if (target1)
38308
+ target1.copy(point1);
38309
+ if (target2)
38310
+ target2.copy(end);
38311
+ }
38312
+ return Math.sqrt(closestDistanceSq);
38313
+ };
38314
+ }();
38315
+ ExtendedTriangle.prototype.intersectsTriangle = function() {
38316
+ const saTri2 = new ExtendedTriangle();
38317
+ const arr1 = new Array(3);
38318
+ const arr2 = new Array(3);
38319
+ const cachedSatBounds = new SeparatingAxisBounds();
38320
+ const cachedSatBounds2 = new SeparatingAxisBounds();
38321
+ const cachedAxis = new Vector3();
38322
+ const dir = new Vector3();
38323
+ const dir1 = new Vector3();
38324
+ const dir2 = new Vector3();
38325
+ const tempDir = new Vector3();
38326
+ const edge = new Line3();
38327
+ const edge1 = new Line3();
38328
+ const edge2 = new Line3();
38329
+ const tempPoint = new Vector3();
38330
+ function triIntersectPlane(tri, plane, targetEdge) {
38331
+ const points = tri.points;
38332
+ let count = 0;
38333
+ let startPointIntersection = -1;
38334
+ for (let i = 0; i < 3; i++) {
38335
+ const { start, end } = edge;
38336
+ start.copy(points[i]);
38337
+ end.copy(points[(i + 1) % 3]);
38338
+ edge.delta(dir);
38339
+ const startIntersects = isNearZero(plane.distanceToPoint(start));
38340
+ if (isNearZero(plane.normal.dot(dir)) && startIntersects) {
38341
+ targetEdge.copy(edge);
38342
+ count = 2;
38343
+ break;
38344
+ }
38345
+ const doesIntersect = plane.intersectLine(edge, tempPoint);
38346
+ if (!doesIntersect && startIntersects) {
38347
+ tempPoint.copy(start);
38348
+ }
38349
+ if ((doesIntersect || startIntersects) && !isNearZero(tempPoint.distanceTo(end))) {
38350
+ if (count <= 1) {
38351
+ const point = count === 1 ? targetEdge.start : targetEdge.end;
38352
+ point.copy(tempPoint);
38353
+ if (startIntersects) {
38354
+ startPointIntersection = count;
38355
+ }
38356
+ } else if (count >= 2) {
38357
+ const point = startPointIntersection === 1 ? targetEdge.start : targetEdge.end;
38358
+ point.copy(tempPoint);
38359
+ count = 2;
38360
+ break;
38361
+ }
38362
+ count++;
38363
+ if (count === 2 && startPointIntersection === -1) {
38364
+ break;
38365
+ }
38366
+ }
38367
+ }
38368
+ return count;
38369
+ }
38370
+ return function intersectsTriangle(other, target = null, suppressLog = false) {
38371
+ if (this.needsUpdate) {
38372
+ this.update();
38373
+ }
38374
+ if (!other.isExtendedTriangle) {
38375
+ saTri2.copy(other);
38376
+ saTri2.update();
38377
+ other = saTri2;
38378
+ } else if (other.needsUpdate) {
38379
+ other.update();
38380
+ }
38381
+ const plane1 = this.plane;
38382
+ const plane2 = other.plane;
38383
+ if (Math.abs(plane1.normal.dot(plane2.normal)) > 1 - 1e-10) {
38384
+ const satBounds1 = this.satBounds;
38385
+ const satAxes1 = this.satAxes;
38386
+ arr2[0] = other.a;
38387
+ arr2[1] = other.b;
38388
+ arr2[2] = other.c;
38389
+ for (let i = 0; i < 4; i++) {
38390
+ const sb = satBounds1[i];
38391
+ const sa = satAxes1[i];
38392
+ cachedSatBounds.setFromPoints(sa, arr2);
38393
+ if (sb.isSeparated(cachedSatBounds))
38394
+ return false;
38395
+ }
38396
+ const satBounds2 = other.satBounds;
38397
+ const satAxes2 = other.satAxes;
38398
+ arr1[0] = this.a;
38399
+ arr1[1] = this.b;
38400
+ arr1[2] = this.c;
38401
+ for (let i = 0; i < 4; i++) {
38402
+ const sb = satBounds2[i];
38403
+ const sa = satAxes2[i];
38404
+ cachedSatBounds.setFromPoints(sa, arr1);
38405
+ if (sb.isSeparated(cachedSatBounds))
38406
+ return false;
38407
+ }
38408
+ for (let i = 0; i < 4; i++) {
38409
+ const sa1 = satAxes1[i];
38410
+ for (let i2 = 0; i2 < 4; i2++) {
38411
+ const sa2 = satAxes2[i2];
38412
+ cachedAxis.crossVectors(sa1, sa2);
38413
+ cachedSatBounds.setFromPoints(cachedAxis, arr1);
38414
+ cachedSatBounds2.setFromPoints(cachedAxis, arr2);
38415
+ if (cachedSatBounds.isSeparated(cachedSatBounds2))
38416
+ return false;
38417
+ }
38418
+ }
38419
+ if (target) {
38420
+ if (!suppressLog) {
38421
+ console.warn("ExtendedTriangle.intersectsTriangle: Triangles are coplanar which does not support an output edge. Setting edge to 0, 0, 0.");
38422
+ }
38423
+ target.start.set(0, 0, 0);
38424
+ target.end.set(0, 0, 0);
38425
+ }
38426
+ return true;
38427
+ } else {
38428
+ const count1 = triIntersectPlane(this, plane2, edge1);
38429
+ if (count1 === 1 && other.containsPoint(edge1.end)) {
38430
+ if (target) {
38431
+ target.start.copy(edge1.end);
38432
+ target.end.copy(edge1.end);
38433
+ }
38434
+ return true;
38435
+ } else if (count1 !== 2) {
38436
+ return false;
38437
+ }
38438
+ const count2 = triIntersectPlane(other, plane1, edge2);
38439
+ if (count2 === 1 && this.containsPoint(edge2.end)) {
38440
+ if (target) {
38441
+ target.start.copy(edge2.end);
38442
+ target.end.copy(edge2.end);
38443
+ }
38444
+ return true;
38445
+ } else if (count2 !== 2) {
38446
+ return false;
38447
+ }
38448
+ edge1.delta(dir1);
38449
+ edge2.delta(dir2);
38450
+ if (dir1.dot(dir2) < 0) {
38451
+ let tmp = edge2.start;
38452
+ edge2.start = edge2.end;
38453
+ edge2.end = tmp;
38454
+ }
38455
+ const s1 = edge1.start.dot(dir1);
38456
+ const e1 = edge1.end.dot(dir1);
38457
+ const s2 = edge2.start.dot(dir1);
38458
+ const e2 = edge2.end.dot(dir1);
38459
+ const separated1 = e1 < s2;
38460
+ const separated2 = s1 < e2;
38461
+ if (s1 !== e2 && s2 !== e1 && separated1 === separated2) {
38462
+ return false;
38463
+ }
38464
+ if (target) {
38465
+ tempDir.subVectors(edge1.start, edge2.start);
38466
+ if (tempDir.dot(dir1) > 0) {
38467
+ target.start.copy(edge1.start);
38468
+ } else {
38469
+ target.start.copy(edge2.start);
38470
+ }
38471
+ tempDir.subVectors(edge1.end, edge2.end);
38472
+ if (tempDir.dot(dir1) < 0) {
38473
+ target.end.copy(edge1.end);
38474
+ } else {
38475
+ target.end.copy(edge2.end);
38476
+ }
38477
+ }
38478
+ return true;
38479
+ }
38480
+ };
38481
+ }();
38482
+ ExtendedTriangle.prototype.distanceToPoint = function() {
38483
+ const target = new Vector3();
38484
+ return function distanceToPoint(point) {
38485
+ this.closestPointToPoint(point, target);
38486
+ return point.distanceTo(target);
38487
+ };
38488
+ }();
38489
+ ExtendedTriangle.prototype.distanceToTriangle = function() {
38490
+ const point = new Vector3();
38491
+ const point2 = new Vector3();
38492
+ const cornerFields = ["a", "b", "c"];
38493
+ const line1 = new Line3();
38494
+ const line2 = new Line3();
38495
+ return function distanceToTriangle(other, target1 = null, target2 = null) {
38496
+ const lineTarget = target1 || target2 ? line1 : null;
38497
+ if (this.intersectsTriangle(other, lineTarget)) {
38498
+ if (target1 || target2) {
38499
+ if (target1)
38500
+ lineTarget.getCenter(target1);
38501
+ if (target2)
38502
+ lineTarget.getCenter(target2);
38503
+ }
38504
+ return 0;
38505
+ }
38506
+ let closestDistanceSq = Infinity;
38507
+ for (let i = 0; i < 3; i++) {
38508
+ let dist;
38509
+ const field = cornerFields[i];
38510
+ const otherVec = other[field];
38511
+ this.closestPointToPoint(otherVec, point);
38512
+ dist = otherVec.distanceToSquared(point);
38513
+ if (dist < closestDistanceSq) {
38514
+ closestDistanceSq = dist;
38515
+ if (target1)
38516
+ target1.copy(point);
38517
+ if (target2)
38518
+ target2.copy(otherVec);
38519
+ }
38520
+ const thisVec = this[field];
38521
+ other.closestPointToPoint(thisVec, point);
38522
+ dist = thisVec.distanceToSquared(point);
38523
+ if (dist < closestDistanceSq) {
38524
+ closestDistanceSq = dist;
38525
+ if (target1)
38526
+ target1.copy(thisVec);
38527
+ if (target2)
38528
+ target2.copy(point);
38529
+ }
38530
+ }
38531
+ for (let i = 0; i < 3; i++) {
38532
+ const f11 = cornerFields[i];
38533
+ const f12 = cornerFields[(i + 1) % 3];
38534
+ line1.set(this[f11], this[f12]);
38535
+ for (let i2 = 0; i2 < 3; i2++) {
38536
+ const f21 = cornerFields[i2];
38537
+ const f22 = cornerFields[(i2 + 1) % 3];
38538
+ line2.set(other[f21], other[f22]);
38539
+ closestPointsSegmentToSegment(line1, line2, point, point2);
38540
+ const dist = point.distanceToSquared(point2);
38541
+ if (dist < closestDistanceSq) {
38542
+ closestDistanceSq = dist;
38543
+ if (target1)
38544
+ target1.copy(point);
38545
+ if (target2)
38546
+ target2.copy(point2);
38547
+ }
38548
+ }
38549
+ }
38550
+ return Math.sqrt(closestDistanceSq);
38551
+ };
38552
+ }();
38553
+ class OrientedBox {
38554
+ constructor(min, max, matrix) {
38555
+ this.isOrientedBox = true;
38556
+ this.min = new Vector3();
38557
+ this.max = new Vector3();
38558
+ this.matrix = new Matrix4();
38559
+ this.invMatrix = new Matrix4();
38560
+ this.points = new Array(8).fill().map(() => new Vector3());
38561
+ this.satAxes = new Array(3).fill().map(() => new Vector3());
38562
+ this.satBounds = new Array(3).fill().map(() => new SeparatingAxisBounds());
38563
+ this.alignedSatBounds = new Array(3).fill().map(() => new SeparatingAxisBounds());
38564
+ this.needsUpdate = false;
38565
+ if (min)
38566
+ this.min.copy(min);
38567
+ if (max)
38568
+ this.max.copy(max);
38569
+ if (matrix)
38570
+ this.matrix.copy(matrix);
38571
+ }
38572
+ set(min, max, matrix) {
38573
+ this.min.copy(min);
38574
+ this.max.copy(max);
38575
+ this.matrix.copy(matrix);
38576
+ this.needsUpdate = true;
38577
+ }
38578
+ copy(other) {
38579
+ this.min.copy(other.min);
38580
+ this.max.copy(other.max);
38581
+ this.matrix.copy(other.matrix);
38582
+ this.needsUpdate = true;
38583
+ }
38584
+ }
38585
+ OrientedBox.prototype.update = function() {
38586
+ return function update() {
38587
+ const matrix = this.matrix;
38588
+ const min = this.min;
38589
+ const max = this.max;
38590
+ const points = this.points;
38591
+ for (let x2 = 0; x2 <= 1; x2++) {
38592
+ for (let y = 0; y <= 1; y++) {
38593
+ for (let z = 0; z <= 1; z++) {
38594
+ const i = (1 << 0) * x2 | (1 << 1) * y | (1 << 2) * z;
38595
+ const v = points[i];
38596
+ v.x = x2 ? max.x : min.x;
38597
+ v.y = y ? max.y : min.y;
38598
+ v.z = z ? max.z : min.z;
38599
+ v.applyMatrix4(matrix);
38600
+ }
38601
+ }
38602
+ }
38603
+ const satBounds = this.satBounds;
38604
+ const satAxes = this.satAxes;
38605
+ const minVec = points[0];
38606
+ for (let i = 0; i < 3; i++) {
38607
+ const axis = satAxes[i];
38608
+ const sb = satBounds[i];
38609
+ const index = 1 << i;
38610
+ const pi = points[index];
38611
+ axis.subVectors(minVec, pi);
38612
+ sb.setFromPoints(axis, points);
38613
+ }
38614
+ const alignedSatBounds = this.alignedSatBounds;
38615
+ alignedSatBounds[0].setFromPointsField(points, "x");
38616
+ alignedSatBounds[1].setFromPointsField(points, "y");
38617
+ alignedSatBounds[2].setFromPointsField(points, "z");
38618
+ this.invMatrix.copy(this.matrix).invert();
38619
+ this.needsUpdate = false;
38620
+ };
38621
+ }();
38622
+ OrientedBox.prototype.intersectsBox = function() {
38623
+ const aabbBounds = new SeparatingAxisBounds();
38624
+ return function intersectsBox(box) {
38625
+ if (this.needsUpdate) {
38626
+ this.update();
38627
+ }
38628
+ const min = box.min;
38629
+ const max = box.max;
38630
+ const satBounds = this.satBounds;
38631
+ const satAxes = this.satAxes;
38632
+ const alignedSatBounds = this.alignedSatBounds;
38633
+ aabbBounds.min = min.x;
38634
+ aabbBounds.max = max.x;
38635
+ if (alignedSatBounds[0].isSeparated(aabbBounds))
38636
+ return false;
38637
+ aabbBounds.min = min.y;
38638
+ aabbBounds.max = max.y;
38639
+ if (alignedSatBounds[1].isSeparated(aabbBounds))
38640
+ return false;
38641
+ aabbBounds.min = min.z;
38642
+ aabbBounds.max = max.z;
38643
+ if (alignedSatBounds[2].isSeparated(aabbBounds))
38644
+ return false;
38645
+ for (let i = 0; i < 3; i++) {
38646
+ const axis = satAxes[i];
38647
+ const sb = satBounds[i];
38648
+ aabbBounds.setFromBox(axis, box);
38649
+ if (sb.isSeparated(aabbBounds))
38650
+ return false;
38651
+ }
38652
+ return true;
38653
+ };
38654
+ }();
38655
+ OrientedBox.prototype.intersectsTriangle = function() {
38656
+ const saTri = new ExtendedTriangle();
38657
+ const pointsArr = new Array(3);
38658
+ const cachedSatBounds = new SeparatingAxisBounds();
38659
+ const cachedSatBounds2 = new SeparatingAxisBounds();
38660
+ const cachedAxis = new Vector3();
38661
+ return function intersectsTriangle(triangle3) {
38662
+ if (this.needsUpdate) {
38663
+ this.update();
38664
+ }
38665
+ if (!triangle3.isExtendedTriangle) {
38666
+ saTri.copy(triangle3);
38667
+ saTri.update();
38668
+ triangle3 = saTri;
38669
+ } else if (triangle3.needsUpdate) {
38670
+ triangle3.update();
38671
+ }
38672
+ const satBounds = this.satBounds;
38673
+ const satAxes = this.satAxes;
38674
+ pointsArr[0] = triangle3.a;
38675
+ pointsArr[1] = triangle3.b;
38676
+ pointsArr[2] = triangle3.c;
38677
+ for (let i = 0; i < 3; i++) {
38678
+ const sb = satBounds[i];
38679
+ const sa = satAxes[i];
38680
+ cachedSatBounds.setFromPoints(sa, pointsArr);
38681
+ if (sb.isSeparated(cachedSatBounds))
38682
+ return false;
38683
+ }
38684
+ const triSatBounds = triangle3.satBounds;
38685
+ const triSatAxes = triangle3.satAxes;
38686
+ const points = this.points;
38687
+ for (let i = 0; i < 3; i++) {
38688
+ const sb = triSatBounds[i];
38689
+ const sa = triSatAxes[i];
38690
+ cachedSatBounds.setFromPoints(sa, points);
38691
+ if (sb.isSeparated(cachedSatBounds))
38692
+ return false;
38693
+ }
38694
+ for (let i = 0; i < 3; i++) {
38695
+ const sa1 = satAxes[i];
38696
+ for (let i2 = 0; i2 < 4; i2++) {
38697
+ const sa2 = triSatAxes[i2];
38698
+ cachedAxis.crossVectors(sa1, sa2);
38699
+ cachedSatBounds.setFromPoints(cachedAxis, pointsArr);
38700
+ cachedSatBounds2.setFromPoints(cachedAxis, points);
38701
+ if (cachedSatBounds.isSeparated(cachedSatBounds2))
38702
+ return false;
38703
+ }
38704
+ }
38705
+ return true;
38706
+ };
38707
+ }();
38708
+ OrientedBox.prototype.closestPointToPoint = function() {
38709
+ return function closestPointToPoint2(point, target1) {
38710
+ if (this.needsUpdate) {
38711
+ this.update();
38712
+ }
38713
+ target1.copy(point).applyMatrix4(this.invMatrix).clamp(this.min, this.max).applyMatrix4(this.matrix);
38714
+ return target1;
38715
+ };
38716
+ }();
38717
+ OrientedBox.prototype.distanceToPoint = function() {
38718
+ const target = new Vector3();
38719
+ return function distanceToPoint(point) {
38720
+ this.closestPointToPoint(point, target);
38721
+ return point.distanceTo(target);
38722
+ };
38723
+ }();
38724
+ OrientedBox.prototype.distanceToBox = function() {
38725
+ const xyzFields = ["x", "y", "z"];
38726
+ const segments1 = new Array(12).fill().map(() => new Line3());
38727
+ const segments2 = new Array(12).fill().map(() => new Line3());
38728
+ const point1 = new Vector3();
38729
+ const point2 = new Vector3();
38730
+ return function distanceToBox(box, threshold = 0, target1 = null, target2 = null) {
38731
+ if (this.needsUpdate) {
38732
+ this.update();
38733
+ }
38734
+ if (this.intersectsBox(box)) {
38735
+ if (target1 || target2) {
38736
+ box.getCenter(point2);
38737
+ this.closestPointToPoint(point2, point1);
38738
+ box.closestPointToPoint(point1, point2);
38739
+ if (target1)
38740
+ target1.copy(point1);
38741
+ if (target2)
38742
+ target2.copy(point2);
38743
+ }
38744
+ return 0;
38745
+ }
38746
+ const threshold2 = threshold * threshold;
38747
+ const min = box.min;
38748
+ const max = box.max;
38749
+ const points = this.points;
38750
+ let closestDistanceSq = Infinity;
38751
+ for (let i = 0; i < 8; i++) {
38752
+ const p2 = points[i];
38753
+ point2.copy(p2).clamp(min, max);
38754
+ const dist = p2.distanceToSquared(point2);
38755
+ if (dist < closestDistanceSq) {
38756
+ closestDistanceSq = dist;
38757
+ if (target1)
38758
+ target1.copy(p2);
38759
+ if (target2)
38760
+ target2.copy(point2);
38761
+ if (dist < threshold2)
38762
+ return Math.sqrt(dist);
38763
+ }
38764
+ }
38765
+ let count = 0;
38766
+ for (let i = 0; i < 3; i++) {
38767
+ for (let i1 = 0; i1 <= 1; i1++) {
38768
+ for (let i2 = 0; i2 <= 1; i2++) {
38769
+ const nextIndex = (i + 1) % 3;
38770
+ const nextIndex2 = (i + 2) % 3;
38771
+ const index = i1 << nextIndex | i2 << nextIndex2;
38772
+ const index2 = 1 << i | i1 << nextIndex | i2 << nextIndex2;
38773
+ const p1 = points[index];
38774
+ const p2 = points[index2];
38775
+ const line1 = segments1[count];
38776
+ line1.set(p1, p2);
38777
+ const f1 = xyzFields[i];
38778
+ const f2 = xyzFields[nextIndex];
38779
+ const f3 = xyzFields[nextIndex2];
38780
+ const line2 = segments2[count];
38781
+ const start = line2.start;
38782
+ const end = line2.end;
38783
+ start[f1] = min[f1];
38784
+ start[f2] = i1 ? min[f2] : max[f2];
38785
+ start[f3] = i2 ? min[f3] : max[f2];
38786
+ end[f1] = max[f1];
38787
+ end[f2] = i1 ? min[f2] : max[f2];
38788
+ end[f3] = i2 ? min[f3] : max[f2];
38789
+ count++;
38790
+ }
38791
+ }
38792
+ }
38793
+ for (let x2 = 0; x2 <= 1; x2++) {
38794
+ for (let y = 0; y <= 1; y++) {
38795
+ for (let z = 0; z <= 1; z++) {
38796
+ point2.x = x2 ? max.x : min.x;
38797
+ point2.y = y ? max.y : min.y;
38798
+ point2.z = z ? max.z : min.z;
38799
+ this.closestPointToPoint(point2, point1);
38800
+ const dist = point2.distanceToSquared(point1);
38801
+ if (dist < closestDistanceSq) {
38802
+ closestDistanceSq = dist;
38803
+ if (target1)
38804
+ target1.copy(point1);
38805
+ if (target2)
38806
+ target2.copy(point2);
38807
+ if (dist < threshold2)
38808
+ return Math.sqrt(dist);
38809
+ }
38810
+ }
38811
+ }
38812
+ }
38813
+ for (let i = 0; i < 12; i++) {
38814
+ const l1 = segments1[i];
38815
+ for (let i2 = 0; i2 < 12; i2++) {
38816
+ const l2 = segments2[i2];
38817
+ closestPointsSegmentToSegment(l1, l2, point1, point2);
38818
+ const dist = point1.distanceToSquared(point2);
38819
+ if (dist < closestDistanceSq) {
38820
+ closestDistanceSq = dist;
38821
+ if (target1)
38822
+ target1.copy(point1);
38823
+ if (target2)
38824
+ target2.copy(point2);
38825
+ if (dist < threshold2)
38826
+ return Math.sqrt(dist);
38827
+ }
38828
+ }
38829
+ }
38830
+ return Math.sqrt(closestDistanceSq);
38831
+ };
38832
+ }();
38833
+ class PrimitivePool {
38834
+ constructor(getNewPrimitive) {
38835
+ this._getNewPrimitive = getNewPrimitive;
38836
+ this._primitives = [];
38837
+ }
38838
+ getPrimitive() {
38839
+ const primitives = this._primitives;
38840
+ if (primitives.length === 0) {
38841
+ return this._getNewPrimitive();
38842
+ } else {
38843
+ return primitives.pop();
38844
+ }
38845
+ }
38846
+ releasePrimitive(primitive) {
38847
+ this._primitives.push(primitive);
38848
+ }
38849
+ }
38850
+ class ExtendedTrianglePoolBase extends PrimitivePool {
38851
+ constructor() {
38852
+ super(() => new ExtendedTriangle());
38853
+ }
38854
+ }
38855
+ const ExtendedTrianglePool = /* @__PURE__ */ new ExtendedTrianglePoolBase();
38856
+ function IS_LEAF(n16, uint16Array) {
38857
+ return uint16Array[n16 + 15] === 65535;
38858
+ }
38859
+ function OFFSET(n32, uint32Array) {
38860
+ return uint32Array[n32 + 6];
38861
+ }
38862
+ function COUNT(n16, uint16Array) {
38863
+ return uint16Array[n16 + 14];
38864
+ }
38865
+ function LEFT_NODE(n32) {
38866
+ return n32 + 8;
38867
+ }
38868
+ function RIGHT_NODE(n32, uint32Array) {
38869
+ return uint32Array[n32 + 6];
38870
+ }
38871
+ function SPLIT_AXIS(n32, uint32Array) {
38872
+ return uint32Array[n32 + 7];
38873
+ }
38874
+ function BOUNDING_DATA_INDEX(n32) {
38875
+ return n32;
38876
+ }
38877
+ class _BufferStack {
38878
+ constructor() {
38879
+ this.float32Array = null;
38880
+ this.uint16Array = null;
38881
+ this.uint32Array = null;
38882
+ const stack = [];
38883
+ let prevBuffer = null;
38884
+ this.setBuffer = (buffer) => {
38885
+ if (prevBuffer) {
38886
+ stack.push(prevBuffer);
38887
+ }
38888
+ prevBuffer = buffer;
38889
+ this.float32Array = new Float32Array(buffer);
38890
+ this.uint16Array = new Uint16Array(buffer);
38891
+ this.uint32Array = new Uint32Array(buffer);
38892
+ };
38893
+ this.clearBuffer = () => {
38894
+ prevBuffer = null;
38895
+ this.float32Array = null;
38896
+ this.uint16Array = null;
38897
+ this.uint32Array = null;
38898
+ if (stack.length !== 0) {
38899
+ this.setBuffer(stack.pop());
38900
+ }
38901
+ };
38902
+ }
38903
+ }
38904
+ const BufferStack = new _BufferStack();
38905
+ let _box1, _box2;
38906
+ const boxStack = [];
38907
+ const boxPool = /* @__PURE__ */ new PrimitivePool(() => new Box3());
38908
+ function shapecast(bvh, root, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset) {
38909
+ _box1 = boxPool.getPrimitive();
38910
+ _box2 = boxPool.getPrimitive();
38911
+ boxStack.push(_box1, _box2);
38912
+ BufferStack.setBuffer(bvh._roots[root]);
38913
+ const result = shapecastTraverse(0, bvh.geometry, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset);
38914
+ BufferStack.clearBuffer();
38915
+ boxPool.releasePrimitive(_box1);
38916
+ boxPool.releasePrimitive(_box2);
38917
+ boxStack.pop();
38918
+ boxStack.pop();
38919
+ const length = boxStack.length;
38920
+ if (length > 0) {
38921
+ _box2 = boxStack[length - 1];
38922
+ _box1 = boxStack[length - 2];
38923
+ }
38924
+ return result;
38925
+ }
38926
+ function shapecastTraverse(nodeIndex32, geometry, intersectsBoundsFunc, intersectsRangeFunc, nodeScoreFunc = null, nodeIndexByteOffset = 0, depth = 0) {
38927
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
38928
+ let nodeIndex16 = nodeIndex32 * 2;
38929
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
38930
+ if (isLeaf) {
38931
+ const offset = OFFSET(nodeIndex32, uint32Array);
38932
+ const count = COUNT(nodeIndex16, uint16Array);
38933
+ arrayToBox(BOUNDING_DATA_INDEX(nodeIndex32), float32Array, _box1);
38934
+ return intersectsRangeFunc(offset, count, false, depth, nodeIndexByteOffset + nodeIndex32, _box1);
38935
+ } else {
38936
+ let getLeftOffset = function(nodeIndex322) {
38937
+ const { uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
38938
+ let nodeIndex162 = nodeIndex322 * 2;
38939
+ while (!IS_LEAF(nodeIndex162, uint16Array2)) {
38940
+ nodeIndex322 = LEFT_NODE(nodeIndex322);
38941
+ nodeIndex162 = nodeIndex322 * 2;
38942
+ }
38943
+ return OFFSET(nodeIndex322, uint32Array2);
38944
+ }, getRightEndOffset = function(nodeIndex322) {
38945
+ const { uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
38946
+ let nodeIndex162 = nodeIndex322 * 2;
38947
+ while (!IS_LEAF(nodeIndex162, uint16Array2)) {
38948
+ nodeIndex322 = RIGHT_NODE(nodeIndex322, uint32Array2);
38949
+ nodeIndex162 = nodeIndex322 * 2;
38950
+ }
38951
+ return OFFSET(nodeIndex322, uint32Array2) + COUNT(nodeIndex162, uint16Array2);
38952
+ };
38953
+ const left = LEFT_NODE(nodeIndex32);
38954
+ const right = RIGHT_NODE(nodeIndex32, uint32Array);
38955
+ let c1 = left;
38956
+ let c2 = right;
38957
+ let score1, score2;
38958
+ let box1, box2;
38959
+ if (nodeScoreFunc) {
38960
+ box1 = _box1;
38961
+ box2 = _box2;
38962
+ arrayToBox(BOUNDING_DATA_INDEX(c1), float32Array, box1);
38963
+ arrayToBox(BOUNDING_DATA_INDEX(c2), float32Array, box2);
38964
+ score1 = nodeScoreFunc(box1);
38965
+ score2 = nodeScoreFunc(box2);
38966
+ if (score2 < score1) {
38967
+ c1 = right;
38968
+ c2 = left;
38969
+ const temp5 = score1;
38970
+ score1 = score2;
38971
+ score2 = temp5;
38972
+ box1 = box2;
38973
+ }
38974
+ }
38975
+ if (!box1) {
38976
+ box1 = _box1;
38977
+ arrayToBox(BOUNDING_DATA_INDEX(c1), float32Array, box1);
38978
+ }
38979
+ const isC1Leaf = IS_LEAF(c1 * 2, uint16Array);
38980
+ const c1Intersection = intersectsBoundsFunc(box1, isC1Leaf, score1, depth + 1, nodeIndexByteOffset + c1);
38981
+ let c1StopTraversal;
38982
+ if (c1Intersection === CONTAINED) {
38983
+ const offset = getLeftOffset(c1);
38984
+ const end = getRightEndOffset(c1);
38985
+ const count = end - offset;
38986
+ c1StopTraversal = intersectsRangeFunc(offset, count, true, depth + 1, nodeIndexByteOffset + c1, box1);
38987
+ } else {
38988
+ c1StopTraversal = c1Intersection && shapecastTraverse(
38989
+ c1,
38990
+ geometry,
38991
+ intersectsBoundsFunc,
38992
+ intersectsRangeFunc,
38993
+ nodeScoreFunc,
38994
+ nodeIndexByteOffset,
38995
+ depth + 1
38996
+ );
38997
+ }
38998
+ if (c1StopTraversal)
38999
+ return true;
39000
+ box2 = _box2;
39001
+ arrayToBox(BOUNDING_DATA_INDEX(c2), float32Array, box2);
39002
+ const isC2Leaf = IS_LEAF(c2 * 2, uint16Array);
39003
+ const c2Intersection = intersectsBoundsFunc(box2, isC2Leaf, score2, depth + 1, nodeIndexByteOffset + c2);
39004
+ let c2StopTraversal;
39005
+ if (c2Intersection === CONTAINED) {
39006
+ const offset = getLeftOffset(c2);
39007
+ const end = getRightEndOffset(c2);
39008
+ const count = end - offset;
39009
+ c2StopTraversal = intersectsRangeFunc(offset, count, true, depth + 1, nodeIndexByteOffset + c2, box2);
39010
+ } else {
39011
+ c2StopTraversal = c2Intersection && shapecastTraverse(
39012
+ c2,
39013
+ geometry,
39014
+ intersectsBoundsFunc,
39015
+ intersectsRangeFunc,
39016
+ nodeScoreFunc,
39017
+ nodeIndexByteOffset,
39018
+ depth + 1
39019
+ );
39020
+ }
39021
+ if (c2StopTraversal)
39022
+ return true;
39023
+ return false;
39024
+ }
39025
+ }
39026
+ const temp = /* @__PURE__ */ new Vector3();
39027
+ const temp1$2 = /* @__PURE__ */ new Vector3();
39028
+ function closestPointToPoint(bvh, point, target = {}, minThreshold = 0, maxThreshold = Infinity) {
39029
+ const minThresholdSq = minThreshold * minThreshold;
39030
+ const maxThresholdSq = maxThreshold * maxThreshold;
39031
+ let closestDistanceSq = Infinity;
39032
+ let closestDistanceTriIndex = null;
39033
+ bvh.shapecast(
39034
+ {
39035
+ boundsTraverseOrder: (box) => {
39036
+ temp.copy(point).clamp(box.min, box.max);
39037
+ return temp.distanceToSquared(point);
39038
+ },
39039
+ intersectsBounds: (box, isLeaf, score) => {
39040
+ return score < closestDistanceSq && score < maxThresholdSq;
39041
+ },
39042
+ intersectsTriangle: (tri, triIndex) => {
39043
+ tri.closestPointToPoint(point, temp);
39044
+ const distSq = point.distanceToSquared(temp);
39045
+ if (distSq < closestDistanceSq) {
39046
+ temp1$2.copy(temp);
39047
+ closestDistanceSq = distSq;
39048
+ closestDistanceTriIndex = triIndex;
39049
+ }
39050
+ if (distSq < minThresholdSq) {
39051
+ return true;
39052
+ } else {
39053
+ return false;
39054
+ }
39055
+ }
39056
+ }
39057
+ );
39058
+ if (closestDistanceSq === Infinity)
39059
+ return null;
39060
+ const closestDistance = Math.sqrt(closestDistanceSq);
39061
+ if (!target.point)
39062
+ target.point = temp1$2.clone();
39063
+ else
39064
+ target.point.copy(temp1$2);
39065
+ target.distance = closestDistance, target.faceIndex = closestDistanceTriIndex;
39066
+ return target;
39067
+ }
39068
+ const _vA = /* @__PURE__ */ new Vector3();
39069
+ const _vB = /* @__PURE__ */ new Vector3();
39070
+ const _vC = /* @__PURE__ */ new Vector3();
39071
+ const _uvA = /* @__PURE__ */ new Vector2();
39072
+ const _uvB = /* @__PURE__ */ new Vector2();
39073
+ const _uvC = /* @__PURE__ */ new Vector2();
39074
+ const _normalA = /* @__PURE__ */ new Vector3();
39075
+ const _normalB = /* @__PURE__ */ new Vector3();
39076
+ const _normalC = /* @__PURE__ */ new Vector3();
39077
+ const _intersectionPoint = /* @__PURE__ */ new Vector3();
39078
+ function checkIntersection(ray, pA, pB, pC, point, side) {
39079
+ let intersect;
39080
+ if (side === BackSide) {
39081
+ intersect = ray.intersectTriangle(pC, pB, pA, true, point);
39082
+ } else {
39083
+ intersect = ray.intersectTriangle(pA, pB, pC, side !== DoubleSide, point);
39084
+ }
39085
+ if (intersect === null)
39086
+ return null;
39087
+ const distance = ray.origin.distanceTo(point);
39088
+ return {
39089
+ distance,
39090
+ point: point.clone()
39091
+ };
39092
+ }
39093
+ function checkBufferGeometryIntersection(ray, position, normal, uv, uv1, a, b, c2, side) {
39094
+ _vA.fromBufferAttribute(position, a);
39095
+ _vB.fromBufferAttribute(position, b);
39096
+ _vC.fromBufferAttribute(position, c2);
39097
+ const intersection = checkIntersection(ray, _vA, _vB, _vC, _intersectionPoint, side);
39098
+ if (intersection) {
39099
+ if (uv) {
39100
+ _uvA.fromBufferAttribute(uv, a);
39101
+ _uvB.fromBufferAttribute(uv, b);
39102
+ _uvC.fromBufferAttribute(uv, c2);
39103
+ intersection.uv = Triangle.getInterpolation(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2());
39104
+ }
39105
+ if (uv1) {
39106
+ _uvA.fromBufferAttribute(uv1, a);
39107
+ _uvB.fromBufferAttribute(uv1, b);
39108
+ _uvC.fromBufferAttribute(uv1, c2);
39109
+ intersection.uv1 = Triangle.getInterpolation(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2());
39110
+ }
39111
+ if (normal) {
39112
+ _normalA.fromBufferAttribute(normal, a);
39113
+ _normalB.fromBufferAttribute(normal, b);
39114
+ _normalC.fromBufferAttribute(normal, c2);
39115
+ intersection.normal = Triangle.getInterpolation(_intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, new Vector3());
39116
+ if (intersection.normal.dot(ray.direction) > 0) {
39117
+ intersection.normal.multiplyScalar(-1);
39118
+ }
39119
+ }
39120
+ const face = {
39121
+ a,
39122
+ b,
39123
+ c: c2,
39124
+ normal: new Vector3(),
39125
+ materialIndex: 0
39126
+ };
39127
+ Triangle.getNormal(_vA, _vB, _vC, face.normal);
39128
+ intersection.face = face;
39129
+ intersection.faceIndex = a;
39130
+ }
39131
+ return intersection;
39132
+ }
39133
+ function intersectTri(geo, side, ray, tri, intersections) {
39134
+ const triOffset = tri * 3;
39135
+ let a = triOffset + 0;
39136
+ let b = triOffset + 1;
39137
+ let c2 = triOffset + 2;
39138
+ const index = geo.index;
39139
+ if (geo.index) {
39140
+ a = index.getX(a);
39141
+ b = index.getX(b);
39142
+ c2 = index.getX(c2);
39143
+ }
39144
+ const { position, normal, uv, uv1 } = geo.attributes;
39145
+ const intersection = checkBufferGeometryIntersection(ray, position, normal, uv, uv1, a, b, c2, side);
39146
+ if (intersection) {
39147
+ intersection.faceIndex = tri;
39148
+ if (intersections)
39149
+ intersections.push(intersection);
39150
+ return intersection;
39151
+ }
39152
+ return null;
39153
+ }
39154
+ function setTriangle(tri, i, index, pos) {
39155
+ const ta = tri.a;
39156
+ const tb = tri.b;
39157
+ const tc = tri.c;
39158
+ let i0 = i;
39159
+ let i1 = i + 1;
39160
+ let i2 = i + 2;
39161
+ if (index) {
39162
+ i0 = index.getX(i0);
39163
+ i1 = index.getX(i1);
39164
+ i2 = index.getX(i2);
39165
+ }
39166
+ ta.x = pos.getX(i0);
39167
+ ta.y = pos.getY(i0);
39168
+ ta.z = pos.getZ(i0);
39169
+ tb.x = pos.getX(i1);
39170
+ tb.y = pos.getY(i1);
39171
+ tb.z = pos.getZ(i1);
39172
+ tc.x = pos.getX(i2);
39173
+ tc.y = pos.getY(i2);
39174
+ tc.z = pos.getZ(i2);
39175
+ }
39176
+ function intersectTris(bvh, side, ray, offset, count, intersections) {
39177
+ const { geometry, _indirectBuffer } = bvh;
39178
+ for (let i = offset, end = offset + count; i < end; i++) {
39179
+ intersectTri(geometry, side, ray, i, intersections);
39180
+ }
39181
+ }
39182
+ function intersectClosestTri(bvh, side, ray, offset, count) {
39183
+ const { geometry, _indirectBuffer } = bvh;
39184
+ let dist = Infinity;
39185
+ let res = null;
39186
+ for (let i = offset, end = offset + count; i < end; i++) {
39187
+ let intersection;
39188
+ intersection = intersectTri(geometry, side, ray, i);
39189
+ if (intersection && intersection.distance < dist) {
39190
+ res = intersection;
39191
+ dist = intersection.distance;
39192
+ }
39193
+ }
39194
+ return res;
39195
+ }
39196
+ function iterateOverTriangles(offset, count, bvh, intersectsTriangleFunc, contained, depth, triangle3) {
39197
+ const { geometry } = bvh;
39198
+ const { index } = geometry;
39199
+ const pos = geometry.attributes.position;
39200
+ for (let i = offset, l = count + offset; i < l; i++) {
39201
+ let tri;
39202
+ tri = i;
39203
+ setTriangle(triangle3, tri * 3, index, pos);
39204
+ triangle3.needsUpdate = true;
39205
+ if (intersectsTriangleFunc(triangle3, tri, contained, depth)) {
39206
+ return true;
39207
+ }
39208
+ }
39209
+ return false;
39210
+ }
39211
+ function refit(bvh, nodeIndices = null) {
39212
+ if (nodeIndices && Array.isArray(nodeIndices)) {
39213
+ nodeIndices = new Set(nodeIndices);
39214
+ }
39215
+ const geometry = bvh.geometry;
39216
+ const indexArr = geometry.index ? geometry.index.array : null;
39217
+ const posAttr = geometry.attributes.position;
39218
+ let buffer, uint32Array, uint16Array, float32Array;
39219
+ let byteOffset = 0;
39220
+ const roots = bvh._roots;
39221
+ for (let i = 0, l = roots.length; i < l; i++) {
39222
+ buffer = roots[i];
39223
+ uint32Array = new Uint32Array(buffer);
39224
+ uint16Array = new Uint16Array(buffer);
39225
+ float32Array = new Float32Array(buffer);
39226
+ _traverse2(0, byteOffset);
39227
+ byteOffset += buffer.byteLength;
39228
+ }
39229
+ function _traverse2(node32Index, byteOffset2, force = false) {
39230
+ const node16Index = node32Index * 2;
39231
+ const isLeaf = uint16Array[node16Index + 15] === IS_LEAFNODE_FLAG;
39232
+ if (isLeaf) {
39233
+ const offset = uint32Array[node32Index + 6];
39234
+ const count = uint16Array[node16Index + 14];
39235
+ let minx = Infinity;
39236
+ let miny = Infinity;
39237
+ let minz = Infinity;
39238
+ let maxx = -Infinity;
39239
+ let maxy = -Infinity;
39240
+ let maxz = -Infinity;
39241
+ for (let i = 3 * offset, l = 3 * (offset + count); i < l; i++) {
39242
+ let index = indexArr[i];
39243
+ const x2 = posAttr.getX(index);
39244
+ const y = posAttr.getY(index);
39245
+ const z = posAttr.getZ(index);
39246
+ if (x2 < minx)
39247
+ minx = x2;
39248
+ if (x2 > maxx)
39249
+ maxx = x2;
39250
+ if (y < miny)
39251
+ miny = y;
39252
+ if (y > maxy)
39253
+ maxy = y;
39254
+ if (z < minz)
39255
+ minz = z;
39256
+ if (z > maxz)
39257
+ maxz = z;
39258
+ }
39259
+ if (float32Array[node32Index + 0] !== minx || float32Array[node32Index + 1] !== miny || float32Array[node32Index + 2] !== minz || float32Array[node32Index + 3] !== maxx || float32Array[node32Index + 4] !== maxy || float32Array[node32Index + 5] !== maxz) {
39260
+ float32Array[node32Index + 0] = minx;
39261
+ float32Array[node32Index + 1] = miny;
39262
+ float32Array[node32Index + 2] = minz;
39263
+ float32Array[node32Index + 3] = maxx;
39264
+ float32Array[node32Index + 4] = maxy;
39265
+ float32Array[node32Index + 5] = maxz;
39266
+ return true;
39267
+ } else {
39268
+ return false;
39269
+ }
39270
+ } else {
39271
+ const left = node32Index + 8;
39272
+ const right = uint32Array[node32Index + 6];
39273
+ const offsetLeft = left + byteOffset2;
39274
+ const offsetRight = right + byteOffset2;
39275
+ let forceChildren = force;
39276
+ let includesLeft = false;
39277
+ let includesRight = false;
39278
+ if (nodeIndices) {
39279
+ if (!forceChildren) {
39280
+ includesLeft = nodeIndices.has(offsetLeft);
39281
+ includesRight = nodeIndices.has(offsetRight);
39282
+ forceChildren = !includesLeft && !includesRight;
39283
+ }
39284
+ } else {
39285
+ includesLeft = true;
39286
+ includesRight = true;
39287
+ }
39288
+ const traverseLeft = forceChildren || includesLeft;
39289
+ const traverseRight = forceChildren || includesRight;
39290
+ let leftChange = false;
39291
+ if (traverseLeft) {
39292
+ leftChange = _traverse2(left, byteOffset2, forceChildren);
39293
+ }
39294
+ let rightChange = false;
39295
+ if (traverseRight) {
39296
+ rightChange = _traverse2(right, byteOffset2, forceChildren);
39297
+ }
39298
+ const didChange = leftChange || rightChange;
39299
+ if (didChange) {
39300
+ for (let i = 0; i < 3; i++) {
39301
+ const lefti = left + i;
39302
+ const righti = right + i;
39303
+ const minLeftValue = float32Array[lefti];
39304
+ const maxLeftValue = float32Array[lefti + 3];
39305
+ const minRightValue = float32Array[righti];
39306
+ const maxRightValue = float32Array[righti + 3];
39307
+ float32Array[node32Index + i] = minLeftValue < minRightValue ? minLeftValue : minRightValue;
39308
+ float32Array[node32Index + i + 3] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;
39309
+ }
39310
+ }
39311
+ return didChange;
39312
+ }
39313
+ }
39314
+ }
39315
+ const _boundingBox = /* @__PURE__ */ new Box3();
39316
+ function intersectRay(nodeIndex32, array, ray, target) {
39317
+ arrayToBox(nodeIndex32, array, _boundingBox);
39318
+ return ray.intersectBox(_boundingBox, target);
39319
+ }
39320
+ function intersectTris_indirect(bvh, side, ray, offset, count, intersections) {
39321
+ const { geometry, _indirectBuffer } = bvh;
39322
+ for (let i = offset, end = offset + count; i < end; i++) {
39323
+ let vi = _indirectBuffer ? _indirectBuffer[i] : i;
39324
+ intersectTri(geometry, side, ray, vi, intersections);
39325
+ }
39326
+ }
39327
+ function intersectClosestTri_indirect(bvh, side, ray, offset, count) {
39328
+ const { geometry, _indirectBuffer } = bvh;
39329
+ let dist = Infinity;
39330
+ let res = null;
39331
+ for (let i = offset, end = offset + count; i < end; i++) {
39332
+ let intersection;
39333
+ intersection = intersectTri(geometry, side, ray, _indirectBuffer ? _indirectBuffer[i] : i);
39334
+ if (intersection && intersection.distance < dist) {
39335
+ res = intersection;
39336
+ dist = intersection.distance;
39337
+ }
39338
+ }
39339
+ return res;
39340
+ }
39341
+ function iterateOverTriangles_indirect(offset, count, bvh, intersectsTriangleFunc, contained, depth, triangle3) {
39342
+ const { geometry } = bvh;
39343
+ const { index } = geometry;
39344
+ const pos = geometry.attributes.position;
39345
+ for (let i = offset, l = count + offset; i < l; i++) {
39346
+ let tri;
39347
+ tri = bvh.resolveTriangleIndex(i);
39348
+ setTriangle(triangle3, tri * 3, index, pos);
39349
+ triangle3.needsUpdate = true;
39350
+ if (intersectsTriangleFunc(triangle3, tri, contained, depth)) {
39351
+ return true;
39352
+ }
39353
+ }
39354
+ return false;
39355
+ }
39356
+ const _boxIntersection$3 = /* @__PURE__ */ new Vector3();
39357
+ function raycast(bvh, root, side, ray, intersects) {
39358
+ BufferStack.setBuffer(bvh._roots[root]);
39359
+ _raycast$1(0, bvh, side, ray, intersects);
39360
+ BufferStack.clearBuffer();
39361
+ }
39362
+ function _raycast$1(nodeIndex32, bvh, side, ray, intersects) {
39363
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
39364
+ const nodeIndex16 = nodeIndex32 * 2;
39365
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
39366
+ if (isLeaf) {
39367
+ const offset = OFFSET(nodeIndex32, uint32Array);
39368
+ const count = COUNT(nodeIndex16, uint16Array);
39369
+ intersectTris(bvh, side, ray, offset, count, intersects);
39370
+ } else {
39371
+ const leftIndex = LEFT_NODE(nodeIndex32);
39372
+ if (intersectRay(leftIndex, float32Array, ray, _boxIntersection$3)) {
39373
+ _raycast$1(leftIndex, bvh, side, ray, intersects);
39374
+ }
39375
+ const rightIndex = RIGHT_NODE(nodeIndex32, uint32Array);
39376
+ if (intersectRay(rightIndex, float32Array, ray, _boxIntersection$3)) {
39377
+ _raycast$1(rightIndex, bvh, side, ray, intersects);
39378
+ }
39379
+ }
39380
+ }
39381
+ const _boxIntersection$2 = /* @__PURE__ */ new Vector3();
39382
+ const _xyzFields$1 = ["x", "y", "z"];
39383
+ function raycastFirst(bvh, root, side, ray) {
39384
+ BufferStack.setBuffer(bvh._roots[root]);
39385
+ const result = _raycastFirst$1(0, bvh, side, ray);
39386
+ BufferStack.clearBuffer();
39387
+ return result;
39388
+ }
39389
+ function _raycastFirst$1(nodeIndex32, bvh, side, ray) {
39390
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
39391
+ let nodeIndex16 = nodeIndex32 * 2;
39392
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
39393
+ if (isLeaf) {
39394
+ const offset = OFFSET(nodeIndex32, uint32Array);
39395
+ const count = COUNT(nodeIndex16, uint16Array);
39396
+ return intersectClosestTri(bvh, side, ray, offset, count);
39397
+ } else {
39398
+ const splitAxis = SPLIT_AXIS(nodeIndex32, uint32Array);
39399
+ const xyzAxis = _xyzFields$1[splitAxis];
39400
+ const rayDir = ray.direction[xyzAxis];
39401
+ const leftToRight = rayDir >= 0;
39402
+ let c1, c2;
39403
+ if (leftToRight) {
39404
+ c1 = LEFT_NODE(nodeIndex32);
39405
+ c2 = RIGHT_NODE(nodeIndex32, uint32Array);
39406
+ } else {
39407
+ c1 = RIGHT_NODE(nodeIndex32, uint32Array);
39408
+ c2 = LEFT_NODE(nodeIndex32);
39409
+ }
39410
+ const c1Intersection = intersectRay(c1, float32Array, ray, _boxIntersection$2);
39411
+ const c1Result = c1Intersection ? _raycastFirst$1(c1, bvh, side, ray) : null;
39412
+ if (c1Result) {
39413
+ const point = c1Result.point[xyzAxis];
39414
+ const isOutside = leftToRight ? point <= float32Array[c2 + splitAxis] : (
39415
+ // min bounding data
39416
+ point >= float32Array[c2 + splitAxis + 3]
39417
+ );
39418
+ if (isOutside) {
39419
+ return c1Result;
39420
+ }
39421
+ }
39422
+ const c2Intersection = intersectRay(c2, float32Array, ray, _boxIntersection$2);
39423
+ const c2Result = c2Intersection ? _raycastFirst$1(c2, bvh, side, ray) : null;
39424
+ if (c1Result && c2Result) {
39425
+ return c1Result.distance <= c2Result.distance ? c1Result : c2Result;
39426
+ } else {
39427
+ return c1Result || c2Result || null;
39428
+ }
39429
+ }
39430
+ }
39431
+ const boundingBox$1 = /* @__PURE__ */ new Box3();
39432
+ const triangle$1 = /* @__PURE__ */ new ExtendedTriangle();
39433
+ const triangle2$1 = /* @__PURE__ */ new ExtendedTriangle();
39434
+ const invertedMat$1 = /* @__PURE__ */ new Matrix4();
39435
+ const obb$4 = /* @__PURE__ */ new OrientedBox();
39436
+ const obb2$3 = /* @__PURE__ */ new OrientedBox();
39437
+ function intersectsGeometry(bvh, root, otherGeometry, geometryToBvh) {
39438
+ BufferStack.setBuffer(bvh._roots[root]);
39439
+ const result = _intersectsGeometry$1(0, bvh, otherGeometry, geometryToBvh);
39440
+ BufferStack.clearBuffer();
39441
+ return result;
39442
+ }
39443
+ function _intersectsGeometry$1(nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null) {
39444
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
39445
+ let nodeIndex16 = nodeIndex32 * 2;
39446
+ if (cachedObb === null) {
39447
+ if (!otherGeometry.boundingBox) {
39448
+ otherGeometry.computeBoundingBox();
39449
+ }
39450
+ obb$4.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
39451
+ cachedObb = obb$4;
39452
+ }
39453
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
39454
+ if (isLeaf) {
39455
+ const thisGeometry = bvh.geometry;
39456
+ const thisIndex = thisGeometry.index;
39457
+ const thisPos = thisGeometry.attributes.position;
39458
+ const index = otherGeometry.index;
39459
+ const pos = otherGeometry.attributes.position;
39460
+ const offset = OFFSET(nodeIndex32, uint32Array);
39461
+ const count = COUNT(nodeIndex16, uint16Array);
39462
+ invertedMat$1.copy(geometryToBvh).invert();
39463
+ if (otherGeometry.boundsTree) {
39464
+ arrayToBox(BOUNDING_DATA_INDEX(nodeIndex32), float32Array, obb2$3);
39465
+ obb2$3.matrix.copy(invertedMat$1);
39466
+ obb2$3.needsUpdate = true;
39467
+ const res = otherGeometry.boundsTree.shapecast({
39468
+ intersectsBounds: (box) => obb2$3.intersectsBox(box),
39469
+ intersectsTriangle: (tri) => {
39470
+ tri.a.applyMatrix4(geometryToBvh);
39471
+ tri.b.applyMatrix4(geometryToBvh);
39472
+ tri.c.applyMatrix4(geometryToBvh);
39473
+ tri.needsUpdate = true;
39474
+ for (let i = offset * 3, l = (count + offset) * 3; i < l; i += 3) {
39475
+ setTriangle(triangle2$1, i, thisIndex, thisPos);
39476
+ triangle2$1.needsUpdate = true;
39477
+ if (tri.intersectsTriangle(triangle2$1)) {
39478
+ return true;
39479
+ }
39480
+ }
39481
+ return false;
39482
+ }
39483
+ });
39484
+ return res;
39485
+ } else {
39486
+ for (let i = offset * 3, l = (count + offset) * 3; i < l; i += 3) {
39487
+ setTriangle(triangle$1, i, thisIndex, thisPos);
39488
+ triangle$1.a.applyMatrix4(invertedMat$1);
39489
+ triangle$1.b.applyMatrix4(invertedMat$1);
39490
+ triangle$1.c.applyMatrix4(invertedMat$1);
39491
+ triangle$1.needsUpdate = true;
39492
+ for (let i2 = 0, l2 = index.count; i2 < l2; i2 += 3) {
39493
+ setTriangle(triangle2$1, i2, index, pos);
39494
+ triangle2$1.needsUpdate = true;
39495
+ if (triangle$1.intersectsTriangle(triangle2$1)) {
39496
+ return true;
39497
+ }
39498
+ }
39499
+ }
39500
+ }
39501
+ } else {
39502
+ const left = nodeIndex32 + 8;
39503
+ const right = uint32Array[nodeIndex32 + 6];
39504
+ arrayToBox(BOUNDING_DATA_INDEX(left), float32Array, boundingBox$1);
39505
+ const leftIntersection = cachedObb.intersectsBox(boundingBox$1) && _intersectsGeometry$1(left, bvh, otherGeometry, geometryToBvh, cachedObb);
39506
+ if (leftIntersection)
39507
+ return true;
39508
+ arrayToBox(BOUNDING_DATA_INDEX(right), float32Array, boundingBox$1);
39509
+ const rightIntersection = cachedObb.intersectsBox(boundingBox$1) && _intersectsGeometry$1(right, bvh, otherGeometry, geometryToBvh, cachedObb);
39510
+ if (rightIntersection)
39511
+ return true;
39512
+ return false;
39513
+ }
39514
+ }
39515
+ const tempMatrix$1 = /* @__PURE__ */ new Matrix4();
39516
+ const obb$3 = /* @__PURE__ */ new OrientedBox();
39517
+ const obb2$2 = /* @__PURE__ */ new OrientedBox();
39518
+ const temp1$1 = /* @__PURE__ */ new Vector3();
39519
+ const temp2$1 = /* @__PURE__ */ new Vector3();
39520
+ const temp3$1 = /* @__PURE__ */ new Vector3();
39521
+ const temp4$1 = /* @__PURE__ */ new Vector3();
39522
+ function closestPointToGeometry(bvh, otherGeometry, geometryToBvh, target1 = {}, target2 = {}, minThreshold = 0, maxThreshold = Infinity) {
39523
+ if (!otherGeometry.boundingBox) {
39524
+ otherGeometry.computeBoundingBox();
39525
+ }
39526
+ obb$3.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
39527
+ obb$3.needsUpdate = true;
39528
+ const geometry = bvh.geometry;
39529
+ const pos = geometry.attributes.position;
39530
+ const index = geometry.index;
39531
+ const otherPos = otherGeometry.attributes.position;
39532
+ const otherIndex = otherGeometry.index;
39533
+ const triangle3 = ExtendedTrianglePool.getPrimitive();
39534
+ const triangle22 = ExtendedTrianglePool.getPrimitive();
39535
+ let tempTarget1 = temp1$1;
39536
+ let tempTargetDest1 = temp2$1;
39537
+ let tempTarget2 = null;
39538
+ let tempTargetDest2 = null;
39539
+ if (target2) {
39540
+ tempTarget2 = temp3$1;
39541
+ tempTargetDest2 = temp4$1;
39542
+ }
39543
+ let closestDistance = Infinity;
39544
+ let closestDistanceTriIndex = null;
39545
+ let closestDistanceOtherTriIndex = null;
39546
+ tempMatrix$1.copy(geometryToBvh).invert();
39547
+ obb2$2.matrix.copy(tempMatrix$1);
39548
+ bvh.shapecast(
39549
+ {
39550
+ boundsTraverseOrder: (box) => {
39551
+ return obb$3.distanceToBox(box);
39552
+ },
39553
+ intersectsBounds: (box, isLeaf, score) => {
39554
+ if (score < closestDistance && score < maxThreshold) {
39555
+ if (isLeaf) {
39556
+ obb2$2.min.copy(box.min);
39557
+ obb2$2.max.copy(box.max);
39558
+ obb2$2.needsUpdate = true;
39559
+ }
39560
+ return true;
39561
+ }
39562
+ return false;
39563
+ },
39564
+ intersectsRange: (offset, count) => {
39565
+ if (otherGeometry.boundsTree) {
39566
+ const otherBvh = otherGeometry.boundsTree;
39567
+ return otherBvh.shapecast({
39568
+ boundsTraverseOrder: (box) => {
39569
+ return obb2$2.distanceToBox(box);
39570
+ },
39571
+ intersectsBounds: (box, isLeaf, score) => {
39572
+ return score < closestDistance && score < maxThreshold;
39573
+ },
39574
+ intersectsRange: (otherOffset, otherCount) => {
39575
+ for (let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2++) {
39576
+ setTriangle(triangle22, 3 * i2, otherIndex, otherPos);
39577
+ triangle22.a.applyMatrix4(geometryToBvh);
39578
+ triangle22.b.applyMatrix4(geometryToBvh);
39579
+ triangle22.c.applyMatrix4(geometryToBvh);
39580
+ triangle22.needsUpdate = true;
39581
+ for (let i = offset, l = offset + count; i < l; i++) {
39582
+ setTriangle(triangle3, 3 * i, index, pos);
39583
+ triangle3.needsUpdate = true;
39584
+ const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
39585
+ if (dist < closestDistance) {
39586
+ tempTargetDest1.copy(tempTarget1);
39587
+ if (tempTargetDest2) {
39588
+ tempTargetDest2.copy(tempTarget2);
39589
+ }
39590
+ closestDistance = dist;
39591
+ closestDistanceTriIndex = i;
39592
+ closestDistanceOtherTriIndex = i2;
39593
+ }
39594
+ if (dist < minThreshold) {
39595
+ return true;
39596
+ }
39597
+ }
39598
+ }
39599
+ }
39600
+ });
39601
+ } else {
39602
+ const triCount = getTriCount(otherGeometry);
39603
+ for (let i2 = 0, l2 = triCount; i2 < l2; i2++) {
39604
+ setTriangle(triangle22, 3 * i2, otherIndex, otherPos);
39605
+ triangle22.a.applyMatrix4(geometryToBvh);
39606
+ triangle22.b.applyMatrix4(geometryToBvh);
39607
+ triangle22.c.applyMatrix4(geometryToBvh);
39608
+ triangle22.needsUpdate = true;
39609
+ for (let i = offset, l = offset + count; i < l; i++) {
39610
+ setTriangle(triangle3, 3 * i, index, pos);
39611
+ triangle3.needsUpdate = true;
39612
+ const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
39613
+ if (dist < closestDistance) {
39614
+ tempTargetDest1.copy(tempTarget1);
39615
+ if (tempTargetDest2) {
39616
+ tempTargetDest2.copy(tempTarget2);
39617
+ }
39618
+ closestDistance = dist;
39619
+ closestDistanceTriIndex = i;
39620
+ closestDistanceOtherTriIndex = i2;
39621
+ }
39622
+ if (dist < minThreshold) {
39623
+ return true;
39624
+ }
39625
+ }
39626
+ }
39627
+ }
39628
+ }
39629
+ }
39630
+ );
39631
+ ExtendedTrianglePool.releasePrimitive(triangle3);
39632
+ ExtendedTrianglePool.releasePrimitive(triangle22);
39633
+ if (closestDistance === Infinity) {
39634
+ return null;
39635
+ }
39636
+ if (!target1.point) {
39637
+ target1.point = tempTargetDest1.clone();
39638
+ } else {
39639
+ target1.point.copy(tempTargetDest1);
39640
+ }
39641
+ target1.distance = closestDistance, target1.faceIndex = closestDistanceTriIndex;
39642
+ if (target2) {
39643
+ if (!target2.point)
39644
+ target2.point = tempTargetDest2.clone();
39645
+ else
39646
+ target2.point.copy(tempTargetDest2);
39647
+ target2.point.applyMatrix4(tempMatrix$1);
39648
+ tempTargetDest1.applyMatrix4(tempMatrix$1);
39649
+ target2.distance = tempTargetDest1.sub(target2.point).length();
39650
+ target2.faceIndex = closestDistanceOtherTriIndex;
39651
+ }
39652
+ return target1;
39653
+ }
39654
+ function refit_indirect(bvh, nodeIndices = null) {
39655
+ if (nodeIndices && Array.isArray(nodeIndices)) {
39656
+ nodeIndices = new Set(nodeIndices);
39657
+ }
39658
+ const geometry = bvh.geometry;
39659
+ const indexArr = geometry.index ? geometry.index.array : null;
39660
+ const posAttr = geometry.attributes.position;
39661
+ let buffer, uint32Array, uint16Array, float32Array;
39662
+ let byteOffset = 0;
39663
+ const roots = bvh._roots;
39664
+ for (let i = 0, l = roots.length; i < l; i++) {
39665
+ buffer = roots[i];
39666
+ uint32Array = new Uint32Array(buffer);
39667
+ uint16Array = new Uint16Array(buffer);
39668
+ float32Array = new Float32Array(buffer);
39669
+ _traverse2(0, byteOffset);
39670
+ byteOffset += buffer.byteLength;
39671
+ }
39672
+ function _traverse2(node32Index, byteOffset2, force = false) {
39673
+ const node16Index = node32Index * 2;
39674
+ const isLeaf = uint16Array[node16Index + 15] === IS_LEAFNODE_FLAG;
39675
+ if (isLeaf) {
39676
+ const offset = uint32Array[node32Index + 6];
39677
+ const count = uint16Array[node16Index + 14];
39678
+ let minx = Infinity;
39679
+ let miny = Infinity;
39680
+ let minz = Infinity;
39681
+ let maxx = -Infinity;
39682
+ let maxy = -Infinity;
39683
+ let maxz = -Infinity;
39684
+ for (let i = offset, l = offset + count; i < l; i++) {
39685
+ const t2 = 3 * bvh.resolveTriangleIndex(i);
39686
+ for (let j = 0; j < 3; j++) {
39687
+ let index = t2 + j;
39688
+ index = indexArr ? indexArr[index] : index;
39689
+ const x2 = posAttr.getX(index);
39690
+ const y = posAttr.getY(index);
39691
+ const z = posAttr.getZ(index);
39692
+ if (x2 < minx)
39693
+ minx = x2;
39694
+ if (x2 > maxx)
39695
+ maxx = x2;
39696
+ if (y < miny)
39697
+ miny = y;
39698
+ if (y > maxy)
39699
+ maxy = y;
39700
+ if (z < minz)
39701
+ minz = z;
39702
+ if (z > maxz)
39703
+ maxz = z;
39704
+ }
39705
+ }
39706
+ if (float32Array[node32Index + 0] !== minx || float32Array[node32Index + 1] !== miny || float32Array[node32Index + 2] !== minz || float32Array[node32Index + 3] !== maxx || float32Array[node32Index + 4] !== maxy || float32Array[node32Index + 5] !== maxz) {
39707
+ float32Array[node32Index + 0] = minx;
39708
+ float32Array[node32Index + 1] = miny;
39709
+ float32Array[node32Index + 2] = minz;
39710
+ float32Array[node32Index + 3] = maxx;
39711
+ float32Array[node32Index + 4] = maxy;
39712
+ float32Array[node32Index + 5] = maxz;
39713
+ return true;
39714
+ } else {
39715
+ return false;
39716
+ }
39717
+ } else {
39718
+ const left = node32Index + 8;
39719
+ const right = uint32Array[node32Index + 6];
39720
+ const offsetLeft = left + byteOffset2;
39721
+ const offsetRight = right + byteOffset2;
39722
+ let forceChildren = force;
39723
+ let includesLeft = false;
39724
+ let includesRight = false;
39725
+ if (nodeIndices) {
39726
+ if (!forceChildren) {
39727
+ includesLeft = nodeIndices.has(offsetLeft);
39728
+ includesRight = nodeIndices.has(offsetRight);
39729
+ forceChildren = !includesLeft && !includesRight;
39730
+ }
39731
+ } else {
39732
+ includesLeft = true;
39733
+ includesRight = true;
39734
+ }
39735
+ const traverseLeft = forceChildren || includesLeft;
39736
+ const traverseRight = forceChildren || includesRight;
39737
+ let leftChange = false;
39738
+ if (traverseLeft) {
39739
+ leftChange = _traverse2(left, byteOffset2, forceChildren);
39740
+ }
39741
+ let rightChange = false;
39742
+ if (traverseRight) {
39743
+ rightChange = _traverse2(right, byteOffset2, forceChildren);
39744
+ }
39745
+ const didChange = leftChange || rightChange;
39746
+ if (didChange) {
39747
+ for (let i = 0; i < 3; i++) {
39748
+ const lefti = left + i;
39749
+ const righti = right + i;
39750
+ const minLeftValue = float32Array[lefti];
39751
+ const maxLeftValue = float32Array[lefti + 3];
39752
+ const minRightValue = float32Array[righti];
39753
+ const maxRightValue = float32Array[righti + 3];
39754
+ float32Array[node32Index + i] = minLeftValue < minRightValue ? minLeftValue : minRightValue;
39755
+ float32Array[node32Index + i + 3] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;
39756
+ }
39757
+ }
39758
+ return didChange;
39759
+ }
39760
+ }
39761
+ }
39762
+ const _boxIntersection$1 = /* @__PURE__ */ new Vector3();
39763
+ function raycast_indirect(bvh, root, side, ray, intersects) {
39764
+ BufferStack.setBuffer(bvh._roots[root]);
39765
+ _raycast(0, bvh, side, ray, intersects);
39766
+ BufferStack.clearBuffer();
39767
+ }
39768
+ function _raycast(nodeIndex32, bvh, side, ray, intersects) {
39769
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
39770
+ const nodeIndex16 = nodeIndex32 * 2;
39771
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
39772
+ if (isLeaf) {
39773
+ const offset = OFFSET(nodeIndex32, uint32Array);
39774
+ const count = COUNT(nodeIndex16, uint16Array);
39775
+ intersectTris_indirect(bvh, side, ray, offset, count, intersects);
39776
+ } else {
39777
+ const leftIndex = LEFT_NODE(nodeIndex32);
39778
+ if (intersectRay(leftIndex, float32Array, ray, _boxIntersection$1)) {
39779
+ _raycast(leftIndex, bvh, side, ray, intersects);
39780
+ }
39781
+ const rightIndex = RIGHT_NODE(nodeIndex32, uint32Array);
39782
+ if (intersectRay(rightIndex, float32Array, ray, _boxIntersection$1)) {
39783
+ _raycast(rightIndex, bvh, side, ray, intersects);
39784
+ }
39785
+ }
39786
+ }
39787
+ const _boxIntersection = /* @__PURE__ */ new Vector3();
39788
+ const _xyzFields = ["x", "y", "z"];
39789
+ function raycastFirst_indirect(bvh, root, side, ray) {
39790
+ BufferStack.setBuffer(bvh._roots[root]);
39791
+ const result = _raycastFirst(0, bvh, side, ray);
39792
+ BufferStack.clearBuffer();
39793
+ return result;
39794
+ }
39795
+ function _raycastFirst(nodeIndex32, bvh, side, ray) {
39796
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
39797
+ let nodeIndex16 = nodeIndex32 * 2;
39798
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
39799
+ if (isLeaf) {
39800
+ const offset = OFFSET(nodeIndex32, uint32Array);
39801
+ const count = COUNT(nodeIndex16, uint16Array);
39802
+ return intersectClosestTri_indirect(bvh, side, ray, offset, count);
39803
+ } else {
39804
+ const splitAxis = SPLIT_AXIS(nodeIndex32, uint32Array);
39805
+ const xyzAxis = _xyzFields[splitAxis];
39806
+ const rayDir = ray.direction[xyzAxis];
39807
+ const leftToRight = rayDir >= 0;
39808
+ let c1, c2;
39809
+ if (leftToRight) {
39810
+ c1 = LEFT_NODE(nodeIndex32);
39811
+ c2 = RIGHT_NODE(nodeIndex32, uint32Array);
39812
+ } else {
39813
+ c1 = RIGHT_NODE(nodeIndex32, uint32Array);
39814
+ c2 = LEFT_NODE(nodeIndex32);
39815
+ }
39816
+ const c1Intersection = intersectRay(c1, float32Array, ray, _boxIntersection);
39817
+ const c1Result = c1Intersection ? _raycastFirst(c1, bvh, side, ray) : null;
39818
+ if (c1Result) {
39819
+ const point = c1Result.point[xyzAxis];
39820
+ const isOutside = leftToRight ? point <= float32Array[c2 + splitAxis] : (
39821
+ // min bounding data
39822
+ point >= float32Array[c2 + splitAxis + 3]
39823
+ );
39824
+ if (isOutside) {
39825
+ return c1Result;
39826
+ }
39827
+ }
39828
+ const c2Intersection = intersectRay(c2, float32Array, ray, _boxIntersection);
39829
+ const c2Result = c2Intersection ? _raycastFirst(c2, bvh, side, ray) : null;
39830
+ if (c1Result && c2Result) {
39831
+ return c1Result.distance <= c2Result.distance ? c1Result : c2Result;
39832
+ } else {
39833
+ return c1Result || c2Result || null;
39834
+ }
39835
+ }
39836
+ }
39837
+ const boundingBox = /* @__PURE__ */ new Box3();
39838
+ const triangle = /* @__PURE__ */ new ExtendedTriangle();
39839
+ const triangle2 = /* @__PURE__ */ new ExtendedTriangle();
39840
+ const invertedMat = /* @__PURE__ */ new Matrix4();
39841
+ const obb$2 = /* @__PURE__ */ new OrientedBox();
39842
+ const obb2$1 = /* @__PURE__ */ new OrientedBox();
39843
+ function intersectsGeometry_indirect(bvh, root, otherGeometry, geometryToBvh) {
39844
+ BufferStack.setBuffer(bvh._roots[root]);
39845
+ const result = _intersectsGeometry(0, bvh, otherGeometry, geometryToBvh);
39846
+ BufferStack.clearBuffer();
39847
+ return result;
39848
+ }
39849
+ function _intersectsGeometry(nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null) {
39850
+ const { float32Array, uint16Array, uint32Array } = BufferStack;
39851
+ let nodeIndex16 = nodeIndex32 * 2;
39852
+ if (cachedObb === null) {
39853
+ if (!otherGeometry.boundingBox) {
39854
+ otherGeometry.computeBoundingBox();
39855
+ }
39856
+ obb$2.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
39857
+ cachedObb = obb$2;
39858
+ }
39859
+ const isLeaf = IS_LEAF(nodeIndex16, uint16Array);
39860
+ if (isLeaf) {
39861
+ const thisGeometry = bvh.geometry;
39862
+ const thisIndex = thisGeometry.index;
39863
+ const thisPos = thisGeometry.attributes.position;
39864
+ const index = otherGeometry.index;
39865
+ const pos = otherGeometry.attributes.position;
39866
+ const offset = OFFSET(nodeIndex32, uint32Array);
39867
+ const count = COUNT(nodeIndex16, uint16Array);
39868
+ invertedMat.copy(geometryToBvh).invert();
39869
+ if (otherGeometry.boundsTree) {
39870
+ arrayToBox(BOUNDING_DATA_INDEX(nodeIndex32), float32Array, obb2$1);
39871
+ obb2$1.matrix.copy(invertedMat);
39872
+ obb2$1.needsUpdate = true;
39873
+ const res = otherGeometry.boundsTree.shapecast({
39874
+ intersectsBounds: (box) => obb2$1.intersectsBox(box),
39875
+ intersectsTriangle: (tri) => {
39876
+ tri.a.applyMatrix4(geometryToBvh);
39877
+ tri.b.applyMatrix4(geometryToBvh);
39878
+ tri.c.applyMatrix4(geometryToBvh);
39879
+ tri.needsUpdate = true;
39880
+ for (let i = offset, l = count + offset; i < l; i++) {
39881
+ setTriangle(triangle2, 3 * bvh.resolveTriangleIndex(i), thisIndex, thisPos);
39882
+ triangle2.needsUpdate = true;
39883
+ if (tri.intersectsTriangle(triangle2)) {
39884
+ return true;
39885
+ }
39886
+ }
39887
+ return false;
39888
+ }
39889
+ });
39890
+ return res;
39891
+ } else {
39892
+ for (let i = offset, l = count + offset; i < l; i++) {
39893
+ const ti = bvh.resolveTriangleIndex(i);
39894
+ setTriangle(triangle, 3 * ti, thisIndex, thisPos);
39895
+ triangle.a.applyMatrix4(invertedMat);
39896
+ triangle.b.applyMatrix4(invertedMat);
39897
+ triangle.c.applyMatrix4(invertedMat);
39898
+ triangle.needsUpdate = true;
39899
+ for (let i2 = 0, l2 = index.count; i2 < l2; i2 += 3) {
39900
+ setTriangle(triangle2, i2, index, pos);
39901
+ triangle2.needsUpdate = true;
39902
+ if (triangle.intersectsTriangle(triangle2)) {
39903
+ return true;
39904
+ }
39905
+ }
39906
+ }
39907
+ }
39908
+ } else {
39909
+ const left = nodeIndex32 + 8;
39910
+ const right = uint32Array[nodeIndex32 + 6];
39911
+ arrayToBox(BOUNDING_DATA_INDEX(left), float32Array, boundingBox);
39912
+ const leftIntersection = cachedObb.intersectsBox(boundingBox) && _intersectsGeometry(left, bvh, otherGeometry, geometryToBvh, cachedObb);
39913
+ if (leftIntersection)
39914
+ return true;
39915
+ arrayToBox(BOUNDING_DATA_INDEX(right), float32Array, boundingBox);
39916
+ const rightIntersection = cachedObb.intersectsBox(boundingBox) && _intersectsGeometry(right, bvh, otherGeometry, geometryToBvh, cachedObb);
39917
+ if (rightIntersection)
39918
+ return true;
39919
+ return false;
39920
+ }
39921
+ }
39922
+ const tempMatrix = /* @__PURE__ */ new Matrix4();
39923
+ const obb$1 = /* @__PURE__ */ new OrientedBox();
39924
+ const obb2 = /* @__PURE__ */ new OrientedBox();
39925
+ const temp1 = /* @__PURE__ */ new Vector3();
39926
+ const temp2 = /* @__PURE__ */ new Vector3();
39927
+ const temp3 = /* @__PURE__ */ new Vector3();
39928
+ const temp4 = /* @__PURE__ */ new Vector3();
39929
+ function closestPointToGeometry_indirect(bvh, otherGeometry, geometryToBvh, target1 = {}, target2 = {}, minThreshold = 0, maxThreshold = Infinity) {
39930
+ if (!otherGeometry.boundingBox) {
39931
+ otherGeometry.computeBoundingBox();
39932
+ }
39933
+ obb$1.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
39934
+ obb$1.needsUpdate = true;
39935
+ const geometry = bvh.geometry;
39936
+ const pos = geometry.attributes.position;
39937
+ const index = geometry.index;
39938
+ const otherPos = otherGeometry.attributes.position;
39939
+ const otherIndex = otherGeometry.index;
39940
+ const triangle3 = ExtendedTrianglePool.getPrimitive();
39941
+ const triangle22 = ExtendedTrianglePool.getPrimitive();
39942
+ let tempTarget1 = temp1;
39943
+ let tempTargetDest1 = temp2;
39944
+ let tempTarget2 = null;
39945
+ let tempTargetDest2 = null;
39946
+ if (target2) {
39947
+ tempTarget2 = temp3;
39948
+ tempTargetDest2 = temp4;
39949
+ }
39950
+ let closestDistance = Infinity;
39951
+ let closestDistanceTriIndex = null;
39952
+ let closestDistanceOtherTriIndex = null;
39953
+ tempMatrix.copy(geometryToBvh).invert();
39954
+ obb2.matrix.copy(tempMatrix);
39955
+ bvh.shapecast(
39956
+ {
39957
+ boundsTraverseOrder: (box) => {
39958
+ return obb$1.distanceToBox(box);
39959
+ },
39960
+ intersectsBounds: (box, isLeaf, score) => {
39961
+ if (score < closestDistance && score < maxThreshold) {
39962
+ if (isLeaf) {
39963
+ obb2.min.copy(box.min);
39964
+ obb2.max.copy(box.max);
39965
+ obb2.needsUpdate = true;
39966
+ }
39967
+ return true;
39968
+ }
39969
+ return false;
39970
+ },
39971
+ intersectsRange: (offset, count) => {
39972
+ if (otherGeometry.boundsTree) {
39973
+ const otherBvh = otherGeometry.boundsTree;
39974
+ return otherBvh.shapecast({
39975
+ boundsTraverseOrder: (box) => {
39976
+ return obb2.distanceToBox(box);
39977
+ },
39978
+ intersectsBounds: (box, isLeaf, score) => {
39979
+ return score < closestDistance && score < maxThreshold;
39980
+ },
39981
+ intersectsRange: (otherOffset, otherCount) => {
39982
+ for (let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2++) {
39983
+ const ti2 = otherBvh.resolveTriangleIndex(i2);
39984
+ setTriangle(triangle22, 3 * ti2, otherIndex, otherPos);
39985
+ triangle22.a.applyMatrix4(geometryToBvh);
39986
+ triangle22.b.applyMatrix4(geometryToBvh);
39987
+ triangle22.c.applyMatrix4(geometryToBvh);
39988
+ triangle22.needsUpdate = true;
39989
+ for (let i = offset, l = offset + count; i < l; i++) {
39990
+ const ti = bvh.resolveTriangleIndex(i);
39991
+ setTriangle(triangle3, 3 * ti, index, pos);
39992
+ triangle3.needsUpdate = true;
39993
+ const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
39994
+ if (dist < closestDistance) {
39995
+ tempTargetDest1.copy(tempTarget1);
39996
+ if (tempTargetDest2) {
39997
+ tempTargetDest2.copy(tempTarget2);
39998
+ }
39999
+ closestDistance = dist;
40000
+ closestDistanceTriIndex = i;
40001
+ closestDistanceOtherTriIndex = i2;
40002
+ }
40003
+ if (dist < minThreshold) {
40004
+ return true;
40005
+ }
40006
+ }
40007
+ }
40008
+ }
40009
+ });
40010
+ } else {
40011
+ const triCount = getTriCount(otherGeometry);
40012
+ for (let i2 = 0, l2 = triCount; i2 < l2; i2++) {
40013
+ setTriangle(triangle22, 3 * i2, otherIndex, otherPos);
40014
+ triangle22.a.applyMatrix4(geometryToBvh);
40015
+ triangle22.b.applyMatrix4(geometryToBvh);
40016
+ triangle22.c.applyMatrix4(geometryToBvh);
40017
+ triangle22.needsUpdate = true;
40018
+ for (let i = offset, l = offset + count; i < l; i++) {
40019
+ const ti = bvh.resolveTriangleIndex(i);
40020
+ setTriangle(triangle3, 3 * ti, index, pos);
40021
+ triangle3.needsUpdate = true;
40022
+ const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
40023
+ if (dist < closestDistance) {
40024
+ tempTargetDest1.copy(tempTarget1);
40025
+ if (tempTargetDest2) {
40026
+ tempTargetDest2.copy(tempTarget2);
40027
+ }
40028
+ closestDistance = dist;
40029
+ closestDistanceTriIndex = i;
40030
+ closestDistanceOtherTriIndex = i2;
40031
+ }
40032
+ if (dist < minThreshold) {
40033
+ return true;
40034
+ }
40035
+ }
40036
+ }
40037
+ }
40038
+ }
40039
+ }
40040
+ );
40041
+ ExtendedTrianglePool.releasePrimitive(triangle3);
40042
+ ExtendedTrianglePool.releasePrimitive(triangle22);
40043
+ if (closestDistance === Infinity) {
40044
+ return null;
40045
+ }
40046
+ if (!target1.point) {
40047
+ target1.point = tempTargetDest1.clone();
40048
+ } else {
40049
+ target1.point.copy(tempTargetDest1);
40050
+ }
40051
+ target1.distance = closestDistance, target1.faceIndex = closestDistanceTriIndex;
40052
+ if (target2) {
40053
+ if (!target2.point)
40054
+ target2.point = tempTargetDest2.clone();
40055
+ else
40056
+ target2.point.copy(tempTargetDest2);
40057
+ target2.point.applyMatrix4(tempMatrix);
40058
+ tempTargetDest1.applyMatrix4(tempMatrix);
40059
+ target2.distance = tempTargetDest1.sub(target2.point).length();
40060
+ target2.faceIndex = closestDistanceOtherTriIndex;
40061
+ }
40062
+ return target1;
40063
+ }
40064
+ function isSharedArrayBufferSupported() {
40065
+ return typeof SharedArrayBuffer !== "undefined";
40066
+ }
40067
+ const _bufferStack1 = new BufferStack.constructor();
40068
+ const _bufferStack2 = new BufferStack.constructor();
40069
+ const _boxPool = new PrimitivePool(() => new Box3());
40070
+ const _leftBox1 = new Box3();
40071
+ const _rightBox1 = new Box3();
40072
+ const _leftBox2 = new Box3();
40073
+ const _rightBox2 = new Box3();
40074
+ let _active = false;
40075
+ function bvhcast(bvh, otherBvh, matrixToLocal, intersectsRanges) {
40076
+ if (_active) {
40077
+ throw new Error("MeshBVH: Recursive calls to bvhcast not supported.");
40078
+ }
40079
+ _active = true;
40080
+ const roots = bvh._roots;
40081
+ const otherRoots = otherBvh._roots;
40082
+ let result;
40083
+ let offset1 = 0;
40084
+ let offset2 = 0;
40085
+ const invMat = new Matrix4().copy(matrixToLocal).invert();
40086
+ for (let i = 0, il = roots.length; i < il; i++) {
40087
+ _bufferStack1.setBuffer(roots[i]);
40088
+ offset2 = 0;
40089
+ const localBox = _boxPool.getPrimitive();
40090
+ arrayToBox(BOUNDING_DATA_INDEX(0), _bufferStack1.float32Array, localBox);
40091
+ localBox.applyMatrix4(invMat);
40092
+ for (let j = 0, jl = otherRoots.length; j < jl; j++) {
40093
+ _bufferStack2.setBuffer(otherRoots[i]);
40094
+ result = _traverse(
40095
+ 0,
40096
+ 0,
40097
+ matrixToLocal,
40098
+ invMat,
40099
+ intersectsRanges,
40100
+ offset1,
40101
+ offset2,
40102
+ 0,
40103
+ 0,
40104
+ localBox
40105
+ );
40106
+ _bufferStack2.clearBuffer();
40107
+ offset2 += otherRoots[j].length;
40108
+ if (result) {
40109
+ break;
40110
+ }
40111
+ }
40112
+ _boxPool.releasePrimitive(localBox);
40113
+ _bufferStack1.clearBuffer();
40114
+ offset1 += roots[i].length;
40115
+ if (result) {
40116
+ break;
40117
+ }
40118
+ }
40119
+ _active = false;
40120
+ return result;
40121
+ }
40122
+ function _traverse(node1Index32, node2Index32, matrix2to1, matrix1to2, intersectsRangesFunc, node1IndexByteOffset = 0, node2IndexByteOffset = 0, depth1 = 0, depth2 = 0, currBox = null, reversed = false) {
40123
+ let bufferStack1, bufferStack2;
40124
+ if (reversed) {
40125
+ bufferStack1 = _bufferStack2;
40126
+ bufferStack2 = _bufferStack1;
40127
+ } else {
40128
+ bufferStack1 = _bufferStack1;
40129
+ bufferStack2 = _bufferStack2;
40130
+ }
40131
+ const float32Array1 = bufferStack1.float32Array, uint32Array1 = bufferStack1.uint32Array, uint16Array1 = bufferStack1.uint16Array, float32Array2 = bufferStack2.float32Array, uint32Array2 = bufferStack2.uint32Array, uint16Array2 = bufferStack2.uint16Array;
40132
+ const node1Index16 = node1Index32 * 2;
40133
+ const node2Index16 = node2Index32 * 2;
40134
+ const isLeaf1 = IS_LEAF(node1Index16, uint16Array1);
40135
+ const isLeaf2 = IS_LEAF(node2Index16, uint16Array2);
40136
+ let result = false;
40137
+ if (isLeaf2 && isLeaf1) {
40138
+ if (reversed) {
40139
+ result = intersectsRangesFunc(
40140
+ OFFSET(node2Index32, uint32Array2),
40141
+ COUNT(node2Index32 * 2, uint16Array2),
40142
+ OFFSET(node1Index32, uint32Array1),
40143
+ COUNT(node1Index32 * 2, uint16Array1),
40144
+ depth2,
40145
+ node2IndexByteOffset + node2Index32,
40146
+ depth1,
40147
+ node1IndexByteOffset + node1Index32
40148
+ );
40149
+ } else {
40150
+ result = intersectsRangesFunc(
40151
+ OFFSET(node1Index32, uint32Array1),
40152
+ COUNT(node1Index32 * 2, uint16Array1),
40153
+ OFFSET(node2Index32, uint32Array2),
40154
+ COUNT(node2Index32 * 2, uint16Array2),
40155
+ depth1,
40156
+ node1IndexByteOffset + node1Index32,
40157
+ depth2,
40158
+ node2IndexByteOffset + node2Index32
40159
+ );
40160
+ }
40161
+ } else if (isLeaf2) {
40162
+ const newBox = _boxPool.getPrimitive();
40163
+ arrayToBox(BOUNDING_DATA_INDEX(node2Index32), float32Array2, newBox);
40164
+ newBox.applyMatrix4(matrix2to1);
40165
+ const cl1 = LEFT_NODE(node1Index32);
40166
+ const cr1 = RIGHT_NODE(node1Index32, uint32Array1);
40167
+ arrayToBox(BOUNDING_DATA_INDEX(cl1), float32Array1, _leftBox1);
40168
+ arrayToBox(BOUNDING_DATA_INDEX(cr1), float32Array1, _rightBox1);
40169
+ const intersectCl1 = newBox.intersectsBox(_leftBox1);
40170
+ const intersectCr1 = newBox.intersectsBox(_rightBox1);
40171
+ result = intersectCl1 && _traverse(
40172
+ node2Index32,
40173
+ cl1,
40174
+ matrix1to2,
40175
+ matrix2to1,
40176
+ intersectsRangesFunc,
40177
+ node2IndexByteOffset,
40178
+ node1IndexByteOffset,
40179
+ depth2,
40180
+ depth1 + 1,
40181
+ newBox,
40182
+ !reversed
40183
+ ) || intersectCr1 && _traverse(
40184
+ node2Index32,
40185
+ cr1,
40186
+ matrix1to2,
40187
+ matrix2to1,
40188
+ intersectsRangesFunc,
40189
+ node2IndexByteOffset,
40190
+ node1IndexByteOffset,
40191
+ depth2,
40192
+ depth1 + 1,
40193
+ newBox,
40194
+ !reversed
40195
+ );
40196
+ _boxPool.releasePrimitive(newBox);
40197
+ } else {
40198
+ const cl2 = LEFT_NODE(node2Index32);
40199
+ const cr2 = RIGHT_NODE(node2Index32, uint32Array2);
40200
+ arrayToBox(BOUNDING_DATA_INDEX(cl2), float32Array2, _leftBox2);
40201
+ arrayToBox(BOUNDING_DATA_INDEX(cr2), float32Array2, _rightBox2);
40202
+ const leftIntersects = currBox.intersectsBox(_leftBox2);
40203
+ const rightIntersects = currBox.intersectsBox(_rightBox2);
40204
+ if (leftIntersects && rightIntersects) {
40205
+ result = _traverse(
40206
+ node1Index32,
40207
+ cl2,
40208
+ matrix2to1,
40209
+ matrix1to2,
40210
+ intersectsRangesFunc,
40211
+ node1IndexByteOffset,
40212
+ node2IndexByteOffset,
40213
+ depth1,
40214
+ depth2 + 1,
40215
+ currBox,
40216
+ reversed
40217
+ ) || _traverse(
40218
+ node1Index32,
40219
+ cr2,
40220
+ matrix2to1,
40221
+ matrix1to2,
40222
+ intersectsRangesFunc,
40223
+ node1IndexByteOffset,
40224
+ node2IndexByteOffset,
40225
+ depth1,
40226
+ depth2 + 1,
40227
+ currBox,
40228
+ reversed
40229
+ );
40230
+ } else if (leftIntersects) {
40231
+ if (isLeaf1) {
40232
+ result = _traverse(
40233
+ node1Index32,
40234
+ cl2,
40235
+ matrix2to1,
40236
+ matrix1to2,
40237
+ intersectsRangesFunc,
40238
+ node1IndexByteOffset,
40239
+ node2IndexByteOffset,
40240
+ depth1,
40241
+ depth2 + 1,
40242
+ currBox,
40243
+ reversed
40244
+ );
40245
+ } else {
40246
+ const newBox = _boxPool.getPrimitive();
40247
+ newBox.copy(_leftBox2).applyMatrix4(matrix2to1);
40248
+ const cl1 = LEFT_NODE(node1Index32);
40249
+ const cr1 = RIGHT_NODE(node1Index32, uint32Array1);
40250
+ arrayToBox(BOUNDING_DATA_INDEX(cl1), float32Array1, _leftBox1);
40251
+ arrayToBox(BOUNDING_DATA_INDEX(cr1), float32Array1, _rightBox1);
40252
+ const intersectCl1 = newBox.intersectsBox(_leftBox1);
40253
+ const intersectCr1 = newBox.intersectsBox(_rightBox1);
40254
+ result = intersectCl1 && _traverse(
40255
+ cl2,
40256
+ cl1,
40257
+ matrix1to2,
40258
+ matrix2to1,
40259
+ intersectsRangesFunc,
40260
+ node2IndexByteOffset,
40261
+ node1IndexByteOffset,
40262
+ depth2,
40263
+ depth1 + 1,
40264
+ newBox,
40265
+ !reversed
40266
+ ) || intersectCr1 && _traverse(
40267
+ cl2,
40268
+ cr1,
40269
+ matrix1to2,
40270
+ matrix2to1,
40271
+ intersectsRangesFunc,
40272
+ node2IndexByteOffset,
40273
+ node1IndexByteOffset,
40274
+ depth2,
40275
+ depth1 + 1,
40276
+ newBox,
40277
+ !reversed
40278
+ );
40279
+ _boxPool.releasePrimitive(newBox);
40280
+ }
40281
+ } else if (rightIntersects) {
40282
+ if (isLeaf1) {
40283
+ result = _traverse(
40284
+ node1Index32,
40285
+ cr2,
40286
+ matrix2to1,
40287
+ matrix1to2,
40288
+ intersectsRangesFunc,
40289
+ node1IndexByteOffset,
40290
+ node2IndexByteOffset,
40291
+ depth1,
40292
+ depth2 + 1,
40293
+ currBox,
40294
+ reversed
40295
+ );
40296
+ } else {
40297
+ const newBox = _boxPool.getPrimitive();
40298
+ newBox.copy(_rightBox2).applyMatrix4(matrix2to1);
40299
+ const cl1 = LEFT_NODE(node1Index32);
40300
+ const cr1 = RIGHT_NODE(node1Index32, uint32Array1);
40301
+ arrayToBox(BOUNDING_DATA_INDEX(cl1), float32Array1, _leftBox1);
40302
+ arrayToBox(BOUNDING_DATA_INDEX(cr1), float32Array1, _rightBox1);
40303
+ const intersectCl1 = newBox.intersectsBox(_leftBox1);
40304
+ const intersectCr1 = newBox.intersectsBox(_rightBox1);
40305
+ result = intersectCl1 && _traverse(
40306
+ cr2,
40307
+ cl1,
40308
+ matrix1to2,
40309
+ matrix2to1,
40310
+ intersectsRangesFunc,
40311
+ node2IndexByteOffset,
40312
+ node1IndexByteOffset,
40313
+ depth2,
40314
+ depth1 + 1,
40315
+ newBox,
40316
+ !reversed
40317
+ ) || intersectCr1 && _traverse(
40318
+ cr2,
40319
+ cr1,
40320
+ matrix1to2,
40321
+ matrix2to1,
40322
+ intersectsRangesFunc,
40323
+ node2IndexByteOffset,
40324
+ node1IndexByteOffset,
40325
+ depth2,
40326
+ depth1 + 1,
40327
+ newBox,
40328
+ !reversed
40329
+ );
40330
+ _boxPool.releasePrimitive(newBox);
40331
+ }
40332
+ }
40333
+ }
40334
+ return result;
40335
+ }
40336
+ const obb = /* @__PURE__ */ new OrientedBox();
40337
+ const tempBox = /* @__PURE__ */ new Box3();
40338
+ class MeshBVH {
40339
+ static serialize(bvh, options = {}) {
40340
+ options = {
40341
+ cloneBuffers: true,
40342
+ ...options
40343
+ };
40344
+ const geometry = bvh.geometry;
40345
+ const rootData = bvh._roots;
40346
+ const indirectBuffer = bvh._indirectBuffer;
40347
+ const indexAttribute = geometry.getIndex();
40348
+ let result;
40349
+ if (options.cloneBuffers) {
40350
+ result = {
40351
+ roots: rootData.map((root) => root.slice()),
40352
+ index: indexAttribute.array.slice(),
40353
+ indirectBuffer: indirectBuffer ? indirectBuffer.slice() : null
40354
+ };
40355
+ } else {
40356
+ result = {
40357
+ roots: rootData,
40358
+ index: indexAttribute.array,
40359
+ indirectBuffer
40360
+ };
40361
+ }
40362
+ return result;
40363
+ }
40364
+ static deserialize(data, geometry, options = {}) {
40365
+ options = {
40366
+ setIndex: true,
40367
+ indirect: Boolean(data.indirectBuffer),
40368
+ ...options
40369
+ };
40370
+ const { index, roots, indirectBuffer } = data;
40371
+ const bvh = new MeshBVH(geometry, { ...options, [SKIP_GENERATION]: true });
40372
+ bvh._roots = roots;
40373
+ bvh._indirectBuffer = indirectBuffer || null;
40374
+ if (options.setIndex) {
40375
+ const indexAttribute = geometry.getIndex();
40376
+ if (indexAttribute === null) {
40377
+ const newIndex = new BufferAttribute(data.index, 1, false);
40378
+ geometry.setIndex(newIndex);
40379
+ } else if (indexAttribute.array !== index) {
40380
+ indexAttribute.array.set(index);
40381
+ indexAttribute.needsUpdate = true;
40382
+ }
40383
+ }
40384
+ return bvh;
40385
+ }
40386
+ get indirect() {
40387
+ return !!this._indirectBuffer;
40388
+ }
40389
+ constructor(geometry, options = {}) {
40390
+ if (!geometry.isBufferGeometry) {
40391
+ throw new Error("MeshBVH: Only BufferGeometries are supported.");
40392
+ } else if (geometry.index && geometry.index.isInterleavedBufferAttribute) {
40393
+ throw new Error("MeshBVH: InterleavedBufferAttribute is not supported for the index attribute.");
40394
+ }
40395
+ options = Object.assign({
40396
+ strategy: CENTER,
40397
+ maxDepth: 40,
40398
+ maxLeafTris: 10,
40399
+ verbose: true,
40400
+ useSharedArrayBuffer: false,
40401
+ setBoundingBox: true,
40402
+ onProgress: null,
40403
+ indirect: false,
40404
+ // undocumented options
40405
+ // Whether to skip generating the tree. Used for deserialization.
40406
+ [SKIP_GENERATION]: false
40407
+ }, options);
40408
+ if (options.useSharedArrayBuffer && !isSharedArrayBufferSupported()) {
40409
+ throw new Error("MeshBVH: SharedArrayBuffer is not available.");
40410
+ }
40411
+ this.geometry = geometry;
40412
+ this._roots = null;
40413
+ this._indirectBuffer = null;
40414
+ if (!options[SKIP_GENERATION]) {
40415
+ buildPackedTree(this, options);
40416
+ if (!geometry.boundingBox && options.setBoundingBox) {
40417
+ geometry.boundingBox = this.getBoundingBox(new Box3());
40418
+ }
40419
+ }
40420
+ const { _indirectBuffer } = this;
40421
+ this.resolveTriangleIndex = options.indirect ? (i) => _indirectBuffer[i] : (i) => i;
40422
+ }
40423
+ refit(nodeIndices = null) {
40424
+ const refitFunc = this.indirect ? refit_indirect : refit;
40425
+ return refitFunc(this, nodeIndices);
40426
+ }
40427
+ traverse(callback, rootIndex = 0) {
40428
+ const buffer = this._roots[rootIndex];
40429
+ const uint32Array = new Uint32Array(buffer);
40430
+ const uint16Array = new Uint16Array(buffer);
40431
+ _traverse2(0);
40432
+ function _traverse2(node32Index, depth = 0) {
40433
+ const node16Index = node32Index * 2;
40434
+ const isLeaf = uint16Array[node16Index + 15] === IS_LEAFNODE_FLAG;
40435
+ if (isLeaf) {
40436
+ const offset = uint32Array[node32Index + 6];
40437
+ const count = uint16Array[node16Index + 14];
40438
+ callback(depth, isLeaf, new Float32Array(buffer, node32Index * 4, 6), offset, count);
40439
+ } else {
40440
+ const left = node32Index + BYTES_PER_NODE / 4;
40441
+ const right = uint32Array[node32Index + 6];
40442
+ const splitAxis = uint32Array[node32Index + 7];
40443
+ const stopTraversal = callback(depth, isLeaf, new Float32Array(buffer, node32Index * 4, 6), splitAxis);
40444
+ if (!stopTraversal) {
40445
+ _traverse2(left, depth + 1);
40446
+ _traverse2(right, depth + 1);
40447
+ }
40448
+ }
40449
+ }
40450
+ }
40451
+ /* Core Cast Functions */
40452
+ raycast(ray, materialOrSide = FrontSide) {
40453
+ const roots = this._roots;
40454
+ const geometry = this.geometry;
40455
+ const intersects = [];
40456
+ const isMaterial = materialOrSide.isMaterial;
40457
+ const isArrayMaterial = Array.isArray(materialOrSide);
40458
+ const groups = geometry.groups;
40459
+ const side = isMaterial ? materialOrSide.side : materialOrSide;
40460
+ const raycastFunc = this.indirect ? raycast_indirect : raycast;
40461
+ for (let i = 0, l = roots.length; i < l; i++) {
40462
+ const materialSide = isArrayMaterial ? materialOrSide[groups[i].materialIndex].side : side;
40463
+ const startCount = intersects.length;
40464
+ raycastFunc(this, i, materialSide, ray, intersects);
40465
+ if (isArrayMaterial) {
40466
+ const materialIndex = groups[i].materialIndex;
40467
+ for (let j = startCount, jl = intersects.length; j < jl; j++) {
40468
+ intersects[j].face.materialIndex = materialIndex;
40469
+ }
40470
+ }
40471
+ }
40472
+ return intersects;
40473
+ }
40474
+ raycastFirst(ray, materialOrSide = FrontSide) {
40475
+ const roots = this._roots;
40476
+ const geometry = this.geometry;
40477
+ const isMaterial = materialOrSide.isMaterial;
40478
+ const isArrayMaterial = Array.isArray(materialOrSide);
40479
+ let closestResult = null;
40480
+ const groups = geometry.groups;
40481
+ const side = isMaterial ? materialOrSide.side : materialOrSide;
40482
+ const raycastFirstFunc = this.indirect ? raycastFirst_indirect : raycastFirst;
40483
+ for (let i = 0, l = roots.length; i < l; i++) {
40484
+ const materialSide = isArrayMaterial ? materialOrSide[groups[i].materialIndex].side : side;
40485
+ const result = raycastFirstFunc(this, i, materialSide, ray);
40486
+ if (result != null && (closestResult == null || result.distance < closestResult.distance)) {
40487
+ closestResult = result;
40488
+ if (isArrayMaterial) {
40489
+ result.face.materialIndex = groups[i].materialIndex;
40490
+ }
40491
+ }
40492
+ }
40493
+ return closestResult;
40494
+ }
40495
+ intersectsGeometry(otherGeometry, geomToMesh) {
40496
+ let result = false;
40497
+ const roots = this._roots;
40498
+ const intersectsGeometryFunc = this.indirect ? intersectsGeometry_indirect : intersectsGeometry;
40499
+ for (let i = 0, l = roots.length; i < l; i++) {
40500
+ result = intersectsGeometryFunc(this, i, otherGeometry, geomToMesh);
40501
+ if (result) {
40502
+ break;
40503
+ }
40504
+ }
40505
+ return result;
40506
+ }
40507
+ shapecast(callbacks) {
40508
+ const triangle3 = ExtendedTrianglePool.getPrimitive();
40509
+ const iterateFunc = this.indirect ? iterateOverTriangles_indirect : iterateOverTriangles;
40510
+ let {
40511
+ boundsTraverseOrder,
40512
+ intersectsBounds,
40513
+ intersectsRange,
40514
+ intersectsTriangle
40515
+ } = callbacks;
40516
+ if (intersectsRange && intersectsTriangle) {
40517
+ const originalIntersectsRange = intersectsRange;
40518
+ intersectsRange = (offset, count, contained, depth, nodeIndex) => {
40519
+ if (!originalIntersectsRange(offset, count, contained, depth, nodeIndex)) {
40520
+ return iterateFunc(offset, count, this, intersectsTriangle, contained, depth, triangle3);
40521
+ }
40522
+ return true;
40523
+ };
40524
+ } else if (!intersectsRange) {
40525
+ if (intersectsTriangle) {
40526
+ intersectsRange = (offset, count, contained, depth) => {
40527
+ return iterateFunc(offset, count, this, intersectsTriangle, contained, depth, triangle3);
40528
+ };
40529
+ } else {
40530
+ intersectsRange = (offset, count, contained) => {
40531
+ return contained;
40532
+ };
40533
+ }
40534
+ }
40535
+ let result = false;
40536
+ let byteOffset = 0;
40537
+ const roots = this._roots;
40538
+ for (let i = 0, l = roots.length; i < l; i++) {
40539
+ const root = roots[i];
40540
+ result = shapecast(this, i, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset);
40541
+ if (result) {
40542
+ break;
40543
+ }
40544
+ byteOffset += root.byteLength;
40545
+ }
40546
+ ExtendedTrianglePool.releasePrimitive(triangle3);
40547
+ return result;
40548
+ }
40549
+ bvhcast(otherBvh, matrixToLocal, callbacks) {
40550
+ let {
40551
+ intersectsRanges,
40552
+ intersectsTriangles
40553
+ } = callbacks;
40554
+ const triangle1 = ExtendedTrianglePool.getPrimitive();
40555
+ const indexAttr1 = this.geometry.index;
40556
+ const positionAttr1 = this.geometry.attributes.position;
40557
+ const assignTriangle1 = this.indirect ? (i1) => {
40558
+ const ti = this.resolveTriangleIndex(i1);
40559
+ setTriangle(triangle1, ti * 3, indexAttr1, positionAttr1);
40560
+ } : (i1) => {
40561
+ setTriangle(triangle1, i1 * 3, indexAttr1, positionAttr1);
40562
+ };
40563
+ const triangle22 = ExtendedTrianglePool.getPrimitive();
40564
+ const indexAttr2 = otherBvh.geometry.index;
40565
+ const positionAttr2 = otherBvh.geometry.attributes.position;
40566
+ const assignTriangle2 = otherBvh.indirect ? (i2) => {
40567
+ const ti2 = otherBvh.resolveTriangleIndex(i2);
40568
+ setTriangle(triangle22, ti2 * 3, indexAttr2, positionAttr2);
40569
+ } : (i2) => {
40570
+ setTriangle(triangle22, i2 * 3, indexAttr2, positionAttr2);
40571
+ };
40572
+ if (intersectsTriangles) {
40573
+ const iterateOverDoubleTriangles = (offset1, count1, offset2, count2, depth1, index1, depth2, index2) => {
40574
+ for (let i2 = offset2, l2 = offset2 + count2; i2 < l2; i2++) {
40575
+ assignTriangle2(i2);
40576
+ triangle22.a.applyMatrix4(matrixToLocal);
40577
+ triangle22.b.applyMatrix4(matrixToLocal);
40578
+ triangle22.c.applyMatrix4(matrixToLocal);
40579
+ triangle22.needsUpdate = true;
40580
+ for (let i1 = offset1, l1 = offset1 + count1; i1 < l1; i1++) {
40581
+ assignTriangle1(i1);
40582
+ triangle1.needsUpdate = true;
40583
+ if (intersectsTriangles(triangle1, triangle22, i1, i2, depth1, index1, depth2, index2)) {
40584
+ return true;
40585
+ }
40586
+ }
40587
+ }
40588
+ return false;
40589
+ };
40590
+ if (intersectsRanges) {
40591
+ const originalIntersectsRanges = intersectsRanges;
40592
+ intersectsRanges = function(offset1, count1, offset2, count2, depth1, index1, depth2, index2) {
40593
+ if (!originalIntersectsRanges(offset1, count1, offset2, count2, depth1, index1, depth2, index2)) {
40594
+ return iterateOverDoubleTriangles(offset1, count1, offset2, count2, depth1, index1, depth2, index2);
40595
+ }
40596
+ return true;
40597
+ };
40598
+ } else {
40599
+ intersectsRanges = iterateOverDoubleTriangles;
40600
+ }
40601
+ }
40602
+ return bvhcast(this, otherBvh, matrixToLocal, intersectsRanges);
40603
+ }
40604
+ /* Derived Cast Functions */
40605
+ intersectsBox(box, boxToMesh) {
40606
+ obb.set(box.min, box.max, boxToMesh);
40607
+ obb.needsUpdate = true;
40608
+ return this.shapecast(
40609
+ {
40610
+ intersectsBounds: (box2) => obb.intersectsBox(box2),
40611
+ intersectsTriangle: (tri) => obb.intersectsTriangle(tri)
40612
+ }
40613
+ );
40614
+ }
40615
+ intersectsSphere(sphere) {
40616
+ return this.shapecast(
40617
+ {
40618
+ intersectsBounds: (box) => sphere.intersectsBox(box),
40619
+ intersectsTriangle: (tri) => tri.intersectsSphere(sphere)
40620
+ }
40621
+ );
40622
+ }
40623
+ closestPointToGeometry(otherGeometry, geometryToBvh, target1 = {}, target2 = {}, minThreshold = 0, maxThreshold = Infinity) {
40624
+ const closestPointToGeometryFunc = this.indirect ? closestPointToGeometry_indirect : closestPointToGeometry;
40625
+ return closestPointToGeometryFunc(
40626
+ this,
40627
+ otherGeometry,
40628
+ geometryToBvh,
40629
+ target1,
40630
+ target2,
40631
+ minThreshold,
40632
+ maxThreshold
40633
+ );
40634
+ }
40635
+ closestPointToPoint(point, target = {}, minThreshold = 0, maxThreshold = Infinity) {
40636
+ return closestPointToPoint(
40637
+ this,
40638
+ point,
40639
+ target,
40640
+ minThreshold,
40641
+ maxThreshold
40642
+ );
40643
+ }
40644
+ getBoundingBox(target) {
40645
+ target.makeEmpty();
40646
+ const roots = this._roots;
40647
+ roots.forEach((buffer) => {
40648
+ arrayToBox(0, new Float32Array(buffer), tempBox);
40649
+ target.union(tempBox);
40650
+ });
40651
+ return target;
40652
+ }
40653
+ }
40654
+ function countToStringFormat(count) {
40655
+ switch (count) {
40656
+ case 1:
40657
+ return "R";
40658
+ case 2:
40659
+ return "RG";
40660
+ case 3:
40661
+ return "RGBA";
40662
+ case 4:
40663
+ return "RGBA";
40664
+ }
40665
+ throw new Error();
40666
+ }
40667
+ function countToFormat(count) {
40668
+ switch (count) {
40669
+ case 1:
40670
+ return RedFormat;
40671
+ case 2:
40672
+ return RGFormat;
40673
+ case 3:
40674
+ return RGBAFormat;
40675
+ case 4:
40676
+ return RGBAFormat;
40677
+ }
40678
+ }
40679
+ function countToIntFormat(count) {
40680
+ switch (count) {
40681
+ case 1:
40682
+ return RedIntegerFormat;
40683
+ case 2:
40684
+ return RGIntegerFormat;
40685
+ case 3:
40686
+ return RGBAIntegerFormat;
40687
+ case 4:
40688
+ return RGBAIntegerFormat;
40689
+ }
40690
+ }
40691
+ class VertexAttributeTexture extends DataTexture {
40692
+ constructor() {
40693
+ super();
40694
+ this.minFilter = NearestFilter;
40695
+ this.magFilter = NearestFilter;
40696
+ this.generateMipmaps = false;
40697
+ this.overrideItemSize = null;
40698
+ this._forcedType = null;
40699
+ }
40700
+ updateFrom(attr) {
40701
+ const overrideItemSize = this.overrideItemSize;
40702
+ const originalItemSize = attr.itemSize;
40703
+ const originalCount = attr.count;
40704
+ if (overrideItemSize !== null) {
40705
+ if (originalItemSize * originalCount % overrideItemSize !== 0) {
40706
+ throw new Error("VertexAttributeTexture: overrideItemSize must divide evenly into buffer length.");
40707
+ }
40708
+ attr.itemSize = overrideItemSize;
40709
+ attr.count = originalCount * originalItemSize / overrideItemSize;
40710
+ }
40711
+ const itemSize = attr.itemSize;
40712
+ const count = attr.count;
40713
+ const normalized = attr.normalized;
40714
+ const originalBufferCons = attr.array.constructor;
40715
+ const byteCount = originalBufferCons.BYTES_PER_ELEMENT;
40716
+ let targetType = this._forcedType;
40717
+ let finalStride = itemSize;
40718
+ if (targetType === null) {
40719
+ switch (originalBufferCons) {
40720
+ case Float32Array:
40721
+ targetType = FloatType;
40722
+ break;
40723
+ case Uint8Array:
40724
+ case Uint16Array:
40725
+ case Uint32Array:
40726
+ targetType = UnsignedIntType;
40727
+ break;
40728
+ case Int8Array:
40729
+ case Int16Array:
40730
+ case Int32Array:
40731
+ targetType = IntType;
40732
+ break;
40733
+ }
40734
+ }
40735
+ let type, format, normalizeValue, targetBufferCons;
40736
+ let internalFormat = countToStringFormat(itemSize);
40737
+ switch (targetType) {
40738
+ case FloatType:
40739
+ normalizeValue = 1;
40740
+ format = countToFormat(itemSize);
40741
+ if (normalized && byteCount === 1) {
40742
+ targetBufferCons = originalBufferCons;
40743
+ internalFormat += "8";
40744
+ if (originalBufferCons === Uint8Array) {
40745
+ type = UnsignedByteType;
40746
+ } else {
40747
+ type = ByteType;
40748
+ internalFormat += "_SNORM";
40749
+ }
40750
+ } else {
40751
+ targetBufferCons = Float32Array;
40752
+ internalFormat += "32F";
40753
+ type = FloatType;
40754
+ }
40755
+ break;
40756
+ case IntType:
40757
+ internalFormat += byteCount * 8 + "I";
40758
+ normalizeValue = normalized ? Math.pow(2, originalBufferCons.BYTES_PER_ELEMENT * 8 - 1) : 1;
40759
+ format = countToIntFormat(itemSize);
40760
+ if (byteCount === 1) {
40761
+ targetBufferCons = Int8Array;
40762
+ type = ByteType;
40763
+ } else if (byteCount === 2) {
40764
+ targetBufferCons = Int16Array;
40765
+ type = ShortType;
40766
+ } else {
40767
+ targetBufferCons = Int32Array;
40768
+ type = IntType;
40769
+ }
40770
+ break;
40771
+ case UnsignedIntType:
40772
+ internalFormat += byteCount * 8 + "UI";
40773
+ normalizeValue = normalized ? Math.pow(2, originalBufferCons.BYTES_PER_ELEMENT * 8 - 1) : 1;
40774
+ format = countToIntFormat(itemSize);
40775
+ if (byteCount === 1) {
40776
+ targetBufferCons = Uint8Array;
40777
+ type = UnsignedByteType;
40778
+ } else if (byteCount === 2) {
40779
+ targetBufferCons = Uint16Array;
40780
+ type = UnsignedShortType;
40781
+ } else {
40782
+ targetBufferCons = Uint32Array;
40783
+ type = UnsignedIntType;
40784
+ }
40785
+ break;
40786
+ }
40787
+ if (finalStride === 3 && (format === RGBAFormat || format === RGBAIntegerFormat)) {
40788
+ finalStride = 4;
40789
+ }
40790
+ const dimension = Math.ceil(Math.sqrt(count));
40791
+ const length = finalStride * dimension * dimension;
40792
+ const dataArray = new targetBufferCons(length);
40793
+ const originalNormalized = attr.normalized;
40794
+ attr.normalized = false;
40795
+ for (let i = 0; i < count; i++) {
40796
+ const ii = finalStride * i;
40797
+ dataArray[ii] = attr.getX(i) / normalizeValue;
40798
+ if (itemSize >= 2) {
40799
+ dataArray[ii + 1] = attr.getY(i) / normalizeValue;
40800
+ }
40801
+ if (itemSize >= 3) {
40802
+ dataArray[ii + 2] = attr.getZ(i) / normalizeValue;
40803
+ if (finalStride === 4) {
40804
+ dataArray[ii + 3] = 1;
40805
+ }
40806
+ }
40807
+ if (itemSize >= 4) {
40808
+ dataArray[ii + 3] = attr.getW(i) / normalizeValue;
40809
+ }
40810
+ }
40811
+ attr.normalized = originalNormalized;
40812
+ this.internalFormat = internalFormat;
40813
+ this.format = format;
40814
+ this.type = type;
40815
+ this.image.width = dimension;
40816
+ this.image.height = dimension;
40817
+ this.image.data = dataArray;
40818
+ this.needsUpdate = true;
40819
+ this.dispose();
40820
+ attr.itemSize = originalItemSize;
40821
+ attr.count = originalCount;
40822
+ }
40823
+ }
40824
+ class UIntVertexAttributeTexture extends VertexAttributeTexture {
40825
+ constructor() {
40826
+ super();
40827
+ this._forcedType = UnsignedIntType;
40828
+ }
40829
+ }
40830
+ class FloatVertexAttributeTexture extends VertexAttributeTexture {
40831
+ constructor() {
40832
+ super();
40833
+ this._forcedType = FloatType;
40834
+ }
40835
+ }
40836
+ class MeshBVHUniformStruct {
40837
+ constructor() {
40838
+ this.index = new UIntVertexAttributeTexture();
40839
+ this.position = new FloatVertexAttributeTexture();
40840
+ this.bvhBounds = new DataTexture();
40841
+ this.bvhContents = new DataTexture();
40842
+ this._cachedIndexAttr = null;
40843
+ this.index.overrideItemSize = 3;
40844
+ }
40845
+ updateFrom(bvh) {
40846
+ const { geometry } = bvh;
40847
+ bvhToTextures(bvh, this.bvhBounds, this.bvhContents);
40848
+ this.position.updateFrom(geometry.attributes.position);
40849
+ if (bvh.indirect) {
40850
+ const indirectBuffer = bvh._indirectBuffer;
40851
+ if (this._cachedIndexAttr === null || this._cachedIndexAttr.count !== indirectBuffer.length) {
40852
+ if (geometry.index) {
40853
+ this._cachedIndexAttr = geometry.index.clone();
40854
+ } else {
40855
+ const array = getIndexArray(getVertexCount(geometry));
40856
+ this._cachedIndexAttr = new BufferAttribute(array, 1, false);
40857
+ }
40858
+ }
40859
+ dereferenceIndex(geometry, indirectBuffer, this._cachedIndexAttr);
40860
+ this.index.updateFrom(this._cachedIndexAttr);
40861
+ } else {
40862
+ this.index.updateFrom(geometry.index);
40863
+ }
40864
+ }
40865
+ dispose() {
40866
+ const { index, position, bvhBounds, bvhContents } = this;
40867
+ if (index)
40868
+ index.dispose();
40869
+ if (position)
40870
+ position.dispose();
40871
+ if (bvhBounds)
40872
+ bvhBounds.dispose();
40873
+ if (bvhContents)
40874
+ bvhContents.dispose();
40875
+ }
40876
+ }
40877
+ function dereferenceIndex(geometry, indirectBuffer, target) {
40878
+ const unpacked = target.array;
40879
+ const indexArray = geometry.index ? geometry.index.array : null;
40880
+ for (let i = 0, l = indirectBuffer.length; i < l; i++) {
40881
+ const i3 = 3 * i;
40882
+ const v3 = 3 * indirectBuffer[i];
40883
+ for (let c2 = 0; c2 < 3; c2++) {
40884
+ unpacked[i3 + c2] = indexArray ? indexArray[v3 + c2] : v3 + c2;
40885
+ }
40886
+ }
40887
+ }
40888
+ function bvhToTextures(bvh, boundsTexture, contentsTexture) {
40889
+ const roots = bvh._roots;
40890
+ if (roots.length !== 1) {
40891
+ throw new Error("MeshBVHUniformStruct: Multi-root BVHs not supported.");
40892
+ }
40893
+ const root = roots[0];
40894
+ const uint16Array = new Uint16Array(root);
40895
+ const uint32Array = new Uint32Array(root);
40896
+ const float32Array = new Float32Array(root);
40897
+ const nodeCount = root.byteLength / BYTES_PER_NODE;
40898
+ const boundsDimension = 2 * Math.ceil(Math.sqrt(nodeCount / 2));
40899
+ const boundsArray = new Float32Array(4 * boundsDimension * boundsDimension);
40900
+ const contentsDimension = Math.ceil(Math.sqrt(nodeCount));
40901
+ const contentsArray = new Uint32Array(2 * contentsDimension * contentsDimension);
40902
+ for (let i = 0; i < nodeCount; i++) {
40903
+ const nodeIndex32 = i * BYTES_PER_NODE / 4;
40904
+ const nodeIndex16 = nodeIndex32 * 2;
40905
+ const boundsIndex = BOUNDING_DATA_INDEX(nodeIndex32);
40906
+ for (let b = 0; b < 3; b++) {
40907
+ boundsArray[8 * i + 0 + b] = float32Array[boundsIndex + 0 + b];
40908
+ boundsArray[8 * i + 4 + b] = float32Array[boundsIndex + 3 + b];
40909
+ }
40910
+ if (IS_LEAF(nodeIndex16, uint16Array)) {
40911
+ const count = COUNT(nodeIndex16, uint16Array);
40912
+ const offset = OFFSET(nodeIndex32, uint32Array);
40913
+ const mergedLeafCount = 4294901760 | count;
40914
+ contentsArray[i * 2 + 0] = mergedLeafCount;
40915
+ contentsArray[i * 2 + 1] = offset;
40916
+ } else {
40917
+ const rightIndex = 4 * RIGHT_NODE(nodeIndex32, uint32Array) / BYTES_PER_NODE;
40918
+ const splitAxis = SPLIT_AXIS(nodeIndex32, uint32Array);
40919
+ contentsArray[i * 2 + 0] = splitAxis;
40920
+ contentsArray[i * 2 + 1] = rightIndex;
40921
+ }
40922
+ }
40923
+ boundsTexture.image.data = boundsArray;
40924
+ boundsTexture.image.width = boundsDimension;
40925
+ boundsTexture.image.height = boundsDimension;
40926
+ boundsTexture.format = RGBAFormat;
40927
+ boundsTexture.type = FloatType;
40928
+ boundsTexture.internalFormat = "RGBA32F";
40929
+ boundsTexture.minFilter = NearestFilter;
40930
+ boundsTexture.magFilter = NearestFilter;
40931
+ boundsTexture.generateMipmaps = false;
40932
+ boundsTexture.needsUpdate = true;
40933
+ boundsTexture.dispose();
40934
+ contentsTexture.image.data = contentsArray;
40935
+ contentsTexture.image.width = contentsDimension;
40936
+ contentsTexture.image.height = contentsDimension;
40937
+ contentsTexture.format = RGIntegerFormat;
40938
+ contentsTexture.type = UnsignedIntType;
40939
+ contentsTexture.internalFormat = "RG32UI";
40940
+ contentsTexture.minFilter = NearestFilter;
40941
+ contentsTexture.magFilter = NearestFilter;
40942
+ contentsTexture.generateMipmaps = false;
40943
+ contentsTexture.needsUpdate = true;
40944
+ contentsTexture.dispose();
40945
+ }
40946
+ const shaderStructs = (
40947
+ /* glsl */
40948
+ `
40949
+ #ifndef TRI_INTERSECT_EPSILON
40950
+ #define TRI_INTERSECT_EPSILON 1e-5
40951
+ #endif
40952
+
40953
+ #ifndef INFINITY
40954
+ #define INFINITY 1e20
40955
+ #endif
40956
+
40957
+ struct BVH {
40958
+
40959
+ usampler2D index;
40960
+ sampler2D position;
40961
+
40962
+ sampler2D bvhBounds;
40963
+ usampler2D bvhContents;
40964
+
40965
+ };
40966
+ `
40967
+ );
40968
+ const shaderIntersectFunction = (
40969
+ /* glsl */
40970
+ `
40971
+
40972
+ // Utilities
40973
+ uvec4 uTexelFetch1D( usampler2D tex, uint index ) {
40974
+
40975
+ uint width = uint( textureSize( tex, 0 ).x );
40976
+ uvec2 uv;
40977
+ uv.x = index % width;
40978
+ uv.y = index / width;
40979
+
40980
+ return texelFetch( tex, ivec2( uv ), 0 );
40981
+
40982
+ }
40983
+
40984
+ ivec4 iTexelFetch1D( isampler2D tex, uint index ) {
40985
+
40986
+ uint width = uint( textureSize( tex, 0 ).x );
40987
+ uvec2 uv;
40988
+ uv.x = index % width;
40989
+ uv.y = index / width;
40990
+
40991
+ return texelFetch( tex, ivec2( uv ), 0 );
40992
+
40993
+ }
40994
+
40995
+ vec4 texelFetch1D( sampler2D tex, uint index ) {
40996
+
40997
+ uint width = uint( textureSize( tex, 0 ).x );
40998
+ uvec2 uv;
40999
+ uv.x = index % width;
41000
+ uv.y = index / width;
41001
+
41002
+ return texelFetch( tex, ivec2( uv ), 0 );
41003
+
41004
+ }
41005
+
41006
+ vec4 textureSampleBarycoord( sampler2D tex, vec3 barycoord, uvec3 faceIndices ) {
41007
+
41008
+ return
41009
+ barycoord.x * texelFetch1D( tex, faceIndices.x ) +
41010
+ barycoord.y * texelFetch1D( tex, faceIndices.y ) +
41011
+ barycoord.z * texelFetch1D( tex, faceIndices.z );
41012
+
41013
+ }
41014
+
41015
+ void ndcToCameraRay(
41016
+ vec2 coord, mat4 cameraWorld, mat4 invProjectionMatrix,
41017
+ out vec3 rayOrigin, out vec3 rayDirection
41018
+ ) {
41019
+
41020
+ // get camera look direction and near plane for camera clipping
41021
+ vec4 lookDirection = cameraWorld * vec4( 0.0, 0.0, - 1.0, 0.0 );
41022
+ vec4 nearVector = invProjectionMatrix * vec4( 0.0, 0.0, - 1.0, 1.0 );
41023
+ float near = abs( nearVector.z / nearVector.w );
41024
+
41025
+ // get the camera direction and position from camera matrices
41026
+ vec4 origin = cameraWorld * vec4( 0.0, 0.0, 0.0, 1.0 );
41027
+ vec4 direction = invProjectionMatrix * vec4( coord, 0.5, 1.0 );
41028
+ direction /= direction.w;
41029
+ direction = cameraWorld * direction - origin;
41030
+
41031
+ // slide the origin along the ray until it sits at the near clip plane position
41032
+ origin.xyz += direction.xyz * near / dot( direction, lookDirection );
41033
+
41034
+ rayOrigin = origin.xyz;
41035
+ rayDirection = direction.xyz;
41036
+
41037
+ }
41038
+
41039
+ // Raycasting
41040
+ float intersectsBounds( vec3 rayOrigin, vec3 rayDirection, vec3 boundsMin, vec3 boundsMax ) {
41041
+
41042
+ // https://www.reddit.com/r/opengl/comments/8ntzz5/fast_glsl_ray_box_intersection/
41043
+ // https://tavianator.com/2011/ray_box.html
41044
+ vec3 invDir = 1.0 / rayDirection;
41045
+
41046
+ // find intersection distances for each plane
41047
+ vec3 tMinPlane = invDir * ( boundsMin - rayOrigin );
41048
+ vec3 tMaxPlane = invDir * ( boundsMax - rayOrigin );
41049
+
41050
+ // get the min and max distances from each intersection
41051
+ vec3 tMinHit = min( tMaxPlane, tMinPlane );
41052
+ vec3 tMaxHit = max( tMaxPlane, tMinPlane );
41053
+
41054
+ // get the furthest hit distance
41055
+ vec2 t = max( tMinHit.xx, tMinHit.yz );
41056
+ float t0 = max( t.x, t.y );
41057
+
41058
+ // get the minimum hit distance
41059
+ t = min( tMaxHit.xx, tMaxHit.yz );
41060
+ float t1 = min( t.x, t.y );
41061
+
41062
+ // set distance to 0.0 if the ray starts inside the box
41063
+ float dist = max( t0, 0.0 );
41064
+
41065
+ return t1 >= dist ? dist : INFINITY;
41066
+
41067
+ }
41068
+
41069
+ bool intersectsTriangle(
41070
+ vec3 rayOrigin, vec3 rayDirection, vec3 a, vec3 b, vec3 c,
41071
+ out vec3 barycoord, out vec3 norm, out float dist, out float side
41072
+ ) {
41073
+
41074
+ // https://stackoverflow.com/questions/42740765/intersection-between-line-and-triangle-in-3d
41075
+ vec3 edge1 = b - a;
41076
+ vec3 edge2 = c - a;
41077
+ norm = cross( edge1, edge2 );
41078
+
41079
+ float det = - dot( rayDirection, norm );
41080
+ float invdet = 1.0 / det;
41081
+
41082
+ vec3 AO = rayOrigin - a;
41083
+ vec3 DAO = cross( AO, rayDirection );
41084
+
41085
+ vec4 uvt;
41086
+ uvt.x = dot( edge2, DAO ) * invdet;
41087
+ uvt.y = - dot( edge1, DAO ) * invdet;
41088
+ uvt.z = dot( AO, norm ) * invdet;
41089
+ uvt.w = 1.0 - uvt.x - uvt.y;
41090
+
41091
+ // set the hit information
41092
+ barycoord = uvt.wxy; // arranged in A, B, C order
41093
+ dist = uvt.z;
41094
+ side = sign( det );
41095
+ norm = side * normalize( norm );
41096
+
41097
+ // add an epsilon to avoid misses between triangles
41098
+ uvt += vec4( TRI_INTERSECT_EPSILON );
41099
+
41100
+ return all( greaterThanEqual( uvt, vec4( 0.0 ) ) );
41101
+
41102
+ }
41103
+
41104
+ bool intersectTriangles(
41105
+ BVH bvh, vec3 rayOrigin, vec3 rayDirection, uint offset, uint count,
41106
+ inout float minDistance, inout uvec4 faceIndices, inout vec3 faceNormal, inout vec3 barycoord,
41107
+ inout float side, inout float dist
41108
+ ) {
41109
+
41110
+ bool found = false;
41111
+ vec3 localBarycoord, localNormal;
41112
+ float localDist, localSide;
41113
+ for ( uint i = offset, l = offset + count; i < l; i ++ ) {
41114
+
41115
+ uvec3 indices = uTexelFetch1D( bvh.index, i ).xyz;
41116
+ vec3 a = texelFetch1D( bvh.position, indices.x ).rgb;
41117
+ vec3 b = texelFetch1D( bvh.position, indices.y ).rgb;
41118
+ vec3 c = texelFetch1D( bvh.position, indices.z ).rgb;
41119
+
41120
+ if (
41121
+ intersectsTriangle( rayOrigin, rayDirection, a, b, c, localBarycoord, localNormal, localDist, localSide )
41122
+ && localDist < minDistance
41123
+ ) {
41124
+
41125
+ found = true;
41126
+ minDistance = localDist;
41127
+
41128
+ faceIndices = uvec4( indices.xyz, i );
41129
+ faceNormal = localNormal;
41130
+
41131
+ side = localSide;
41132
+ barycoord = localBarycoord;
41133
+ dist = localDist;
41134
+
41135
+ }
41136
+
41137
+ }
41138
+
41139
+ return found;
41140
+
41141
+ }
41142
+
41143
+ float intersectsBVHNodeBounds( vec3 rayOrigin, vec3 rayDirection, BVH bvh, uint currNodeIndex ) {
41144
+
41145
+ vec3 boundsMin = texelFetch1D( bvh.bvhBounds, currNodeIndex * 2u + 0u ).xyz;
41146
+ vec3 boundsMax = texelFetch1D( bvh.bvhBounds, currNodeIndex * 2u + 1u ).xyz;
41147
+ return intersectsBounds( rayOrigin, rayDirection, boundsMin, boundsMax );
41148
+
41149
+ }
41150
+
41151
+ bool bvhIntersectFirstHit(
41152
+ BVH bvh, vec3 rayOrigin, vec3 rayDirection,
41153
+
41154
+ // output variables
41155
+ inout uvec4 faceIndices, inout vec3 faceNormal, inout vec3 barycoord,
41156
+ inout float side, inout float dist
41157
+ ) {
41158
+
41159
+ // stack needs to be twice as long as the deepest tree we expect because
41160
+ // we push both the left and right child onto the stack every traversal
41161
+ int ptr = 0;
41162
+ uint stack[ 60 ];
41163
+ stack[ 0 ] = 0u;
41164
+
41165
+ float triangleDistance = 1e20;
41166
+ bool found = false;
41167
+ while ( ptr > - 1 && ptr < 60 ) {
41168
+
41169
+ uint currNodeIndex = stack[ ptr ];
41170
+ ptr --;
41171
+
41172
+ // check if we intersect the current bounds
41173
+ float boundsHitDistance = intersectsBVHNodeBounds( rayOrigin, rayDirection, bvh, currNodeIndex );
41174
+ if ( boundsHitDistance == INFINITY || boundsHitDistance > triangleDistance ) {
41175
+
41176
+ continue;
41177
+
41178
+ }
41179
+
41180
+ uvec2 boundsInfo = uTexelFetch1D( bvh.bvhContents, currNodeIndex ).xy;
41181
+ bool isLeaf = bool( boundsInfo.x & 0xffff0000u );
41182
+
41183
+ if ( isLeaf ) {
41184
+
41185
+ uint count = boundsInfo.x & 0x0000ffffu;
41186
+ uint offset = boundsInfo.y;
41187
+
41188
+ found = intersectTriangles(
41189
+ bvh, rayOrigin, rayDirection, offset, count, triangleDistance,
41190
+ faceIndices, faceNormal, barycoord, side, dist
41191
+ ) || found;
41192
+
41193
+ } else {
41194
+
41195
+ uint leftIndex = currNodeIndex + 1u;
41196
+ uint splitAxis = boundsInfo.x & 0x0000ffffu;
41197
+ uint rightIndex = boundsInfo.y;
41198
+
41199
+ bool leftToRight = rayDirection[ splitAxis ] >= 0.0;
41200
+ uint c1 = leftToRight ? leftIndex : rightIndex;
41201
+ uint c2 = leftToRight ? rightIndex : leftIndex;
41202
+
41203
+ // set c2 in the stack so we traverse it later. We need to keep track of a pointer in
41204
+ // the stack while we traverse. The second pointer added is the one that will be
41205
+ // traversed first
41206
+ ptr ++;
41207
+ stack[ ptr ] = c2;
41208
+
41209
+ ptr ++;
41210
+ stack[ ptr ] = c1;
41211
+
41212
+ }
41213
+
41214
+ }
41215
+
41216
+ return found;
41217
+
41218
+ }
41219
+ `
41220
+ );
41221
+ function shaderMaterial(uniforms, vertexShader, fragmentShader, onInit) {
41222
+ const material = class material extends ShaderMaterial {
41223
+ constructor(parameters = {}) {
41224
+ const entries = Object.entries(uniforms);
41225
+ super({
41226
+ uniforms: entries.reduce((acc, [name, value]) => {
41227
+ const uniform = UniformsUtils.clone({
41228
+ [name]: {
41229
+ value
41230
+ }
41231
+ });
41232
+ return {
41233
+ ...acc,
41234
+ ...uniform
41235
+ };
41236
+ }, {}),
41237
+ vertexShader,
41238
+ fragmentShader
41239
+ });
41240
+ this.key = "";
41241
+ entries.forEach(([name]) => Object.defineProperty(this, name, {
41242
+ get: () => this.uniforms[name].value,
41243
+ set: (v) => this.uniforms[name].value = v
41244
+ }));
41245
+ Object.assign(this, parameters);
41246
+ if (onInit)
41247
+ onInit(this);
41248
+ }
41249
+ };
41250
+ material.key = MathUtils.generateUUID();
41251
+ return material;
41252
+ }
41253
+ const getVersion = () => parseInt(REVISION.replace(/\D+/g, ""));
41254
+ const version = /* @__PURE__ */ getVersion();
41255
+ const MeshRefractionMaterial = /* @__PURE__ */ shaderMaterial(
41256
+ {
41257
+ envMap: null,
41258
+ bounces: 2,
41259
+ ior: 2.5,
41260
+ correctMips: true,
41261
+ aberrationStrength: 0.01,
41262
+ fresnel: 0.4,
41263
+ bvh: /* @__PURE__ */ new MeshBVHUniformStruct(),
41264
+ color: /* @__PURE__ */ new Color("white"),
41265
+ resolution: /* @__PURE__ */ new Vector2(),
41266
+ viewMatrixInverse: /* @__PURE__ */ new Matrix4(),
41267
+ projectionMatrixInverse: /* @__PURE__ */ new Matrix4()
41268
+ },
41269
+ /*glsl*/
41270
+ `
41271
+ uniform mat4 viewMatrixInverse;
41272
+
41273
+ varying vec3 vWorldPosition;
41274
+ varying vec3 vNormal;
41275
+ varying mat4 vModelMatrixInverse;
41276
+
41277
+ #ifdef USE_INSTANCING_COLOR
41278
+ varying vec3 vInstanceColor;
41279
+ #endif
41280
+
41281
+ void main() {
41282
+ vec4 transformedNormal = vec4(normal, 0.0);
41283
+ vec4 transformedPosition = vec4(position, 1.0);
41284
+ #ifdef USE_INSTANCING
41285
+ transformedNormal = instanceMatrix * transformedNormal;
41286
+ transformedPosition = instanceMatrix * transformedPosition;
41287
+ #endif
41288
+
41289
+ #ifdef USE_INSTANCING
41290
+ vModelMatrixInverse = inverse(modelMatrix * instanceMatrix);
41291
+ #else
41292
+ vModelMatrixInverse = inverse(modelMatrix);
41293
+ #endif
41294
+
41295
+ #ifdef USE_INSTANCING_COLOR
41296
+ vInstanceColor = instanceColor.rgb;
41297
+ #endif
41298
+
41299
+ vWorldPosition = (modelMatrix * transformedPosition).xyz;
41300
+ vNormal = normalize((viewMatrixInverse * vec4(normalMatrix * transformedNormal.xyz, 0.0)).xyz);
41301
+ gl_Position = projectionMatrix * viewMatrix * modelMatrix * transformedPosition;
41302
+ }`,
41303
+ /*glsl*/
41304
+ `
41305
+ #define ENVMAP_TYPE_CUBE_UV
41306
+ precision highp isampler2D;
41307
+ precision highp usampler2D;
41308
+ varying vec3 vWorldPosition;
41309
+ varying vec3 vNormal;
41310
+ varying mat4 vModelMatrixInverse;
41311
+
41312
+ #ifdef USE_INSTANCING_COLOR
41313
+ varying vec3 vInstanceColor;
41314
+ #endif
41315
+
41316
+ #ifdef ENVMAP_TYPE_CUBEM
41317
+ uniform samplerCube envMap;
41318
+ #else
41319
+ uniform sampler2D envMap;
41320
+ #endif
41321
+
41322
+ uniform float bounces;
41323
+ ${shaderStructs}
41324
+ ${shaderIntersectFunction}
41325
+ uniform BVH bvh;
41326
+ uniform float ior;
41327
+ uniform bool correctMips;
41328
+ uniform vec2 resolution;
41329
+ uniform float fresnel;
41330
+ uniform mat4 modelMatrix;
41331
+ uniform mat4 projectionMatrixInverse;
41332
+ uniform mat4 viewMatrixInverse;
41333
+ uniform float aberrationStrength;
41334
+ uniform vec3 color;
41335
+
41336
+ float fresnelFunc(vec3 viewDirection, vec3 worldNormal) {
41337
+ return pow( 1.0 + dot( viewDirection, worldNormal), 10.0 );
41338
+ }
41339
+
41340
+ vec3 totalInternalReflection(vec3 ro, vec3 rd, vec3 normal, float ior, mat4 modelMatrixInverse) {
41341
+ vec3 rayOrigin = ro;
41342
+ vec3 rayDirection = rd;
41343
+ rayDirection = refract(rayDirection, normal, 1.0 / ior);
41344
+ rayOrigin = vWorldPosition + rayDirection * 0.001;
41345
+ rayOrigin = (modelMatrixInverse * vec4(rayOrigin, 1.0)).xyz;
41346
+ rayDirection = normalize((modelMatrixInverse * vec4(rayDirection, 0.0)).xyz);
41347
+ for(float i = 0.0; i < bounces; i++) {
41348
+ uvec4 faceIndices = uvec4( 0u );
41349
+ vec3 faceNormal = vec3( 0.0, 0.0, 1.0 );
41350
+ vec3 barycoord = vec3( 0.0 );
41351
+ float side = 1.0;
41352
+ float dist = 0.0;
41353
+ bvhIntersectFirstHit( bvh, rayOrigin, rayDirection, faceIndices, faceNormal, barycoord, side, dist );
41354
+ vec3 hitPos = rayOrigin + rayDirection * max(dist - 0.001, 0.0);
41355
+ vec3 tempDir = refract(rayDirection, faceNormal, ior);
41356
+ if (length(tempDir) != 0.0) {
41357
+ rayDirection = tempDir;
41358
+ break;
41359
+ }
41360
+ rayDirection = reflect(rayDirection, faceNormal);
41361
+ rayOrigin = hitPos + rayDirection * 0.01;
41362
+ }
41363
+ rayDirection = normalize((modelMatrix * vec4(rayDirection, 0.0)).xyz);
41364
+ return rayDirection;
41365
+ }
41366
+
41367
+ #include <common>
41368
+ #include <cube_uv_reflection_fragment>
41369
+
41370
+ #ifdef ENVMAP_TYPE_CUBEM
41371
+ vec4 textureGradient(samplerCube envMap, vec3 rayDirection, vec3 directionCamPerfect) {
41372
+ return textureGrad(envMap, rayDirection, dFdx(correctMips ? directionCamPerfect: rayDirection), dFdy(correctMips ? directionCamPerfect: rayDirection));
41373
+ }
41374
+ #else
41375
+ vec4 textureGradient(sampler2D envMap, vec3 rayDirection, vec3 directionCamPerfect) {
41376
+ vec2 uvv = equirectUv( rayDirection );
41377
+ vec2 smoothUv = equirectUv( directionCamPerfect );
41378
+ return textureGrad(envMap, uvv, dFdx(correctMips ? smoothUv : uvv), dFdy(correctMips ? smoothUv : uvv));
41379
+ }
41380
+ #endif
41381
+
41382
+ void main() {
41383
+ vec2 uv = gl_FragCoord.xy / resolution;
41384
+ vec3 directionCamPerfect = (projectionMatrixInverse * vec4(uv * 2.0 - 1.0, 0.0, 1.0)).xyz;
41385
+ directionCamPerfect = (viewMatrixInverse * vec4(directionCamPerfect, 0.0)).xyz;
41386
+ directionCamPerfect = normalize(directionCamPerfect);
41387
+ vec3 normal = vNormal;
41388
+ vec3 rayOrigin = cameraPosition;
41389
+ vec3 rayDirection = normalize(vWorldPosition - cameraPosition);
41390
+ vec3 finalColor;
41391
+ #ifdef CHROMATIC_ABERRATIONS
41392
+ vec3 rayDirectionG = totalInternalReflection(rayOrigin, rayDirection, normal, max(ior, 1.0), vModelMatrixInverse);
41393
+ #ifdef FAST_CHROMA
41394
+ vec3 rayDirectionR = normalize(rayDirectionG + 1.0 * vec3(aberrationStrength / 2.0));
41395
+ vec3 rayDirectionB = normalize(rayDirectionG - 1.0 * vec3(aberrationStrength / 2.0));
41396
+ #else
41397
+ vec3 rayDirectionR = totalInternalReflection(rayOrigin, rayDirection, normal, max(ior * (1.0 - aberrationStrength), 1.0), vModelMatrixInverse);
41398
+ vec3 rayDirectionB = totalInternalReflection(rayOrigin, rayDirection, normal, max(ior * (1.0 + aberrationStrength), 1.0), vModelMatrixInverse);
41399
+ #endif
41400
+ float finalColorR = textureGradient(envMap, rayDirectionR, directionCamPerfect).r;
41401
+ float finalColorG = textureGradient(envMap, rayDirectionG, directionCamPerfect).g;
41402
+ float finalColorB = textureGradient(envMap, rayDirectionB, directionCamPerfect).b;
41403
+ finalColor = vec3(finalColorR, finalColorG, finalColorB);
41404
+ #else
41405
+ rayDirection = totalInternalReflection(rayOrigin, rayDirection, normal, max(ior, 1.0), vModelMatrixInverse);
41406
+ finalColor = textureGradient(envMap, rayDirection, directionCamPerfect).rgb;
41407
+ #endif
41408
+
41409
+ finalColor *= color;
41410
+ #ifdef USE_INSTANCING_COLOR
41411
+ finalColor *= vInstanceColor;
41412
+ #endif
41413
+
41414
+ vec3 viewDirection = normalize(vWorldPosition - cameraPosition);
41415
+ float nFresnel = fresnelFunc(viewDirection, normal) * fresnel;
41416
+ gl_FragColor = vec4(mix(finalColor, vec3(1.0), nFresnel), 1.0);
41417
+ #include <tonemapping_fragment>
41418
+ #include <${version >= 154 ? "colorspace_fragment" : "encodings_fragment"}>
41419
+ }`
41420
+ );
37285
41421
  let lensMaterial;
41422
+ let envMap;
37286
41423
  const positions = [0, 0.4, 0.7, 1];
37287
41424
  const opacities = [0.85, 0.62, 0.3, 0];
37288
41425
  const colors = [
@@ -37307,6 +41444,11 @@ var __publicField = (obj, key, value) => {
37307
41444
  opacities: { value: opacities }
37308
41445
  };
37309
41446
  document.getElementById("gui-container");
41447
+ const diamondMaterial = new MeshRefractionMaterial();
41448
+ const BLOOM_SCENE = 1;
41449
+ const bloomLayer = new Layers();
41450
+ bloomLayer.set(BLOOM_SCENE);
41451
+ new MeshBasicMaterial({ color: "black" });
37310
41452
  class CustomRenderer {
37311
41453
  // lensMaterial:THREE.MeshPhysicalMaterial| any
37312
41454
  constructor(apiService) {
@@ -37319,6 +41461,7 @@ var __publicField = (obj, key, value) => {
37319
41461
  this.scene = new Scene();
37320
41462
  }
37321
41463
  async intialize() {
41464
+ var _a;
37322
41465
  const newWidth = document.querySelector("canvas.sprie-config-webgl").clientWidth;
37323
41466
  const newHeight = document.querySelector("canvas.sprie-config-webgl").clientHeight;
37324
41467
  this.camera = new PerspectiveCamera(
@@ -37336,6 +41479,39 @@ var __publicField = (obj, key, value) => {
37336
41479
  });
37337
41480
  this.renderer.setSize(newWidth, newHeight);
37338
41481
  this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
41482
+ const rgbeLoader = new RGBELoader();
41483
+ rgbeLoader.load(
41484
+ "https://sprie-jarvis-public.s3.eu-west-2.amazonaws.com/royal_esplanade_1k_desaturated.hdr",
41485
+ (environmentMap) => {
41486
+ environmentMap.mapping = EquirectangularReflectionMapping;
41487
+ this.scene.environment = environmentMap;
41488
+ }
41489
+ );
41490
+ rgbeLoader.setPath("src/assets/").load("studio1.hdr", function(reflectionMap) {
41491
+ reflectionMap.mapping = EquirectangularReflectionMapping;
41492
+ diamondMaterial.uniforms.envMap.value = reflectionMap;
41493
+ envMap = reflectionMap;
41494
+ });
41495
+ const aberrationStrength = 0.01;
41496
+ const isCubeTexture = (def) => def && def.isCubeTexture;
41497
+ diamondMaterial.uniforms.aberrationStrength.value = aberrationStrength;
41498
+ diamondMaterial.uniforms.resolution.value = new Vector2(newWidth, newHeight);
41499
+ const temp5 = {};
41500
+ const isCubeMap = isCubeTexture(envMap);
41501
+ const w2 = (isCubeMap ? (_a = envMap == null ? void 0 : envMap.image[0]) == null ? void 0 : _a.width : envMap == null ? void 0 : envMap.image.width) ?? 1024;
41502
+ const cubeSize = w2 / 4;
41503
+ const _lodMax = Math.floor(Math.log2(cubeSize));
41504
+ const _cubeSize = Math.pow(2, _lodMax);
41505
+ const width = 3 * Math.max(_cubeSize, 16 * 7);
41506
+ const height = 4 * _cubeSize;
41507
+ if (isCubeMap)
41508
+ temp5.ENVMAP_TYPE_CUBEM = "";
41509
+ temp5.CUBEUV_TEXEL_WIDTH = `${1 / width}`;
41510
+ temp5.CUBEUV_TEXEL_HEIGHT = `${1 / height}`;
41511
+ temp5.CUBEUV_MAX_MIP = `${_lodMax}.0`;
41512
+ temp5.CHROMATIC_ABERRATIONS = "";
41513
+ temp5.FAST_CHROMA = "";
41514
+ diamondMaterial.defines = temp5;
37339
41515
  }
37340
41516
  cleanUp() {
37341
41517
  if (this.renderer) {
@@ -37395,6 +41571,7 @@ var __publicField = (obj, key, value) => {
37395
41571
  gltf.scene.traverse((node) => {
37396
41572
  if (node.isMesh) {
37397
41573
  bottom = Math.min(bottom, this.getMinY(node));
41574
+ console.log("node name", node.name);
37398
41575
  if (node.material && node.material.name == "Lenses") {
37399
41576
  let lowestY = Number.POSITIVE_INFINITY;
37400
41577
  let highestY = Number.NEGATIVE_INFINITY;
@@ -37453,7 +41630,7 @@ var __publicField = (obj, key, value) => {
37453
41630
  `
37454
41631
  )}
37455
41632
  `;
37456
- shader.fragmentShader = shader.fragmentShader = `uniform sampler2D uTexture;
41633
+ shader.fragmentShader = `uniform sampler2D uTexture;
37457
41634
  uniform vec2 resolution;
37458
41635
  uniform vec3 color;
37459
41636
  uniform bool uAlpha;
@@ -37499,6 +41676,14 @@ var __publicField = (obj, key, value) => {
37499
41676
  lensMaterial.needsUpdate = true;
37500
41677
  }
37501
41678
  }
41679
+ if (node.material && node.name === "Diamonds") {
41680
+ console.log("Diamond mesh detected");
41681
+ diamondMaterial.uniforms.bvh.value = new MeshBVHUniformStruct();
41682
+ diamondMaterial.uniforms.bvh.value.updateFrom(
41683
+ new MeshBVH(node.geometry.clone().toNonIndexed(), { strategy: SAH })
41684
+ );
41685
+ node.material = diamondMaterial;
41686
+ }
37502
41687
  }
37503
41688
  });
37504
41689
  let diff = targetY - bottom;
@@ -37735,7 +41920,6 @@ var __publicField = (obj, key, value) => {
37735
41920
  }
37736
41921
  setupLensMaterial(selectedLens) {
37737
41922
  if (lensMaterial) {
37738
- console.log(selectedLens);
37739
41923
  if (selectedLens.direction == "u") {
37740
41924
  lensMaterial.color = new Color(selectedLens.color);
37741
41925
  lensMaterial.opacity = selectedLens.opacity;
@@ -37766,17 +41950,6 @@ var __publicField = (obj, key, value) => {
37766
41950
  }
37767
41951
  }
37768
41952
  setupAndRenderScene() {
37769
- const rgbeLoader = new RGBELoader();
37770
- rgbeLoader.load(
37771
- "https://sprie-jarvis-public.s3.eu-west-2.amazonaws.com/royal_esplanade_1k_desaturated.hdr",
37772
- (environmentMap) => {
37773
- const pmremGenerator = new PMREMGenerator(this.renderer);
37774
- pmremGenerator.compileCubemapShader();
37775
- const hdrCubeRenderTarget = pmremGenerator.fromEquirectangular(environmentMap).texture;
37776
- this.scene.environment = hdrCubeRenderTarget;
37777
- pmremGenerator.dispose();
37778
- }
37779
- );
37780
41953
  if (!this.camera || !this.renderer)
37781
41954
  return;
37782
41955
  this.scene.add(this.camera);
@@ -37791,8 +41964,8 @@ var __publicField = (obj, key, value) => {
37791
41964
  2.2,
37792
41965
  4
37793
41966
  );
37794
- controls.minDistance = 2;
37795
- controls.maxDistance = 7;
41967
+ controls.minDistance = 1;
41968
+ controls.maxDistance = 5;
37796
41969
  controls.enableDamping = true;
37797
41970
  controls.dampingFactor = 0.2;
37798
41971
  controls.enablePan = true;
@@ -37802,6 +41975,7 @@ var __publicField = (obj, key, value) => {
37802
41975
  this.renderer.toneMapping = ACESFilmicToneMapping;
37803
41976
  this.renderer.toneMappingExposure = 1.2;
37804
41977
  this.renderer.setClearColor(15724527);
41978
+ this.renderer.outputColorSpace = SRGBColorSpace;
37805
41979
  const PLANE_WIDTH = 2.5;
37806
41980
  const PLANE_HEIGHT = 2.5;
37807
41981
  const CAMERA_HEIGHT = 0.4;
@@ -37893,11 +42067,11 @@ var __publicField = (obj, key, value) => {
37893
42067
  shadowCamera.updateProjectionMatrix();
37894
42068
  }
37895
42069
  const outputPass = new OutputPass();
37896
- const size = this.renderer.getDrawingBufferSize(new Vector2());
37897
- const renderTarget2 = new WebGLRenderTarget(size.width, size.height, { samples: 4, type: HalfFloatType });
37898
42070
  const renderPass = new RenderPass(this.scene, this.camera);
37899
42071
  renderPass.clearAlpha = 0;
37900
- let composer = new EffectComposer(this.renderer, renderTarget2);
42072
+ const size = this.renderer.getDrawingBufferSize(new Vector2());
42073
+ const renderTargetAA = new WebGLRenderTarget(size.width, size.height, { samples: 4, type: HalfFloatType });
42074
+ const composer = new EffectComposer(this.renderer, renderTargetAA);
37901
42075
  composer.addPass(renderPass);
37902
42076
  composer.addPass(outputPass);
37903
42077
  const animate = () => {
@@ -37918,6 +42092,8 @@ var __publicField = (obj, key, value) => {
37918
42092
  this.renderer.setRenderTarget(null);
37919
42093
  this.renderer.setClearAlpha(initialClearAlpha);
37920
42094
  this.scene.background = initialBackground;
42095
+ diamondMaterial.uniforms.viewMatrixInverse.value = this.camera.matrixWorld;
42096
+ diamondMaterial.uniforms.projectionMatrixInverse.value = this.camera.projectionMatrixInverse;
37921
42097
  requestAnimationFrame(animate);
37922
42098
  composer.render();
37923
42099
  };
@@ -46848,7 +51024,7 @@ var __publicField = (obj, key, value) => {
46848
51024
  log,
46849
51025
  logErr,
46850
51026
  metaData: {
46851
- appVersion: version,
51027
+ appVersion: version$1,
46852
51028
  previewUrlPrams,
46853
51029
  targetClassName: "sprie-embed-element"
46854
51030
  }