@takram/three-clouds
Version:
A Three.js and R3F implementation of geospatial volumetric clouds
200 lines (199 loc) • 5.3 kB
JavaScript
import { jsx as E, jsxs as M, Fragment as N } from "react/jsx-runtime";
import { useFrame as k, useThree as B } from "@react-three/fiber";
import { EffectComposerContext as W } from "@react-three/postprocessing";
import { createContext as j, useState as A, useLayoutEffect as x, useContext as y, useMemo as L, useEffect as i, useCallback as X } from "react";
import { TextureLoader as Z, LinearMipMapLinearFilter as $, LinearFilter as C, RepeatWrapping as p, NoColorSpace as F, Data3DTexture as q, RedFormat as G } from "three";
import { AtmosphereContext as J, separateProps as K } from "@takram/three-atmosphere/r3f";
import { DEFAULT_STBN_URL as Q, DataTextureLoader as V, parseUint8Array as Y, STBNLoader as z } from "@takram/three-geospatial";
import { c as D, b as w, d as ee, e as te, D as re, f as oe, g as se, h as ae, a as ne, C as le } from "./shared.js";
const S = /* @__PURE__ */ j(null), ue = ({
layers: e,
disableDefault: t = !1,
children: s
}) => {
const [a, u] = A();
return x(() => {
e.set(
t ? Array(4).fill(w.DEFAULT) : D.DEFAULT
), u({
layers: e,
indexPool: [0, 1, 2, 3],
disableDefault: t
});
}, [e, t]), a != null && /* @__PURE__ */ E(S.Provider, { value: a, children: s });
};
function U(e, t) {
const s = L(
() => typeof e == "string" ? new Z().load(e, (a) => {
a.minFilter = $, a.magFilter = C, a.wrapS = p, a.wrapT = p, a.colorSpace = F, a.needsUpdate = !0;
}) : void 0,
[e]
);
return i(() => {
if (s != null)
return () => {
s.dispose();
};
}, [s]), (typeof e == "string" ? s : e) ?? null;
}
function g(e, t) {
const s = L(
() => typeof e == "string" ? new V(q, Y, {
width: t,
height: t,
depth: t,
format: G,
minFilter: C,
magFilter: C,
wrapS: p,
wrapT: p,
wrapR: p,
colorSpace: F
}).load(e) : void 0,
[e, t]
);
return i(() => {
if (s != null)
return () => {
s.dispose();
};
}, [s]), (typeof e == "string" ? s : e) ?? null;
}
function ce(e) {
const t = L(
() => typeof e == "string" ? new z().load(e) : void 0,
[e]
);
return i(() => {
if (t != null)
return () => {
t.dispose();
};
}, [t]), (typeof e == "string" ? t : e) ?? null;
}
const Ee = ({
ref: e,
disableDefaultLayers: t = !1,
localWeatherTexture: s = re,
shapeTexture: a = oe,
shapeDetailTexture: u = se,
turbulenceTexture: c = ae,
stbnTexture: h = Q,
children: n,
...d
}) => {
const { textures: l, transientStates: r, ...f } = y(J), [v, _] = K({
...ee,
...f,
...l,
...d
}), o = L(() => new te(), []);
i(() => () => {
o.dispose();
}, [o]), k(() => {
r != null && (o.sunDirection.copy(r.sunDirection), o.worldToECEFMatrix.copy(r.worldToECEFMatrix));
}), i(() => {
if (r != null)
return r.overlay = o.atmosphereOverlay, r.shadow = o.atmosphereShadow, r.shadowLength = o.atmosphereShadowLength, () => {
r.overlay = null, r.shadow = null, r.shadowLength = null;
};
}, [o, r]);
const T = X(
(m) => {
if (r != null)
switch (m.property) {
case "atmosphereOverlay":
r.overlay = o.atmosphereOverlay;
break;
case "atmosphereShadow":
r.shadow = o.atmosphereShadow;
break;
case "atmosphereShadowLength":
r.shadowLength = o.atmosphereShadowLength;
break;
}
},
[o, r]
);
i(() => (o.events.addEventListener("change", T), () => {
o.events.removeEventListener("change", T);
}), [o, T]), B(({ gl: m }) => m);
const b = U(s), O = g(
a,
le
), R = g(
u,
ne
), P = U(c), I = ce(h), { camera: H } = y(W);
return /* @__PURE__ */ M(N, { children: [
/* @__PURE__ */ E(
"primitive",
{
ref: e,
object: o,
mainCamera: H,
...v,
localWeatherTexture: b,
shapeTexture: O,
shapeDetailTexture: R,
turbulenceTexture: P,
stbnTexture: I,
..._
}
),
/* @__PURE__ */ E(
ue,
{
layers: o.cloudLayers,
disableDefault: t,
children: n
}
)
] });
}, xe = ({
ref: e,
index: t,
...s
}) => {
const a = y(S);
if (a == null)
throw new Error("CloudLayer can only be used within the Clouds component!");
const { layers: u, indexPool: c, disableDefault: h } = a, [n, d] = A();
if (x(() => {
if (t != null) {
const l = c.indexOf(t);
if (l !== -1)
return c.splice(l, 1), d(t), () => {
c.push(t), d(void 0);
};
} else {
const l = c.sort((r, f) => r - f).shift();
if (l != null)
return d(l), () => {
c.push(l), d(void 0);
};
}
}, [t, u, c]), x(() => {
if (n == null)
return;
const l = u[n];
return () => {
l.copy(
h ? w.DEFAULT : D.DEFAULT[n]
);
};
}, [u, n, h]), i(() => {
n != null && (typeof e == "function" ? e(u[n]) : e != null && (e.current = u[n]));
}, [e, u, n]), n != null) {
const l = u[n];
l.copy(
h ? w.DEFAULT : D.DEFAULT[n]
), l.set(s);
}
return null;
};
export {
xe as CloudLayer,
Ee as Clouds
};
//# sourceMappingURL=r3f.js.map