@three3d/effect
Version:
@three3d/effect 提供了 ThreeJS 的特效
991 lines (987 loc) • 29.7 kB
JavaScript
var oe = Object.defineProperty;
var se = (e, s, t) => s in e ? oe(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t;
var A = (e, s, t) => (se(e, typeof s != "symbol" ? s + "" : s, t), t);
import { createLineCurves as Ct, createLineCurve as Lt, getCurveDivisionLength as xt, getLinesInfo as re, closeCurvePath as ie, LineConnectionType as ae, computeCurveFrenetFrames as le, createSymmetricSegmentedTrigonometricIndexs as St, computePolylineFrenetFramesByFixUp as Tt, computePolylineFrenetFrames as ce, createLineConnection as ue, createSymmetricSegmentedTrigonometricIndexsByVertexs as It } from "@three3d/tools";
import { Curve as lt, CurvePath as Ft, Color as y, BufferGeometry as he, Float32BufferAttribute as gt, Vector3 as yt, Quaternion as ge, Vector2 as Ut } from "three";
function pe(e, s) {
const t = e.length;
let n = 1 / 0, o = 0;
for (; o < t; ) {
const r = e[o], i = s - r;
if (s < r)
return -i > n ? o - 1 : o;
n = i, o++;
}
return o;
}
function fe(e, s, t) {
const n = e.length;
let o = 0;
for (; o < n; ) {
const r = e[o];
if (s < r)
return t ? o : o - 1;
o++;
}
return t ? -1 : o;
}
function de(e) {
var n;
let s;
const t = [];
for (let o of e) {
let r, i = null;
if (o instanceof lt ? (i = [o], r = o.getPoint(0)) : Array.isArray(o) ? (o.length > 1 && (i = Ct(o)), r = o[0]) : r = o, s && !s.equals(r)) {
const l = Lt(s, r);
t.push(l);
}
i && t.push(...i), s = (n = t.at(-1)) == null ? void 0 : n.getPoint(1);
}
return t;
}
function Ie(e) {
let s;
const t = [];
for (let n of e) {
if (n instanceof lt) {
t.push(n), s = n.getPoint(1);
continue;
} else if (Array.isArray(n)) {
if (n.length > 1) {
const o = Ct(n);
t.push(...o), s = n.at(-1);
continue;
}
n = n[0];
}
if (s && !s.equals(n)) {
const o = Lt(s, n);
t.push(o);
}
s = n;
}
return t;
}
function wt(e, s, t) {
let n, o = [];
if (e instanceof lt ? (n = e.getPoint(0), o = [e]) : Array.isArray(e) ? (e.length > 1 && (o = Ct(e)), n = e[0]) : n = e, s && (t || o.length === 0) && (t || o.length === 0)) {
const r = Lt(s, n);
o.unshift(r);
}
return o;
}
function Ue(e, s, t) {
const n = wt(e, s, t);
switch (n.length) {
case 0:
return null;
case 1:
return n[0];
}
const o = new Ft();
return o.curves.push(...n), o;
}
function Rt(e) {
return e instanceof lt ? e.getPoint(0) : Array.isArray(e) ? e[0] : e;
}
function Mt(e) {
return e instanceof lt ? e.getPoint(1) : Array.isArray(e) ? e.at(-1) : e;
}
const ft = "lineDistance", pt = {
width: 1,
sampleLength: 1,
startLength: 0,
startColor: 65280,
endColor: 255,
autoClose: !1
};
function me(e, s) {
const { division: t } = xt({ ...s, curve: e });
return e.getPoints(t);
}
function ve(e, s) {
const { startColor: t, endColor: n, color: o, startLength: r } = s || {}, i = o ? new y(o) : null, l = t ? new y(t) : i ?? new y(0, 1, 0), a = n ? new y(n) : i ?? new y(0, 0, 1), c = r ?? 0, u = [], g = [], h = re(e).lengths, m = 1 / (h.at(-1) + c), d = new y();
return e.forEach((f, b) => {
f.toArray(u, b * 3);
const D = h[b] + c;
h[b] = D;
const _ = D * m;
d.lerpColors(l, a, _), d.toArray(g, b * 3);
}), { color: g, position: u, lineDistance: h, lengths: h, points: e };
}
class Nt extends he {
constructor(t) {
super();
A(this, "isPathGeometry", !0);
A(this, "_options", null);
A(this, "_startDrawLength", 0);
A(this, "_endDrawLength", 1 / 0);
A(this, "_pathData", []);
A(this, "_curves", []);
A(this, "_curvePath", this.generateCurvePath());
/**
* 所有的顶点
*/
A(this, "points", []);
/**
* 曲线上生成的点
*/
A(this, "lengths", []);
t && (this.options = t);
}
/**
* 全局选项
*/
get globalOptions() {
return this.constructor.options;
}
/**
* 实例级别的选项
* @remarks
* 优先级高于 类级别的选项
*/
get options() {
return this._options ?? (this._options = structuredClone(this.globalOptions));
}
set options(t) {
const n = this.options;
this._options = t ? Object.assign(n, t) : null;
}
/**
* 路径的宽度
*/
get width() {
return this.options.width ?? (this.options.width = this.globalOptions.width ?? pt.width);
}
set width(t) {
this.options.width = t;
}
/**
* 采样长度
*/
get sampleLength() {
return this.options.sampleLength ?? (this.options.sampleLength = this.globalOptions.sampleLength ?? pt.sampleLength);
}
set sampleLength(t) {
this.options.sampleLength = t;
}
/**
* 采样数
*/
get sampleNum() {
return this.options.sampleNum ?? (this.options.sampleNum = this.globalOptions.sampleNum);
}
set sampleNum(t) {
this.options.sampleNum = t;
}
/**
* 是否自动闭合
*/
get autoClose() {
return this.options.autoClose ?? (this.options.autoClose = this.globalOptions.autoClose);
}
set autoClose(t) {
this.options.autoClose = t, this.curvePath.autoClose = !!t;
}
/**
* 当前是否已经闭合
*/
get closed() {
const { points: t } = this, n = t[0], o = t.at(-1);
return n && o ? n.equals(o) : !1;
}
/**
* 线的颜色
* @remarks
* 顶点颜色
*/
get color() {
let t = this.options.color;
if (!t) {
const n = this.globalOptions.color;
n && (this.options.color = t = structuredClone(n));
}
return t;
}
set color(t) {
this.options.color = t;
}
/**
* 线开始处的颜色
* @remarks
* 用于生成路径的从开始颜色到结束颜色的过渡颜色
*
* @defaultValue this.color
*/
get startColor() {
let t = this.options.startColor;
if (!t) {
const n = this.globalOptions.startColor ?? pt.startColor;
this.options.startColor = t = structuredClone(n);
}
return t;
}
set startColor(t) {
this.options.startColor = t;
}
/**
* 终点处的颜色
* @remarks
* 用于生成路径的从开始颜色到结束颜色的过渡颜色
*
* @defaultValue this.color
*/
get endColor() {
let t = this.options.endColor;
if (!t) {
const n = this.globalOptions.endColor ?? pt.endColor;
this.options.endColor = t = structuredClone(n);
}
return t;
}
set endColor(t) {
this.options.endColor = t;
}
/**
* 路径起始位置处的长度
*/
get startLength() {
return this.options.startLength ?? (this.options.startLength = this.globalOptions.startLength ?? 0);
}
set startLength(t) {
this.options.startLength = t;
}
/**
* 终点位置处的长度
*/
get endLength() {
return this.lengths.at(-1) ?? this.startLength;
}
/**
* 获取顶点对应的长度的数组
*/
get lineDistance() {
var t;
return (t = this.getAttribute(ft)) == null ? void 0 : t.array;
}
/**
* 获取与指定长度值最近的索引
* @param length - 目标长度值
* @returns
*/
getClosestIndex(t) {
return pe(this.lineDistance, t);
}
/**
* 获取目标长度值附近的索引
* @param length - 目标长度值
* @param right - 是否获取目标值右侧的索引;
* @returns 当返回 -1 时,表示没找到
*/
getNearbyIndex(t, n) {
return fe(this.lineDistance, t, n);
}
/**
* 设置绘制的长度范围
* @param startLength
* @param endLength
*/
setDrawLength(t, n) {
const o = this.getClosestIndex(t);
let r = 1 / 0;
n == null || n === 1 / 0 || (r = this.getClosestIndex(n) - o + 1), this.setDrawRange(o, r);
}
/**
* 开始绘制的长度范围
*/
get startDrawLength() {
return this._startDrawLength;
}
set startDrawLength(t) {
this._startDrawLength = t, this.setDrawLength(t, this.endDrawLength);
}
/**
* 结束绘制的长度范围
*/
get endDrawLength() {
return this._endDrawLength ?? (this._endDrawLength = 1 / 0);
}
set endDrawLength(t) {
this._endDrawLength = t, this.setDrawLength(this.startDrawLength, t);
}
copy(t) {
super.copy(t);
const { lengths: n, _startDrawLength: o, _endDrawLength: r } = t;
return this.lengths = n ? [...n] : [], this._startDrawLength = o ?? 0, this._endDrawLength = r || null, this;
}
/**
* 顶点个数
*/
get vertexCount() {
var t;
return ((t = this.getAttribute("position")) == null ? void 0 : t.count) ?? 0;
}
/**
* 路径数据
*/
get pathData() {
return this._pathData;
}
set pathData(t) {
this._pathData = t, this.curves = de(t);
}
get closedPathData() {
let t = this.pathData;
if (this.autoClose) {
const n = Rt(t[0]), o = Mt(t.at(-1));
n.equals(o) || (t = [...t, n.clone()]);
}
return t;
}
/**
* 组成路径的曲线列表
*/
get curves() {
return this._curves;
}
set curves(t) {
this._curves = t, this.curvePath = this.generateCurvePath();
}
/**
* 表示路径的曲线
*/
get curvePath() {
return this._curvePath;
}
set curvePath(t) {
this._curvePath = t, this.updateGeometry();
}
/**
* 闭合的曲线路径
*/
get closedCurvePath() {
let t = this.curvePath;
return this.autoClose && (t = t.clone(), ie(t), t.autoClose = !1), t;
}
/**
* 生成曲线
* @returns
*/
generateCurvePath() {
const t = new Ft();
return t.curves = this.curves, t.autoClose = !!this.autoClose, t;
}
/**
* 线性几何体本身的长度
*/
get length() {
return this.endLength - this.startLength;
}
/**
* curvePath 上的最后一个点
*/
get lastPoint() {
return this.curvePath.getPoint(1);
}
/**
* curvePath 上的第一个点
*/
get firstPoint() {
return this.curvePath.getPoint(0);
}
append(t) {
const n = wt(t, this.lastPoint, !0);
this.pathData.push(t), this.curves.push(...n), this.updateGeometry();
}
set(t) {
this.pathData = [t], this.updateGeometry();
}
updateGeometry() {
const { curvePath: t, options: n } = this, o = me(t, n), r = ve(o, n);
this.resetAttributes(r);
}
/**
* 追加新的属性
* @param attrs
*/
appendAttributes(t) {
var m, d, f, b, D, _;
const { position: n, normal: o, uv: r, lengths: i, lineDistance: l, index: a, color: c, points: u } = t, g = ((m = this.getAttribute("position")) == null ? void 0 : m.array) ?? [], h = this.lengths, p = {
// @ts-ignore
position: [...g, ...n],
lengths: [...h, ...i],
points: [...this.points, ...u]
};
if (o) {
const v = ((d = this.getAttribute("normal")) == null ? void 0 : d.array) ?? [];
p.normal = [...v, ...o];
}
if (r) {
const v = ((f = this.getAttribute("uv")) == null ? void 0 : f.array) ?? [];
p.uv = [...v, ...r];
}
if (a) {
const v = ((b = this.getIndex()) == null ? void 0 : b.array) ?? [];
p.index = [...v, ...a];
}
if (c) {
const v = ((D = this.getAttribute("color")) == null ? void 0 : D.array) ?? [];
p.color = [...v, ...c];
}
if (l) {
const v = ((_ = this.getAttribute(ft)) == null ? void 0 : _.array) ?? [];
p.lineDistance = [...v, ...l];
}
this.resetAttributes(p);
}
/**
* 重围所有的 Attributes
* @param attrs
*/
resetAttributes(t) {
const { position: n, normal: o, uv: r, lineDistance: i, lengths: l, index: a, color: c, points: u } = t;
this.setAttribute("position", new gt(n, 3)), a && this.setIndex(a), o ? this.setAttribute("normal", new gt(o, 3)) : this.deleteAttribute("normal"), r ? this.setAttribute("uv", new gt(r, 2)) : this.deleteAttribute("uv"), c ? this.setAttribute("color", new gt(c, 3)) : this.deleteAttribute("color"), i ? this.setAttribute(ft, new gt(i, 1)) : this.deleteAttribute(ft), this.lengths = l, this.points = u, this.boundingBox !== null && this.computeBoundingBox(), this.boundingSphere !== null && this.computeBoundingSphere();
}
/**
* position 属性中的最后一个点
*/
get lastPosition() {
const t = this.getAttribute("position");
if (!t)
return null;
const n = t.count;
return new yt().fromBufferAttribute(t, n - 1);
}
}
/**
* 全局选项
* @remarks
* 类级别的选项,对所有后续创建的实例有效;
* 优化级低于实例级别的选项
*
* @defaultValue default_PathGeometryOptions
*/
A(Nt, "options", structuredClone(pt));
var be = /* @__PURE__ */ ((e) => (e.curve = "curve", e.polyline = "polyline", e.blend = "blend", e))(be || {});
const $ = {
up: { x: 0, y: 1, z: 0 },
useU: !1,
fixUp: !1,
uvStep: 1,
drawType: "blend",
connectionType: ae.round,
smoothStepAngle: 0.5
};
function Vt(e, s) {
const { up: t, autoClose: n } = s, { division: o, length: r } = xt({ ...s, curve: e }), i = le(e, o, t, { ...s, closed: n });
return i.length = r, ye(i, s);
}
function ye(e, s) {
const { startColor: t, endColor: n, color: o, preIndex: r, prePoint: i, connectPre: l } = s, a = o ? new y(o) : null, c = t ? new y(t) : a ?? new y(0, 1, 0), u = n ? new y(n) : a ?? new y(0, 0, 1), g = s.width ?? 1, h = s.preLength ?? 0, { points: p, tangents: m, normals: d, binormals: f, length: b } = e, D = p[0], _ = i ? D.distanceTo(i) : 0, v = b + _ + h, k = s.uvStep ?? v, O = p.length - 1, W = g / 2, H = [], U = [], q = [], tt = [], J = [], R = [], M = 1 / k, K = 1 / v;
let w = h;
const S = new y();
let X = p[0];
for (let B = 0; B <= O; B++) {
const I = p[B], nt = d[B], C = f[B];
w += I.distanceTo(X), H.push(w), R.push(w, w);
const j = w * M;
tt.push(0, j, 1, j);
const z = w * K;
S.lerpColors(c, u, z);
const Q = C.clone().multiplyScalar(W), N = I.clone().sub(Q);
let x = B * 2 * 3;
N.toArray(U, x), nt.toArray(q, x), S.toArray(J, x);
const ot = I.clone().add(Q);
x += 3, ot.toArray(U, x), nt.toArray(q, x), S.toArray(J, x), X = I;
}
const et = U.length / 3, Y = r ? St(et, r + 1, l) : St(et);
return { position: U, normal: q, uv: tt, index: Y, color: J, lineDistance: R, lengths: H, points: p, tangents: m, normals: d, binormals: f };
}
function Dt(e, s) {
const { up: t, autoClose: n } = s;
if (n) {
const r = e[0], i = e.at(-1);
r.equals(i) || (e = [...e, r.clone()]);
}
const o = s.fixUp ? Tt(e, t) : ce(e, t);
return o.points = e, Gt(o, s);
}
function Gt(e, s) {
const { startColor: t, endColor: n, color: o, prePoint: r, preIndex: i, connectPre: l } = s, a = o ? new y(o) : null, c = t ? new y(t) : a ?? new y(0, 1, 0), u = n ? new y(n) : a ?? new y(0, 0, 1), g = s.width ?? 1, h = g / 2, p = s.preLength ?? 0, { tangents: m, normals: d, binormals: f, lengths: b, points: D } = e, _ = b.at(-1);
let v = m[0], k = d[0], O = f[0];
const W = D[0], U = (r ? W.distanceTo(r) : 0) + p, q = _ + U, tt = s.uvStep ?? q, J = b.map((C) => C + U), R = [], M = [], K = [], w = [], S = [], X = 1 / tt, et = 1 / q, Y = new y(), B = D.length - 1;
let I = 0;
for (let C = 0; C <= B; C++) {
const j = J[C], z = D[C], Q = m[C], N = d[C], x = f[C], ot = C < B, mt = C > 0, vt = ot && mt;
let Z, st, rt;
if (vt) {
let G = ue({ point: z, length: j, width: g }, { tangent: v, normal: k, binormal: O }, { tangent: Q, normal: N, binormal: x }, s);
Z = G.points, st = G.normals, rt = G.lengths;
} else {
const L = x.clone().multiplyScalar(h), V = z.clone().sub(L), T = z.clone().add(L);
Z = [V, T], st = [N, N], rt = [j, j];
}
const it = Z.length;
for (let L = 0; L < it; L++) {
const V = Z[L], T = rt[L], G = st[L], ct = T * et;
Y.lerpColors(c, u, ct), Y.toArray(w, I), V.toArray(R, I), G.toArray(M, I), S.push(T);
const ut = L % 2, ht = T * X;
K.push(ut, ht), I += 3;
}
v = Q, k = N, O = x;
}
const nt = i ? It(R, i + 1, l) : It(R);
return { position: R, normal: M, uv: K, color: w, index: nt, lineDistance: S, length, lengths: J, points: D, tangents: m, normals: d, binormals: f };
}
var De = /* @__PURE__ */ ((e) => (e.intact = "intact", e.add = "add", e.addGap = "addGap", e))(De || {});
function Ce(e, s, t, n = "intact") {
let { points: o, index: r, lengths: i, position: l, normal: a, uv: c, color: u, lineDistance: g, tangents: h, normals: p, binormals: m } = e, { points: d, index: f, lengths: b, position: D, normal: _, uv: v, color: k, lineDistance: O, tangents: W, normals: H, binormals: U } = s;
const { fixUp: q, up: tt } = t, R = r.at(-3) - 4, M = o.at(-1), K = o.at(-2);
let w = b.at(-1);
const S = d[0], X = d[1];
if (n && n !== "intact") {
let P = i.at(-1);
n === "addGap" && (P += M.distanceTo(S));
const at = P / w;
w += P;
let E = O.length;
for (let F = 0; F < E; F++)
O[F] += P, v[F * 2 + 1] += at;
E = b.length;
for (let F = 0; F < E; F++)
b[F] += P;
}
const et = h.at(-1), Y = h.at(-2), B = p.at(-1), I = p.at(-2), nt = m.at(-1), C = m.at(-2), j = i.at(-1), z = i.at(-2), Q = W[0], N = W[1], x = H[0], ot = H[1], mt = U[0], vt = U[1], Z = b[0], st = b[1], rt = M.equals(S), it = rt ? [K, S, X] : [K, M, S, X];
let L;
if (q)
L = {
...Tt(it, tt),
points: it
};
else if (rt)
L = {
tangents: [Y, Q, N],
normals: [I, x, ot],
binormals: [C, mt, vt],
lengths: [z, Z, st],
points: it
};
else {
const P = S.clone().sub(M).normalize(), at = new ge().setFromUnitVectors(et, P), E = B.clone().applyQuaternion(at), F = nt.clone().applyQuaternion(at);
L = {
tangents: [Y, P, Q, N],
normals: [I, E, x, ot],
binormals: [C, F, mt, vt],
lengths: [z, j, Z, st],
points: it
};
}
let { index: V, position: T, normal: G, uv: ct, color: ut, lineDistance: ht } = Gt(L, { ...t, preLength: void 0, preIndex: R, prePoint: void 0, connectPre: !1 });
if (l = l.slice(0, -6), a = a.slice(0, -6), c = c.slice(0, -4), u = u.slice(0, -6), g = g.slice(0, -2), T = T.slice(6, -6), G = G.slice(6, -6), ct = ct.slice(4, -4), ut = ut.slice(6, -6), ht = ht.slice(2, -2), V = V.slice(6, -6), D = D.slice(6), _ = _.slice(6), v = v.slice(4), k = k.slice(6), O = O.slice(2), t.connectPre) {
const P = f.length % 6;
f = f.slice(P);
}
const At = Math.min(...f.slice(0, 3)), _t = Math.max(...V.slice(-3)) - 1;
if (_t !== At) {
let P = f.length;
const at = _t - At;
for (let E = 0; E < P; E++)
f[E] += at;
}
const Wt = [...l, ...T, ...D], Ht = [...a, ...G, ..._], Jt = [...c, ...ct, ...v], Kt = [...u, ...ut, ...k], Xt = [...g, ...ht, ...O], Yt = [...r, ...V, ...f], Zt = [...o, ...d], $t = [...i, ...b], te = [...h, ...W], ee = [...p, ...H], ne = [...m, ...U];
return { position: Wt, normal: Ht, uv: Jt, color: Kt, lineDistance: Xt, index: Yt, points: Zt, lengths: $t, length: w, tangents: te, normals: ee, binormals: ne };
}
function Bt(e, s, t) {
let n = t, o;
const { autoClose: r } = s;
if (r) {
const i = (t == null ? void 0 : t.points) ?? [Rt(e[0]), Mt(e.at(-1))], l = i[0], a = i.at(-1);
l.equals(a) || e.push(l.clone());
}
s = { ...s, autoClose: !1 };
for (let i of e) {
let l, a, c = o, u = s;
if (n) {
const { points: p, lengths: m, index: d } = n;
l = m.at(-1), a = d.at(-3), c = p.at(-1), u = { ...s, preLength: l, preIndex: a, prePoint: c, connectPre: !1 };
}
o && (u = { ...s, prePoint: c });
let g, h;
i instanceof lt ? h = Vt(i, u) : Array.isArray(i) ? (i.length > 1 && (h = Dt(i, u)), g = i[0]) : g = i, !h && c && g && !c.equals(g) && (h = Dt([c, g], n ? u : s)), h ? (n = n ? Ce(n, h, { ...s, connectPre: !1 }) : h, o = void 0) : o = g;
}
return n;
}
class Le extends Nt {
constructor(t) {
super(t);
A(this, "isBandGeometry", !0);
A(this, "frenetFrames", null);
}
/**
* 起点处的向上的方向 { x: 0, y: 1, z: 0 }
* @defaultValue
*/
get up() {
return this.options.up ?? (this.options.up = Object.assign({}, this.globalOptions.up ?? $.up));
}
set up(t) {
this.options.up = t;
}
/**
* 是否固定 up;保证up不变
* @defaultValue false
*/
get fixUp() {
return this.options.fixUp ?? (this.options.fixUp = this.globalOptions.fixUp ?? $.fixUp);
}
set fixUp(t) {
this.options.fixUp = t;
}
/**
* 是否固定 up;保证up不变
* @defaultValue false
*/
get useU() {
return this.options.useU ?? (this.options.useU = this.globalOptions.useU ?? $.useU);
}
set useU(t) {
this.options.useU = t;
}
/**
* uv的步长
*
* @defaultValue 1
*/
get uvStep() {
return this.options.uvStep ?? (this.options.uvStep = this.globalOptions.uvStep ?? $.uvStep);
}
set uvStep(t) {
this.options.uvStep = t;
}
/**
* CurvePath 的绘制类型
* @defaultValue BandDrawType.blend
*/
get drawType() {
return this.options.drawType ?? (this.options.drawType = this.globalOptions.drawType ?? $.drawType);
}
set drawType(t) {
this.options.drawType = t;
}
/**
* 线的衔接类型
* @defaultValue LineConnectionType.round
*/
get connectionType() {
return this.options.connectionType ?? (this.options.connectionType = this.globalOptions.connectionType ?? $.connectionType);
}
set connectionType(t) {
this.options.connectionType = t;
}
/**
* 圆形衔接角的长度步长
* @remarks
* 与 smoothStepAngle 作用相同
* smoothStepAngle 的优先级高于 smoothStepLength
*/
get smoothStepLength() {
return this.options.smoothStepLength;
}
set smoothStepLength(t) {
this.options.smoothStepLength = t;
}
/**
* 圆形衔接角的步长角
* @remarks
* 与 smoothStepLength 作用相同
* smoothStepAngle 的优先级高于 smoothStepLength
* @defaultValue LineConnectionType.round
*/
get smoothStepAngle() {
return this.options.smoothStepAngle;
}
set smoothStepAngle(t) {
this.options.smoothStepAngle = t;
}
append(t) {
const { lastPoint: n, endLength: o } = this, r = wt(t, n, !0);
if (this.pathData.push(t), this.curves.push(...r), this.drawType !== "blend")
return this.updateGeometry();
const { openedGeometryData: i, options: l } = this, a = [t], c = new yt().copy(l.up ?? { x: 0, y: 1, z: 0 }).normalize(), u = { ...l, preLength: o, up: c, connectPre: !0 };
if (i) {
const { lengths: h, index: p, points: m } = i;
u.preLength = h.at(-1), u.preIndex = p.at(-3), u.prePoint = m.at(-1);
}
const g = Bt(a, u, i);
this.resetAttributes(g);
}
updateGeometry() {
const { closedCurvePath: t, closedPathData: n, endLength: o, drawType: r, options: i } = this, l = new yt().copy(i.up ?? { x: 0, y: 1, z: 0 }).normalize(), a = { ...i, preLength: o, autoClose: !1, up: l, connectPre: !0 };
let c;
switch (r) {
case "curve": {
c = Vt(t, a);
break;
}
case "polyline": {
const { division: u } = xt({ ...a, curve: t }), g = t.getPoints(u);
c = Dt(g, a);
break;
}
default: {
c = Bt(n, a);
break;
}
}
this.resetAttributes(c);
}
/**
* 几何体的数据
*/
get geometryData() {
const t = this.frenetFrames;
if (!t)
return null;
const n = this.getAttribute("position").array, o = this.getAttribute("normal").array, r = this.getAttribute("uv").array, i = this.getIndex().array, l = this.getAttribute("color").array, a = this.getAttribute(ft).array;
return {
position: n,
normal: o,
uv: r,
index: i,
color: l,
lineDistance: a,
...t
};
}
/**
* 未闭合的几何体的数据
*/
get openedGeometryData() {
const { geometryData: t, closed: n } = this;
if (!(t && n))
return t;
const { position: o, normal: r, uv: i, index: l, color: a, lineDistance: c, lengths: u, points: g, tangents: h, normals: p, binormals: m } = t, d = -6, f = -1;
return {
position: o.slice(0, d),
normal: r.slice(0, d),
uv: i.slice(0, -4),
color: a.slice(0, d),
lineDistance: c.slice(0, -2),
index: l.slice(0, d),
lengths: u.slice(0, f),
points: g.slice(0, f),
tangents: h.slice(0, f),
normals: p.slice(0, f),
binormals: m.slice(0, f)
};
}
/**
* 重围所有的 Attributes
* @param attrs
*/
resetAttributes(t) {
super.resetAttributes(t);
const { points: n, tangents: o, normals: r, binormals: i, lengths: l } = t;
this.frenetFrames = { points: n, tangents: o, normals: r, binormals: i, lengths: l };
}
/**
* 获取顶点索引对应的分段索引
* @remarks
* 分段指的是沿路径的方向上的分段
* @param vertexIndex
* @returns
*/
getDivisionIndex(t) {
return Math.floor(t / 2);
}
/**
* 设置绘制的长度范围
* @param startLength
* @param endLength
*/
setDrawLength(t, n) {
var l;
let o = ((l = this.getIndex()) == null ? void 0 : l.count) ?? 1;
o -= 1;
let r = this.getClosestIndex(t);
r = this.getDivisionIndex(r) * 6, r = Math.min(r, o);
let i = 1 / 0;
if (!(n == null || n === 1 / 0)) {
let a = this.getClosestIndex(n);
a = this.getDivisionIndex(a) * 6, a = Math.min(a, o), i = a - r + 1;
}
this.setDrawRange(r, i);
}
}
Object.assign(Le.options, $);
function Et(e, s) {
for (const [t, n] of Object.entries(s))
e[t] = { value: n };
return e;
}
function Ot(e, s, t) {
e.uniforms = Et(t || e.uniforms || {}, s);
const n = {}, o = Object.keys(e);
for (const [r, i] of Object.entries(s)) {
if (o.includes(r))
continue;
const l = function() {
return this.uniforms[r].value;
}, a = i.copy ? function(c) {
this.uniforms[r].value.copy(c);
} : function(c) {
this.uniforms[r].value = c;
};
n[r] = {
configurable: !0,
enumerable: !0,
get: l,
set: a
};
}
return Object.defineProperties(e, n), e;
}
function dt(e, s, t) {
let n;
return t && s ? (Ot(t, s), n = function(o, ...r) {
const i = o.uniforms;
this.uniforms = Et(i, s), e.call(this, o, ...r);
}) : s ? n = function(o, ...r) {
const i = o.uniforms;
Ot(this, s, i), e.call(this, o, ...r);
} : n = function(o, ...r) {
this.uniforms = o.uniforms, e.call(this, o, ...r);
}, n;
}
const bt = /void\s+main\s*\(\)\s*\{\s*/, kt = {
invert: !1,
enableURange: !0,
enableVRange: !0,
uvMax: new Ut(1e5, 1e5),
uvMin: new Ut(0, 0)
}, xe = (
/* glsl */
`
uniform bool invert;
uniform bool enableURange;
uniform bool enableVRange;
uniform vec2 uvMax;
uniform vec2 uvMin;
void main() {
bool isDiscard = false;
#if defined(USE_MAP) || defined(USE_UV)
vec2 rangeUV;
#ifdef USE_MAP
rangeUV = vMapUv;
#else
rangeUV = vUv;
#endif
bool xDiscard = enableURange && ( uvMin.x > rangeUV.x || rangeUV.x > uvMax.x);
bool yDiscard = enableVRange && (uvMin.y > rangeUV.y || rangeUV.y > uvMax.y);
isDiscard = xDiscard || yDiscard;
#endif
if (invert){
isDiscard = !isDiscard;
}
if (isDiscard) discard;
`
);
function qt(e) {
e.fragmentShader = e.fragmentShader.replace(bt, xe);
}
const Be = dt(qt, kt);
function Oe(e) {
const s = e.defines ?? (e.defines = {});
return s.USE_UV = !0, e.onBeforeCompile = dt(qt, kt, e), e;
}
const Pt = {
invert: !1,
enableStart: !0,
enableEnd: !0,
startLength: 0,
endLength: 1e6
}, we = (
/* glsl */
`
attribute float lineDistance;
varying float vLineDistance;
void main() {
vLineDistance = lineDistance;
`
), Pe = (
/* glsl */
`
varying float vLineDistance;
`
), jt = (
/* glsl */
`
uniform bool invert;
uniform bool enableStart;
uniform bool enableEnd;
uniform float startLength;
uniform float endLength;
void main() {
bool startDiscard = enableStart && vLineDistance < startLength;
bool endDiscard = enableEnd && vLineDistance > endLength;
bool isDiscard = startDiscard || endDiscard;
if (invert){
isDiscard = !isDiscard;
}
if (isDiscard) discard;
`
);
function zt(e) {
e.vertexShader = e.vertexShader.replace(bt, we);
const s = Pe + jt;
e.fragmentShader = e.fragmentShader.replace(bt, s);
}
function Qt(e) {
e.fragmentShader = e.fragmentShader.replace(bt, jt);
}
const Te = dt(zt, Pt), Fe = dt(Qt, Pt);
function Re(e) {
const s = e.isLineDashedMaterial ? Qt : zt;
return e.onBeforeCompile = dt(s, Pt, e), e;
}
export {
Le as BandGeometry,
De as LengthConnectType,
be as PathDrawType,
Nt as PathGeometry,
Ot as addUniformPropertiesOnMaterial,
Et as addUniforms,
Ce as connectBandGeometryData,
Bt as createBlendBandGeometryData,
Vt as createCurveBandGeometryData,
ye as createCurveBandGeometryDataByFrenetFrames,
dt as createOnBeforeCompile,
Dt as createPolylineBandGeometryData,
Gt as createPolylineBandGeometryDataByFrenetFrames,
ve as createPolylinePathGeometryData,
pe as getClosestIndex,
me as getCurvePoints,
fe as getNearbyIndex,
Mt as getPathItemEndPoint,
Rt as getPathItemStartPoint,
ft as lengthAttributeName,
Re as lengthDrawRangeModifier,
zt as lengthDrawRange_Mender,
jt as lengthDrawRange_fragment_mainReplace,
Pe as lengthDrawRange_fragment_pars_mainReplace,
Te as lengthDrawRange_onBeforeCompile,
Pt as lengthDrawRange_uniforms,
we as lengthDrawRange_vertex_mainReplace,
Qt as lineDashedLengthDrawRange_Mender,
Fe as lineDashedLengthDrawRange_onBeforeCompile,
bt as minFun_Regex,
de as pathDataToContinuousCurves,
Ie as pathDataToCurves,
Ue as pathItemToCurve,
wt as pathItemToCurves,
Oe as uvDrawRangeModifier,
qt as uvDrawRange_Mender,
xe as uvDrawRange_fragment_mainReplace,
Be as uvDrawRange_onBeforeCompile,
kt as uvDrawRange_uniforms
};