UNPKG

videx-3d

Version:

React 3D component library designed for sub surface visualizations in the browser

611 lines (610 loc) 22.1 kB
import { wrap as Z } from "comlink"; import $ from "p-limit"; import { x as ct, D as ft, P as ut, b as dt, a as gt, c as pt, T as wt, y as yt, z as mt, A as xt, B as bt, p as vt, d as _t, E as Mt, F as At, G as Ft, H as Lt, I as St, J as Vt, K as It, L as Bt, M as Et, e as Tt, N as Dt, o as qt, O as zt, Q as Gt, R as kt, i as Pt, S as jt, U as Nt, V as Ct, X as Qt, g as Ut, Y as Wt, Z as Ht, _ as Zt, $ as $t, h as Jt, m as Kt, a0 as Ot, a1 as Xt, a2 as Yt, n as Rt, a3 as te, f as ee, a4 as se, a5 as ie, a6 as re, a7 as ne, a8 as ae, a9 as le, aa as oe, ab as he, ac as ce, ad as fe, ae as ue, af as de, ag as ge, s as pe, ah as we, ai as ye, aj as me, u as xe, ak as be } from "./chunk-iY0wQ9Z6.js"; import { C as _e, T as Me, c as Ae, b as Fe, a as Le, d as Se, e as Ve, g as Ie, f as Be, t as Ee, h as Te, w as De } from "./chunk-CnY6Tmof.js"; import { D as ze, c as Ge, a as ke, b as Pe, t as je, d as Ne } from "./chunk-MFzFdEWm.js"; const J = 10, K = 25; class Y { store; config; cached = /* @__PURE__ */ new Map(); _activeLoaders = {}; _batchqueue = /* @__PURE__ */ new Map(); _flushScheduled = null; constructor(t, e = {}) { this.store = t, this.config = { ...e }, this.config.batched && (this.config.batchSize === void 0 && (this.config.batchSize = J), this.config.batchMaxDelay === void 0 && (this.config.batchMaxDelay = K)), this._flushScheduled = null; } async init(...t) { if (this.config.init) try { const e = await this.config.init(...t); if (Array.isArray(e)) return this.cached = new Map(e), !0; } catch (e) { console.warn("Init failed", e); } return this.clear(), !1; } async all() { if (this.config.preloaded) { if (this.config.transform) { const t = this.config.transform; return Array.from(this.cached.values()).map((e) => t(e)); } return Array.from(this.cached.values()); } else console.warn('Data Loader: "all" called on non-preloaded dataset!'); return []; } async _enqueueRequest(t) { if (this._batchqueue.has(t)) return this._batchqueue.get(t).promise; let e = null; const i = new Promise((n) => { e = n; }), r = { key: t, promise: i, _resolve: e }; return this._batchqueue.set(t, r), this._flushScheduled || (this._flushScheduled = setTimeout(() => { this._processBatchQueue(); }, this.config.batchMaxDelay)), i; } async _processBatch(t) { const e = t.map((i) => i.key); if (!this.config.batchLoad) return null; this.config.batchLoad(e).then((i) => { Array.isArray(i) && i.forEach(([r, n]) => { this.set(r, n); }); }).catch((i) => { console.warn("Batch load failed", i); }).finally(() => { t.forEach((i) => { const r = this.cached.get(i.key) || null; i._resolve(r); }); }); } async _processBatchQueue() { let t = []; for (const e of this._batchqueue.values()) t.push(e), this._batchqueue.delete(e.key), (t.length >= this.config.batchSize || this._batchqueue.size === 0) && (this._processBatch(t), t = []); this._batchqueue.size ? this._flushScheduled = setTimeout(() => this._processBatchQueue(), 1) : this._flushScheduled = null; } async get(t, e) { if (this.cached.has(t)) return this.config.transform ? this.config.transform(this.cached.get(t)) : this.cached.get(t); if (this.config.preloaded) return null; if (!this.config.batched && this.config.load) { if (this.config.noCache) return this.config.load(t, e); let i = this._activeLoaders[t]; if (!i) { if (e) throw Error( "DataLoader: A load function with additional args may not be cached. Set noCache to true in config." ); i = this.config.load(t).then((r) => { r && this.cached.set(t, r); }).catch((r) => { console.warn("Load failed", r); }).finally(() => { delete this._activeLoaders[t]; }), this._activeLoaders[t] = i; } return await i, this.config.transform ? this.config.transform(this.cached.get(t)) : this.cached.get(t); } return this.config.batched && this.config.batchLoad ? this._enqueueRequest(t) : null; } set(t, e) { this.cached.set(t, e); } clear() { this.cached.clear(); } } class R { store = null; config; generators = /* @__PURE__ */ new Map(); constructor(t = {}, e) { this.config = { concurrentStoreCalls: 0, ...t }, e && this.setStore(e); } add(t, e) { this.generators.set(t, e); } setStore(t) { if (t && this.config.concurrentStoreCalls) { const e = $(this.config.concurrentStoreCalls), i = { get: (r, n, s) => e(() => t.get(r, n, s)), all: (r) => e(() => t.all(r)), query: (r, n) => e(() => t.query(r, n)) }; this.store = i; } else this.store = t; } async connectRemoteStore(t) { const e = Z(t); this.setStore(e); } async invoke(t, ...e) { if (!this.store) throw Error("No available store!"); if (!this.generators.has(t)) throw Error(`Generator with key '${t}' not found!`); return this.generators.get(t).bind(this.store)(...e); } } function tt(u, t, e = 1, i = 1, r = (n) => n) { console.time("triangulate"); const n = [], s = [], a = [], c = [], h = u.length / t; let l, o, d, g, v, y, m, _, A, S, b, V, M, F, L, k, f, C, D, q, z, p, x, Q, H = 0, U = 0, W = 0, B = new Array(t).fill(null), P = new Array(t).fill(null); const w = new Array(t - 1).fill(null); function j(I, T, G) { return n.push({ x: I * e, y: G, z: T * i, edge: null }), a.push(I / (t - 1), 1 - T / (h - 1)), H++; } function E(I, T, G) { D = { index: U++, tail: I, head: T, twin: null, prev: null, next: null }, q = { index: U++, tail: T, head: G, twin: null, prev: null, next: null }, z = { index: U++, tail: G, head: I, twin: null, prev: null, next: null }, D.next = q, q.next = z, z.next = D, D.prev = z, q.prev = D, z.prev = q, n[I].edge || (n[I].edge = D), n[T].edge || (n[T].edge = q), n[G].edge || (n[G].edge = z), s.push(D, q, z), c.push(I, T, G); } for (k = 1; k < h - 1; k++) { Q = !1; const I = B; for (B = P, P = I.fill(null), p = null, C = k - 1, W += t, L = 1; L < t - 1; L++) f = L - 1, S = W + L, A = S - 1, _ = S - t, m = _ - 1, b = r(u[m]), V = r(u[_]), M = r(u[A]), F = r(u[S]), b !== null && V !== null && M !== null && F !== null ? x = 1 : b !== null && V !== null && M !== null ? x = 2 : b !== null && V !== null && F !== null ? x = 3 : b !== null && M !== null && F !== null ? x = 4 : V !== null && M !== null && F !== null ? x = 5 : x = 0, d = null, g = null, x !== 0 ? (Q ? (l = B[f], d = P[f]) : (x !== 5 && (B[f] === null ? (l = j(f, C, b), B[f] = l) : l = B[f]), x !== 3 && (d = j(f, k, M)), P[f] = d), x !== 4 && (B[L] === null ? (o = j(L, C, V), B[L] = o) : o = B[L]), x !== 2 && (g = j(L, k, F)), x === 1 ? (v = Math.abs(n[l].y - n[g].y), y = Math.abs(n[o].y - n[d].y), v < y ? (E(l, d, g), p !== null && (s[s.length - 3].twin = p, p.twin = s[s.length - 3]), E(g, o, l), w[f] !== null && (s[s.length - 2].twin = w[f], w[f].twin = s[s.length - 2]), s[s.length - 4].twin = s[s.length - 1], s[s.length - 1].twin = s[s.length - 4], w[f] = s[s.length - 5], p = s[s.length - 3]) : (E(l, d, o), w[f] !== null && (s[s.length - 1].twin = w[f], w[f].twin = s[s.length - 1]), p !== null && (s[s.length - 3].twin = p, p.twin = s[s.length - 3]), E(o, d, g), s[s.length - 5].twin = s[s.length - 3], s[s.length - 3].twin = s[s.length - 5], w[f] = s[s.length - 2], p = s[s.length - 1])) : x === 2 ? (E(l, d, o), w[f] !== null && (s[s.length - 1].twin = w[f], w[f].twin = s[s.length - 1]), p !== null && (s[s.length - 3].twin = p, p.twin = s[s.length - 3]), w[f] = null, p = null) : x === 5 ? (E(o, d, g), w[f] = s[s.length - 2], p = s[s.length - 1]) : x === 3 ? (E(o, l, g), w[f] !== null && (s[s.length - 3].twin = w[f], w[f].twin = s[s.length - 3]), w[f] = null, p = s[s.length - 1]) : (E(l, d, g), p !== null && (s[s.length - 3].twin = p, p.twin = s[s.length - 3]), w[f] = s[s.length - 2], p = null)) : (w[f] = null, p = null), P[L] = g, Q = !!x; } return console.timeEnd("triangulate"), console.log(c.length / 3), { vertices: n, indices: c, uvs: a, edges: s }; } const et = (u) => `#${u.toString(16).padStart(6, "0")}`; function st() { const u = "123456789ABCDEF"; let t = "#"; for (let e = 0; e < 6; e++) t += u[Math.floor(Math.random() * 16)]; return t; } async function it(u, t = -1, e = null) { const i = await u.arrayBuffer(), r = new DataView(i), n = { ny: r.getInt32(8, !1), xori: r.getFloat32(12, !1), xmax: r.getFloat32(16, !1), yori: r.getFloat32(20, !1), ymax: r.getFloat32(24, !1), xinc: r.getFloat32(28, !1), yinc: r.getFloat32(32, !1), nx: r.getInt32(44, !1), rot: r.getFloat32(48, !1) }, s = 1e30, a = 1e-30, c = new Float32Array(n.nx * n.ny); let h, l, o, d, g, v = 0, y = 100; for (; y < r.byteLength; ) { l = r.getInt32(y), y += 4; for (let m = 0; m < l; m += 4) h = r.getFloat32(y + m, !1), o = v % n.nx, d = n.ny - Math.floor(v / n.nx), g = (d - 1) * n.nx + o, c[g] = h < a || h > s ? t : e ? e - h : h, v++; y += l + 4; } return { header: n, data: c }; } function rt(u) { return u.map((t) => -t); } function nt(u, t) { return u.map((e) => e * t); } function at(u, t, e) { const i = (r) => { if (r.userData[u] && r.userData[u] === t) return r; if (r.children && r.children.length) for (let n = 0; n < r.children.length; n++) { const s = i(r.children[n]); if (s) return s; } return null; }; return i(e); } class N { data; columns; rows; stride; _rowLength; _lerpFn = []; arrayConstructor; constructor(t, e, i = 1) { this.data = t, this.columns = e, this.stride = i, this._rowLength = e * i, this.rows = this.data.length / this._rowLength, this.arrayConstructor = (r) => new this.data.constructor( r ); } static readWriteBlock(t, e, i, r, n, s, a, c, h, l, o = null) { if (!(t instanceof N && s instanceof N)) throw Error("Source and target must be of type Typed2dArray"); if (a < 0 || a + h > s.columns || c < 0 || c + l > s.rows) throw Error("Invalid target block dimensions!"); if (e < 0 || e + r > t.columns || i < 0 || i + n > t.rows) throw Error("Invalid source block dimensions!"); const d = Math.max(1, h - 1), g = Math.max(1, l - 1), v = Math.max(1, r - 1), y = Math.max(1, n - 1); for (let m = 0; m < l; m++) { const _ = s.index(0, m + c), A = m / g * y + i; for (let S = 0; S < h; S++) { const b = _ + (S + a) * s.stride, V = S / d * v + e; let M = t.valueAt(V, A); if (o && (M = o(M)), s.stride === 1) s.data[b] = M; else if (Array.isArray(M)) for (let F = 0; F < M.length; F++) s.data[b + F] = M[F]; } } return this; } // built-in interpolation methods static logInterp(t, e, i, r, n, s) { const a = (e * e - t * t) * n + t * t, c = (r * r - i * i) * n + i * i; return Math.sqrt((c - a) * s + a); } static linearInterp(t, e, i, r, n, s) { const a = (e - t) * n + t; return ((r - i) * n + i - a) * s + a; } static nearestInterp(t, e, i, r, n, s) { const a = n <= 0.5 ? t : e, c = n <= 0.5 ? i : r; return s <= 0.5 ? a : c; } // // create a new Typed2DArray instance using an existing data array // static from<ArrayType>(source: ArrayType, columns: number, stride = 1, copyData = false) { // const data = source instanceof Typed2DArray ? source.data : source; // const array = new Typed2DArray(data.constructor, columns, data.length / (columns * stride), stride, false); // array.data = copyData ? new array.type(data) : data; // if (source instanceof Typed2DArray) { // array.setInterpolator(...source._lerpFn); // } // return array; // } // alias for columns get width() { return this.columns; } // alias for rows get height() { return this.rows; } // get the array index to the first component from the provided column and row indices index(t, e) { if (t < 0 || e < 0 || t >= this.columns || e >= this.rows) throw Error("Index out of bounds!"); return e * this._rowLength + t * this.stride; } // get the column and row at the beginning of the item according to stride from an index into the data array positionOf(t) { if (t < 0 || t > this.data.length) return; const e = t % this.stride, i = Math.floor((t - e) / this._rowLength), r = Math.floor((t - i * this._rowLength) / this.stride); return { row: i, col: r }; } // allow you to set a custom interpolation function per component, which are used when interpolating values setInterpolator(...t) { return this._lerpFn = t, this; } // get the configured interpolation function for the given component index getInterpolator(t) { return this._lerpFn.length > 0 ? this._lerpFn[Math.min(t, this._lerpFn.length - 1)] : N.linearInterp; } // convenience function for reading an entire column col(t, e) { return this.readBlock( Math.floor(t), 0, 1, this.rows, void 0, void 0, e ); } // convenience function for reading an entire row row(t, e) { const i = this.index(0, Math.floor(t)); if (e) { for (let r = 0; r < this._rowLength; r++) e[r] = this.data[i + r]; return e; } return this.data.subarray(i, i + this._rowLength); } // set a single value into the provided column and row setValue(t, e, ...i) { const r = this.index(t, e); for (let n = 0; n < Math.min(i.length, this.stride); n++) this.data[r + n] = i[n]; return this; } // read all the values within the provided block dimension readBlock(t, e, i, r, n, s, a) { if (t < 0 || t + i > this.columns || e < 0 || e + r > this.rows) throw Error("Invalid block dimensions!"); n = Number.isFinite(n) ? n : i, s = Number.isFinite(s) ? s : r, a = a || this.arrayConstructor(n * s * this.stride); const c = Math.max(1, n - 1), h = Math.max(1, s - 1), l = Math.max(1, i - 1), o = Math.max(1, r - 1); let d = 0; for (let g = 0; g < s; g++) { const v = g / h * o + e; for (let y = 0; y < n; y++) { const m = y / c * l + t, _ = this.valueAt(m, v); if (this.stride === 1) a[d++] = _; else if (Array.isArray(_)) for (let A = 0; A < _.length; A++) a[d++] = _[A]; } } return a; } // upscale grid using the current interpolation method upscale(t, e) { if (t < this.columns || e < this.rows) throw Error( "New column and row size must be equal or bigger than the current sizes!" ); const i = this.readBlock( 0, 0, this.columns, this.rows, t, e ); return this.columns = t, this.rows = e, this._rowLength = t * this.stride, this.data = i, this; } // write values into a given block dimension writeBlock(t, e, i, r, n) { if (n.length !== i * r * this.stride) throw Error("Incorrect number of values"); if (t < 0 || t + i > this.columns || e < 0 || e + r > this.rows) throw Error("Invalid block dimensions!"); let s = 0; for (let a = e; a < e + r; a++) { const c = this.index(t, a); for (let h = 0; h < i; h++) { const l = c + h * this.stride; for (let o = 0; o < this.stride; o++) this.data[l + o] = n[s++]; } } return this; } // fills the block with a single value fillBlock(t, e, i, r, n) { if (t < 0 || t + i > this.columns || e < 0 || e + r > this.rows) throw Error("Invalid block dimensions!"); let s = (a, c, h) => { this.data[h] = n; }; typeof n == "function" ? s = (a, c, h) => { const l = n(a, c, h); if (Array.isArray(l) && l.length && l.length > 0) for (let o = 0; o < Math.min(l.length, this.stride); o++) this.data[h + o] = l[o]; else this.data[h] = l; } : this.stride > 1 && Array.isArray(n) && (s = (a, c, h) => { for (let l = 0; l < Math.min(n.length, this.stride); l++) this.data[h + l] = n[l]; }); for (let a = e; a < e + r; a++) { const c = this.index(t, a); for (let h = 0; h < i; h++) { const l = c + h * this.stride; s(h, a, l); } } return this; } // get the value corresponding to the specified index according to stride valueOf(t, e) { const { stride: i, data: r } = this; if (i > 1) { t = t % i, e = e || this.arrayConstructor(i); for (let n = 0; n < i; n++) e[n] = r[t + n]; return e; } return r[t]; } // get the calue at the requested column and row, which may be given as fractions, which in case // bilinear filtering will be applied to interpolate values (for each component) in between columns and rows valueAt(t, e, i) { const { columns: r, rows: n, stride: s, data: a } = this, c = t % 1, h = e % 1; if (c > 0 || h > 0) { const o = (t < 0 ? 0 : t >= r ? r - 1 : t) | 0, d = (e < 0 ? 0 : e >= n ? n - 1 : e) | 0, g = o === r - 1 ? o : o + 1, v = d === n - 1 ? d : d + 1; let y = this.index(o, d), m = this.index(g, d), _ = this.index(o, v), A = this.index(g, v); if (s > 1) { i = i || this.arrayConstructor(s); for (let b = 0; b < s; b++) { const V = this.getInterpolator(b); i[b] = V(a[y++], a[m++], a[_++], a[A++], c, h); } return i; } return this.getInterpolator(0)(a[y], a[m], a[_], a[A], c, h); } const l = this.index(t, e); if (s > 1) { i = i || this.arrayConstructor(s); for (let o = 0; o < s; o++) i[o] = a[l + o]; return i; } return a[l]; } // swap all values from one row with all values from another row swapRows(t, e, i) { i = i || this.arrayConstructor(this._rowLength), this.row(t, i); const r = this.index(0, t), n = this.index(0, e); for (let s = 0; s < this._rowLength; s++) this.data[r + s] = this.data[n + s], this.data[n + s] = i[s]; return this; } // invert all rows (top-bottom to bottom-top) invertRows() { const t = Math.floor(this.rows / 2), e = this.arrayConstructor(this._rowLength); for (let i = this.rows - 1, r = 0; i > t; i--, r++) this.swapRows(i, r, e); return this; } copyInto(t, e = 0, i = 0, r = this.columns - e, n = this.rows - i) { if (t.length !== r * n * this.stride) throw Error("Target is not of the correct size!"); let s = 0; for (let a = i; a < i + n; a++) { const c = this.index(0, a); for (let h = e; h < e + r; h++) { const l = c + h * this.stride; for (let o = 0; o < this.stride; o++) t[s++] = this.data[l + o]; } } return this; } // return a multi-dimensional javascript array of the data (main purpose for debugging) toJsArray() { const t = new Array(this.rows); for (let e = 0; e < this.rows; e++) { const i = this.index(0, e); t[e] = new Array(this.columns); for (let r = 0; r < this.columns; r++) if (this.stride > 1) { t[e][r] = new Array(this.stride); for (let n = 0; n < this.stride; n++) t[e][r][n] = this.data[i + r * this.stride + n]; } else t[e][r] = this.data[i + r * this.stride]; } return t; } } function lt(u) { const t = new Float32Array(u.length * 3); for (let e = 0; e < u.length; e++) { const i = e * 3; t[i + 0] = u[e][0], t[i + 1] = u[e][1], t[i + 2] = u[e][2]; } return t; } export { _e as CRS, ct as CameraManager, Y as DataLoader, ze as Delatin, ft as DepthReadMaterial, R as GeneratorRegistry, ut as PI, dt as PI2, gt as PI4, pt as PI8, wt as TAU, Me as TubeMaterial, N as Typed2DArray, yt as WellboreManager, mt as addVec2, xt as addVec3, bt as angleVec3, vt as calculateFrenetFrames, Ge as calculateHashValue, Ae as calculateWellSegments, _t as clamp, Mt as copyVec3, Fe as createConfig, Le as createElevationTexture, ke as createFenceGeometry, Se as createNormalTexture, Pe as createTubeGeometry, At as crossVec3, Ft as degreesToRadians, Lt as directionVec2, St as directionVec3, Vt as distanceVec2, It as distanceVec3, Bt as dotVec2, Et as dotVec3, Tt as edgeOfRectangle, Ve as elevationMapNormalsToRGBA, Dt as feetToMeters, qt as getCurvePositions, zt as getFormationMarkers, at as getObjectByCustomProperty, Gt as getProjectedTrajectory, Ie as getProjectionDefFromUtmZone, kt as getSplineCurve, Pt as getTrajectory, jt as getTypedArrayFromBuffer, Nt as getTypedArrayType, Be as getUtmZoneFromLatLng, Ct as getVec2, Qt as getVec3, Ut as getWellboreFormations, et as idToHexColor, Wt as inverseLerp, Ht as lengthVec2, Zt as lengthVec3, $t as lerp, Jt as mergeFormationIntervals, Kt as mixVec2, Ot as mixVec3, nt as multiply, rt as negate, Xt as negateVec2, Yt as negateVec3, Rt as normalizeVec2, te as normalizeVec3, ee as normalizedDeviceToScreen, se as packAttribute, ie as packBufferGeometries, re as packBufferGeometry, ne as packBufferGeometryLike, it as parseIrapbin, st as randomColor, ae as readDepth, le as remap, oe as rotateVec3, he as scaleVec2, ce as scaleVec3, fe as screenToNormalizedDevice, ue as setVec2, de as setVec3, ge as simplifyCurve2D, pe as subVec2, we as subVec3, je as titleCase, lt as toFloat32Array, ye as toRGB, Ee as toSegments, Te as triangleNormal, tt as triangulateGrid, Ne as triangulateGridDelaunay, me as unpackBufferGeometries, xe as unpackBufferGeometry, be as uvMaterial, De as wgs84Def };