UNPKG

3d-tiles-renderer

Version:

https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification

1,686 lines 78.4 kB
import { B3DMLoaderBase as Ve, PNTSLoaderBase as Le, I3DMLoaderBase as We, CMPTLoaderBase as Ne, TilesRendererBase as ke } from "./index.core.js";
import { g as Be, r as He } from "./LoaderBase-CfTLVHyZ.js";
import { DefaultLoadingManager as At, Matrix4 as O, Vector3 as y, Vector2 as F, MathUtils as v, PointsMaterial as je, BufferGeometry as Ge, BufferAttribute as st, Color as Ze, Points as qe, InstancedMesh as Qe, Quaternion as it, Group as Pt, Ray as Ft, Sphere as $e, Frustum as Ye, Matrix3 as Xe, LoadingManager as Ke, EventDispatcher as mt, Euler as Je, Mesh as ti, PlaneGeometry as ei, ShaderMaterial as ii, Plane as ve, Raycaster as si, Clock as Te, PerspectiveCamera as Kt, OrthographicCamera as we } from "three";
import { GLTFLoader as Xt } from "three/examples/jsm/loaders/GLTFLoader.js";
import { W as vt, c as Jt, b as oi, e as ni, a as ri } from "./MemoryUtils-R1TfIs9h.js";
class De extends Ve {
  constructor(t = At) {
    super(), this.manager = t, this.adjustmentTransform = new O();
  }
  parse(t) {
    const e = super.parse(t), i = e.glbBytes.slice().buffer;
    return new Promise((s, o) => {
      const r = this.manager, n = this.fetchOptions, a = r.getHandler("path.gltf") || new Xt(r);
      n.credentials === "include" && n.mode === "cors" && a.setCrossOrigin("use-credentials"), "credentials" in n && a.setWithCredentials(n.credentials === "include"), n.headers && a.setRequestHeader(n.headers);
      let l = this.workingPath;
      !/[\\/]$/.test(l) && l.length && (l += "/");
      const h = this.adjustmentTransform;
      a.parse(i, l, (c) => {
        const { batchTable: p, featureTable: m } = e, { scene: u } = c, d = m.getData("RTC_CENTER", 1, "FLOAT", "VEC3");
        d && (u.position.x += d[0], u.position.y += d[1], u.position.z += d[2]), c.scene.updateMatrix(), c.scene.matrix.multiply(h), c.scene.matrix.decompose(c.scene.position, c.scene.quaternion, c.scene.scale), c.batchTable = p, c.featureTable = m, u.batchTable = p, u.featureTable = m, s(c);
      }, o);
    });
  }
}
function ai(f) {
  const t = f >> 11, e = f >> 5 & 63, i = f & 31, s = Math.round(t / 31 * 255), o = Math.round(e / 63 * 255), r = Math.round(i / 31 * 255);
  return [s, o, r];
}
const gt = /* @__PURE__ */ new F();
function ci(f, t, e = new y()) {
  gt.set(f, t).divideScalar(256).multiplyScalar(2).subScalar(1), e.set(gt.x, gt.y, 1 - Math.abs(gt.x) - Math.abs(gt.y));
  const i = v.clamp(-e.z, 0, 1);
  return e.x >= 0 ? e.setX(e.x - i) : e.setX(e.x + i), e.y >= 0 ? e.setY(e.y - i) : e.setY(e.y + i), e.normalize(), e;
}
const te = {
  RGB: "color",
  POSITION: "position"
};
class Ce extends Le {
  constructor(t = At) {
    super(), this.manager = t;
  }
  parse(t) {
    return super.parse(t).then(async (e) => {
      const { featureTable: i, batchTable: s } = e, o = new je(), r = i.header.extensions, n = new y();
      let a;
      if (r && r["3DTILES_draco_point_compression"]) {
        const { byteOffset: c, byteLength: p, properties: m } = r["3DTILES_draco_point_compression"], u = this.manager.getHandler("draco.drc");
        if (u == null)
          throw new Error("PNTSLoader: dracoLoader not available.");
        const d = {};
        for (const _ in m)
          if (_ in te && _ in m) {
            const U = te[_];
            d[U] = m[_];
          }
        const x = {
          attributeIDs: d,
          attributeTypes: {
            position: "Float32Array",
            color: "Uint8Array"
          },
          useUniqueIDs: !0
        }, E = i.getBuffer(c, p);
        a = await u.decodeGeometry(E, x), a.attributes.color && (o.vertexColors = !0);
      } else {
        const c = i.getData("POINTS_LENGTH"), p = i.getData("POSITION", c, "FLOAT", "VEC3"), m = i.getData("NORMAL", c, "FLOAT", "VEC3"), u = i.getData("NORMAL", c, "UNSIGNED_BYTE", "VEC2"), d = i.getData("RGB", c, "UNSIGNED_BYTE", "VEC3"), x = i.getData("RGBA", c, "UNSIGNED_BYTE", "VEC4"), E = i.getData("RGB565", c, "UNSIGNED_SHORT", "SCALAR"), _ = i.getData("CONSTANT_RGBA", c, "UNSIGNED_BYTE", "VEC4"), U = i.getData("POSITION_QUANTIZED", c, "UNSIGNED_SHORT", "VEC3"), g = i.getData("QUANTIZED_VOLUME_SCALE", c, "FLOAT", "VEC3"), C = i.getData("QUANTIZED_VOLUME_OFFSET", c, "FLOAT", "VEC3");
        if (a = new Ge(), U) {
          const S = new Float32Array(c * 3);
          for (let T = 0; T < c; T++)
            for (let V = 0; V < 3; V++) {
              const z = 3 * T + V;
              S[z] = U[z] / 65535 * g[V];
            }
          n.x = C[0], n.y = C[1], n.z = C[2], a.setAttribute("position", new st(S, 3, !1));
        } else
          a.setAttribute("position", new st(p, 3, !1));
        if (m !== null)
          a.setAttribute("normal", new st(m, 3, !1));
        else if (u !== null) {
          const S = new Float32Array(c * 3), T = new y();
          for (let V = 0; V < c; V++) {
            const z = u[V * 2], J = u[V * 2 + 1], at = ci(z, J, T);
            S[V * 3] = at.x, S[V * 3 + 1] = at.y, S[V * 3 + 2] = at.z;
          }
          a.setAttribute("normal", new st(S, 3, !1));
        }
        if (x !== null)
          a.setAttribute("color", new st(x, 4, !0)), o.vertexColors = !0, o.transparent = !0, o.depthWrite = !1;
        else if (d !== null)
          a.setAttribute("color", new st(d, 3, !0)), o.vertexColors = !0;
        else if (E !== null) {
          const S = new Uint8Array(c * 3);
          for (let T = 0; T < c; T++) {
            const V = ai(E[T]);
            for (let z = 0; z < 3; z++) {
              const J = 3 * T + z;
              S[J] = V[z];
            }
          }
          a.setAttribute("color", new st(S, 3, !0)), o.vertexColors = !0;
        } else if (_ !== null) {
          const S = new Ze(_[0], _[1], _[2]);
          o.color = S;
          const T = _[3] / 255;
          T < 1 && (o.opacity = T, o.transparent = !0, o.depthWrite = !1);
        }
      }
      const l = new qe(a, o);
      l.position.copy(n), e.scene = l, e.scene.featureTable = i, e.scene.batchTable = s;
      const h = i.getData("RTC_CENTER", 1, "FLOAT", "VEC3");
      return h && (e.scene.position.x += h[0], e.scene.position.y += h[1], e.scene.position.z += h[2]), e;
    });
  }
}
const ee = /* @__PURE__ */ new y(), Vt = /* @__PURE__ */ new y(), Lt = /* @__PURE__ */ new y(), Wt = /* @__PURE__ */ new y(), Nt = /* @__PURE__ */ new it(), Tt = /* @__PURE__ */ new y(), wt = /* @__PURE__ */ new O(), ie = /* @__PURE__ */ new O(), se = /* @__PURE__ */ new y(), oe = /* @__PURE__ */ new O(), kt = /* @__PURE__ */ new it(), Bt = {};
class Se extends We {
  constructor(t = At) {
    super(), this.manager = t, this.adjustmentTransform = new O(), this.ellipsoid = vt.clone();
  }
  resolveExternalURL(t) {
    return this.manager.resolveURL(super.resolveExternalURL(t));
  }
  parse(t) {
    return super.parse(t).then((e) => {
      const { featureTable: i, batchTable: s } = e, o = e.glbBytes.slice().buffer;
      return new Promise((r, n) => {
        const a = this.fetchOptions, l = this.manager, h = l.getHandler("path.gltf") || new Xt(l);
        a.credentials === "include" && a.mode === "cors" && h.setCrossOrigin("use-credentials"), "credentials" in a && h.setWithCredentials(a.credentials === "include"), a.headers && h.setRequestHeader(a.headers);
        let c = e.gltfWorkingPath ?? this.workingPath;
        /[\\/]$/.test(c) || (c += "/");
        const p = this.adjustmentTransform;
        h.parse(o, c, (m) => {
          const u = i.getData("INSTANCES_LENGTH");
          let d = i.getData("POSITION", u, "FLOAT", "VEC3");
          const x = i.getData("POSITION_QUANTIZED", u, "UNSIGNED_SHORT", "VEC3"), E = i.getData("QUANTIZED_VOLUME_OFFSET", 1, "FLOAT", "VEC3"), _ = i.getData("QUANTIZED_VOLUME_SCALE", 1, "FLOAT", "VEC3"), U = i.getData("NORMAL_UP", u, "FLOAT", "VEC3"), g = i.getData("NORMAL_RIGHT", u, "FLOAT", "VEC3"), C = i.getData("SCALE_NON_UNIFORM", u, "FLOAT", "VEC3"), S = i.getData("SCALE", u, "FLOAT", "SCALAR"), T = i.getData("RTC_CENTER", 1, "FLOAT", "VEC3"), V = i.getData("EAST_NORTH_UP");
          if ([
            "NORMAL_UP_OCT32P",
            "NORMAL_RIGHT_OCT32P"
          ].forEach((b) => {
            b in i.header && console.warn(`I3DMLoader: Unsupported FeatureTable feature "${b}" detected.`);
          }), !d && x) {
            d = new Float32Array(u * 3);
            for (let b = 0; b < u; b++)
              d[b * 3 + 0] = E[0] + x[b * 3 + 0] / 65535 * _[0], d[b * 3 + 1] = E[1] + x[b * 3 + 1] / 65535 * _[1], d[b * 3 + 2] = E[2] + x[b * 3 + 2] / 65535 * _[2];
          }
          const z = new y();
          for (let b = 0; b < u; b++)
            z.x += d[b * 3 + 0] / u, z.y += d[b * 3 + 1] / u, z.z += d[b * 3 + 2] / u;
          const J = [], at = [];
          m.scene.updateMatrixWorld(), m.scene.traverse((b) => {
            if (b.isMesh) {
              at.push(b);
              const { geometry: ct, material: Ut } = b, Z = new Qe(ct, Ut, u);
              Z.position.copy(z), T && (Z.position.x += T[0], Z.position.y += T[1], Z.position.z += T[2]), J.push(Z);
            }
          });
          for (let b = 0; b < u; b++) {
            Wt.set(
              d[b * 3 + 0] - z.x,
              d[b * 3 + 1] - z.y,
              d[b * 3 + 2] - z.z
            ), Nt.identity(), U && (Vt.set(
              U[b * 3 + 0],
              U[b * 3 + 1],
              U[b * 3 + 2]
            ), Lt.set(
              g[b * 3 + 0],
              g[b * 3 + 1],
              g[b * 3 + 2]
            ), ee.crossVectors(Lt, Vt).normalize(), wt.makeBasis(
              Lt,
              Vt,
              ee
            ), Nt.setFromRotationMatrix(wt)), Tt.set(1, 1, 1), C && Tt.set(
              C[b * 3 + 0],
              C[b * 3 + 1],
              C[b * 3 + 2]
            ), S && Tt.multiplyScalar(S[b]);
            for (let ct = 0, Ut = J.length; ct < Ut; ct++) {
              const Z = J[ct];
              kt.copy(Nt), V && (Z.updateMatrixWorld(), se.copy(Wt).applyMatrix4(Z.matrixWorld), this.ellipsoid.getPositionToCartographic(se, Bt), this.ellipsoid.getEastNorthUpFrame(Bt.lat, Bt.lon, oe), kt.setFromRotationMatrix(oe)), wt.compose(Wt, kt, Tt).multiply(p);
              const Ue = at[ct];
              ie.multiplyMatrices(wt, Ue.matrixWorld), Z.setMatrixAt(b, ie);
            }
          }
          m.scene.clear(), m.scene.add(...J), m.batchTable = s, m.featureTable = i, m.scene.batchTable = s, m.scene.featureTable = i, r(m);
        }, n);
      });
    });
  }
}
class li extends Ne {
  constructor(t = At) {
    super(), this.manager = t, this.adjustmentTransform = new O(), this.ellipsoid = vt.clone();
  }
  parse(t) {
    const e = super.parse(t), { manager: i, ellipsoid: s, adjustmentTransform: o } = this, r = [];
    for (const n in e.tiles) {
      const { type: a, buffer: l } = e.tiles[n];
      switch (a) {
        case "b3dm": {
          const h = l.slice(), c = new De(i);
          c.workingPath = this.workingPath, c.fetchOptions = this.fetchOptions, c.adjustmentTransform.copy(o);
          const p = c.parse(h.buffer);
          r.push(p);
          break;
        }
        case "pnts": {
          const h = l.slice(), c = new Ce(i);
          c.workingPath = this.workingPath, c.fetchOptions = this.fetchOptions;
          const p = c.parse(h.buffer);
          r.push(p);
          break;
        }
        case "i3dm": {
          const h = l.slice(), c = new Se(i);
          c.workingPath = this.workingPath, c.fetchOptions = this.fetchOptions, c.ellipsoid.copy(s), c.adjustmentTransform.copy(o);
          const p = c.parse(h.buffer);
          r.push(p);
          break;
        }
      }
    }
    return Promise.all(r).then((n) => {
      const a = new Pt();
      return n.forEach((l) => {
        a.add(l.scene);
      }), {
        tiles: n,
        scene: a
      };
    });
  }
}
const yt = /* @__PURE__ */ new O();
class hi extends Pt {
  constructor(t) {
    super(), this.isTilesGroup = !0, this.name = "TilesRenderer.TilesGroup", this.tilesRenderer = t, this.matrixWorldInverse = new O();
  }
  raycast(t, e) {
    return this.tilesRenderer.optimizeRaycast ? (this.tilesRenderer.raycast(t, e), !1) : !0;
  }
  updateMatrixWorld(t) {
    if (this.matrixAutoUpdate && this.updateMatrix(), this.matrixWorldNeedsUpdate || t) {
      this.parent === null ? yt.copy(this.matrix) : yt.multiplyMatrices(this.parent.matrixWorld, this.matrix), this.matrixWorldNeedsUpdate = !1;
      const e = yt.elements, i = this.matrixWorld.elements;
      let s = !1;
      for (let o = 0; o < 16; o++) {
        const r = e[o], n = i[o];
        if (Math.abs(r - n) > Number.EPSILON) {
          s = !0;
          break;
        }
      }
      if (s) {
        this.matrixWorld.copy(yt), this.matrixWorldInverse.copy(yt).invert();
        const o = this.children;
        for (let r = 0, n = o.length; r < n; r++)
          o[r].updateMatrixWorld();
      }
    }
  }
  updateWorldMatrix(t, e) {
    this.parent && t && this.parent.updateWorldMatrix(t, !1), this.updateMatrixWorld(!0);
  }
}
const Ee = /* @__PURE__ */ new Ft(), Ht = /* @__PURE__ */ new y(), Dt = [];
function Ie(f, t) {
  return f.distance - t.distance;
}
function Oe(f, t, e, i) {
  const { scene: s } = f.cached;
  e.invokeOnePlugin((r) => r.raycastTile && r.raycastTile(f, s, t, i)) || t.intersectObject(s, !0, i);
}
function pi(f, t, e) {
  Oe(f, t, e, Dt), Dt.sort(Ie);
  const i = Dt[0] || null;
  return Dt.length = 0, i;
}
function Re(f) {
  return "__used" in f;
}
function ze(f, t, e, i = null) {
  const { group: s, activeTiles: o } = f;
  i === null && (i = Ee, i.copy(e.ray).applyMatrix4(s.matrixWorldInverse));
  const r = [], n = t.children;
  for (let h = 0, c = n.length; h < c; h++) {
    const p = n[h];
    if (!Re(p) || !p.__used)
      continue;
    p.cached.boundingVolume.intersectRay(i, Ht) !== null && (Ht.applyMatrix4(s.matrixWorld), r.push({
      distance: Ht.distanceToSquared(e.ray.origin),
      tile: p
    }));
  }
  r.sort(Ie);
  let a = null, l = 1 / 0;
  if (o.has(t)) {
    const h = pi(t, e, f);
    h && (a = h, l = h.distance * h.distance);
  }
  for (let h = 0, c = r.length; h < c; h++) {
    const p = r[h], m = p.distance, u = p.tile;
    if (m > l)
      break;
    const d = ze(f, u, e, i);
    if (d) {
      const x = d.distance * d.distance;
      x < l && (a = d, l = x);
    }
  }
  return a;
}
function Ae(f, t, e, i, s = null) {
  if (!Re(t))
    return;
  const { group: o, activeTiles: r } = f, { boundingVolume: n } = t.cached;
  if (s === null && (s = Ee, s.copy(e.ray).applyMatrix4(o.matrixWorldInverse)), !t.__used || !n.intersectsRay(s))
    return;
  r.has(t) && Oe(t, e, f, i);
  const a = t.children;
  for (let l = 0, h = a.length; l < h; l++)
    Ae(f, a[l], e, i, s);
}
const q = /* @__PURE__ */ new y(), Q = /* @__PURE__ */ new y(), $ = /* @__PURE__ */ new y(), ne = /* @__PURE__ */ new y(), re = /* @__PURE__ */ new y();
class di {
  constructor() {
    this.sphere = null, this.obb = null, this.region = null, this.regionObb = null;
  }
  intersectsRay(t) {
    const e = this.sphere, i = this.obb || this.regionObb;
    return !(e && !t.intersectsSphere(e) || i && !i.intersectsRay(t));
  }
  intersectRay(t, e = null) {
    const i = this.sphere, s = this.obb || this.regionObb;
    let o = -1 / 0, r = -1 / 0;
    i && t.intersectSphere(i, ne) && (o = i.containsPoint(t.origin) ? 0 : t.origin.distanceToSquared(ne)), s && s.intersectRay(t, re) && (r = s.containsPoint(t.origin) ? 0 : t.origin.distanceToSquared(re));
    const n = Math.max(o, r);
    return n === -1 / 0 ? null : (t.at(Math.sqrt(n), e), e);
  }
  distanceToPoint(t) {
    const e = this.sphere, i = this.obb || this.regionObb;
    let s = -1 / 0, o = -1 / 0;
    return e && (s = Math.max(e.distanceToPoint(t), 0)), i && (o = i.distanceToPoint(t)), s > o ? s : o;
  }
  intersectsFrustum(t) {
    const e = this.obb || this.regionObb, i = this.sphere;
    return i && !t.intersectsSphere(i) || e && !e.intersectsFrustum(t) ? !1 : !!(i || e);
  }
  intersectsSphere(t) {
    const e = this.obb || this.regionObb, i = this.sphere;
    return i && !i.intersectsSphere(t) || e && !e.intersectsSphere(t) ? !1 : !!(i || e);
  }
  intersectsOBB(t) {
    const e = this.obb || this.regionObb, i = this.sphere;
    return i && !t.intersectsSphere(i) || e && !e.intersectsOBB(t) ? !1 : !!(i || e);
  }
  getOBB(t, e) {
    const i = this.obb || this.regionObb;
    i ? (t.copy(i.box), e.copy(i.transform)) : (this.getAABB(t), e.identity());
  }
  getAABB(t) {
    if (this.sphere)
      this.sphere.getBoundingBox(t);
    else {
      const e = this.obb || this.regionObb;
      t.copy(e.box).applyMatrix4(e.transform);
    }
  }
  getSphere(t) {
    if (this.sphere)
      t.copy(this.sphere);
    else if (this.region)
      this.region.getBoundingSphere(t);
    else {
      const e = this.obb || this.regionObb;
      e.box.getBoundingSphere(t), t.applyMatrix4(e.transform);
    }
  }
  setObbData(t, e) {
    const i = new Jt();
    q.set(t[3], t[4], t[5]), Q.set(t[6], t[7], t[8]), $.set(t[9], t[10], t[11]);
    const s = q.length(), o = Q.length(), r = $.length();
    q.normalize(), Q.normalize(), $.normalize(), s === 0 && q.crossVectors(Q, $), o === 0 && Q.crossVectors(q, $), r === 0 && $.crossVectors(q, Q), i.transform.set(
      q.x,
      Q.x,
      $.x,
      t[0],
      q.y,
      Q.y,
      $.y,
      t[1],
      q.z,
      Q.z,
      $.z,
      t[2],
      0,
      0,
      0,
      1
    ).premultiply(e), i.box.min.set(-s, -o, -r), i.box.max.set(s, o, r), i.update(), this.obb = i;
  }
  setSphereData(t, e, i, s, o) {
    const r = new $e();
    r.center.set(t, e, i), r.radius = s, r.applyMatrix4(o), this.sphere = r;
  }
  setRegionData(t, e, i, s, o, r, n) {
    const a = new oi(
      ...t.radius,
      i,
      o,
      e,
      s,
      r,
      n
    ), l = new Jt();
    a.getBoundingBox(l.box, l.transform), l.update(), this.region = a, this.regionObb = l;
  }
}
const ui = /* @__PURE__ */ new Xe();
function mi(f, t, e, i) {
  const s = ui.set(
    f.normal.x,
    f.normal.y,
    f.normal.z,
    t.normal.x,
    t.normal.y,
    t.normal.z,
    e.normal.x,
    e.normal.y,
    e.normal.z
  );
  return i.set(-f.constant, -t.constant, -e.constant), i.applyMatrix3(s.invert()), i;
}
class fi extends Ye {
  constructor() {
    super(), this.points = Array(8).fill().map(() => new y());
  }
  setFromProjectionMatrix(t, e) {
    return super.setFromProjectionMatrix(t, e), this.calculateFrustumPoints(), this;
  }
  calculateFrustumPoints() {
    const { planes: t, points: e } = this;
    [
      [t[0], t[3], t[4]],
      // Near top left
      [t[1], t[3], t[4]],
      // Near top right
      [t[0], t[2], t[4]],
      // Near bottom left
      [t[1], t[2], t[4]],
      // Near bottom right
      [t[0], t[3], t[5]],
      // Far top left
      [t[1], t[3], t[5]],
      // Far top right
      [t[0], t[2], t[5]],
      // Far bottom left
      [t[1], t[2], t[5]]
      // Far bottom right
    ].forEach((s, o) => {
      mi(s[0], s[1], s[2], e[o]);
    });
  }
}
const ae = /* @__PURE__ */ new O(), ce = /* @__PURE__ */ new Je(), Fe = Symbol("INITIAL_FRUSTUM_CULLED"), Ct = /* @__PURE__ */ new O(), xt = /* @__PURE__ */ new y(), jt = /* @__PURE__ */ new F(), lt = {
  inView: !1,
  error: 1 / 0
}, gi = /* @__PURE__ */ new y(1, 0, 0), yi = /* @__PURE__ */ new y(0, 1, 0);
function le(f, t) {
  f.traverse((e) => {
    e.frustumCulled = e[Fe] && t;
  });
}
class Ai extends ke {
  get autoDisableRendererCulling() {
    return this._autoDisableRendererCulling;
  }
  set autoDisableRendererCulling(t) {
    this._autoDisableRendererCulling !== t && (super._autoDisableRendererCulling = t, this.forEachLoadedModel((e) => {
      le(e, !t);
    }));
  }
  get optimizeRaycast() {
    return this._optimizeRaycast;
  }
  set optimizeRaycast(t) {
    console.warn('TilesRenderer: The "optimizeRaycast" option has been deprecated.'), this._optimizeRaycast = t;
  }
  constructor(...t) {
    super(...t), this.group = new hi(this), this.ellipsoid = vt.clone(), this.cameras = [], this.cameraMap = /* @__PURE__ */ new Map(), this.cameraInfo = [], this._optimizeRaycast = !0, this._upRotationMatrix = new O(), this._bytesUsed = /* @__PURE__ */ new WeakMap(), this._autoDisableRendererCulling = !0, this.manager = new Ke(), this._listeners = {};
  }
  addEventListener(t, e) {
    t === "load-tile-set" && (console.warn('TilesRenderer: "load-tile-set" event has been deprecated. Use "load-tileset" instead.'), t = "load-tileset"), mt.prototype.addEventListener.call(this, t, e);
  }
  hasEventListener(t, e) {
    return t === "load-tile-set" && (console.warn('TilesRenderer: "load-tile-set" event has been deprecated. Use "load-tileset" instead.'), t = "load-tileset"), mt.prototype.hasEventListener.call(this, t, e);
  }
  removeEventListener(t, e) {
    t === "load-tile-set" && (console.warn('TilesRenderer: "load-tile-set" event has been deprecated. Use "load-tileset" instead.'), t = "load-tileset"), mt.prototype.removeEventListener.call(this, t, e);
  }
  dispatchEvent(t) {
    "tileset" in t && Object.defineProperty(t, "tileSet", {
      get() {
        return console.warn('TilesRenderer: "event.tileSet" has been deprecated. Use "event.tileset" instead.'), t.tileset;
      },
      enumerable: !1,
      configurable: !0
    }), mt.prototype.dispatchEvent.call(this, t);
  }
  /* Public API */
  getBoundingBox(t) {
    if (!this.root)
      return !1;
    const e = this.root.cached.boundingVolume;
    return e ? (e.getAABB(t), !0) : !1;
  }
  getOrientedBoundingBox(t, e) {
    if (!this.root)
      return !1;
    const i = this.root.cached.boundingVolume;
    return i ? (i.getOBB(t, e), !0) : !1;
  }
  getBoundingSphere(t) {
    if (!this.root)
      return !1;
    const e = this.root.cached.boundingVolume;
    return e ? (e.getSphere(t), !0) : !1;
  }
  forEachLoadedModel(t) {
    this.traverse((e) => {
      const i = e.cached && e.cached.scene;
      i && t(i, e);
    }, null, !1);
  }
  raycast(t, e) {
    if (this.root)
      if (t.firstHitOnly) {
        const i = ze(this, this.root, t);
        i && e.push(i);
      } else
        Ae(this, this.root, t, e);
  }
  hasCamera(t) {
    return this.cameraMap.has(t);
  }
  setCamera(t) {
    const e = this.cameras, i = this.cameraMap;
    return i.has(t) ? !1 : (i.set(t, new F()), e.push(t), this.dispatchEvent({ type: "add-camera", camera: t }), !0);
  }
  setResolution(t, e, i) {
    const s = this.cameraMap;
    if (!s.has(t))
      return !1;
    const o = e.isVector2 ? e.x : e, r = e.isVector2 ? e.y : i, n = s.get(t);
    return (n.width !== o || n.height !== r) && (n.set(o, r), this.dispatchEvent({ type: "camera-resolution-change" })), !0;
  }
  setResolutionFromRenderer(t, e) {
    return e.getSize(jt), this.setResolution(t, jt.x, jt.y);
  }
  deleteCamera(t) {
    const e = this.cameras, i = this.cameraMap;
    if (i.has(t)) {
      const s = e.indexOf(t);
      return e.splice(s, 1), i.delete(t), this.dispatchEvent({ type: "delete-camera", camera: t }), !0;
    }
    return !1;
  }
  /* Overriden */
  loadRootTileset(...t) {
    return super.loadRootTileset(...t).then((e) => {
      const { asset: i, extensions: s = {} } = e;
      switch ((i && i.gltfUpAxis || "y").toLowerCase()) {
        case "x":
          this._upRotationMatrix.makeRotationAxis(yi, -Math.PI / 2);
          break;
        case "y":
          this._upRotationMatrix.makeRotationAxis(gi, Math.PI / 2);
          break;
      }
      if ("3DTILES_ellipsoid" in s) {
        const r = s["3DTILES_ellipsoid"], { ellipsoid: n } = this;
        n.name = r.body, r.radii ? n.radius.set(...r.radii) : n.radius.set(1, 1, 1);
      }
      return e;
    });
  }
  update() {
    let t = null;
    if (this.invokeAllPlugins((r) => {
      if (r.doTilesNeedUpdate) {
        const n = r.doTilesNeedUpdate();
        t === null ? t = n : t = !!(t || n);
      }
    }), t === !1) {
      this.dispatchEvent({ type: "update-before" }), this.dispatchEvent({ type: "update-after" });
      return;
    }
    this.dispatchEvent({ type: "update-before" });
    const e = this.group, i = this.cameras, s = this.cameraMap, o = this.cameraInfo;
    for (; o.length > i.length; )
      o.pop();
    for (; o.length < i.length; )
      o.push({
        frustum: new fi(),
        isOrthographic: !1,
        sseDenominator: -1,
        // used if isOrthographic:false
        position: new y(),
        invScale: -1,
        pixelSize: 0
        // used if isOrthographic:true
      });
    xt.setFromMatrixScale(e.matrixWorldInverse), Math.abs(Math.max(xt.x - xt.y, xt.x - xt.z)) > 1e-6 && console.warn("ThreeTilesRenderer : Non uniform scale used for tile which may cause issues when calculating screen space error.");
    for (let r = 0, n = o.length; r < n; r++) {
      const a = i[r], l = o[r], h = l.frustum, c = l.position, p = s.get(a);
      (p.width === 0 || p.height === 0) && console.warn("TilesRenderer: resolution for camera error calculation is not set.");
      const m = a.projectionMatrix.elements;
      if (l.isOrthographic = m[15] === 1, l.isOrthographic) {
        const u = 2 / m[0], d = 2 / m[5];
        l.pixelSize = Math.max(d / p.height, u / p.width);
      } else
        l.sseDenominator = 2 / m[5] / p.height;
      Ct.copy(e.matrixWorld), Ct.premultiply(a.matrixWorldInverse), Ct.premultiply(a.projectionMatrix), h.setFromProjectionMatrix(Ct), c.set(0, 0, 0), c.applyMatrix4(a.matrixWorld), c.applyMatrix4(e.matrixWorldInverse);
    }
    if (super.update(), this.dispatchEvent({ type: "update-after" }), i.length === 0 && this.root) {
      let r = !1;
      this.invokeAllPlugins((n) => r = r || !!(n !== this && n.calculateTileViewError)), r === !1 && console.warn("TilesRenderer: no cameras defined. Cannot update 3d tiles.");
    }
  }
  preprocessNode(t, e, i = null) {
    super.preprocessNode(t, e, i);
    const s = new O();
    if (t.transform) {
      const n = t.transform;
      for (let a = 0; a < 16; a++)
        s.elements[a] = n[a];
    }
    i && s.premultiply(i.cached.transform);
    const o = new O().copy(s).invert(), r = new di();
    "sphere" in t.boundingVolume && r.setSphereData(...t.boundingVolume.sphere, s), "box" in t.boundingVolume && r.setObbData(t.boundingVolume.box, s), "region" in t.boundingVolume && r.setRegionData(this.ellipsoid, ...t.boundingVolume.region), t.cached = {
      transform: s,
      transformInverse: o,
      active: !1,
      boundingVolume: r,
      metadata: null,
      scene: null,
      geometry: null,
      materials: null,
      textures: null
    };
  }
  async parseTile(t, e, i, s, o) {
    const r = e.cached, n = Be(s), a = this.fetchOptions, l = this.manager;
    let h = null;
    const c = r.transform, p = this._upRotationMatrix, m = (He(t) || i).toLowerCase();
    switch (m) {
      case "b3dm": {
        const g = new De(l);
        g.workingPath = n, g.fetchOptions = a, g.adjustmentTransform.copy(p), h = g.parse(t);
        break;
      }
      case "pnts": {
        const g = new Ce(l);
        g.workingPath = n, g.fetchOptions = a, h = g.parse(t);
        break;
      }
      case "i3dm": {
        const g = new Se(l);
        g.workingPath = n, g.fetchOptions = a, g.adjustmentTransform.copy(p), g.ellipsoid.copy(this.ellipsoid), h = g.parse(t);
        break;
      }
      case "cmpt": {
        const g = new li(l);
        g.workingPath = n, g.fetchOptions = a, g.adjustmentTransform.copy(p), g.ellipsoid.copy(this.ellipsoid), h = g.parse(t).then((C) => C.scene);
        break;
      }
      // 3DTILES_content_gltf
      case "gltf":
      case "glb": {
        const g = l.getHandler("path.gltf") || l.getHandler("path.glb") || new Xt(l);
        g.setWithCredentials(a.credentials === "include"), g.setRequestHeader(a.headers || {}), a.credentials === "include" && a.mode === "cors" && g.setCrossOrigin("use-credentials");
        let C = g.resourcePath || g.path || n;
        !/[\\/]$/.test(C) && C.length && (C += "/"), h = g.parseAsync(t, C).then((S) => {
          S.scene = S.scene || new Pt();
          const { scene: T } = S;
          return T.updateMatrix(), T.matrix.multiply(p).decompose(T.position, T.quaternion, T.scale), S;
        });
        break;
      }
      default: {
        h = this.invokeOnePlugin((g) => g.parseToMesh && g.parseToMesh(t, e, i, s, o));
        break;
      }
    }
    const u = await h;
    if (u === null)
      throw new Error(`TilesRenderer: Content type "${m}" not supported.`);
    let d, x;
    u.isObject3D ? (d = u, x = null) : (d = u.scene, x = u), d.updateMatrix(), d.matrix.premultiply(c), d.matrix.decompose(d.position, d.quaternion, d.scale), await this.invokeAllPlugins((g) => g.processTileModel && g.processTileModel(d, e)), d.traverse((g) => {
      g[Fe] = g.frustumCulled;
    }), le(d, !this.autoDisableRendererCulling);
    const E = [], _ = [], U = [];
    if (d.traverse((g) => {
      if (g.geometry && _.push(g.geometry), g.material) {
        const C = g.material;
        E.push(g.material);
        for (const S in C) {
          const T = C[S];
          T && T.isTexture && U.push(T);
        }
      }
    }), o.aborted) {
      for (let g = 0, C = U.length; g < C; g++) {
        const S = U[g];
        S.image instanceof ImageBitmap && S.image.close(), S.dispose();
      }
      return;
    }
    r.materials = E, r.geometry = _, r.textures = U, r.scene = d, r.metadata = x;
  }
  disposeTile(t) {
    super.disposeTile(t);
    const e = t.cached;
    if (e.scene) {
      const i = e.materials, s = e.geometry, o = e.textures, r = e.scene.parent;
      e.scene.traverse((n) => {
        n.userData.meshFeatures && n.userData.meshFeatures.dispose(), n.userData.structuralMetadata && n.userData.structuralMetadata.dispose();
      });
      for (let n = 0, a = s.length; n < a; n++)
        s[n].dispose();
      for (let n = 0, a = i.length; n < a; n++)
        i[n].dispose();
      for (let n = 0, a = o.length; n < a; n++) {
        const l = o[n];
        l.image instanceof ImageBitmap && l.image.close(), l.dispose();
      }
      r && r.remove(e.scene), this.dispatchEvent({
        type: "dispose-model",
        scene: e.scene,
        tile: t
      }), e.scene = null, e.materials = null, e.textures = null, e.geometry = null, e.metadata = null;
    }
  }
  setTileVisible(t, e) {
    const i = t.cached.scene, s = this.group;
    e ? i && (s.add(i), i.updateMatrixWorld(!0)) : i && s.remove(i), super.setTileVisible(t, e), this.dispatchEvent({
      type: "tile-visibility-change",
      scene: i,
      tile: t,
      visible: e
    });
  }
  calculateBytesUsed(t, e) {
    const i = this._bytesUsed;
    return !i.has(t) && e && i.set(t, ni(e)), i.get(t) ?? null;
  }
  calculateTileViewError(t, e) {
    const i = t.cached, s = this.cameras, o = this.cameraInfo, r = i.boundingVolume;
    let n = !1, a = -1 / 0, l = 1 / 0, h = -1 / 0, c = 1 / 0;
    for (let p = 0, m = s.length; p < m; p++) {
      const u = o[p];
      let d, x;
      if (u.isOrthographic) {
        const _ = u.pixelSize;
        d = t.geometricError / _, x = 1 / 0;
      } else {
        const _ = u.sseDenominator;
        x = r.distanceToPoint(u.position), d = x === 0 ? 1 / 0 : t.geometricError / (x * _);
      }
      const E = o[p].frustum;
      r.intersectsFrustum(E) && (n = !0, a = Math.max(a, d), l = Math.min(l, x)), h = Math.max(h, d), c = Math.min(c, x);
    }
    this.invokeAllPlugins((p) => {
      p !== this && p.calculateTileViewError && p.calculateTileViewError(t, lt) && (n = n && lt.inView, h = Math.max(h, lt.error), lt.inView && (a = Math.max(a, lt.error)));
    }), n ? (e.inView = !0, e.error = a, e.distanceFromCamera = l) : (e.inView = lt.inView, e.error = h, e.distanceFromCamera = c);
  }
  // adjust the rotation of the group such that Y is altitude, X is North, and Z is East
  setLatLonToYUp(t, e) {
    console.warn("TilesRenderer: setLatLonToYUp is deprecated. Use the ReorientationPlugin, instead.");
    const { ellipsoid: i, group: s } = this;
    ce.set(Math.PI / 2, Math.PI / 2, 0), ae.makeRotationFromEuler(ce), i.getEastNorthUpFrame(t, e, 0, s.matrix).multiply(ae).invert().decompose(
      s.position,
      s.quaternion,
      s.scale
    ), s.updateMatrixWorld(!0);
  }
  dispose() {
    super.dispose(), this.group.removeFromParent();
  }
}
class xi extends ti {
  constructor() {
    super(new ei(0, 0), new bi()), this.renderOrder = 1 / 0;
  }
  onBeforeRender(t) {
    const e = this.material.uniforms;
    t.getSize(e.resolution.value);
  }
  updateMatrixWorld() {
    this.matrixWorld.makeTranslation(this.position);
  }
  dispose() {
    this.geometry.dispose(), this.material.dispose();
  }
}
class bi extends ii {
  constructor() {
    super({
      depthWrite: !1,
      depthTest: !1,
      transparent: !0,
      uniforms: {
        resolution: { value: new F() },
        size: { value: 15 },
        thickness: { value: 2 },
        opacity: { value: 1 }
      },
      vertexShader: (
        /* glsl */
        `

				uniform float pixelRatio;
				uniform float size;
				uniform float thickness;
				uniform vec2 resolution;
				varying vec2 vUv;

				void main() {

					vUv = uv;

					float aspect = resolution.x / resolution.y;
					vec2 offset = uv * 2.0 - vec2( 1.0 );
					offset.y *= aspect;

					vec4 screenPoint = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
					screenPoint.xy += offset * ( size + thickness ) * screenPoint.w / resolution.x;

					gl_Position = screenPoint;

				}
			`
      ),
      fragmentShader: (
        /* glsl */
        `

				uniform float size;
				uniform float thickness;
				uniform float opacity;

				varying vec2 vUv;
				void main() {

					float ht = 0.5 * thickness;
					float planeDim = size + thickness;
					float offset = ( planeDim - ht - 2.0 ) / planeDim;
					float texelThickness = ht / planeDim;

					vec2 vec = vUv * 2.0 - vec2( 1.0 );
					float dist = abs( length( vec ) - offset );
					float fw = fwidth( dist ) * 0.5;
					float a = smoothstep( texelThickness - fw, texelThickness + fw, dist );

					gl_FragColor = vec4( 1, 1, 1, opacity * ( 1.0 - a ) );

				}
			`
      )
    });
  }
}
const he = /* @__PURE__ */ new F(), pe = /* @__PURE__ */ new F();
class Mi {
  constructor() {
    this.domElement = null, this.buttons = 0, this.pointerType = null, this.pointerOrder = [], this.previousPositions = {}, this.pointerPositions = {}, this.startPositions = {}, this.pointerSetThisFrame = {}, this.hoverPosition = new F(), this.hoverSet = !1;
  }
  reset() {
    this.buttons = 0, this.pointerType = null, this.pointerOrder = [], this.previousPositions = {}, this.pointerPositions = {}, this.startPositions = {}, this.pointerSetThisFrame = {}, this.hoverPosition = new F(), this.hoverSet = !1;
  }
  // The pointers can be set multiple times per frame so track whether the pointer has
  // been set this frame or not so we don't overwrite the previous position and lose information
  // about pointer movement
  updateFrame() {
    const { previousPositions: t, pointerPositions: e } = this;
    for (const i in e)
      t[i].copy(e[i]);
  }
  setHoverEvent(t) {
    (t.pointerType === "mouse" || t.type === "wheel") && (this.getAdjustedPointer(t, this.hoverPosition), this.hoverSet = !0);
  }
  getLatestPoint(t) {
    return this.pointerType !== null ? (this.getCenterPoint(t), t) : this.hoverSet ? (t.copy(this.hoverPosition), t) : null;
  }
  // get the pointer position in the coordinate system of the target element
  getAdjustedPointer(t, e) {
    const s = (this.domElement ? this.domElement : t.target).getBoundingClientRect(), o = t.clientX - s.left, r = t.clientY - s.top;
    e.set(o, r);
  }
  addPointer(t) {
    const e = t.pointerId, i = new F();
    this.getAdjustedPointer(t, i), this.pointerOrder.push(e), this.pointerPositions[e] = i, this.previousPositions[e] = i.clone(), this.startPositions[e] = i.clone(), this.getPointerCount() === 1 && (this.pointerType = t.pointerType, this.buttons = t.buttons);
  }
  updatePointer(t) {
    const e = t.pointerId;
    return e in this.pointerPositions ? (this.getAdjustedPointer(t, this.pointerPositions[e]), !0) : !1;
  }
  deletePointer(t) {
    const e = t.pointerId, i = this.pointerOrder;
    i.splice(i.indexOf(e), 1), delete this.pointerPositions[e], delete this.previousPositions[e], delete this.startPositions[e], this.getPointerCount() === 0 && (this.buttons = 0, this.pointerType = null);
  }
  getPointerCount() {
    return this.pointerOrder.length;
  }
  getCenterPoint(t, e = this.pointerPositions) {
    const i = this.pointerOrder;
    if (this.getPointerCount() === 1 || this.getPointerType() === "mouse") {
      const s = i[0];
      return t.copy(e[s]), t;
    } else if (this.getPointerCount() === 2) {
      const s = this.pointerOrder[0], o = this.pointerOrder[1], r = e[s], n = e[o];
      return t.addVectors(r, n).multiplyScalar(0.5), t;
    }
    return null;
  }
  getPreviousCenterPoint(t) {
    return this.getCenterPoint(t, this.previousPositions);
  }
  getStartCenterPoint(t) {
    return this.getCenterPoint(t, this.startPositions);
  }
  getMoveDistance() {
    return this.getCenterPoint(he), this.getPreviousCenterPoint(pe), he.sub(pe).length();
  }
  getTouchPointerDistance(t = this.pointerPositions) {
    if (this.getPointerCount() <= 1 || this.getPointerType() === "mouse")
      return 0;
    const { pointerOrder: e } = this, i = e[0], s = e[1], o = t[i], r = t[s];
    return o.distanceTo(r);
  }
  getPreviousTouchPointerDistance() {
    return this.getTouchPointerDistance(this.previousPositions);
  }
  getStartTouchPointerDistance() {
    return this.getTouchPointerDistance(this.startPositions);
  }
  getPointerType() {
    return this.pointerType;
  }
  isPointerTouch() {
    return this.getPointerType() === "touch";
  }
  getPointerButtons() {
    return this.buttons;
  }
  isLeftClicked() {
    return !!(this.buttons & 1);
  }
  isRightClicked() {
    return !!(this.buttons & 2);
  }
}
const St = /* @__PURE__ */ new O();
function ft(f, t, e) {
  return e.makeTranslation(-f.x, -f.y, -f.z), St.makeRotationFromQuaternion(t), e.premultiply(St), St.makeTranslation(f.x, f.y, f.z), e.premultiply(St), e;
}
function dt(f, t, e, i) {
  i.x = (f - e.offsetLeft) / e.clientWidth * 2 - 1, i.y = -((t - e.offsetTop) / e.clientHeight) * 2 + 1, i.isVector3 && (i.z = 0);
}
function H(f, t, e) {
  const i = f instanceof Ft ? f : f.ray, { origin: s, direction: o } = i;
  s.set(t.x, t.y, -1).unproject(e), o.set(t.x, t.y, 1).unproject(e).sub(s), f.isRay || (f.near = 0, f.far = o.length(), f.camera = e), o.normalize();
}
const G = 0, et = 1, Y = 2, ut = 3, Gt = 4, Zt = 0.05, qt = 0.025, tt = /* @__PURE__ */ new O(), Et = /* @__PURE__ */ new O(), W = /* @__PURE__ */ new y(), M = /* @__PURE__ */ new y(), It = /* @__PURE__ */ new y(), Ot = /* @__PURE__ */ new y(), A = /* @__PURE__ */ new y(), B = /* @__PURE__ */ new y(), Qt = /* @__PURE__ */ new y(), Rt = /* @__PURE__ */ new y(), j = /* @__PURE__ */ new it(), de = /* @__PURE__ */ new ve(), I = /* @__PURE__ */ new y(), zt = /* @__PURE__ */ new y(), $t = /* @__PURE__ */ new y(), _i = /* @__PURE__ */ new it(), w = /* @__PURE__ */ new Ft(), bt = /* @__PURE__ */ new F(), R = /* @__PURE__ */ new F(), ue = /* @__PURE__ */ new F(), Mt = /* @__PURE__ */ new F(), Yt = /* @__PURE__ */ new F(), me = /* @__PURE__ */ new F(), fe = { type: "change" }, ge = { type: "start" }, ye = { type: "end" };
class Pi extends mt {
  get enabled() {
    return this._enabled;
  }
  set enabled(t) {
    t !== this.enabled && (this._enabled = t, this.resetState(), this.pointerTracker.reset(), this.enabled || (this.dragInertia.set(0, 0, 0), this.rotationInertia.set(0, 0)));
  }
  constructor(t = null, e = null, i = null, s = null) {
    super(), this.isEnvironmentControls = !0, this.domElement = null, this.camera = null, this.scene = null, this.tilesRenderer = null, this._enabled = !0, this.cameraRadius = 5, this.rotationSpeed = 1, this.minAltitude = 0, this.maxAltitude = 0.45 * Math.PI, this.minDistance = 10, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.zoomSpeed = 1, this.adjustHeight = !0, this.enableDamping = !1, this.dampingFactor = 0.15, this.fallbackPlane = new ve(new y(0, 1, 0), 0), this.useFallbackPlane = !0, this.scaleZoomOrientationAtEdges = !1, this.autoAdjustCameraRotation = !0, this.state = G, this.pointerTracker = new Mi(), this.needsUpdate = !1, this.actionHeightOffset = 0, this.pivotPoint = new y(), this.zoomDirectionSet = !1, this.zoomPointSet = !1, this.zoomDirection = new y(), this.zoomPoint = new y(), this.zoomDelta = 0, this.rotationInertiaPivot = new y(), this.rotationInertia = new F(), this.dragInertia = new y(), this.inertiaTargetDistance = 1 / 0, this.inertiaStableFrames = 0, this.pivotMesh = new xi(), this.pivotMesh.raycast = () => {
    }, this.pivotMesh.scale.setScalar(0.25), this.raycaster = new si(), this.raycaster.firstHitOnly = !0, this.up = new y(0, 1, 0), this.clock = new Te(), this._detachCallback = null, this._upInitialized = !1, this._lastUsedState = G, this._zoomPointWasSet = !1, this._tilesOnChangeCallback = () => this.zoomPointSet = !1, i && this.attach(i), e && this.setCamera(e), t && this.setScene(t), s && this.setTilesRenderer(s);
  }
  setScene(t) {
    this.scene = t;
  }
  setCamera(t) {
    this.camera = t, this._upInitialized = !1, this.zoomDirectionSet = !1, this.zoomPointSet = !1, this.needsUpdate = !0, this.raycaster.camera = t, this.resetState();
  }
  setTilesRenderer(t) {
    console.warn('EnvironmentControls: "setTilesRenderer" has been deprecated. Use "setScene" and "setEllipsoid", instead.'), this.tilesRenderer = t, this.tilesRenderer !== null && this.setScene(this.tilesRenderer.group);
  }
  attach(t) {
    if (this.domElement)
      throw new Error("EnvironmentControls: Controls already attached to element");
    this.domElement = t, this.pointerTracker.domElement = t, t.style.touchAction = "none";
    const e = (h) => {
      this.enabled && h.preventDefault();
    }, i = (h) => {
      if (!this.enabled)
        return;
      h.preventDefault();
      const {
        camera: c,
        raycaster: p,
        domElement: m,
        up: u,
        pivotMesh: d,
        pointerTracker: x,
        scene: E,
        pivotPoint: _,
        enabled: U
      } = this;
      if (x.addPointer(h), this.needsUpdate = !0, x.isPointerTouch()) {
        if (d.visible = !1, x.getPointerCount() === 0)
          m.setPointerCapture(h.pointerId);
        else if (x.getPointerCount() > 2) {
          this.resetState();
          return;
        }
      }
      x.getCenterPoint(R), dt(R.x, R.y, m, R), H(p, R, c);
      const g = Math.abs(p.ray.direction.dot(u));
      if (g < Zt || g < qt)
        return;
      const C = this._raycast(p);
      C && (x.getPointerCount() === 2 || x.isRightClicked() || x.isLeftClicked() && h.shiftKey ? (this.setState(x.isPointerTouch() ? Gt : Y), _.copy(C.point), d.position.copy(C.point), d.visible = x.isPointerTouch() ? !1 : U, d.updateMatrixWorld(), E.add(d)) : x.isLeftClicked() && (this.setState(et), _.copy(C.point), d.position.copy(C.point), d.updateMatrixWorld(), E.add(d)));
    };
    let s = !1;
    const o = (h) => {
      const { pointerTracker: c } = this;
      if (!this.enabled)
        return;
      h.preventDefault();
      const {
        pivotMesh: p,
        enabled: m
      } = this;
      this.zoomDirectionSet = !1, this.zoomPointSet = !1, this.state !== G && (this.needsUpdate = !0), c.setHoverEvent(h), c.updatePointer(h) && (c.isPointerTouch() && c.getPointerCount() === 2 && (s || (s = !0, queueMicrotask(() => {
        s = !1, c.getCenterPoint(Yt);
        const u = c.getStartTouchPointerDistance(), d = c.getTouchPointerDistance(), x = d - u;
        if (this.state === G || this.state === Gt) {
          c.getCenterPoint(Yt), c.getStartCenterPoint(me);
          const E = 2 * window.devicePixelRatio, _ = Yt.distanceTo(me);
          (Math.abs(x) > E || _ > E) && (Math.abs(x) > _ ? (this.setState(ut), this.zoomDirectionSet = !1) : this.setState(Y));
        }
        if (this.state === ut) {
          const E = c.getPreviousTouchPointerDistance();
          this.zoomDelta += d - E, p.visible = !1;
        } else this.state === Y && (p.visible = m);
      }))), this.dispatchEvent(fe));
    }, r = (h) => {
      const { pointerTracker: c } = this;
      !this.enabled || c.getPointerCount() === 0 || (c.deletePointer(h), c.getPointerType() === "touch" && c.getPointerCount() === 0 && t.releasePointerCapture(h.pointerId), this.resetState(), this.needsUpdate = !0);
    }, n = (h) => {
      if (!this.enabled)
        return;
      h.preventDefault();
      const { pointerTracker: c } = this;
      c.setHoverEvent(h), c.updatePointer(h), this.dispatchEvent(ge);
      let p;
      switch (h.deltaMode) {
        case 2:
          p = h.deltaY * 800;
          break;
        case 1:
          p = h.deltaY * 40;
          break;
        case 0:
          p = h.deltaY;
          break;
      }
      const m = Math.sign(p), u = Math.abs(p);
      this.zoomDelta -= 0.25 * m * u, this.needsUpdate = !0, this._lastUsedState = ut, this.dispatchEvent(ye);
    }, a = (h) => {
      this.enabled && this.resetState();
    };
    t.addEventListener("contextmenu", e), t.addEventListener("pointerdown", i), t.addEventListener("wheel", n, { passive: !1 });
    const l = t.getRootNode();
    l.addEventListener("pointermove", o), l.addEventListener("pointerup", r), l.addEventListener("pointerleave", a), this._detachCallback = () => {
      t.removeEventListener("contextmenu", e), t.removeEventListener("pointerdown", i), t.removeEventListener("wheel", n), l.removeEventListener("pointermove", o), l.removeEventListener("pointerup", r), l.removeEventListener("pointerleave", a);
    };
  }
  detach() {
    this.domElement = null, this._detachCallback && (this._detachCallback(), this._detachCallback = null, this.pointerTracker.reset());
  }
  // override-able functions for retrieving the up direction at a point
  getUpDirection(t, e) {
    e.copy(this.up);
  }
  getCameraUpDirection(t) {
    this.getUpDirection(this.camera.position, t);
  }
  // returns the active / last used pivot point for the scene
  getPivotPoint(t) {
    let e = null;
    this._lastUsedState === ut ? this._zoomPointWasSet && (e = t.copy(this.zoomPoint)) : (this._lastUsedState === Y || this._lastUsedState === et) && (e = t.copy(this.pivotPoint));
    const { camera: i, raycaster: s } = this;
    e !== null && (M.copy(e).project(i), (M.x < -1 || M.x > 1 || M.y < -1 || M.y > 1) && (e = null)), H(s, { x: 0, y: 0 }, i);
    const o = this._raycast(s);
    return o && (e === null || o.distance < e.distanceTo(s.ray.origin)) && (e = t.copy(o.point)), e;
  }
  resetState() {
    this.state !== G && this.dispatchEvent(ye), this.state = G, this.pivotMesh.removeFromParent(), this.pivotMesh.visible = this.enabled, this.actionHeightOffset = 0, this.pointerTracker.reset();
  }
  setState(t = this.state, e = !0) {
    this.state !== t && (this.state === G && e && this.dispatchEvent(ge), this.pivotMesh.visible = this.enabled, this.dragInertia.set(0, 0, 0), this.rotationInertia.set(0, 0), this.inertiaStableFrames = 0, this.state = t, t !== G && t !== Gt && (this._lastUsedState = t));
  }
  update(t = Math.min(this.clock.getDelta(), 64 / 1e3)) {
    if (!this.enabled || !this.camera || t === 0)
      return;
    const {
      camera: e,
      cameraRadius: i,
      pivotPoint: s,
      up: o,
      state: r,
      adjustHeight: n,
      autoAdjustCameraRotation: a
    } = this;
    e.updateMatrixWorld(), this.getCameraUpDirection(I), this._upInitialized || (this._upInitialized = !0, this.up.copy(I)), this.zoomPointSet = !1;
    const l = this._inertiaNeedsUpdate(), h = this.needsUpdate || l;
    if (this.needsUpdate || l) {
      const p = this.zoomDelta;
      this._updateZoom(), this._updatePosition(t), this._updateRotation(t), r === et || r === Y ? (A.set(0, 0, -1).transformDirection(e.matrixWorld), this.inertiaTargetDistance = M.copy(s).sub(e.position).dot(A)) : r === G && this._updateInertia(t), (r !== G || p !== 0 || l) && this.dispatchEvent(fe), this.needsUpdate = !1;
    }
    const c = e.isOrthographicCamera ? null : n && this._getPointBelowCamera() || null;
    if (this.getCameraUpDirection(I), this._setFrame(I), (this.state === et || this.state === Y) && this.actionHeightOffset !== 0) {
      const { actionHeightOffset: p } = this;
      e.position.addScaledVector(o, -p), s.addScaledVector(o, -p), c && (c.distance -= p);
    }
    if (this.actionHeightOffset = 0, c) {
      const p = c.distance;
      if (p < i) {
        const m = i - p;
        e.position.addScaledVector(o, m), s.addScaledVector(o, m), this.actionHeightOffset = m;
      }
    }
    this.pointerTracker.updateFrame(), h && a && (this.getCameraUpDirection(I), this._alignCameraUp(I, 1), this.getCameraUpDirection(I), this._clampRotation(I));
  }
  // updates the camera to position it based on the constraints of the controls
  adjustCamera(t) {
    const { adjustHeight: e, cameraRadius: i } = this;
    if (t.isPerspectiveCamera) {
      this.getUpDirection(t.position, I);
      const s = e && this._getPointBelowCamera(t.position, I) || null;
      if (s) {
        const o = s.distance;
        o < i && t.position.addScaledVector(I, i - o);
      }
    }
  }
  dispose() {
    this.detach();
  }
  // private
  _updateInertia(t) {
    const {
      rotationInertia: e,
      pivotPoint: i,
      dragInertia: s,
      enableDamping: o,
      dampingFactor: r,
      camera: n,
      cameraRadius: a,
      minDistance: l,
      inertiaTargetDistance: h
    } = this;
    if (!this.enableDamping || this.inertiaStableFrames > 1) {
      s.set(0, 0, 0), e.set(0, 0, 0);
      return;
    }
    const c = Math.pow(2, -t / r), p = Math.max(n.near, a, l, h), d = 0.25 * (2 / (2 * 1e3));
    if (e.lengthSq() > 0) {
      H(w, M.set(0, 0, -1), n), w.applyMatrix4(n.matrixWorldInverse), w.direction.normalize(), w.recast(-w.direction.dot(w.origin)).at(p / w.direction.z, M), M.applyMatrix4(n.matrixWorld), H(w, W.set(d, d, -1), n), w.applyMatrix4(n.matrixWorldInverse), w.direction.normalize(), w.recast(-w.direction.dot(w.origin)).at(p / w.direction.z, W), W.applyMatrix4(n.matrixWorld), M.sub(i).normalize(), W.sub(i).normalize();
      const x = M.angleTo(W) / t;
      e.multiplyScalar(c), (e.lengthSq() < x ** 2 || !o) && e.set(0, 0);
    }
    if (s.lengthSq() > 0) {
      H(w, M.set(0, 0, -1), n), w.applyMatrix4(n.matrixWorldInverse), w.direction.normalize(), w.recast(-w.direction.dot(w.origin)).at(p / w.direction.z, M), M.applyMatrix4(n.matrixWorld), H(w, W.set(d, d, -1), n), w.applyMatrix4(n.matrixWorldInverse), w.direction.normalize(), w.recast(-w.direction.dot(w.origin)).at(p / w.direction.z, W), W.applyMatrix4(n.matrixWorld);
      const x = M.distanceTo(W) / t;
      s.multiplyScalar(c), (s.lengthSq() < x ** 2 || !o) && s.set(0, 0, 0);
    }
    e.lengthSq() > 0 && this._applyRotation(e.x * t, e.y * t, i), s.lengthSq() > 0 && (n.position.addScaledVector(s, t), n.updateMatrixWorld());
  }
  _inertiaNeedsUpdate() {
    const { rotationInertia: t, dragInertia: e } = this;
    return t.lengthSq() !== 0 || e.lengthSq() !== 0;
  }
  _updateZoom() {
    const {
      zoomPoint: t,
      zoomDirection: e,
      camera: i,
      minDistance: s,
      maxDistance: o,
      pointerTracker: r,
      domElement: n,
      minZoom: a,
      maxZoom: l,
      zoomSpeed: h,
      state: c
    } = this;
    let p = this.zoomDelta;
    if (this.zoomDelta = 0, !(!r.getLatestPoint(R) || p === 0 && c !== ut))
      if (this.rotationInertia.set(0, 0), this.dragInertia.set(0, 0, 0), i.isOrthographicCamera) {
        this._updateZoomDirection();
        const m = this.zoomPointSet || this._updateZoomPoint();
        zt.unproject(i);
        const u = Math.pow(0.95, Math.abs(p * 0.05));
        let d = p > 0 ? 1 / Math.abs(u) : u;
        d *= h, d > 1 ? l < i.zoom * d && (d = 1) : a > i.zoom * d && (d = 1), i.zoom *= d, i.updateProjectionMatrix(), m && (dt(R.x, R.y, n, $t), $t.unproject(i), i.position.sub($t).add(zt), i.updateMatrixWorld());
      } else {
        this._updateZoomDirection();
        const m = M.copy(e);
        if (this.zoomPointSet || this._updateZoomPoint()) {
          const u = t.distanceTo(i.position);
          if (p < 0) {
            const d = Math.min(0, u - o);
            p = p * u * h * 25e-4, p = Math.max(p, d);
          } else {
            const d = Math.max(0, u - s);
            p = p * Math.max(u - s, 0) * h * 25e-4, p = Math.min(p, d);
          }
          i.position.addScaledVector(e, p), i.updateMatrixWorld();
        } else {
          const u = this._getPointBelowCamera();
          if (u) {
            const d = u.distance;
            m.set(0, 0, -1).transformDirection(i.matrixWorld), i.position.addScaledVector(m, p * d * 0.01), i.updateMatrixWorld();
          }
        }
      }
  }
  _updateZoomDirection() {
    if (this.zoomDirectionSet)
      return;
    const { domElement: t, raycaster: e, camera: i, zoomDirection: s, pointerTracker: o } = this;
    o.getLatestPoint(R), dt(R.x, R.y, t, zt), H(e, zt, i), s.copy(e.ray.direction).normalize(), this.zoomDirectionSet = !0;
  }
  // update the point being zoomed in to based on the zoom direction
  _updateZoomPoint() {
    const {
      camera: t,
      zoomDirectionSet: e,
      zoomDirection: i,
      raycaster: s,
      zoomPoint: o,
      pointerTracker: r,
      domElement: n
    } = this;
    if (this._zoomPointWasSet = !1, !e)
      return !1;
    t.isOrthographicCamera && r.getLatestPoint(bt) ? (dt(bt.x, bt.y, n, bt), H(s, bt, t)) : (s.ray.origin.copy(t.position), s.ray.direction.copy(i), s.near = 0, s.far = 1 / 0);
    const a = this._raycast(s);
    return a ? (o.copy(a.point), this.zoomPointSet = !0, this._zoomPointWasSet = !0, !0) : !1;
  }
  // returns the point below the camera
  _getPointBelowCamera(t = this.camera.position, e = this.up) {
    const { raycaster: i } = this;
    i.ray.direction.copy(e).multiplyScalar(-1), i.ray.origin.copy(t).addScaledVector(e, 1e5), i.near = 0, i.far = 1 / 0;
    const s = this._raycast(i);
    return s && (s.distance -= 1e5), s;
  }
  // update the drag action
  _updatePosition(t) {
    const {
      raycaster: e,
      camera: i,
      pivotPoint: s,
      up: o,
      pointerTracker: r,
      domElement: n,
      state: a,
      dragInertia: l
    } = this;
    if (a === et) {
      if (r.getCenterPoint(R), dt(R.x, R.y, n, R), de.setFromNormalAndCoplanarPoint(o, s), H(e, R, i), Math.abs(e.ray.direction.dot(o)) < Zt) {
        const h = Math.acos(Zt);
        Rt.crossVectors(e.ray.direction, o).normalize(), e.ray.direction.copy(o).applyAxisAngle(Rt, h).multiplyScalar(-1);
      }
      if (this.getUpDirection(s, I), Math.abs(e.ray.direction.dot(I)) < qt) {
        const h = Math.acos(qt);
        Rt.crossVectors(e.ray.direction, I).normalize(), e.ray.direction.copy(I).applyAxisAngle(Rt, h).multiplyScalar(-1);
      }
      e.ray.intersectPlane(de, M) && (W.subVectors(s, M), i.position.add(W), i.updateMatrixWorld(), W.multiplyScalar(1 / t), r.getMoveDistance() / t < 2 * window.devicePixelRatio ? this.inertiaStableFrames++ : (l.copy(W), this.inertiaStableFrames = 0));
    }
  }
  _updateRotation(t) {
    const {
      pivotPoint: e,
      pointerTracker: i,
      domElement: s,
      state: o,
      rotationInertia: r
    } = this;
    o === Y && (i.getCenterPoint(R), i.getPreviousCenterPoint(ue), Mt.subVectors(R, ue).multiplyScalar(2 * Math.PI / s.clientHeight), this._applyRotation(Mt.x, Mt.y, e), Mt.multiplyScalar(1 / t), i.getMoveDistance() / t < 2 * window.devicePixelRatio ? this.inertiaStableFrames++ : (r.copy(Mt), this.inertiaStableFrames = 0));
  }
  _applyRotation(t, e, i) {
    if (t === 0 && e === 0)
      return;
    const {
      camera: s,
      minAltitude: o,
      maxAltitude: r,
      rotationSpeed: n
    } = this, a = -t * n;
    let l = e * n;
    A.set(0, 0, 1).transformDirection(s.matrixWorld), B.set(1, 0, 0).transformDirection(s.matrixWorld), this.getUpDirection(i, I);
    let h;
    I.dot(A) > 1 - 1e-10 ? h = 0 : (M.crossVectors(I, A).normalize(), h = Math.sign(M.dot(B)) * I.angleTo(A)), l > 0 ? (l = Math.min(h - o, l), l = Math.max(0, l)) : (l = Math.max(h - r, l), l = Math.min(0, l)), j.setFromAxisAngle(I, a), ft(i, j, tt), s.matrixWorld.premultiply(tt), B.set(1, 0, 0).transformDirection(s.matrixWorld), j.setFromAxisAngle(B, -l), ft(i, j, tt), s.matrixWorld.premultiply(tt), s.matrixWorld.decompose(s.position, s.quaternion, M);
  }
  // sets the "up" axis for the current surface of the tileset
  _setFrame(t) {
    const {
      up: e,
      camera: i,
      zoomPoint: s,
      zoomDirectionSet: o,
      zoomPointSet: r,
      scaleZoomOrientationAtEdges: n
    } = this;
    if (o && (r || this._updateZoomPoint())) {
      if (j.setFromUnitVectors(e, t), n) {
        this.getUpDirection(s, M);
        let a = Math.max(M.dot(e) - 0.6, 0) / 0.4;
        a = v.mapLinear(a, 0, 0.5, 0, 1), a = Math.min(a, 1), i.isOrthographicCamera && (a *= 0.1), j.slerp(_i, 1 - a);
      }
      ft(s, j, tt), i.updateMatrixWorld(), i.matrixWorld.premultiply(tt), i.matrixWorld.decompose(i.position, i.quaternion, M), this.zoomDirectionSet = !1, this._updateZoomDirection();
    }
    e.copy(t), i.updateMatrixWorld();
  }
  _raycast(t) {
    const { scene: e, useFallbackPlane: i, fallbackPlane: s } = this, o = t.intersectObject(e)[0] || null;
    if (o)
      return o;
    if (i) {
      const r = s;
      if (t.ray.intersectPlane(r, M))
        return {
          point: M.clone(),
          distance: t.ray.origin.distanceTo(M)
        };
    }
    return null;
  }
  // tilt the camera to align with the provided "up" value
  _alignCameraUp(t, e = 1) {
    const { camera: i, state: s, pivotPoint: o, zoomPoint: r, zoomPointSet: n } = this;
    i.updateMatrixWorld(), A.set(0, 0, -1).transformDirection(i.matrixWorld), B.set(-1, 0, 0).transformDirection(i.matrixWorld);
    let a = v.mapLinear(1 - Math.abs(A.dot(t)), 0, 0.2, 0, 1);
    a = v.clamp(a, 0, 1), e *= a, Qt.crossVectors(t, A), Qt.lerp(B, 1 - e).normalize(), j.setFromUnitVectors(B, Qt), i.quaternion.premultiply(j);
    let l = null;
    s === et || s === Y ? l = It.copy(o) : n && (l = It.copy(r)), l && (Et.copy(i.matrixWorld).invert(), M.copy(l).applyMatrix4(Et), i.updateMatrixWorld(), M.applyMatrix4(i.matrixWorld), Ot.subVectors(l, M), i.position.add(Ot)), i.updateMatrixWorld();
  }
  // clamp rotation to the given "up" vector
  _clampRotation(t) {
    const { camera: e, minAltitude: i, maxAltitude: s, state: o, pivotPoint: r, zoomPoint: n, zoomPointSet: a } = this;
    e.updateMatrixWorld(), A.set(0, 0, 1).transformDirection(e.matrixWorld), B.set(1, 0, 0).transformDirection(e.matrixWorld);
    let l;
    t.dot(A) > 1 - 1e-10 ? l = 0 : (M.crossVectors(t, A), l = Math.sign(M.dot(B)) * t.angleTo(A));
    let h;
    if (l > s)
      h = s;
    else if (l < i)
      h = i;
    else
      return;
    A.copy(t), j.setFromAxisAngle(B, h), A.applyQuaternion(j).normalize(), M.crossVectors(A, B).normalize(), tt.makeBasis(B, M, A), e.quaternion.setFromRotationMatrix(tt);
    let c = null;
    o === et || o === Y ? c = It.copy(r) : a && (c = It.copy(n)), c && (Et.copy(e.matrixWorld).invert(), M.copy(c).applyMatrix4(Et), e.updateMatrixWorld(), M.applyMatrix4(e.matrixWorld), Ot.subVectors(c, M), e.position.add(Ot)), e.updateMatrixWorld();
  }
}
const xe = /* @__PURE__ */ new O(), ht = /* @__PURE__ */ new O(), N = /* @__PURE__ */ new y(), P = /* @__PURE__ */ new y(), X = /* @__PURE__ */ new y(), k = /* @__PURE__ */ new y(), vi = /* @__PURE__ */ new y(), pt = /* @__PURE__ */ new y(), K = /* @__PURE__ */ new it(), be = /* @__PURE__ */ new y(), ot = /* @__PURE__ */ new y(), D = /* @__PURE__ */ new Ft(), Me = /* @__PURE__ */ new ri(), _t = /* @__PURE__ */ new F(), _e = {}, Ti = 2550;
class Fi extends Pi {
  get tilesGroup() {
    return console.warn('GlobeControls: "tilesGroup" has been deprecated. Use "ellipsoidGroup", instead.'), this.ellipsoidFrame;
  }
  get ellipsoidFrame() {
    return this.ellipsoidGroup.matrixWorld;
  }
  get ellipsoidFrameInverse() {
    const { ellipsoidGroup: t, ellipsoidFrame: e, _ellipsoidFrameInverse: i } = this;
    return t.matrixWorldInverse ? t.matrixWorldInverse : i.copy(e).invert();
  }
  constructor(t = null, e = null, i = null, s = null) {
    super(t, e, i), this.isGlobeControls = !0, this._dragMode = 0, this._rotationMode = 0, this.maxZoom = 0.01, this.nearMargin = 0.25, this.farMargin = 0, this.useFallbackPlane = !1, this.autoAdjustCameraRotation = !1, this.globeInertia = new it(), this.globeInertiaFactor = 0, this.ellipsoid = vt.clone(), this.ellipsoidGroup = new Pt(), this._ellipsoidFrameInverse = new O(), s !== null && this.setTilesRenderer(s);
  }
  setTilesRenderer(t) {
    super.setTilesRenderer(t), t !== null && this.setEllipsoid(t.ellipsoid, t.group);
  }
  setEllipsoid(t, e) {
    this.ellipsoid = t || vt.clone(), this.ellipsoidGroup = e || new Pt();
  }
  getPivotPoint(t) {
    const { camera: e, ellipsoidFrame: i, ellipsoidFrameInverse: s, ellipsoid: o } = this;
    return k.set(0, 0, -1).transformDirection(e.matrixWorld), D.origin.copy(e.position), D.direction.copy(k), D.applyMatrix4(s), o.closestPointToRayEstimate(D, P).applyMatrix4(i), (super.getPivotPoint(t) === null || N.subVectors(t, D.origin).dot(D.direction) > N.subVectors(P, D.origin).dot(D.direction)) && t.copy(P), t;
  }
  // get the vector to the center of the provided globe
  getVectorToCenter(t) {
    const { ellipsoidFrame: e, camera: i } = this;
    return t.setFromMatrixPosition(e).sub(i.position);
  }
  // get the distance to the center of the globe
  getDistanceToCenter() {
    return this.getVectorToCenter(P).length();
  }
  getUpDirection(t, e) {
    const { ellipsoidFrame: i, ellipsoidFrameInverse: s, ellipsoid: o } = this;
    P.copy(t).applyMatrix4(s), o.getPositionToNormal(P, e), e.transformDirection(i);
  }
  getCameraUpDirection(t) {
    const { ellipsoidFrame: e, ellipsoidFrameInverse: i, ellipsoid: s, camera: o } = this;
    o.isOrthographicCamera ? (this._getVirtualOrthoCameraPosition(P), P.applyMatrix4(i), s.getPositionToNormal(P, t), t.transformDirection(e)) : this.getUpDirection(o.position, t);
  }
  update(t = Math.min(this.clock.getDelta(), 64 / 1e3)) {
    if (!this.enabled || !this.camera || t === 0)
      return;
    const { camera: e, pivotMesh: i } = this;
    this._isNearControls() ? this.scaleZoomOrientationAtEdges = this.zoomDelta < 0 : (this.state !== G && this._dragMode !== 1 && this._rotationMode !== 1 && (i.visible = !1), this.scaleZoomOrientationAtEdges = !1);
    const s = this.needsUpdate || this._inertiaNeedsUpdate();
    super.update(t), this.adjustCamera(e), s && this._isNearControls() && (this.getCameraUpDirection(pt), this._alignCameraUp(pt, 1), this.getCameraUpDirection(pt), this._clampRotation(pt));
  }
  // Updates the passed camera near and far clip planes to encapsulate the ellipsoid from the
  // current position in addition to adjusting the height.
  adjustCamera(t) {
    super.adjustCamera(t);
    const { ellipsoidFrame: e, ellipsoidFrameInverse: i, ellipsoid: s, nearMargin: o, farMargin: r } = this, n = Math.max(...s.radius);
    if (t.isPerspectiveCamera) {
      const a = P.setFromMatrixPosition(e).sub(t.position).length(), l = o * n, h = v.clamp((a - n) / l, 0, 1), c = v.lerp(1, 1e3, h);
      t.near = Math.max(c, a - n - l), N.copy(t.position).applyMatrix4(i), s.getPositionToCartographic(N, _e);
      const p = Math.max(s.getPositionElevation(N), Ti), m = s.calculateHorizonDistance(_e.lat, p);
      t.far = m + 0.1 + n * r, t.updateProjectionMatrix();
    } else {
      this._getVirtualOrthoCameraPosition(t.position, t), t.updateMatrixWorld(), xe.copy(t.matrixWorld).invert(), P.setFromMatrixPosition(e).applyMatrix4(xe);
      const a = -P.z;
      t.near = a - n * (1 + o), t.far = a + 0.1 + n * r, t.position.addScaledVector(k, t.near), t.far -= t.near, t.near = 0, t.updateProjectionMatrix(), t.updateMatrixWorld();
    }
  }
  // resets the "stuck" drag modes
  setState(...t) {
    super.setState(...t), this._dragMode = 0, this._rotationMode = 0;
  }
  _updateInertia(t) {
    super._updateInertia(t);
    const {
      globeInertia: e,
      enableDamping: i,
      dampingFactor: s,
      camera: o,
      cameraRadius: r,
      minDistance: n,
      inertiaTargetDistance: a,
      ellipsoidFrame: l
    } = this;
    if (!this.enableDamping || this.inertiaStableFrames > 1) {
      this.globeInertiaFactor = 0, this.globeInertia.identity();
      return;
    }
    const h = Math.pow(2, -t / s), c = Math.max(o.near, r, n, a), u = 0.25 * (2 / (2 * 1e3));
    if (X.setFromMatrixPosition(l), this.globeInertiaFactor !== 0) {
      H(D, P.set(0, 0, -1), o), D.applyMatrix4(o.matrixWorldInverse), D.direction.normalize(), D.recast(-D.direction.dot(D.origin)).at(c / D.direction.z, P), P.applyMatrix4(o.matrixWorld), H(D, N.set(u, u, -1), o), D.applyMatrix4(o.matrixWorldInverse), D.direction.normalize(), D.recast(-D.direction.dot(D.origin)).at(c / D.direction.z, N), N.applyMatrix4(o.matrixWorld), P.sub(X).normalize(), N.sub(X).normalize(), this.globeInertiaFactor *= h;
      const d = P.angleTo(N) / t;
      (2 * Math.acos(e.w) * this.globeInertiaFactor < d || !i) && (this.globeInertiaFactor = 0, e.identity());
    }
    this.globeInertiaFactor !== 0 && (e.w === 1 && (e.x !== 0 || e.y !== 0 || e.z !== 0) && (e.w = Math.min(e.w, 1 - 1e-9)), X.setFromMatrixPosition(l), K.identity().slerp(e, this.globeInertiaFactor * t), ft(X, K, ht), o.matrixWorld.premultiply(ht), o.matrixWorld.decompose(o.position, o.quaternion, P));
  }
  _inertiaNeedsUpdate() {
    return super._inertiaNeedsUpdate() || this.globeInertiaFactor !== 0;
  }
  _updatePosition(t) {
    if (this.state === et) {
      this._dragMode === 0 && (this._dragMode = this._isNearControls() ? 1 : -1);
      const {
        raycaster: e,
        camera: i,
        pivotPoint: s,
        pointerTracker: o,
        domElement: r,
        ellipsoidFrame: n,
        ellipsoidFrameInverse: a
      } = this, l = N, h = vi;
      o.getCenterPoint(_t), dt(_t.x, _t.y, r, _t), H(e, _t, i), e.ray.applyMatrix4(a);
      const c = P.copy(s).applyMatrix4(a).length();
      if (Me.radius.setScalar(c), !Me.intersectRay(e.ray, P)) {
        this.resetState(), this._updateInertia(t);
        return;
      }
      P.applyMatrix4(n), X.setFromMatrixPosition(n), l.subVectors(s, X).normalize(), h.subVectors(P, X).normalize(), K.setFromUnitVectors(h, l), ft(X, K, ht), i.matrixWorld.premultiply(ht), i.matrixWorld.decompose(i.position, i.quaternion, P), o.getMoveDistance() / t < 2 * window.devicePixelRatio ? this.inertiaStableFrames++ : (this.globeInertia.copy(K), this.globeInertiaFactor = 1 / t, this.inertiaStableFrames = 0);
    }
  }
  // disable rotation once we're outside the control transition
  _updateRotation(...t) {
    this._rotationMode === 1 || this._isNearControls() ? (this._rotationMode = 1, super._updateRotation(...t)) : (this.pivotMesh.visible = !1, this._rotationMode = -1);
  }
  _updateZoom() {
    const { zoomDelta: t, ellipsoid: e, zoomSpeed: i, zoomPoint: s, camera: o, maxZoom: r, state: n } = this;
    if (n !== ut && t === 0)
      return;
    this.rotationInertia.set(0, 0), this.dragInertia.set(0, 0, 0), this.globeInertia.identity(), this.globeInertiaFactor = 0;
    const a = v.clamp(v.mapLinear(Math.abs(t), 0, 20, 0, 1), 0, 1);
    if (this._isNearControls() || t > 0) {
      if (this._updateZoomDirection(), t < 0 && (this.zoomPointSet || this._updateZoomPoint())) {
        k.set(0, 0, -1).transformDirection(o.matrixWorld).normalize(), ot.copy(this.up).multiplyScalar(-1), this.getUpDirection(s, be);
        const l = v.clamp(v.mapLinear(-be.dot(ot), 1, 0.95, 0, 1), 0, 1), h = 1 - k.dot(ot), c = o.isOrthographicCamera ? 0.05 : 1, p = v.clamp(a * 3, 0, 1), m = Math.min(l * h * c * p, 0.1);
        ot.lerpVectors(k, ot, m).normalize(), K.setFromUnitVectors(k, ot), ft(s, K, ht), o.matrixWorld.premultiply(ht), o.matrixWorld.decompose(o.position, o.quaternion, ot), this.zoomDirection.subVectors(s, o.position).normalize();
      }
      super._updateZoom();
    } else if (o.isPerspectiveCamera) {
      const l = this._getPerspectiveTransitionDistance(), h = this._getMaxPerspectiveDistance(), c = v.mapLinear(this.getDistanceToCenter(), l, h, 0, 1);
      this._tiltTowardsCenter(v.lerp(0, 0.4, c * a)), this._alignCameraUpToNorth(v.lerp(0, 0.2, c * a));
      const p = this.getDistanceToCenter() - e.radius.x, m = t * p * i * 25e-4, u = Math.max(m, Math.min(this.getDistanceToCenter() - h, 0));
      this.getVectorToCenter(P).normalize(), this.camera.position.addScaledVector(P, u), this.camera.updateMatrixWorld(), this.zoomDelta = 0;
    } else {
      const l = this._getOrthographicTransitionZoom(), h = this._getMinOrthographicZoom(), c = v.mapLinear(o.zoom, l, h, 0, 1);
      this._tiltTowardsCenter(v.lerp(0, 0.4, c * a)), this._alignCameraUpToNorth(v.lerp(0, 0.2, c * a));
      const p = this.zoomDelta, m = Math.pow(0.95, Math.abs(p * 0.05)), u = p > 0 ? 1 / Math.abs(m) : m, d = h / o.zoom, x = Math.max(u * i, Math.min(d, 1));
      o.zoom = Math.min(r, o.zoom * x), o.updateProjectionMatrix(), this.zoomDelta = 0, this.zoomDirectionSet = !1;
    }
  }
  // tilt the camera to align with north
  _alignCameraUpToNorth(t) {
    const { ellipsoidFrame: e } = this;
    pt.set(0, 0, 1).transformDirection(e), this._alignCameraUp(pt, t);
  }
  // tilt the camera to look at the center of the globe
  _tiltTowardsCenter(t) {
    const {
      camera: e,
      ellipsoidFrame: i
    } = this;
    k.set(0, 0, -1).transformDirection(e.matrixWorld).normalize(), P.setFromMatrixPosition(i).sub(e.position).normalize(), P.lerp(k, 1 - t).normalize(), K.setFromUnitVectors(k, P), e.quaternion.premultiply(K), e.updateMatrixWorld();
  }
  // returns the perspective camera transition distance can move to based on globe size and fov
  _getPerspectiveTransitionDistance() {
    const { camera: t, ellipsoid: e } = this;
    if (!t.isPerspectiveCamera)
      throw new Error();
    const i = Math.max(...e.radius), s = 2 * Math.atan(Math.tan(v.DEG2RAD * t.fov * 0.5) * t.aspect), o = i / Math.tan(v.DEG2RAD * t.fov * 0.5), r = i / Math.tan(s * 0.5);
    return Math.max(o, r);
  }
  // returns the max distance the perspective camera can move to based on globe size and fov
  _getMaxPerspectiveDistance() {
    const { camera: t, ellipsoid: e } = this;
    if (!t.isPerspectiveCamera)
      throw new Error();
    const i = Math.max(...e.radius), s = 2 * Math.atan(Math.tan(v.DEG2RAD * t.fov * 0.5) * t.aspect), o = i / Math.tan(v.DEG2RAD * t.fov * 0.5), r = i / Math.tan(s * 0.5);
    return 2 * Math.max(o, r);
  }
  // returns the transition threshold for orthographic zoom based on the globe size and camera settings
  _getOrthographicTransitionZoom() {
    const { camera: t, ellipsoid: e } = this;
    if (!t.isOrthographicCamera)
      throw new Error();
    const i = t.top - t.bottom, s = t.right - t.left, o = Math.max(i, s), n = 2 * Math.max(...e.radius);
    return 2 * o / n;
  }
  // returns the minimum allowed orthographic zoom based on the globe size and camera settings
  _getMinOrthographicZoom() {
    const { camera: t, ellipsoid: e } = this;
    if (!t.isOrthographicCamera)
      throw new Error();
    const i = t.top - t.bottom, s = t.right - t.left, o = Math.min(i, s), n = 2 * Math.max(...e.radius);
    return 0.7 * o / n;
  }
  // returns the "virtual position" of the orthographic based on where it is and
  // where it's looking primarily so we can reasonably position the camera object
  // in space and derive a reasonable "up" value.
  _getVirtualOrthoCameraPosition(t, e = this.camera) {
    const { ellipsoidFrame: i, ellipsoidFrameInverse: s, ellipsoid: o } = this;
    if (!e.isOrthographicCamera)
      throw new Error();
    D.origin.copy(e.position), D.direction.set(0, 0, -1).transformDirection(e.matrixWorld), D.applyMatrix4(s), o.closestPointToRayEstimate(D, N).applyMatrix4(i);
    const r = e.top - e.bottom, n = e.right - e.left, a = Math.max(r, n) / e.zoom;
    k.set(0, 0, -1).transformDirection(e.matrixWorld);
    const l = N.sub(e.position).dot(k);
    t.copy(e.position).addScaledVector(k, l - a * 4);
  }
  _isNearControls() {
    const { camera: t } = this;
    return t.isPerspectiveCamera ? this.getDistanceToCenter() < this._getPerspectiveTransitionDistance() : t.zoom > this._getOrthographicTransitionZoom();
  }
  _raycast(t) {
    const e = super._raycast(t);
    if (e === null) {
      const { ellipsoid: i, ellipsoidFrame: s, ellipsoidFrameInverse: o } = this;
      D.copy(t.ray).applyMatrix4(o);
      const r = i.intersectRay(D, P);
      return r !== null ? (r.applyMatrix4(s), {
        point: r.clone(),
        distance: r.distanceTo(t.ray.origin)
      }) : null;
    } else
      return e;
  }
}
const L = /* @__PURE__ */ new y(), nt = /* @__PURE__ */ new y(), rt = /* @__PURE__ */ new we(), wi = /* @__PURE__ */ new y(), Di = /* @__PURE__ */ new y(), Ci = /* @__PURE__ */ new y(), Pe = /* @__PURE__ */ new it(), Si = /* @__PURE__ */ new it();
class Ui extends mt {
  get animating() {
    return this._alpha !== 0 && this._alpha !== 1;
  }
  get alpha() {
    return this._target === 0 ? 1 - this._alpha : this._alpha;
  }
  get camera() {
    return this._alpha === 0 ? this.perspectiveCamera : this._alpha === 1 ? this.orthographicCamera : this.transitionCamera;
  }
  get mode() {
    return this._target === 0 ? "perspective" : "orthographic";
  }
  set mode(t) {
    if (t === this.mode)
      return;
    const e = this.camera;
    t === "perspective" ? (this._target = 0, this._alpha = 0) : (this._target = 1, this._alpha = 1), this.dispatchEvent({ type: "camera-change", camera: this.camera, prevCamera: e });
  }
  constructor(t = new Kt(), e = new we()) {
    super(), this.perspectiveCamera = t, this.orthographicCamera = e, this.transitionCamera = new Kt(), this.orthographicPositionalZoom = !0, this.orthographicOffset = 50, this.fixedPoint = new y(), this.duration = 200, this.autoSync = !0, this.easeFunction = (i) => i, this._target = 0, this._alpha = 0, this._clock = new Te();
  }
  toggle() {
    this._target = this._target === 1 ? 0 : 1, this._clock.getDelta(), this.dispatchEvent({ type: "toggle" });
  }
  update(t = Math.min(this._clock.getDelta(), 64 / 1e3)) {
    this.autoSync && this.syncCameras();
    const { perspectiveCamera: e, orthographicCamera: i, transitionCamera: s, camera: o } = this, r = t * 1e3;
    if (this._alpha !== this._target) {
      const h = Math.sign(this._target - this._alpha) * r / this.duration;
      this._alpha = v.clamp(this._alpha + h, 0, 1), this.dispatchEvent({ type: "change", alpha: this.alpha });
    }
    const n = o;
    let a = null;
    this._alpha === 0 ? a = e : this._alpha === 1 ? a = i : (a = s, this._updateTransitionCamera()), n !== a && (a === s && this.dispatchEvent({ type: "transition-start" }), this.dispatchEvent({ type: "camera-change", camera: a, prevCamera: n }), n === s && this.dispatchEvent({ type: "transition-end" }));
  }
  syncCameras() {
    const t = this._getFromCamera(), { perspectiveCamera: e, orthographicCamera: i, transitionCamera: s, fixedPoint: o } = this;
    if (L.set(0, 0, -1).transformDirection(t.matrixWorld).normalize(), t.isPerspectiveCamera) {
      if (this.orthographicPositionalZoom)
        i.position.copy(e.position).addScaledVector(L, -this.orthographicOffset), i.rotation.copy(e.rotation), i.updateMatrixWorld();
      else {
        const l = nt.subVectors(o, i.position).dot(L), h = nt.subVectors(o, e.position).dot(L);
        nt.copy(e.position).addScaledVector(L, h), i.rotation.copy(e.rotation), i.position.copy(nt).addScaledVector(L, -l), i.updateMatrixWorld();
      }
      const r = Math.abs(nt.subVectors(e.position, o).dot(L)), n = 2 * Math.tan(v.DEG2RAD * e.fov * 0.5) * r, a = i.top - i.bottom;
      i.zoom = a / n, i.updateProjectionMatrix();
    } else {
      const r = Math.abs(nt.subVectors(i.position, o).dot(L)), a = (i.top - i.bottom) / i.zoom * 0.5 / Math.tan(v.DEG2RAD * e.fov * 0.5);
      e.rotation.copy(i.rotation), e.position.copy(i.position).addScaledVector(L, r).addScaledVector(L, -a), e.updateMatrixWorld(), this.orthographicPositionalZoom && (i.position.copy(e.position).addScaledVector(L, -this.orthographicOffset), i.updateMatrixWorld());
    }
    s.position.copy(e.position), s.rotation.copy(e.rotation);
  }
  _getTransitionDirection() {
    return Math.sign(this._target - this._alpha);
  }
  _getToCamera() {
    const t = this._getTransitionDirection();
    return t === 0 ? this._target === 0 ? this.perspectiveCamera : this.orthographicCamera : t > 0 ? this.orthographicCamera : this.perspectiveCamera;
  }
  _getFromCamera() {
    const t = this._getTransitionDirection();
    return t === 0 ? this._target === 0 ? this.perspectiveCamera : this.orthographicCamera : t > 0 ? this.perspectiveCamera : this.orthographicCamera;
  }
  _updateTransitionCamera() {
    const { perspectiveCamera: t, orthographicCamera: e, transitionCamera: i, fixedPoint: s } = this, o = this.easeFunction(this._alpha);
    L.set(0, 0, -1).transformDirection(e.matrixWorld).normalize(), rt.copy(e), rt.position.addScaledVector(L, e.near), e.far -= e.near, e.near = 0, L.set(0, 0, -1).transformDirection(t.matrixWorld).normalize();
    const r = Math.abs(nt.subVectors(t.position, s).dot(L)), n = 2 * Math.tan(v.DEG2RAD * t.fov * 0.5) * r, a = Si.slerpQuaternions(t.quaternion, rt.quaternion, o), l = v.lerp(t.fov, 1, o), h = n * 0.5 / Math.tan(v.DEG2RAD * l * 0.5), c = Ci.copy(rt.position).sub(s).applyQuaternion(Pe.copy(rt.quaternion).invert()), p = Di.copy(t.position).sub(s).applyQuaternion(Pe.copy(t.quaternion).invert()), m = wi.lerpVectors(p, c, o);
    m.z -= Math.abs(m.z) - h;
    const u = -(p.z - m.z), d = -(c.z - m.z), x = v.lerp(u + t.near, d + rt.near, o), E = v.lerp(u + t.far, d + rt.far, o), _ = Math.max(E, 0) - Math.max(x, 0);
    i.aspect = t.aspect, i.fov = l, i.near = Math.max(x, _ * 1e-5), i.far = E, i.position.copy(m).applyQuaternion(a).add(s), i.quaternion.copy(a), i.updateProjectionMatrix(), i.updateMatrixWorld();
  }
}
export {
  De as B,
  li as C,
  Pi as E,
  Fi as G,
  Se as I,
  Ce as P,
  Ai as T,
  Ui as a
};
//# sourceMappingURL=CameraTransitionManager-SvgW6Pmv.js.map