@almadar/ui 5.140.0 → 5.141.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +146 -15
- package/dist/avl/index.js +146 -15
- package/dist/{cn-Do5Ra3l3.d.ts → cn-BDwC4QpH.d.ts} +1 -1
- package/dist/{cn-DkGYzPOg.d.cts → cn-rwc3svaX.d.cts} +1 -1
- package/dist/components/index.cjs +146 -15
- package/dist/components/index.d.cts +3 -3
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +146 -15
- package/dist/lib/drawable/three/index.cjs +360 -137
- package/dist/lib/drawable/three/index.d.cts +3 -1
- package/dist/lib/drawable/three/index.d.ts +3 -1
- package/dist/lib/drawable/three/index.js +335 -112
- package/dist/lib/index.d.cts +2 -2
- package/dist/lib/index.d.ts +2 -2
- package/dist/{paintDispatch-B5pPeSEp.d.cts → paintDispatch-BQn5Lyx1.d.cts} +160 -3
- package/dist/{paintDispatch-B5pPeSEp.d.ts → paintDispatch-BQn5Lyx1.d.ts} +160 -3
- package/dist/providers/index.cjs +146 -15
- package/dist/providers/index.js +146 -15
- package/dist/runtime/index.cjs +146 -15
- package/dist/runtime/index.js +146 -15
- package/package.json +4 -4
|
@@ -4,7 +4,7 @@ var React3 = require('react');
|
|
|
4
4
|
var providers = require('@almadar/ui/providers');
|
|
5
5
|
var logger = require('@almadar/logger');
|
|
6
6
|
var fiber = require('@react-three/fiber');
|
|
7
|
-
var
|
|
7
|
+
var THREE10 = require('three');
|
|
8
8
|
var drei = require('@react-three/drei');
|
|
9
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
10
10
|
var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
|
|
@@ -38,7 +38,7 @@ function _interopNamespace(e) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
41
|
-
var
|
|
41
|
+
var THREE10__namespace = /*#__PURE__*/_interopNamespace(THREE10);
|
|
42
42
|
|
|
43
43
|
var __defProp = Object.defineProperty;
|
|
44
44
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -189,6 +189,7 @@ function collectDrawnItems(nodes) {
|
|
|
189
189
|
case "draw-shape":
|
|
190
190
|
case "draw-text":
|
|
191
191
|
case "draw-group":
|
|
192
|
+
case "draw-mesh":
|
|
192
193
|
if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
|
|
193
194
|
break;
|
|
194
195
|
case "draw-sprite-layer":
|
|
@@ -514,7 +515,7 @@ function Lighting3D({
|
|
|
514
515
|
"directionalLightHelper",
|
|
515
516
|
{
|
|
516
517
|
args: [
|
|
517
|
-
new
|
|
518
|
+
new THREE10__namespace.DirectionalLight(directionalColor, directionalIntensity),
|
|
518
519
|
5
|
|
519
520
|
]
|
|
520
521
|
}
|
|
@@ -541,8 +542,8 @@ function FollowCamera3D({
|
|
|
541
542
|
offset
|
|
542
543
|
}) {
|
|
543
544
|
const { camera } = fiber.useThree();
|
|
544
|
-
const look = React3.useRef(new
|
|
545
|
-
const goal = React3.useRef(new
|
|
545
|
+
const look = React3.useRef(new THREE10__namespace.Vector3(target[0], target[1], target[2]));
|
|
546
|
+
const goal = React3.useRef(new THREE10__namespace.Vector3());
|
|
546
547
|
fiber.useFrame((_, delta) => {
|
|
547
548
|
const t = Math.min(1, delta * 5);
|
|
548
549
|
goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
|
|
@@ -553,6 +554,17 @@ function FollowCamera3D({
|
|
|
553
554
|
return null;
|
|
554
555
|
}
|
|
555
556
|
|
|
557
|
+
// lib/drawable/projector3d.ts
|
|
558
|
+
function create3DProjector(opts = {}) {
|
|
559
|
+
const cellSize = opts.cellSize ?? 1;
|
|
560
|
+
const offsetX = opts.offsetX ?? 0;
|
|
561
|
+
const offsetZ = opts.offsetZ ?? 0;
|
|
562
|
+
return {
|
|
563
|
+
cellSize,
|
|
564
|
+
toWorld: (pos) => [pos.x * cellSize + offsetX, pos.z ?? 0, pos.y * cellSize + offsetZ]
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
|
|
556
568
|
// lib/atlasSlice.ts
|
|
557
569
|
var atlasCache = /* @__PURE__ */ new Map();
|
|
558
570
|
function isTilesheet(a) {
|
|
@@ -687,12 +699,12 @@ function ModelLoader({
|
|
|
687
699
|
if (!loadedModel) return null;
|
|
688
700
|
const cloned = SkeletonUtils.clone(loadedModel);
|
|
689
701
|
cloned.updateMatrixWorld(true);
|
|
690
|
-
const tintColor = tint ? new
|
|
702
|
+
const tintColor = tint ? new THREE10__namespace.Color(tint) : null;
|
|
691
703
|
cloned.traverse((child) => {
|
|
692
|
-
if (child instanceof
|
|
704
|
+
if (child instanceof THREE10__namespace.Mesh) {
|
|
693
705
|
child.castShadow = castShadow;
|
|
694
706
|
child.receiveShadow = receiveShadow;
|
|
695
|
-
if (tintColor && child.material instanceof
|
|
707
|
+
if (tintColor && child.material instanceof THREE10__namespace.MeshStandardMaterial) {
|
|
696
708
|
const mat = child.material.clone();
|
|
697
709
|
mat.color.multiply(tintColor);
|
|
698
710
|
child.material = mat;
|
|
@@ -701,7 +713,7 @@ function ModelLoader({
|
|
|
701
713
|
});
|
|
702
714
|
return cloned;
|
|
703
715
|
}, [loadedModel, castShadow, receiveShadow, tint]);
|
|
704
|
-
const mixer = React3.useMemo(() => model ? new
|
|
716
|
+
const mixer = React3.useMemo(() => model ? new THREE10__namespace.AnimationMixer(model) : null, [model]);
|
|
705
717
|
React3.useEffect(() => {
|
|
706
718
|
if (!mixer || !animation || clips.length === 0) return;
|
|
707
719
|
const wanted = animation.toLowerCase();
|
|
@@ -718,8 +730,8 @@ function ModelLoader({
|
|
|
718
730
|
});
|
|
719
731
|
const normFactor = React3.useMemo(() => {
|
|
720
732
|
if (!model) return 1;
|
|
721
|
-
const box = new
|
|
722
|
-
const size = new
|
|
733
|
+
const box = new THREE10__namespace.Box3().setFromObject(model);
|
|
734
|
+
const size = new THREE10__namespace.Vector3();
|
|
723
735
|
box.getSize(size);
|
|
724
736
|
const maxDim = Math.max(size.x, size.y, size.z);
|
|
725
737
|
if (!Number.isFinite(maxDim) || maxDim < 0.05) return 1;
|
|
@@ -809,7 +821,7 @@ var warnUnsupported3d = (kind) => {
|
|
|
809
821
|
warnedUnsupported.add(kind);
|
|
810
822
|
mesh3dLog.warn("unsupported drawable kind on the 3D backend \u2014 skipped", { kind });
|
|
811
823
|
};
|
|
812
|
-
var CrossOriginTextureLoader = class extends
|
|
824
|
+
var CrossOriginTextureLoader = class extends THREE10__namespace.TextureLoader {
|
|
813
825
|
constructor() {
|
|
814
826
|
super();
|
|
815
827
|
this.crossOrigin = "anonymous";
|
|
@@ -827,7 +839,7 @@ function useBillboardTexture(url) {
|
|
|
827
839
|
url,
|
|
828
840
|
(texture) => {
|
|
829
841
|
if (!active) return;
|
|
830
|
-
texture.colorSpace =
|
|
842
|
+
texture.colorSpace = THREE10__namespace.SRGBColorSpace;
|
|
831
843
|
setState({ texture, error: false });
|
|
832
844
|
},
|
|
833
845
|
void 0,
|
|
@@ -859,7 +871,7 @@ function useAtlasFrame(asset) {
|
|
|
859
871
|
return { frame: { x: r.sx, y: r.sy, w: r.sw, h: r.sh }, ready: true };
|
|
860
872
|
}, [asset, tick]);
|
|
861
873
|
}
|
|
862
|
-
function SpriteBillboard({ node, world, cellSize = 1 }) {
|
|
874
|
+
function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
|
|
863
875
|
const { texture, error: textureError } = useBillboardTexture(node.asset.url);
|
|
864
876
|
const { frame: atlasFrame, ready: atlasReady } = useAtlasFrame(node.asset);
|
|
865
877
|
const frame = node.frame ?? atlasFrame;
|
|
@@ -880,7 +892,7 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
|
|
|
880
892
|
}, [texture, frame, node.height, node.width, anchor, cellSize]);
|
|
881
893
|
const groundGeometry = React3__default.default.useMemo(() => {
|
|
882
894
|
if (anchor !== "top-left" || !texture || !atlasReady) return null;
|
|
883
|
-
const g = new
|
|
895
|
+
const g = new THREE10__namespace.PlaneGeometry(size.width, size.height);
|
|
884
896
|
g.rotateX(-Math.PI / 2);
|
|
885
897
|
return g;
|
|
886
898
|
}, [anchor, texture, atlasReady, size.width, size.height]);
|
|
@@ -888,15 +900,15 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
|
|
|
888
900
|
if (anchor === "top-left") {
|
|
889
901
|
return /* @__PURE__ */ jsxRuntime.jsx("group", { position: [world[0] + size.width / 2, 0.02, world[2] + size.height / 2], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], children: [
|
|
890
902
|
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
|
|
891
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side:
|
|
903
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE10__namespace.DoubleSide })
|
|
892
904
|
] }) });
|
|
893
905
|
}
|
|
894
906
|
return /* @__PURE__ */ jsxRuntime.jsx("group", { position: [world[0], world[1] + size.height / 2, world[2]], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
|
|
895
907
|
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
|
|
896
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side:
|
|
908
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE10__namespace.DoubleSide })
|
|
897
909
|
] }) });
|
|
898
910
|
}
|
|
899
|
-
texture.magFilter = texture.minFilter =
|
|
911
|
+
texture.magFilter = texture.minFilter = THREE10__namespace.NearestFilter;
|
|
900
912
|
texture.needsUpdate = true;
|
|
901
913
|
if (frame) {
|
|
902
914
|
texture.repeat.set(frame.w / size.imgW, frame.h / size.imgH);
|
|
@@ -909,8 +921,8 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
|
|
|
909
921
|
map: texture,
|
|
910
922
|
transparent: true,
|
|
911
923
|
alphaTest: 0.1,
|
|
912
|
-
side:
|
|
913
|
-
opacity: node.opacity ?? 1
|
|
924
|
+
side: THREE10__namespace.DoubleSide,
|
|
925
|
+
opacity: (node.opacity ?? 1) * groupOpacity
|
|
914
926
|
}
|
|
915
927
|
) }) });
|
|
916
928
|
}
|
|
@@ -922,13 +934,13 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
|
|
|
922
934
|
map: texture,
|
|
923
935
|
transparent: true,
|
|
924
936
|
alphaTest: 0.1,
|
|
925
|
-
side:
|
|
937
|
+
side: THREE10__namespace.DoubleSide,
|
|
926
938
|
opacity: node.opacity ?? 1
|
|
927
939
|
}
|
|
928
940
|
)
|
|
929
941
|
] }) });
|
|
930
942
|
}
|
|
931
|
-
function Sprite3D({ node, projector }) {
|
|
943
|
+
function Sprite3D({ node, projector, groupOpacity = 1 }) {
|
|
932
944
|
const asset = node.asset;
|
|
933
945
|
if (!asset?.url || !isValidScenePos(node.position)) return null;
|
|
934
946
|
if (asset.dimension === "3d") {
|
|
@@ -942,7 +954,7 @@ function Sprite3D({ node, projector }) {
|
|
|
942
954
|
{
|
|
943
955
|
url: asset.url,
|
|
944
956
|
scale,
|
|
945
|
-
rotation: [0, node.rotation ?? 0, 0],
|
|
957
|
+
rotation: [0, (node.rotation ?? 0) * 180 / Math.PI, 0],
|
|
946
958
|
animation: node.animation,
|
|
947
959
|
fallbackGeometry: "box",
|
|
948
960
|
castShadow: true,
|
|
@@ -950,9 +962,9 @@ function Sprite3D({ node, projector }) {
|
|
|
950
962
|
}
|
|
951
963
|
) });
|
|
952
964
|
}
|
|
953
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SpriteBillboard, { node, world: projector.toWorld(node.position), cellSize: projector.cellSize });
|
|
965
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SpriteBillboard, { node, world: projector.toWorld(node.position), cellSize: projector.cellSize, groupOpacity });
|
|
954
966
|
}
|
|
955
|
-
function Shape3D({ node, projector }) {
|
|
967
|
+
function Shape3D({ node, projector, groupOpacity = 1 }) {
|
|
956
968
|
if (!isValidScenePos(node.position)) return null;
|
|
957
969
|
const world = projector.toWorld(node.position);
|
|
958
970
|
const color = node.fill ?? node.stroke ?? "#ffffff";
|
|
@@ -972,7 +984,7 @@ function Shape3D({ node, projector }) {
|
|
|
972
984
|
}
|
|
973
985
|
case "poly": {
|
|
974
986
|
if (!node.points || node.points.length === 0) return null;
|
|
975
|
-
const s = new
|
|
987
|
+
const s = new THREE10__namespace.Shape();
|
|
976
988
|
node.points.forEach((p, i) => {
|
|
977
989
|
if (i === 0) s.moveTo(p.x, p.y);
|
|
978
990
|
else s.lineTo(p.x, p.y);
|
|
@@ -990,7 +1002,7 @@ function Shape3D({ node, projector }) {
|
|
|
990
1002
|
}
|
|
991
1003
|
return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [world[0], world[1] + 0.02, world[2]], children: [
|
|
992
1004
|
geometry,
|
|
993
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color, transparent: true, opacity: node.opacity ?? 1, side:
|
|
1005
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE10__namespace.DoubleSide })
|
|
994
1006
|
] });
|
|
995
1007
|
}
|
|
996
1008
|
function Text3D({ node, projector }) {
|
|
@@ -1009,37 +1021,246 @@ function Text3D({ node, projector }) {
|
|
|
1009
1021
|
}
|
|
1010
1022
|
) });
|
|
1011
1023
|
}
|
|
1012
|
-
|
|
1024
|
+
var MESH_SEGMENTS_DEFAULT = 24;
|
|
1025
|
+
function clampSegments(segments) {
|
|
1026
|
+
const s = segments ?? MESH_SEGMENTS_DEFAULT;
|
|
1027
|
+
return Math.min(64, Math.max(3, Math.round(s)));
|
|
1028
|
+
}
|
|
1029
|
+
function isAnimatedMesh(node) {
|
|
1030
|
+
return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
|
|
1031
|
+
}
|
|
1032
|
+
var lerp = (a, b, k) => a + (b - a) * k;
|
|
1033
|
+
var NUMERIC_TRACKS = [
|
|
1034
|
+
"offsetX",
|
|
1035
|
+
"offsetY",
|
|
1036
|
+
"offsetZ",
|
|
1037
|
+
"rotateX",
|
|
1038
|
+
"rotateY",
|
|
1039
|
+
"rotateZ",
|
|
1040
|
+
"scale",
|
|
1041
|
+
"opacity",
|
|
1042
|
+
"emissiveIntensity"
|
|
1043
|
+
];
|
|
1044
|
+
function applyMeshAnimation(node, timeMs) {
|
|
1045
|
+
const anim = node.animation;
|
|
1046
|
+
if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
|
|
1047
|
+
const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
|
|
1048
|
+
const cycle = timeMs / anim.durationMs;
|
|
1049
|
+
const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
|
|
1050
|
+
const trackValue = (key) => {
|
|
1051
|
+
const defined = frames.filter((f) => f[key] !== void 0);
|
|
1052
|
+
if (defined.length === 0) return void 0;
|
|
1053
|
+
let prev;
|
|
1054
|
+
let next;
|
|
1055
|
+
for (const f of defined) {
|
|
1056
|
+
if (f.at <= t) prev = f;
|
|
1057
|
+
else if (!next) next = f;
|
|
1058
|
+
}
|
|
1059
|
+
if (!prev) return defined[0][key];
|
|
1060
|
+
if (!next) return prev[key];
|
|
1061
|
+
const span = next.at - prev.at;
|
|
1062
|
+
const k = span > 0 ? (t - prev.at) / span : 1;
|
|
1063
|
+
const a = prev[key];
|
|
1064
|
+
const b = next[key];
|
|
1065
|
+
if (typeof a === "number" && typeof b === "number") return lerp(a, b, k);
|
|
1066
|
+
return a;
|
|
1067
|
+
};
|
|
1068
|
+
const num = {};
|
|
1069
|
+
for (const key of NUMERIC_TRACKS) {
|
|
1070
|
+
const v = trackValue(key);
|
|
1071
|
+
if (v !== void 0) num[key] = v;
|
|
1072
|
+
}
|
|
1073
|
+
return {
|
|
1074
|
+
offset: [num.offsetX ?? 0, num.offsetY ?? 0, num.offsetZ ?? 0],
|
|
1075
|
+
rotate: [num.rotateX ?? 0, num.rotateY ?? 0, num.rotateZ ?? 0],
|
|
1076
|
+
scale: num.scale ?? 1,
|
|
1077
|
+
opacity: num.opacity,
|
|
1078
|
+
emissiveIntensity: num.emissiveIntensity,
|
|
1079
|
+
color: trackValue("color"),
|
|
1080
|
+
emissive: trackValue("emissive")
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
function meshGeometry(node, cellSize) {
|
|
1084
|
+
const seg = clampSegments(node.segments);
|
|
1085
|
+
const r = (node.radius ?? 0.4) * cellSize;
|
|
1086
|
+
const w = (node.width ?? 1) * cellSize;
|
|
1087
|
+
const h = (node.height ?? 1) * cellSize;
|
|
1088
|
+
const d = (node.depth ?? node.width ?? 1) * cellSize;
|
|
1089
|
+
switch (node.shape) {
|
|
1090
|
+
case "box":
|
|
1091
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [w, h, d] }), lift: h / 2, size: Math.max(w, h, d) };
|
|
1092
|
+
case "sphere":
|
|
1093
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [r, seg, seg] }), lift: r, size: r * 2 };
|
|
1094
|
+
case "capsule":
|
|
1095
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("capsuleGeometry", { args: [r, h, Math.max(2, Math.round(seg / 2)), seg] }), lift: h / 2 + r, size: h + r * 2 };
|
|
1096
|
+
case "cylinder":
|
|
1097
|
+
return {
|
|
1098
|
+
element: /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [(node.radiusTop ?? node.radius ?? 0.4) * cellSize, (node.radiusBottom ?? node.radius ?? 0.4) * cellSize, h, seg] }),
|
|
1099
|
+
lift: h / 2,
|
|
1100
|
+
size: Math.max(h, r * 2)
|
|
1101
|
+
};
|
|
1102
|
+
case "cone":
|
|
1103
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [r, h, seg] }), lift: h / 2, size: Math.max(h, r * 2) };
|
|
1104
|
+
case "torus": {
|
|
1105
|
+
const tube = (node.tube ?? (node.radius ?? 0.4) / 3) * cellSize;
|
|
1106
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [r, tube, Math.max(3, Math.round(seg / 2)), seg] }), lift: r + tube, size: (r + tube) * 2 };
|
|
1107
|
+
}
|
|
1108
|
+
case "plane":
|
|
1109
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [w, d] }), lift: 0, size: Math.max(w, d) };
|
|
1110
|
+
case "circle":
|
|
1111
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [r, seg] }), lift: 0, size: r * 2 };
|
|
1112
|
+
default:
|
|
1113
|
+
return null;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
var SIDE_MAP = {
|
|
1117
|
+
front: THREE10__namespace.FrontSide,
|
|
1118
|
+
back: THREE10__namespace.BackSide,
|
|
1119
|
+
double: THREE10__namespace.DoubleSide
|
|
1120
|
+
};
|
|
1121
|
+
function meshMaterial(mat, opacity, ref) {
|
|
1122
|
+
const m = mat ?? {};
|
|
1123
|
+
const common = {
|
|
1124
|
+
ref,
|
|
1125
|
+
color: m.color ?? "#ffffff",
|
|
1126
|
+
transparent: opacity < 1,
|
|
1127
|
+
opacity,
|
|
1128
|
+
side: SIDE_MAP[m.side ?? "front"]
|
|
1129
|
+
};
|
|
1130
|
+
const emissive = m.emissive ? { emissive: m.emissive, emissiveIntensity: m.emissiveIntensity ?? 1 } : {};
|
|
1131
|
+
switch (m.kind ?? "standard") {
|
|
1132
|
+
case "basic":
|
|
1133
|
+
return /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { ...common });
|
|
1134
|
+
case "toon":
|
|
1135
|
+
return /* @__PURE__ */ jsxRuntime.jsx("meshToonMaterial", { ...common, ...emissive });
|
|
1136
|
+
case "physical":
|
|
1137
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1138
|
+
"meshPhysicalMaterial",
|
|
1139
|
+
{
|
|
1140
|
+
...common,
|
|
1141
|
+
...emissive,
|
|
1142
|
+
metalness: m.metalness ?? 0,
|
|
1143
|
+
roughness: m.roughness ?? 0.5,
|
|
1144
|
+
transmission: m.transmission ?? 0,
|
|
1145
|
+
ior: m.ior ?? 1.5,
|
|
1146
|
+
flatShading: m.flatShading ?? false
|
|
1147
|
+
}
|
|
1148
|
+
);
|
|
1149
|
+
case "standard":
|
|
1150
|
+
default:
|
|
1151
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1152
|
+
"meshStandardMaterial",
|
|
1153
|
+
{
|
|
1154
|
+
...common,
|
|
1155
|
+
...emissive,
|
|
1156
|
+
metalness: m.metalness ?? 0,
|
|
1157
|
+
roughness: m.roughness ?? 0.5,
|
|
1158
|
+
flatShading: m.flatShading ?? false
|
|
1159
|
+
}
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
function Mesh3D({
|
|
1164
|
+
node,
|
|
1165
|
+
projector,
|
|
1166
|
+
groupOpacity = 1
|
|
1167
|
+
}) {
|
|
1168
|
+
const groupRef = React3.useRef(null);
|
|
1169
|
+
const meshRef = React3.useRef(null);
|
|
1170
|
+
const materialRef = React3.useRef(null);
|
|
1171
|
+
const animated = isAnimatedMesh(node);
|
|
1172
|
+
const validPos = isValidScenePos(node.position);
|
|
1173
|
+
const baseWorld = validPos ? projector.toWorld(node.position) : [0, 0, 0];
|
|
1174
|
+
const geo = React3.useMemo(() => meshGeometry(node, projector.cellSize), [node, projector.cellSize]);
|
|
1175
|
+
fiber.useFrame(({ clock }) => {
|
|
1176
|
+
if (!animated || !groupRef.current) return;
|
|
1177
|
+
const state = applyMeshAnimation(node, clock.elapsedTime * 1e3);
|
|
1178
|
+
if (!state) return;
|
|
1179
|
+
const [wx, wy, wz] = baseWorld;
|
|
1180
|
+
groupRef.current.position.set(
|
|
1181
|
+
wx + state.offset[0] * projector.cellSize,
|
|
1182
|
+
wy + state.offset[2] * projector.cellSize,
|
|
1183
|
+
wz + state.offset[1] * projector.cellSize
|
|
1184
|
+
);
|
|
1185
|
+
groupRef.current.scale.setScalar(state.scale);
|
|
1186
|
+
if (meshRef.current) {
|
|
1187
|
+
const base = node.rotation ?? [0, 0, 0];
|
|
1188
|
+
meshRef.current.rotation.set(base[0] + state.rotate[0], base[1] + state.rotate[1], base[2] + state.rotate[2]);
|
|
1189
|
+
}
|
|
1190
|
+
const mat = materialRef.current;
|
|
1191
|
+
if (mat) {
|
|
1192
|
+
const effective = (state.opacity ?? node.opacity ?? 1) * (node.material?.opacity ?? 1) * groupOpacity;
|
|
1193
|
+
mat.opacity = effective;
|
|
1194
|
+
mat.transparent = effective < 1;
|
|
1195
|
+
if (state.color && mat.color) mat.color.set(state.color);
|
|
1196
|
+
if (state.emissive && mat.emissive) mat.emissive.set(state.emissive);
|
|
1197
|
+
if (state.emissiveIntensity !== void 0 && mat.emissiveIntensity !== void 0) {
|
|
1198
|
+
mat.emissiveIntensity = state.emissiveIntensity;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
if (!validPos || !geo) return null;
|
|
1203
|
+
const lift = (node.pivot ?? "bottom") === "bottom" ? geo.lift : 0;
|
|
1204
|
+
const opacity = (node.opacity ?? 1) * (node.material?.opacity ?? 1) * groupOpacity;
|
|
1205
|
+
const rotation = node.rotation ?? [0, 0, 0];
|
|
1206
|
+
const outlineScale = geo.size > 0 ? 1 + (node.outline?.width ?? 0.05) * projector.cellSize / geo.size : 1;
|
|
1207
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, position: baseWorld, children: [
|
|
1208
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1209
|
+
"mesh",
|
|
1210
|
+
{
|
|
1211
|
+
ref: meshRef,
|
|
1212
|
+
position: [0, lift, 0],
|
|
1213
|
+
rotation,
|
|
1214
|
+
castShadow: node.castShadow ?? true,
|
|
1215
|
+
receiveShadow: node.receiveShadow ?? true,
|
|
1216
|
+
children: [
|
|
1217
|
+
geo.element,
|
|
1218
|
+
meshMaterial(node.material, opacity, materialRef)
|
|
1219
|
+
]
|
|
1220
|
+
}
|
|
1221
|
+
),
|
|
1222
|
+
node.outline && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, lift, 0], rotation, scale: outlineScale, children: [
|
|
1223
|
+
geo.element,
|
|
1224
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1225
|
+
"meshBasicMaterial",
|
|
1226
|
+
{
|
|
1227
|
+
color: node.outline.color ?? "#101014",
|
|
1228
|
+
side: THREE10__namespace.BackSide,
|
|
1229
|
+
transparent: opacity < 1,
|
|
1230
|
+
opacity
|
|
1231
|
+
}
|
|
1232
|
+
)
|
|
1233
|
+
] })
|
|
1234
|
+
] });
|
|
1235
|
+
}
|
|
1236
|
+
function Drawable3D({ node, projector, groupOpacity = 1 }) {
|
|
1013
1237
|
switch (node.type) {
|
|
1014
1238
|
case "draw-sprite":
|
|
1015
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node, projector });
|
|
1239
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node, projector, groupOpacity });
|
|
1016
1240
|
case "draw-shape":
|
|
1017
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector });
|
|
1241
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector, groupOpacity });
|
|
1018
1242
|
case "draw-text":
|
|
1019
1243
|
return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector });
|
|
1244
|
+
case "draw-mesh":
|
|
1245
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Mesh3D, { node, projector, groupOpacity });
|
|
1020
1246
|
case "draw-sprite-layer":
|
|
1021
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node: item, projector }, i)) });
|
|
1247
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node: item, projector, groupOpacity }, i)) });
|
|
1022
1248
|
case "draw-shape-layer":
|
|
1023
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector }, i)) });
|
|
1249
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
|
|
1024
1250
|
case "draw-text-layer":
|
|
1025
1251
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector }, i)) });
|
|
1026
|
-
case "draw-group":
|
|
1027
|
-
|
|
1028
|
-
|
|
1252
|
+
case "draw-group": {
|
|
1253
|
+
if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
|
|
1254
|
+
if (node.clip) warnUnsupported3d("draw-group:clip");
|
|
1255
|
+
const world = projector.toWorld(node.position);
|
|
1256
|
+
const inner = create3DProjector({ cellSize: projector.cellSize });
|
|
1257
|
+
const opacity = (node.opacity ?? 1) * groupOpacity;
|
|
1258
|
+
const s = node.scale ?? 1;
|
|
1259
|
+
return /* @__PURE__ */ jsxRuntime.jsx("group", { position: world, rotation: [0, -(node.rotate ?? 0), 0], scale: [s, s, s], children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node: item, projector: inner, groupOpacity: opacity }, i)) });
|
|
1260
|
+
}
|
|
1029
1261
|
}
|
|
1030
1262
|
}
|
|
1031
1263
|
|
|
1032
|
-
// lib/drawable/projector3d.ts
|
|
1033
|
-
function create3DProjector(opts = {}) {
|
|
1034
|
-
const cellSize = opts.cellSize ?? 1;
|
|
1035
|
-
const offsetX = opts.offsetX ?? 0;
|
|
1036
|
-
const offsetZ = opts.offsetZ ?? 0;
|
|
1037
|
-
return {
|
|
1038
|
-
cellSize,
|
|
1039
|
-
toWorld: (pos) => [pos.x * cellSize + offsetX, pos.z ?? 0, pos.y * cellSize + offsetZ]
|
|
1040
|
-
};
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
1264
|
// lib/drawable/three/game3dTheme.ts
|
|
1044
1265
|
var GRID_COLORS_3D = {
|
|
1045
1266
|
cell: "#444444",
|
|
@@ -1075,6 +1296,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1075
1296
|
keyMap,
|
|
1076
1297
|
keyUpMap,
|
|
1077
1298
|
pixelsPerUnit,
|
|
1299
|
+
fov,
|
|
1078
1300
|
children,
|
|
1079
1301
|
drawables
|
|
1080
1302
|
}, ref) => {
|
|
@@ -1164,7 +1386,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1164
1386
|
getCameraPosition: () => {
|
|
1165
1387
|
if (controlsRef.current) {
|
|
1166
1388
|
const pos = controlsRef.current.object.position;
|
|
1167
|
-
return new
|
|
1389
|
+
return new THREE10__namespace.Vector3(pos.x, pos.y, pos.z);
|
|
1168
1390
|
}
|
|
1169
1391
|
return null;
|
|
1170
1392
|
},
|
|
@@ -1203,18 +1425,19 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1203
1425
|
const cx = cameraTarget[0];
|
|
1204
1426
|
const cz = cameraTarget[2];
|
|
1205
1427
|
const d = size * 1;
|
|
1428
|
+
const fovDeg = fov ?? 45;
|
|
1206
1429
|
switch (cameraMode) {
|
|
1207
1430
|
case "isometric":
|
|
1208
|
-
return { position: [cx + d, d * 0.8, cz + d], fov:
|
|
1431
|
+
return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
|
|
1209
1432
|
case "top-down":
|
|
1210
|
-
return { position: [cx, d * 2, cz + d * 0.35], fov:
|
|
1433
|
+
return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
|
|
1211
1434
|
case "follow":
|
|
1212
|
-
return { position: [cx, d * 0.5, cz + d], fov:
|
|
1435
|
+
return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
|
|
1213
1436
|
case "perspective":
|
|
1214
1437
|
default:
|
|
1215
|
-
return { position: [cx + d, d, cz + d], fov:
|
|
1438
|
+
return { position: [cx + d, d, cz + d], fov: fovDeg };
|
|
1216
1439
|
}
|
|
1217
|
-
}, [cameraMode, gridBounds, cellSize, cameraTarget]);
|
|
1440
|
+
}, [cameraMode, gridBounds, cellSize, cameraTarget, fov]);
|
|
1218
1441
|
const followWorld = React3.useMemo(() => {
|
|
1219
1442
|
if (followTarget) return drawableProjector.toWorld(followTarget);
|
|
1220
1443
|
return cameraTarget;
|
|
@@ -1358,7 +1581,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1358
1581
|
dampingFactor: 0.05,
|
|
1359
1582
|
enableZoom: true,
|
|
1360
1583
|
enablePan: true,
|
|
1361
|
-
touches: { ONE:
|
|
1584
|
+
touches: { ONE: THREE10__namespace.TOUCH.ROTATE, TWO: THREE10__namespace.TOUCH.DOLLY_PAN },
|
|
1362
1585
|
minDistance: 2,
|
|
1363
1586
|
maxDistance: 100,
|
|
1364
1587
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -1381,15 +1604,15 @@ function Scene3D({ background = "#1a1a2e", fog, children }) {
|
|
|
1381
1604
|
if (initializedRef.current) return;
|
|
1382
1605
|
initializedRef.current = true;
|
|
1383
1606
|
if (background.startsWith("#") || background.startsWith("rgb")) {
|
|
1384
|
-
scene.background = new
|
|
1607
|
+
scene.background = new THREE10__namespace.Color(background);
|
|
1385
1608
|
} else {
|
|
1386
|
-
const loader = new
|
|
1609
|
+
const loader = new THREE10__namespace.TextureLoader();
|
|
1387
1610
|
loader.load(background, (texture) => {
|
|
1388
1611
|
scene.background = texture;
|
|
1389
1612
|
});
|
|
1390
1613
|
}
|
|
1391
1614
|
if (fog) {
|
|
1392
|
-
scene.fog = new
|
|
1615
|
+
scene.fog = new THREE10__namespace.Fog(fog.color, fog.near, fog.far);
|
|
1393
1616
|
}
|
|
1394
1617
|
return () => {
|
|
1395
1618
|
scene.background = null;
|
|
@@ -1412,14 +1635,14 @@ var Camera3D = React3.forwardRef(
|
|
|
1412
1635
|
}, ref) => {
|
|
1413
1636
|
const { camera, set, viewport } = fiber.useThree();
|
|
1414
1637
|
const controlsRef = React3.useRef(null);
|
|
1415
|
-
const initialPosition = React3.useRef(new
|
|
1416
|
-
const initialTarget = React3.useRef(new
|
|
1638
|
+
const initialPosition = React3.useRef(new THREE10__namespace.Vector3(...position));
|
|
1639
|
+
const initialTarget = React3.useRef(new THREE10__namespace.Vector3(...target));
|
|
1417
1640
|
React3.useEffect(() => {
|
|
1418
1641
|
let newCamera;
|
|
1419
1642
|
if (mode === "isometric") {
|
|
1420
1643
|
const aspect = viewport.aspect;
|
|
1421
1644
|
const size = 10 / zoom;
|
|
1422
|
-
newCamera = new
|
|
1645
|
+
newCamera = new THREE10__namespace.OrthographicCamera(
|
|
1423
1646
|
-size * aspect,
|
|
1424
1647
|
size * aspect,
|
|
1425
1648
|
size,
|
|
@@ -1428,7 +1651,7 @@ var Camera3D = React3.forwardRef(
|
|
|
1428
1651
|
1e3
|
|
1429
1652
|
);
|
|
1430
1653
|
} else {
|
|
1431
|
-
newCamera = new
|
|
1654
|
+
newCamera = new THREE10__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
|
|
1432
1655
|
}
|
|
1433
1656
|
newCamera.position.copy(initialPosition.current);
|
|
1434
1657
|
newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
|
|
@@ -1469,8 +1692,8 @@ var Camera3D = React3.forwardRef(
|
|
|
1469
1692
|
}
|
|
1470
1693
|
},
|
|
1471
1694
|
getViewBounds: () => {
|
|
1472
|
-
const min = new
|
|
1473
|
-
const max = new
|
|
1695
|
+
const min = new THREE10__namespace.Vector3(-10, -10, -10);
|
|
1696
|
+
const max = new THREE10__namespace.Vector3(10, 10, 10);
|
|
1474
1697
|
return { min, max };
|
|
1475
1698
|
}
|
|
1476
1699
|
}));
|
|
@@ -1512,7 +1735,7 @@ var AssetLoader = class {
|
|
|
1512
1735
|
__publicField(this, "textureCache");
|
|
1513
1736
|
__publicField(this, "loadingPromises");
|
|
1514
1737
|
this.objLoader = new OBJLoader_js.OBJLoader();
|
|
1515
|
-
this.textureLoader = new
|
|
1738
|
+
this.textureLoader = new THREE10__namespace.TextureLoader();
|
|
1516
1739
|
this.modelCache = /* @__PURE__ */ new Map();
|
|
1517
1740
|
this.textureCache = /* @__PURE__ */ new Map();
|
|
1518
1741
|
this.loadingPromises = /* @__PURE__ */ new Map();
|
|
@@ -1586,7 +1809,7 @@ var AssetLoader = class {
|
|
|
1586
1809
|
return this.loadingPromises.get(`texture:${url}`);
|
|
1587
1810
|
}
|
|
1588
1811
|
const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
|
|
1589
|
-
texture.colorSpace =
|
|
1812
|
+
texture.colorSpace = THREE10__namespace.SRGBColorSpace;
|
|
1590
1813
|
this.textureCache.set(url, texture);
|
|
1591
1814
|
this.loadingPromises.delete(`texture:${url}`);
|
|
1592
1815
|
return texture;
|
|
@@ -1660,7 +1883,7 @@ var AssetLoader = class {
|
|
|
1660
1883
|
});
|
|
1661
1884
|
this.modelCache.forEach((model) => {
|
|
1662
1885
|
model.scene.traverse((child) => {
|
|
1663
|
-
if (child instanceof
|
|
1886
|
+
if (child instanceof THREE10__namespace.Mesh) {
|
|
1664
1887
|
child.geometry.dispose();
|
|
1665
1888
|
if (Array.isArray(child.material)) {
|
|
1666
1889
|
child.material.forEach((m) => m.dispose());
|
|
@@ -1710,21 +1933,21 @@ function useThree4(options = {}) {
|
|
|
1710
1933
|
const [isReady, setIsReady] = React3.useState(false);
|
|
1711
1934
|
const [dimensions, setDimensions] = React3.useState({ width: 0, height: 0 });
|
|
1712
1935
|
const initialCameraPosition = React3.useMemo(
|
|
1713
|
-
() => new
|
|
1936
|
+
() => new THREE10__namespace.Vector3(...opts.cameraPosition),
|
|
1714
1937
|
[]
|
|
1715
1938
|
);
|
|
1716
1939
|
React3.useEffect(() => {
|
|
1717
1940
|
if (!containerRef.current) return;
|
|
1718
1941
|
const container = containerRef.current;
|
|
1719
1942
|
const { clientWidth, clientHeight } = container;
|
|
1720
|
-
const scene = new
|
|
1721
|
-
scene.background = new
|
|
1943
|
+
const scene = new THREE10__namespace.Scene();
|
|
1944
|
+
scene.background = new THREE10__namespace.Color(opts.backgroundColor);
|
|
1722
1945
|
sceneRef.current = scene;
|
|
1723
1946
|
let camera;
|
|
1724
1947
|
const aspect = clientWidth / clientHeight;
|
|
1725
1948
|
if (opts.cameraMode === "isometric") {
|
|
1726
1949
|
const size = 10;
|
|
1727
|
-
camera = new
|
|
1950
|
+
camera = new THREE10__namespace.OrthographicCamera(
|
|
1728
1951
|
-size * aspect,
|
|
1729
1952
|
size * aspect,
|
|
1730
1953
|
size,
|
|
@@ -1733,11 +1956,11 @@ function useThree4(options = {}) {
|
|
|
1733
1956
|
1e3
|
|
1734
1957
|
);
|
|
1735
1958
|
} else {
|
|
1736
|
-
camera = new
|
|
1959
|
+
camera = new THREE10__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
|
|
1737
1960
|
}
|
|
1738
1961
|
camera.position.copy(initialCameraPosition);
|
|
1739
1962
|
cameraRef.current = camera;
|
|
1740
|
-
const renderer = new
|
|
1963
|
+
const renderer = new THREE10__namespace.WebGLRenderer({
|
|
1741
1964
|
antialias: true,
|
|
1742
1965
|
alpha: true,
|
|
1743
1966
|
canvas: canvasRef.current || void 0
|
|
@@ -1745,7 +1968,7 @@ function useThree4(options = {}) {
|
|
|
1745
1968
|
renderer.setSize(clientWidth, clientHeight);
|
|
1746
1969
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
1747
1970
|
renderer.shadowMap.enabled = opts.shadows;
|
|
1748
|
-
renderer.shadowMap.type =
|
|
1971
|
+
renderer.shadowMap.type = THREE10__namespace.PCFSoftShadowMap;
|
|
1749
1972
|
rendererRef.current = renderer;
|
|
1750
1973
|
const controls = new OrbitControls_js.OrbitControls(camera, renderer.domElement);
|
|
1751
1974
|
controls.enableDamping = true;
|
|
@@ -1754,16 +1977,16 @@ function useThree4(options = {}) {
|
|
|
1754
1977
|
controls.maxDistance = 100;
|
|
1755
1978
|
controls.maxPolarAngle = Math.PI / 2 - 0.1;
|
|
1756
1979
|
controlsRef.current = controls;
|
|
1757
|
-
const ambientLight = new
|
|
1980
|
+
const ambientLight = new THREE10__namespace.AmbientLight(16777215, 0.6);
|
|
1758
1981
|
scene.add(ambientLight);
|
|
1759
|
-
const directionalLight = new
|
|
1982
|
+
const directionalLight = new THREE10__namespace.DirectionalLight(16777215, 0.8);
|
|
1760
1983
|
directionalLight.position.set(10, 20, 10);
|
|
1761
1984
|
directionalLight.castShadow = opts.shadows;
|
|
1762
1985
|
directionalLight.shadow.mapSize.width = 2048;
|
|
1763
1986
|
directionalLight.shadow.mapSize.height = 2048;
|
|
1764
1987
|
scene.add(directionalLight);
|
|
1765
1988
|
if (opts.showGrid) {
|
|
1766
|
-
const gridHelper = new
|
|
1989
|
+
const gridHelper = new THREE10__namespace.GridHelper(
|
|
1767
1990
|
opts.gridSize,
|
|
1768
1991
|
opts.gridSize,
|
|
1769
1992
|
4473924,
|
|
@@ -1781,10 +2004,10 @@ function useThree4(options = {}) {
|
|
|
1781
2004
|
const handleResize = () => {
|
|
1782
2005
|
const { clientWidth: width, clientHeight: height } = container;
|
|
1783
2006
|
setDimensions({ width, height });
|
|
1784
|
-
if (camera instanceof
|
|
2007
|
+
if (camera instanceof THREE10__namespace.PerspectiveCamera) {
|
|
1785
2008
|
camera.aspect = width / height;
|
|
1786
2009
|
camera.updateProjectionMatrix();
|
|
1787
|
-
} else if (camera instanceof
|
|
2010
|
+
} else if (camera instanceof THREE10__namespace.OrthographicCamera) {
|
|
1788
2011
|
const aspect2 = width / height;
|
|
1789
2012
|
const size = 10;
|
|
1790
2013
|
camera.left = -size * aspect2;
|
|
@@ -1815,7 +2038,7 @@ function useThree4(options = {}) {
|
|
|
1815
2038
|
let newCamera;
|
|
1816
2039
|
if (opts.cameraMode === "isometric") {
|
|
1817
2040
|
const size = 10;
|
|
1818
|
-
newCamera = new
|
|
2041
|
+
newCamera = new THREE10__namespace.OrthographicCamera(
|
|
1819
2042
|
-size * aspect,
|
|
1820
2043
|
size * aspect,
|
|
1821
2044
|
size,
|
|
@@ -1824,7 +2047,7 @@ function useThree4(options = {}) {
|
|
|
1824
2047
|
1e3
|
|
1825
2048
|
);
|
|
1826
2049
|
} else {
|
|
1827
|
-
newCamera = new
|
|
2050
|
+
newCamera = new THREE10__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
|
|
1828
2051
|
}
|
|
1829
2052
|
newCamera.position.copy(currentPos);
|
|
1830
2053
|
cameraRef.current = newCamera;
|
|
@@ -2154,8 +2377,8 @@ function useSceneGraph() {
|
|
|
2154
2377
|
}
|
|
2155
2378
|
function useRaycaster(options) {
|
|
2156
2379
|
const { camera, canvas, cellSize = 1, offsetX = 0, offsetZ = 0 } = options;
|
|
2157
|
-
const raycaster = React3.useRef(new
|
|
2158
|
-
const mouse = React3.useRef(new
|
|
2380
|
+
const raycaster = React3.useRef(new THREE10__namespace.Raycaster());
|
|
2381
|
+
const mouse = React3.useRef(new THREE10__namespace.Vector2());
|
|
2159
2382
|
const clientToNDC = React3.useCallback(
|
|
2160
2383
|
(clientX, clientY) => {
|
|
2161
2384
|
if (!canvas) {
|
|
@@ -2225,8 +2448,8 @@ function useRaycaster(options) {
|
|
|
2225
2448
|
const ndc = clientToNDC(clientX, clientY);
|
|
2226
2449
|
mouse.current.set(ndc.x, ndc.y);
|
|
2227
2450
|
raycaster.current.setFromCamera(mouse.current, camera);
|
|
2228
|
-
const plane = new
|
|
2229
|
-
const target = new
|
|
2451
|
+
const plane = new THREE10__namespace.Plane(new THREE10__namespace.Vector3(0, 1, 0), 0);
|
|
2452
|
+
const target = new THREE10__namespace.Vector3();
|
|
2230
2453
|
const intersection = raycaster.current.ray.intersectPlane(plane, target);
|
|
2231
2454
|
if (intersection) {
|
|
2232
2455
|
const gridX = Math.round((target.x - offsetX) / cellSize);
|
|
@@ -2264,7 +2487,7 @@ function useRaycaster(options) {
|
|
|
2264
2487
|
return {
|
|
2265
2488
|
gridX: gridCoords.x,
|
|
2266
2489
|
gridZ: gridCoords.z,
|
|
2267
|
-
worldPosition: new
|
|
2490
|
+
worldPosition: new THREE10__namespace.Vector3(
|
|
2268
2491
|
gridCoords.x * cellSize + offsetX,
|
|
2269
2492
|
0,
|
|
2270
2493
|
gridCoords.z * cellSize + offsetZ
|
|
@@ -2294,7 +2517,7 @@ var DEFAULT_CONFIG = {
|
|
|
2294
2517
|
};
|
|
2295
2518
|
function gridToWorld(gridX, gridZ, config = DEFAULT_CONFIG) {
|
|
2296
2519
|
const opts = { ...DEFAULT_CONFIG, ...config };
|
|
2297
|
-
return new
|
|
2520
|
+
return new THREE10__namespace.Vector3(
|
|
2298
2521
|
gridX * opts.cellSize + opts.offsetX,
|
|
2299
2522
|
opts.elevation,
|
|
2300
2523
|
gridZ * opts.cellSize + opts.offsetZ
|
|
@@ -2308,17 +2531,17 @@ function worldToGrid(worldX, worldZ, config = DEFAULT_CONFIG) {
|
|
|
2308
2531
|
};
|
|
2309
2532
|
}
|
|
2310
2533
|
function raycastToPlane(camera, mouseX, mouseY, planeY = 0) {
|
|
2311
|
-
const raycaster = new
|
|
2312
|
-
const mouse = new
|
|
2534
|
+
const raycaster = new THREE10__namespace.Raycaster();
|
|
2535
|
+
const mouse = new THREE10__namespace.Vector2(mouseX, mouseY);
|
|
2313
2536
|
raycaster.setFromCamera(mouse, camera);
|
|
2314
|
-
const plane = new
|
|
2315
|
-
const target = new
|
|
2537
|
+
const plane = new THREE10__namespace.Plane(new THREE10__namespace.Vector3(0, 1, 0), -planeY);
|
|
2538
|
+
const target = new THREE10__namespace.Vector3();
|
|
2316
2539
|
const intersection = raycaster.ray.intersectPlane(plane, target);
|
|
2317
2540
|
return intersection ? target : null;
|
|
2318
2541
|
}
|
|
2319
2542
|
function raycastToObjects(camera, mouseX, mouseY, objects) {
|
|
2320
|
-
const raycaster = new
|
|
2321
|
-
const mouse = new
|
|
2543
|
+
const raycaster = new THREE10__namespace.Raycaster();
|
|
2544
|
+
const mouse = new THREE10__namespace.Vector2(mouseX, mouseY);
|
|
2322
2545
|
raycaster.setFromCamera(mouse, camera);
|
|
2323
2546
|
const intersects = raycaster.intersectObjects(objects, true);
|
|
2324
2547
|
return intersects.length > 0 ? intersects[0] : null;
|
|
@@ -2370,14 +2593,14 @@ function getCellsInRadius(centerX, centerZ, radius) {
|
|
|
2370
2593
|
return cells;
|
|
2371
2594
|
}
|
|
2372
2595
|
function createGridHighlight(color = 16776960, opacity = 0.3) {
|
|
2373
|
-
const geometry = new
|
|
2374
|
-
const material = new
|
|
2596
|
+
const geometry = new THREE10__namespace.PlaneGeometry(0.95, 0.95);
|
|
2597
|
+
const material = new THREE10__namespace.MeshBasicMaterial({
|
|
2375
2598
|
color,
|
|
2376
2599
|
transparent: true,
|
|
2377
2600
|
opacity,
|
|
2378
|
-
side:
|
|
2601
|
+
side: THREE10__namespace.DoubleSide
|
|
2379
2602
|
});
|
|
2380
|
-
const mesh = new
|
|
2603
|
+
const mesh = new THREE10__namespace.Mesh(geometry, material);
|
|
2381
2604
|
mesh.rotation.x = -Math.PI / 2;
|
|
2382
2605
|
mesh.position.y = 0.01;
|
|
2383
2606
|
return mesh;
|
|
@@ -2390,31 +2613,31 @@ function normalizeMouseCoordinates(clientX, clientY, element) {
|
|
|
2390
2613
|
};
|
|
2391
2614
|
}
|
|
2392
2615
|
function isInFrustum(position, camera, padding = 0) {
|
|
2393
|
-
const frustum = new
|
|
2394
|
-
const projScreenMatrix = new
|
|
2616
|
+
const frustum = new THREE10__namespace.Frustum();
|
|
2617
|
+
const projScreenMatrix = new THREE10__namespace.Matrix4();
|
|
2395
2618
|
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
2396
2619
|
frustum.setFromProjectionMatrix(projScreenMatrix);
|
|
2397
|
-
const sphere = new
|
|
2620
|
+
const sphere = new THREE10__namespace.Sphere(position, padding);
|
|
2398
2621
|
return frustum.intersectsSphere(sphere);
|
|
2399
2622
|
}
|
|
2400
2623
|
function filterByFrustum(positions, camera, padding = 0) {
|
|
2401
|
-
const frustum = new
|
|
2402
|
-
const projScreenMatrix = new
|
|
2624
|
+
const frustum = new THREE10__namespace.Frustum();
|
|
2625
|
+
const projScreenMatrix = new THREE10__namespace.Matrix4();
|
|
2403
2626
|
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
2404
2627
|
frustum.setFromProjectionMatrix(projScreenMatrix);
|
|
2405
2628
|
return positions.filter((position) => {
|
|
2406
|
-
const sphere = new
|
|
2629
|
+
const sphere = new THREE10__namespace.Sphere(position, padding);
|
|
2407
2630
|
return frustum.intersectsSphere(sphere);
|
|
2408
2631
|
});
|
|
2409
2632
|
}
|
|
2410
2633
|
function getVisibleIndices(positions, camera, padding = 0) {
|
|
2411
|
-
const frustum = new
|
|
2412
|
-
const projScreenMatrix = new
|
|
2634
|
+
const frustum = new THREE10__namespace.Frustum();
|
|
2635
|
+
const projScreenMatrix = new THREE10__namespace.Matrix4();
|
|
2413
2636
|
const visible = /* @__PURE__ */ new Set();
|
|
2414
2637
|
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
2415
2638
|
frustum.setFromProjectionMatrix(projScreenMatrix);
|
|
2416
2639
|
positions.forEach((position, index) => {
|
|
2417
|
-
const sphere = new
|
|
2640
|
+
const sphere = new THREE10__namespace.Sphere(position, padding);
|
|
2418
2641
|
if (frustum.intersectsSphere(sphere)) {
|
|
2419
2642
|
visible.add(index);
|
|
2420
2643
|
}
|
|
@@ -2438,7 +2661,7 @@ function updateInstanceLOD(instancedMesh, positions, camera, lodDistances) {
|
|
|
2438
2661
|
return lodIndices;
|
|
2439
2662
|
}
|
|
2440
2663
|
function cullInstancedMesh(instancedMesh, positions, visibleIndices) {
|
|
2441
|
-
const dummy = new
|
|
2664
|
+
const dummy = new THREE10__namespace.Object3D();
|
|
2442
2665
|
let visibleCount = 0;
|
|
2443
2666
|
positions.forEach((position, index) => {
|
|
2444
2667
|
if (visibleIndices.has(index)) {
|
|
@@ -3605,25 +3828,25 @@ function orbitRingPositions(count, radius, tilt) {
|
|
|
3605
3828
|
return positions;
|
|
3606
3829
|
}
|
|
3607
3830
|
function arcCurve3D(from, to, offset) {
|
|
3608
|
-
const start = new
|
|
3609
|
-
const end = new
|
|
3610
|
-
const mid = new
|
|
3611
|
-
const dir = new
|
|
3612
|
-
const up = new
|
|
3613
|
-
const perp = new
|
|
3831
|
+
const start = new THREE10.Vector3(...from);
|
|
3832
|
+
const end = new THREE10.Vector3(...to);
|
|
3833
|
+
const mid = new THREE10.Vector3().addVectors(start, end).multiplyScalar(0.5);
|
|
3834
|
+
const dir = new THREE10.Vector3().subVectors(end, start).normalize();
|
|
3835
|
+
const up = new THREE10.Vector3(0, 1, 0);
|
|
3836
|
+
const perp = new THREE10.Vector3().crossVectors(dir, up).normalize();
|
|
3614
3837
|
if (perp.length() < 1e-3) {
|
|
3615
|
-
perp.crossVectors(dir, new
|
|
3838
|
+
perp.crossVectors(dir, new THREE10.Vector3(1, 0, 0)).normalize();
|
|
3616
3839
|
}
|
|
3617
3840
|
const control = mid.clone().add(perp.multiplyScalar(offset));
|
|
3618
3841
|
control.y += Math.abs(offset) * 0.3;
|
|
3619
|
-
return new
|
|
3842
|
+
return new THREE10.QuadraticBezierCurve3(start, control, end);
|
|
3620
3843
|
}
|
|
3621
3844
|
function selfLoopCurve3D(position, loopRadius) {
|
|
3622
|
-
const base = new
|
|
3623
|
-
const start = base.clone().add(new
|
|
3624
|
-
const end = base.clone().add(new
|
|
3625
|
-
const control = base.clone().add(new
|
|
3626
|
-
return new
|
|
3845
|
+
const base = new THREE10.Vector3(...position);
|
|
3846
|
+
const start = base.clone().add(new THREE10.Vector3(-loopRadius * 0.3, 0, 0));
|
|
3847
|
+
const end = base.clone().add(new THREE10.Vector3(loopRadius * 0.3, 0, 0));
|
|
3848
|
+
const control = base.clone().add(new THREE10.Vector3(0, loopRadius, 0));
|
|
3849
|
+
return new THREE10.QuadraticBezierCurve3(start, control, end);
|
|
3627
3850
|
}
|
|
3628
3851
|
function treeLayout3D(node, origin, horizontalSpacing, verticalSpacing = 2) {
|
|
3629
3852
|
const results = [];
|
|
@@ -3790,7 +4013,7 @@ var Avl3DOrbitalNode = ({
|
|
|
3790
4013
|
if (!groupRef.current) return;
|
|
3791
4014
|
groupRef.current.rotation.y += delta * (hovered ? 0.4 : 0.2);
|
|
3792
4015
|
groupRef.current.rotation.x += delta * 0.05;
|
|
3793
|
-
currentScale.current =
|
|
4016
|
+
currentScale.current = THREE10.MathUtils.damp(currentScale.current, targetScale, 6, delta);
|
|
3794
4017
|
});
|
|
3795
4018
|
const baseBrightness = 0.3 + Math.min(pageCount, 5) * 0.05;
|
|
3796
4019
|
const emissiveIntensity = hovered ? 0.8 : baseBrightness;
|
|
@@ -4432,7 +4655,7 @@ var Avl3DStateNode = ({
|
|
|
4432
4655
|
const targetScale = hovered ? 1.08 : 1;
|
|
4433
4656
|
const currentScale = React3.useRef(1);
|
|
4434
4657
|
fiber.useFrame((_, delta) => {
|
|
4435
|
-
currentScale.current =
|
|
4658
|
+
currentScale.current = THREE10.MathUtils.damp(currentScale.current, targetScale, 6, delta);
|
|
4436
4659
|
});
|
|
4437
4660
|
const scale = currentScale.current;
|
|
4438
4661
|
return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
|
|
@@ -4612,9 +4835,9 @@ var Avl3DTransitionArc = ({
|
|
|
4612
4835
|
const guardPt = curve.getPoint(0.3);
|
|
4613
4836
|
const arrowPt = curve.getPoint(0.9);
|
|
4614
4837
|
const arrowTangent = curve.getTangent(0.9);
|
|
4615
|
-
const upVec = new
|
|
4616
|
-
const tangentVec = new
|
|
4617
|
-
const quat = new
|
|
4838
|
+
const upVec = new THREE10.Vector3(0, 1, 0);
|
|
4839
|
+
const tangentVec = new THREE10.Vector3(arrowTangent.x, arrowTangent.y, arrowTangent.z).normalize();
|
|
4840
|
+
const quat = new THREE10.Quaternion().setFromUnitVectors(upVec, tangentVec);
|
|
4618
4841
|
const effectPositions2 = [];
|
|
4619
4842
|
for (let ei = 0; ei < 4; ei++) {
|
|
4620
4843
|
const t = 0.7 + ei * 0.05;
|
|
@@ -4838,14 +5061,14 @@ function operatorColor(label) {
|
|
|
4838
5061
|
return "#4A90D9";
|
|
4839
5062
|
}
|
|
4840
5063
|
function edgeGeometry(parent, child) {
|
|
4841
|
-
const p = new
|
|
4842
|
-
const c = new
|
|
4843
|
-
const mid = new
|
|
4844
|
-
const dir = new
|
|
5064
|
+
const p = new THREE10.Vector3(parent.x, parent.y, parent.z);
|
|
5065
|
+
const c = new THREE10.Vector3(child.x, child.y, child.z);
|
|
5066
|
+
const mid = new THREE10.Vector3().addVectors(p, c).multiplyScalar(0.5);
|
|
5067
|
+
const dir = new THREE10.Vector3().subVectors(c, p);
|
|
4845
5068
|
const length = dir.length();
|
|
4846
|
-
const yAxis = new
|
|
5069
|
+
const yAxis = new THREE10.Vector3(0, 1, 0);
|
|
4847
5070
|
const angle = yAxis.angleTo(dir.normalize());
|
|
4848
|
-
const axis = new
|
|
5071
|
+
const axis = new THREE10.Vector3().crossVectors(yAxis, dir).normalize();
|
|
4849
5072
|
if (axis.length() < 1e-3) {
|
|
4850
5073
|
return {
|
|
4851
5074
|
position: [mid.x, mid.y, mid.z],
|
|
@@ -5221,12 +5444,12 @@ function useAvl3DConfig() {
|
|
|
5221
5444
|
}
|
|
5222
5445
|
function CameraController({ targetPosition, targetLookAt, animated }) {
|
|
5223
5446
|
const { camera } = fiber.useThree();
|
|
5224
|
-
const targetPosVec = React3.useRef(new
|
|
5225
|
-
const targetLookVec = React3.useRef(new
|
|
5447
|
+
const targetPosVec = React3.useRef(new THREE10__namespace.Vector3(...targetPosition));
|
|
5448
|
+
const targetLookVec = React3.useRef(new THREE10__namespace.Vector3(...targetLookAt));
|
|
5226
5449
|
const isAnimating = React3.useRef(false);
|
|
5227
5450
|
React3.useEffect(() => {
|
|
5228
|
-
const newTarget = new
|
|
5229
|
-
const newLookAt = new
|
|
5451
|
+
const newTarget = new THREE10__namespace.Vector3(...targetPosition);
|
|
5452
|
+
const newLookAt = new THREE10__namespace.Vector3(...targetLookAt);
|
|
5230
5453
|
if (!newTarget.equals(targetPosVec.current) || !newLookAt.equals(targetLookVec.current)) {
|
|
5231
5454
|
targetPosVec.current.copy(newTarget);
|
|
5232
5455
|
targetLookVec.current.copy(newLookAt);
|
|
@@ -5241,9 +5464,9 @@ function CameraController({ targetPosition, targetLookAt, animated }) {
|
|
|
5241
5464
|
fiber.useFrame((_, delta) => {
|
|
5242
5465
|
if (!isAnimating.current) return;
|
|
5243
5466
|
const speed = 3;
|
|
5244
|
-
camera.position.x =
|
|
5245
|
-
camera.position.y =
|
|
5246
|
-
camera.position.z =
|
|
5467
|
+
camera.position.x = THREE10__namespace.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
|
|
5468
|
+
camera.position.y = THREE10__namespace.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
|
|
5469
|
+
camera.position.z = THREE10__namespace.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
|
|
5247
5470
|
camera.lookAt(targetLookVec.current);
|
|
5248
5471
|
const dist = camera.position.distanceTo(targetPosVec.current);
|
|
5249
5472
|
if (dist < 0.05) {
|
|
@@ -5258,7 +5481,7 @@ function SceneFade({ animating, children }) {
|
|
|
5258
5481
|
fiber.useFrame((_, delta) => {
|
|
5259
5482
|
if (!groupRef.current) return;
|
|
5260
5483
|
const target = animating ? 0 : 1;
|
|
5261
|
-
opacityRef.current =
|
|
5484
|
+
opacityRef.current = THREE10__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
|
|
5262
5485
|
groupRef.current.visible = opacityRef.current > 0.05;
|
|
5263
5486
|
const s = 0.9 + opacityRef.current * 0.1;
|
|
5264
5487
|
groupRef.current.scale.setScalar(s);
|