@almadar/ui 5.141.0 → 5.143.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 +1326 -1240
- package/dist/avl/index.js +355 -269
- package/dist/{avl-schema-parser-B8Onmfsu.d.cts → avl-schema-parser-0hkiHOq3.d.ts} +233 -2
- package/dist/{avl-schema-parser-B8Onmfsu.d.ts → avl-schema-parser-BZ8pICOS.d.cts} +233 -2
- package/dist/{cn-rwc3svaX.d.cts → cn-CvImTgKH.d.cts} +1 -1
- package/dist/{cn-BDwC4QpH.d.ts → cn-DryTiahe.d.ts} +1 -1
- package/dist/components/index.cjs +1310 -1224
- package/dist/components/index.d.cts +13 -6
- package/dist/components/index.d.ts +13 -6
- package/dist/components/index.js +346 -260
- package/dist/lib/drawable/three/index.cjs +560 -194
- package/dist/lib/drawable/three/index.d.cts +14 -173
- package/dist/lib/drawable/three/index.d.ts +14 -173
- package/dist/lib/drawable/three/index.js +536 -170
- package/dist/lib/index.d.cts +2 -2
- package/dist/lib/index.d.ts +2 -2
- package/dist/{paintDispatch-BQn5Lyx1.d.cts → paintDispatch-D3-5_cOb.d.cts} +72 -32
- package/dist/{paintDispatch-BQn5Lyx1.d.ts → paintDispatch-D3-5_cOb.d.ts} +72 -32
- package/dist/providers/index.cjs +1209 -1123
- package/dist/providers/index.js +330 -244
- package/dist/runtime/index.cjs +1187 -1101
- package/dist/runtime/index.js +335 -249
- package/package.json +8 -8
|
@@ -4,9 +4,11 @@ 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 THREE11 = require('three');
|
|
8
|
+
var RoomEnvironment_js = require('three/examples/jsm/environments/RoomEnvironment.js');
|
|
8
9
|
var drei = require('@react-three/drei');
|
|
9
10
|
var jsxRuntime = require('react/jsx-runtime');
|
|
11
|
+
var postprocessing = require('@react-three/postprocessing');
|
|
10
12
|
var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
|
|
11
13
|
var SkeletonUtils = require('three/examples/jsm/utils/SkeletonUtils');
|
|
12
14
|
var clsx = require('clsx');
|
|
@@ -14,7 +16,6 @@ var tailwindMerge = require('tailwind-merge');
|
|
|
14
16
|
var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
|
|
15
17
|
var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
|
|
16
18
|
var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
|
|
17
|
-
var postprocessing = require('@react-three/postprocessing');
|
|
18
19
|
var hooks = require('@almadar/ui/hooks');
|
|
19
20
|
|
|
20
21
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -38,7 +39,7 @@ function _interopNamespace(e) {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
41
|
-
var
|
|
42
|
+
var THREE11__namespace = /*#__PURE__*/_interopNamespace(THREE11);
|
|
42
43
|
|
|
43
44
|
var __defProp = Object.defineProperty;
|
|
44
45
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -474,6 +475,10 @@ function Lighting3D({
|
|
|
474
475
|
directionalIntensity = 0.8,
|
|
475
476
|
directionalColor = "#ffffff",
|
|
476
477
|
directionalPosition = [10, 20, 10],
|
|
478
|
+
hemisphereIntensity = 0.3,
|
|
479
|
+
hemisphereColor = "#87ceeb",
|
|
480
|
+
hemisphereGroundColor = "#362d1d",
|
|
481
|
+
points,
|
|
477
482
|
shadows = true,
|
|
478
483
|
shadowMapSize = 2048,
|
|
479
484
|
shadowCameraSize = 20,
|
|
@@ -506,22 +511,63 @@ function Lighting3D({
|
|
|
506
511
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
507
512
|
"hemisphereLight",
|
|
508
513
|
{
|
|
509
|
-
intensity:
|
|
510
|
-
color:
|
|
511
|
-
groundColor:
|
|
514
|
+
intensity: hemisphereIntensity,
|
|
515
|
+
color: hemisphereColor,
|
|
516
|
+
groundColor: hemisphereGroundColor
|
|
512
517
|
}
|
|
513
518
|
),
|
|
519
|
+
points?.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
520
|
+
"pointLight",
|
|
521
|
+
{
|
|
522
|
+
position: p.position,
|
|
523
|
+
intensity: p.intensity,
|
|
524
|
+
color: p.color,
|
|
525
|
+
distance: p.distance,
|
|
526
|
+
decay: p.decay
|
|
527
|
+
},
|
|
528
|
+
i
|
|
529
|
+
)),
|
|
514
530
|
showHelpers && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
515
531
|
"directionalLightHelper",
|
|
516
532
|
{
|
|
517
533
|
args: [
|
|
518
|
-
new
|
|
534
|
+
new THREE11__namespace.DirectionalLight(directionalColor, directionalIntensity),
|
|
519
535
|
5
|
|
520
536
|
]
|
|
521
537
|
}
|
|
522
538
|
) })
|
|
523
539
|
] });
|
|
524
540
|
}
|
|
541
|
+
function Effects3D({ post }) {
|
|
542
|
+
if (!post || !post.bloom && !post.vignette) return null;
|
|
543
|
+
const passes = [];
|
|
544
|
+
if (post.bloom) {
|
|
545
|
+
passes.push(
|
|
546
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
547
|
+
postprocessing.Bloom,
|
|
548
|
+
{
|
|
549
|
+
intensity: post.bloom.intensity ?? 1,
|
|
550
|
+
luminanceThreshold: post.bloom.threshold ?? 0.9,
|
|
551
|
+
luminanceSmoothing: post.bloom.smoothing ?? 0.3
|
|
552
|
+
},
|
|
553
|
+
"bloom"
|
|
554
|
+
)
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
if (post.vignette) {
|
|
558
|
+
passes.push(
|
|
559
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
560
|
+
postprocessing.Vignette,
|
|
561
|
+
{
|
|
562
|
+
offset: post.vignette.offset ?? 0.3,
|
|
563
|
+
darkness: post.vignette.darkness ?? 0.6
|
|
564
|
+
},
|
|
565
|
+
"vignette"
|
|
566
|
+
)
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
return /* @__PURE__ */ jsxRuntime.jsx(postprocessing.EffectComposer, { children: passes });
|
|
570
|
+
}
|
|
525
571
|
function CameraController3D({
|
|
526
572
|
onCameraChange
|
|
527
573
|
}) {
|
|
@@ -542,8 +588,8 @@ function FollowCamera3D({
|
|
|
542
588
|
offset
|
|
543
589
|
}) {
|
|
544
590
|
const { camera } = fiber.useThree();
|
|
545
|
-
const look = React3.useRef(new
|
|
546
|
-
const goal = React3.useRef(new
|
|
591
|
+
const look = React3.useRef(new THREE11__namespace.Vector3(target[0], target[1], target[2]));
|
|
592
|
+
const goal = React3.useRef(new THREE11__namespace.Vector3());
|
|
547
593
|
fiber.useFrame((_, delta) => {
|
|
548
594
|
const t = Math.min(1, delta * 5);
|
|
549
595
|
goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
|
|
@@ -564,6 +610,179 @@ function create3DProjector(opts = {}) {
|
|
|
564
610
|
toWorld: (pos) => [pos.x * cellSize + offsetX, pos.z ?? 0, pos.y * cellSize + offsetZ]
|
|
565
611
|
};
|
|
566
612
|
}
|
|
613
|
+
var BoneStore = class {
|
|
614
|
+
constructor() {
|
|
615
|
+
__publicField(this, "bones", /* @__PURE__ */ new Map());
|
|
616
|
+
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
617
|
+
}
|
|
618
|
+
register(name, bone) {
|
|
619
|
+
this.bones.set(name, bone);
|
|
620
|
+
this.notify();
|
|
621
|
+
return () => {
|
|
622
|
+
if (this.bones.get(name) === bone) {
|
|
623
|
+
this.bones.delete(name);
|
|
624
|
+
this.notify();
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
get(name) {
|
|
629
|
+
return this.bones.get(name);
|
|
630
|
+
}
|
|
631
|
+
subscribe(listener) {
|
|
632
|
+
this.listeners.add(listener);
|
|
633
|
+
return () => this.listeners.delete(listener);
|
|
634
|
+
}
|
|
635
|
+
notify() {
|
|
636
|
+
for (const l of this.listeners) l();
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
var BoneRegistryContext = React3.createContext(null);
|
|
640
|
+
function isAnimatedGroup(node) {
|
|
641
|
+
return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
|
|
642
|
+
}
|
|
643
|
+
var MESH_SEGMENTS_DEFAULT = 24;
|
|
644
|
+
function polyhedronBounds(vertices) {
|
|
645
|
+
if (!vertices || vertices.length < 3) return null;
|
|
646
|
+
const min = [Infinity, Infinity, Infinity];
|
|
647
|
+
const max = [-Infinity, -Infinity, -Infinity];
|
|
648
|
+
for (const v of vertices) {
|
|
649
|
+
if (v.length < 3 || !v.every((c) => Number.isFinite(c))) return null;
|
|
650
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
651
|
+
min[axis] = Math.min(min[axis], v[axis]);
|
|
652
|
+
max[axis] = Math.max(max[axis], v[axis]);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return { min, max };
|
|
656
|
+
}
|
|
657
|
+
function clampSegments(segments) {
|
|
658
|
+
const s = segments ?? MESH_SEGMENTS_DEFAULT;
|
|
659
|
+
return Math.min(64, Math.max(3, Math.round(s)));
|
|
660
|
+
}
|
|
661
|
+
function isAnimatedMesh(node) {
|
|
662
|
+
return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
|
|
663
|
+
}
|
|
664
|
+
var lerp = (a, b, k) => a + (b - a) * k;
|
|
665
|
+
var NUMERIC_TRACKS = [
|
|
666
|
+
"offsetX",
|
|
667
|
+
"offsetY",
|
|
668
|
+
"offsetZ",
|
|
669
|
+
"rotateX",
|
|
670
|
+
"rotateY",
|
|
671
|
+
"rotateZ",
|
|
672
|
+
"scale",
|
|
673
|
+
"opacity",
|
|
674
|
+
"emissiveIntensity"
|
|
675
|
+
];
|
|
676
|
+
function applyMeshAnimation(node, timeMs) {
|
|
677
|
+
const anim = node.animation;
|
|
678
|
+
if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
|
|
679
|
+
const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
|
|
680
|
+
const cycle = timeMs / anim.durationMs;
|
|
681
|
+
const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
|
|
682
|
+
const trackValue = (key) => {
|
|
683
|
+
const defined = frames.filter((f) => f[key] !== void 0);
|
|
684
|
+
if (defined.length === 0) return void 0;
|
|
685
|
+
let prev;
|
|
686
|
+
let next;
|
|
687
|
+
for (const f of defined) {
|
|
688
|
+
if (f.at <= t) prev = f;
|
|
689
|
+
else if (!next) next = f;
|
|
690
|
+
}
|
|
691
|
+
if (!prev) return defined[0][key];
|
|
692
|
+
if (!next) return prev[key];
|
|
693
|
+
const span = next.at - prev.at;
|
|
694
|
+
const k = span > 0 ? (t - prev.at) / span : 1;
|
|
695
|
+
const a = prev[key];
|
|
696
|
+
const b = next[key];
|
|
697
|
+
if (typeof a === "number" && typeof b === "number") return lerp(a, b, k);
|
|
698
|
+
return a;
|
|
699
|
+
};
|
|
700
|
+
const num = {};
|
|
701
|
+
for (const key of NUMERIC_TRACKS) {
|
|
702
|
+
const v = trackValue(key);
|
|
703
|
+
if (v !== void 0) num[key] = v;
|
|
704
|
+
}
|
|
705
|
+
return {
|
|
706
|
+
offset: [num.offsetX ?? 0, num.offsetY ?? 0, num.offsetZ ?? 0],
|
|
707
|
+
rotate: [num.rotateX ?? 0, num.rotateY ?? 0, num.rotateZ ?? 0],
|
|
708
|
+
scale: num.scale ?? 1,
|
|
709
|
+
opacity: num.opacity,
|
|
710
|
+
emissiveIntensity: num.emissiveIntensity,
|
|
711
|
+
color: trackValue("color"),
|
|
712
|
+
emissive: trackValue("emissive")
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
var NUMERIC_TRACKS2 = [
|
|
716
|
+
"offsetX",
|
|
717
|
+
"offsetY",
|
|
718
|
+
"rotate",
|
|
719
|
+
"opacity",
|
|
720
|
+
"radiusX",
|
|
721
|
+
"radiusY",
|
|
722
|
+
"width",
|
|
723
|
+
"height",
|
|
724
|
+
"strokeWidth",
|
|
725
|
+
"strokeDashOffset",
|
|
726
|
+
"blur"
|
|
727
|
+
];
|
|
728
|
+
function isAnimatedShape(node) {
|
|
729
|
+
return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
|
|
730
|
+
}
|
|
731
|
+
var lerp2 = (a, b, k) => a + (b - a) * k;
|
|
732
|
+
function applyShapeAnimation(node, timeMs) {
|
|
733
|
+
const anim = node.animation;
|
|
734
|
+
if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return node;
|
|
735
|
+
const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
|
|
736
|
+
const cycle = timeMs / anim.durationMs;
|
|
737
|
+
const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
|
|
738
|
+
const out = { ...node };
|
|
739
|
+
const trackValue = (key) => {
|
|
740
|
+
const defined = frames.filter((f) => f[key] !== void 0);
|
|
741
|
+
if (defined.length === 0) return void 0;
|
|
742
|
+
let prev;
|
|
743
|
+
let next;
|
|
744
|
+
for (const f of defined) {
|
|
745
|
+
if (f.at <= t) prev = f;
|
|
746
|
+
else if (!next) next = f;
|
|
747
|
+
}
|
|
748
|
+
if (!prev) return defined[0][key];
|
|
749
|
+
if (!next) return prev[key];
|
|
750
|
+
const span = next.at - prev.at;
|
|
751
|
+
const k = span > 0 ? (t - prev.at) / span : 1;
|
|
752
|
+
const a = prev[key];
|
|
753
|
+
const b = next[key];
|
|
754
|
+
if (typeof a === "number" && typeof b === "number") return lerp2(a, b, k);
|
|
755
|
+
return a;
|
|
756
|
+
};
|
|
757
|
+
for (const key of NUMERIC_TRACKS2) {
|
|
758
|
+
const v = trackValue(key);
|
|
759
|
+
if (v !== void 0) out[key] = v;
|
|
760
|
+
}
|
|
761
|
+
const fill = trackValue("fill");
|
|
762
|
+
if (fill !== void 0) out.fill = fill;
|
|
763
|
+
const stroke = trackValue("stroke");
|
|
764
|
+
if (stroke !== void 0) out.stroke = stroke;
|
|
765
|
+
const shadowFrames = frames.filter((f) => f.shadow !== void 0);
|
|
766
|
+
if (shadowFrames.length > 0) {
|
|
767
|
+
const sh = trackValue("shadow");
|
|
768
|
+
if (sh !== void 0) {
|
|
769
|
+
let prevSh;
|
|
770
|
+
let nextSh;
|
|
771
|
+
for (const f of shadowFrames) {
|
|
772
|
+
if (f.at <= t) prevSh = f;
|
|
773
|
+
else if (!nextSh) nextSh = f;
|
|
774
|
+
}
|
|
775
|
+
if (prevSh?.shadow && nextSh?.shadow) {
|
|
776
|
+
const span = nextSh.at - prevSh.at;
|
|
777
|
+
const k = span > 0 ? (t - prevSh.at) / span : 1;
|
|
778
|
+
out.shadow = { color: prevSh.shadow.color, blur: lerp2(prevSh.shadow.blur, nextSh.shadow.blur, k) };
|
|
779
|
+
} else {
|
|
780
|
+
out.shadow = sh;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return out;
|
|
785
|
+
}
|
|
567
786
|
|
|
568
787
|
// lib/atlasSlice.ts
|
|
569
788
|
var atlasCache = /* @__PURE__ */ new Map();
|
|
@@ -699,12 +918,12 @@ function ModelLoader({
|
|
|
699
918
|
if (!loadedModel) return null;
|
|
700
919
|
const cloned = SkeletonUtils.clone(loadedModel);
|
|
701
920
|
cloned.updateMatrixWorld(true);
|
|
702
|
-
const tintColor = tint ? new
|
|
921
|
+
const tintColor = tint ? new THREE11__namespace.Color(tint) : null;
|
|
703
922
|
cloned.traverse((child) => {
|
|
704
|
-
if (child instanceof
|
|
923
|
+
if (child instanceof THREE11__namespace.Mesh) {
|
|
705
924
|
child.castShadow = castShadow;
|
|
706
925
|
child.receiveShadow = receiveShadow;
|
|
707
|
-
if (tintColor && child.material instanceof
|
|
926
|
+
if (tintColor && child.material instanceof THREE11__namespace.MeshStandardMaterial) {
|
|
708
927
|
const mat = child.material.clone();
|
|
709
928
|
mat.color.multiply(tintColor);
|
|
710
929
|
child.material = mat;
|
|
@@ -713,7 +932,7 @@ function ModelLoader({
|
|
|
713
932
|
});
|
|
714
933
|
return cloned;
|
|
715
934
|
}, [loadedModel, castShadow, receiveShadow, tint]);
|
|
716
|
-
const mixer = React3.useMemo(() => model ? new
|
|
935
|
+
const mixer = React3.useMemo(() => model ? new THREE11__namespace.AnimationMixer(model) : null, [model]);
|
|
717
936
|
React3.useEffect(() => {
|
|
718
937
|
if (!mixer || !animation || clips.length === 0) return;
|
|
719
938
|
const wanted = animation.toLowerCase();
|
|
@@ -730,8 +949,8 @@ function ModelLoader({
|
|
|
730
949
|
});
|
|
731
950
|
const normFactor = React3.useMemo(() => {
|
|
732
951
|
if (!model) return 1;
|
|
733
|
-
const box = new
|
|
734
|
-
const size = new
|
|
952
|
+
const box = new THREE11__namespace.Box3().setFromObject(model);
|
|
953
|
+
const size = new THREE11__namespace.Vector3();
|
|
735
954
|
box.getSize(size);
|
|
736
955
|
const maxDim = Math.max(size.x, size.y, size.z);
|
|
737
956
|
if (!Number.isFinite(maxDim) || maxDim < 0.05) return 1;
|
|
@@ -821,7 +1040,7 @@ var warnUnsupported3d = (kind) => {
|
|
|
821
1040
|
warnedUnsupported.add(kind);
|
|
822
1041
|
mesh3dLog.warn("unsupported drawable kind on the 3D backend \u2014 skipped", { kind });
|
|
823
1042
|
};
|
|
824
|
-
var CrossOriginTextureLoader = class extends
|
|
1043
|
+
var CrossOriginTextureLoader = class extends THREE11__namespace.TextureLoader {
|
|
825
1044
|
constructor() {
|
|
826
1045
|
super();
|
|
827
1046
|
this.crossOrigin = "anonymous";
|
|
@@ -839,7 +1058,7 @@ function useBillboardTexture(url) {
|
|
|
839
1058
|
url,
|
|
840
1059
|
(texture) => {
|
|
841
1060
|
if (!active) return;
|
|
842
|
-
texture.colorSpace =
|
|
1061
|
+
texture.colorSpace = THREE11__namespace.SRGBColorSpace;
|
|
843
1062
|
setState({ texture, error: false });
|
|
844
1063
|
},
|
|
845
1064
|
void 0,
|
|
@@ -892,7 +1111,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
|
|
|
892
1111
|
}, [texture, frame, node.height, node.width, anchor, cellSize]);
|
|
893
1112
|
const groundGeometry = React3__default.default.useMemo(() => {
|
|
894
1113
|
if (anchor !== "top-left" || !texture || !atlasReady) return null;
|
|
895
|
-
const g = new
|
|
1114
|
+
const g = new THREE11__namespace.PlaneGeometry(size.width, size.height);
|
|
896
1115
|
g.rotateX(-Math.PI / 2);
|
|
897
1116
|
return g;
|
|
898
1117
|
}, [anchor, texture, atlasReady, size.width, size.height]);
|
|
@@ -900,15 +1119,15 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
|
|
|
900
1119
|
if (anchor === "top-left") {
|
|
901
1120
|
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: [
|
|
902
1121
|
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
|
|
903
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side:
|
|
1122
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE11__namespace.DoubleSide })
|
|
904
1123
|
] }) });
|
|
905
1124
|
}
|
|
906
1125
|
return /* @__PURE__ */ jsxRuntime.jsx("group", { position: [world[0], world[1] + size.height / 2, world[2]], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
|
|
907
1126
|
/* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
|
|
908
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side:
|
|
1127
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE11__namespace.DoubleSide })
|
|
909
1128
|
] }) });
|
|
910
1129
|
}
|
|
911
|
-
texture.magFilter = texture.minFilter =
|
|
1130
|
+
texture.magFilter = texture.minFilter = THREE11__namespace.NearestFilter;
|
|
912
1131
|
texture.needsUpdate = true;
|
|
913
1132
|
if (frame) {
|
|
914
1133
|
texture.repeat.set(frame.w / size.imgW, frame.h / size.imgH);
|
|
@@ -921,7 +1140,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
|
|
|
921
1140
|
map: texture,
|
|
922
1141
|
transparent: true,
|
|
923
1142
|
alphaTest: 0.1,
|
|
924
|
-
side:
|
|
1143
|
+
side: THREE11__namespace.DoubleSide,
|
|
925
1144
|
opacity: (node.opacity ?? 1) * groupOpacity
|
|
926
1145
|
}
|
|
927
1146
|
) }) });
|
|
@@ -934,7 +1153,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
|
|
|
934
1153
|
map: texture,
|
|
935
1154
|
transparent: true,
|
|
936
1155
|
alphaTest: 0.1,
|
|
937
|
-
side:
|
|
1156
|
+
side: THREE11__namespace.DoubleSide,
|
|
938
1157
|
opacity: node.opacity ?? 1
|
|
939
1158
|
}
|
|
940
1159
|
)
|
|
@@ -965,8 +1184,27 @@ function Sprite3D({ node, projector, groupOpacity = 1 }) {
|
|
|
965
1184
|
return /* @__PURE__ */ jsxRuntime.jsx(SpriteBillboard, { node, world: projector.toWorld(node.position), cellSize: projector.cellSize, groupOpacity });
|
|
966
1185
|
}
|
|
967
1186
|
function Shape3D({ node, projector, groupOpacity = 1 }) {
|
|
968
|
-
|
|
969
|
-
const
|
|
1187
|
+
const groupRef = React3__default.default.useRef(null);
|
|
1188
|
+
const materialRef = React3__default.default.useRef(null);
|
|
1189
|
+
const animated = isAnimatedShape(node);
|
|
1190
|
+
const validPos = isValidScenePos(node.position);
|
|
1191
|
+
const world = validPos ? projector.toWorld(node.position) : [0, 0, 0];
|
|
1192
|
+
fiber.useFrame(({ clock }) => {
|
|
1193
|
+
if (!animated || !groupRef.current) return;
|
|
1194
|
+
const view = applyShapeAnimation(node, clock.elapsedTime * 1e3);
|
|
1195
|
+
groupRef.current.position.set(
|
|
1196
|
+
world[0] + (view.offsetX ?? 0) * projector.cellSize,
|
|
1197
|
+
world[1] + 0.02,
|
|
1198
|
+
world[2] + (view.offsetY ?? 0) * projector.cellSize
|
|
1199
|
+
);
|
|
1200
|
+
groupRef.current.rotation.y = -(view.rotate ?? 0);
|
|
1201
|
+
const mat = materialRef.current;
|
|
1202
|
+
if (mat) {
|
|
1203
|
+
mat.opacity = (view.opacity ?? node.opacity ?? 1) * groupOpacity;
|
|
1204
|
+
if (view.fill) mat.color.set(view.fill);
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
if (!validPos) return null;
|
|
970
1208
|
const color = node.fill ?? node.stroke ?? "#ffffff";
|
|
971
1209
|
let geometry;
|
|
972
1210
|
switch (node.shape) {
|
|
@@ -984,7 +1222,7 @@ function Shape3D({ node, projector, groupOpacity = 1 }) {
|
|
|
984
1222
|
}
|
|
985
1223
|
case "poly": {
|
|
986
1224
|
if (!node.points || node.points.length === 0) return null;
|
|
987
|
-
const s = new
|
|
1225
|
+
const s = new THREE11__namespace.Shape();
|
|
988
1226
|
node.points.forEach((p, i) => {
|
|
989
1227
|
if (i === 0) s.moveTo(p.x, p.y);
|
|
990
1228
|
else s.lineTo(p.x, p.y);
|
|
@@ -1000,12 +1238,12 @@ function Shape3D({ node, projector, groupOpacity = 1 }) {
|
|
|
1000
1238
|
default:
|
|
1001
1239
|
return null;
|
|
1002
1240
|
}
|
|
1003
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
1241
|
+
return /* @__PURE__ */ jsxRuntime.jsx("group", { ref: groupRef, position: [world[0], world[1] + 0.02, world[2]], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], children: [
|
|
1004
1242
|
geometry,
|
|
1005
|
-
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side:
|
|
1006
|
-
] });
|
|
1243
|
+
/* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { ref: materialRef, color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE11__namespace.DoubleSide })
|
|
1244
|
+
] }) });
|
|
1007
1245
|
}
|
|
1008
|
-
function Text3D({ node, projector }) {
|
|
1246
|
+
function Text3D({ node, projector, groupOpacity = 1 }) {
|
|
1009
1247
|
if (!isValidScenePos(node.position)) return null;
|
|
1010
1248
|
const world = projector.toWorld(node.position);
|
|
1011
1249
|
return /* @__PURE__ */ jsxRuntime.jsx(drei.Billboard, { position: [world[0], world[1] + 1.2, world[2]], children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1017,68 +1255,52 @@ function Text3D({ node, projector }) {
|
|
|
1017
1255
|
anchorY: "middle",
|
|
1018
1256
|
outlineWidth: 0.02,
|
|
1019
1257
|
outlineColor: "#000000",
|
|
1258
|
+
fillOpacity: groupOpacity,
|
|
1259
|
+
outlineOpacity: groupOpacity,
|
|
1020
1260
|
children: node.text
|
|
1021
1261
|
}
|
|
1022
1262
|
) });
|
|
1023
1263
|
}
|
|
1024
|
-
var
|
|
1025
|
-
function
|
|
1026
|
-
const
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
const
|
|
1050
|
-
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1053
|
-
let
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1264
|
+
var GROUND_ROTATION = [-Math.PI / 2, 0, 0];
|
|
1265
|
+
function polyhedronGeometry(node, cellSize) {
|
|
1266
|
+
const verts = node.vertices;
|
|
1267
|
+
const faces = node.faces;
|
|
1268
|
+
const bounds = polyhedronBounds(verts);
|
|
1269
|
+
if (!verts || !bounds || !faces || faces.length === 0) return null;
|
|
1270
|
+
const positions = new Float32Array(verts.length * 3);
|
|
1271
|
+
for (let i = 0; i < verts.length; i++) {
|
|
1272
|
+
positions[i * 3] = verts[i][0] * cellSize;
|
|
1273
|
+
positions[i * 3 + 1] = verts[i][2] * cellSize;
|
|
1274
|
+
positions[i * 3 + 2] = verts[i][1] * cellSize;
|
|
1275
|
+
}
|
|
1276
|
+
const index = [];
|
|
1277
|
+
for (const face of faces) {
|
|
1278
|
+
if (face.length < 3) continue;
|
|
1279
|
+
const [a, b, c] = face;
|
|
1280
|
+
if (a === b || b === c || a === c) continue;
|
|
1281
|
+
if (![a, b, c].every((i) => Number.isInteger(i) && i >= 0 && i < verts.length)) continue;
|
|
1282
|
+
index.push(a, c, b);
|
|
1283
|
+
}
|
|
1284
|
+
if (index.length === 0) return null;
|
|
1285
|
+
const geometry = new THREE11__namespace.BufferGeometry();
|
|
1286
|
+
geometry.setAttribute("position", new THREE11__namespace.BufferAttribute(positions, 3));
|
|
1287
|
+
geometry.setIndex(index);
|
|
1288
|
+
geometry.computeVertexNormals();
|
|
1289
|
+
const skin = node.skin;
|
|
1290
|
+
if (skin && skin.indices.length === verts.length && skin.weights.length === verts.length) {
|
|
1291
|
+
const skinIndex = new Uint16Array(verts.length * 4);
|
|
1292
|
+
const skinWeight = new Float32Array(verts.length * 4);
|
|
1293
|
+
for (let i = 0; i < verts.length; i++) {
|
|
1294
|
+
for (let k = 0; k < 4; k++) {
|
|
1295
|
+
skinIndex[i * 4 + k] = skin.indices[i][k] ?? 0;
|
|
1296
|
+
skinWeight[i * 4 + k] = skin.weights[i][k] ?? 0;
|
|
1297
|
+
}
|
|
1058
1298
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
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;
|
|
1299
|
+
geometry.setAttribute("skinIndex", new THREE11__namespace.BufferAttribute(skinIndex, 4));
|
|
1300
|
+
geometry.setAttribute("skinWeight", new THREE11__namespace.BufferAttribute(skinWeight, 4));
|
|
1072
1301
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
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
|
-
};
|
|
1302
|
+
const size = Math.max(bounds.max[0] - bounds.min[0], bounds.max[1] - bounds.min[1], bounds.max[2] - bounds.min[2]) * cellSize;
|
|
1303
|
+
return { geometry, lift: -bounds.min[2] * cellSize, size };
|
|
1082
1304
|
}
|
|
1083
1305
|
function meshGeometry(node, cellSize) {
|
|
1084
1306
|
const seg = clampSegments(node.segments);
|
|
@@ -1106,17 +1328,20 @@ function meshGeometry(node, cellSize) {
|
|
|
1106
1328
|
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
1329
|
}
|
|
1108
1330
|
case "plane":
|
|
1109
|
-
return { element: /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [w, d] }), lift: 0, size: Math.max(w, d) };
|
|
1331
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [w, d] }), lift: 0, size: Math.max(w, d), baseRotation: GROUND_ROTATION };
|
|
1110
1332
|
case "circle":
|
|
1111
|
-
return { element: /* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [r, seg] }), lift: 0, size: r * 2 };
|
|
1333
|
+
return { element: /* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [r, seg] }), lift: 0, size: r * 2, baseRotation: GROUND_ROTATION };
|
|
1334
|
+
case "polyhedron":
|
|
1335
|
+
return polyhedronGeometry(node, cellSize);
|
|
1112
1336
|
default:
|
|
1113
1337
|
return null;
|
|
1114
1338
|
}
|
|
1115
1339
|
}
|
|
1340
|
+
var warnedPolyhedronOutline = false;
|
|
1116
1341
|
var SIDE_MAP = {
|
|
1117
|
-
front:
|
|
1118
|
-
back:
|
|
1119
|
-
double:
|
|
1342
|
+
front: THREE11__namespace.FrontSide,
|
|
1343
|
+
back: THREE11__namespace.BackSide,
|
|
1344
|
+
double: THREE11__namespace.DoubleSide
|
|
1120
1345
|
};
|
|
1121
1346
|
function meshMaterial(mat, opacity, ref) {
|
|
1122
1347
|
const m = mat ?? {};
|
|
@@ -1160,6 +1385,53 @@ function meshMaterial(mat, opacity, ref) {
|
|
|
1160
1385
|
);
|
|
1161
1386
|
}
|
|
1162
1387
|
}
|
|
1388
|
+
function SkinnedPolyhedron3D({
|
|
1389
|
+
node,
|
|
1390
|
+
skin,
|
|
1391
|
+
geometry,
|
|
1392
|
+
cellSize,
|
|
1393
|
+
opacity
|
|
1394
|
+
}) {
|
|
1395
|
+
const boneStore = React3.useContext(BoneRegistryContext);
|
|
1396
|
+
const meshRef = React3.useRef(null);
|
|
1397
|
+
const [registryTick, setRegistryTick] = React3.useState(0);
|
|
1398
|
+
React3.useEffect(() => boneStore?.subscribe(() => setRegistryTick((t) => t + 1)), [boneStore]);
|
|
1399
|
+
React3.useEffect(() => {
|
|
1400
|
+
const mesh = meshRef.current;
|
|
1401
|
+
if (!mesh || !boneStore) return;
|
|
1402
|
+
const bones = [];
|
|
1403
|
+
for (const name of skin.bones) {
|
|
1404
|
+
const bone = boneStore.get(name);
|
|
1405
|
+
if (!bone) return;
|
|
1406
|
+
bones.push(bone);
|
|
1407
|
+
}
|
|
1408
|
+
if (mesh.skeleton && mesh.skeleton.bones.length === bones.length && mesh.skeleton.bones.every((b, i) => b === bones[i])) return;
|
|
1409
|
+
if (skin.inverseBindMatrices.length !== bones.length) return;
|
|
1410
|
+
const inverses = skin.inverseBindMatrices.map((m) => {
|
|
1411
|
+
const mat = new THREE11__namespace.Matrix4().fromArray(m);
|
|
1412
|
+
mat.elements[12] *= cellSize;
|
|
1413
|
+
mat.elements[13] *= cellSize;
|
|
1414
|
+
mat.elements[14] *= cellSize;
|
|
1415
|
+
return mat;
|
|
1416
|
+
});
|
|
1417
|
+
mesh.bind(new THREE11__namespace.Skeleton(bones, inverses), new THREE11__namespace.Matrix4());
|
|
1418
|
+
}, [registryTick, skin, boneStore, geometry, cellSize]);
|
|
1419
|
+
React3.useEffect(() => {
|
|
1420
|
+
const mesh = meshRef.current;
|
|
1421
|
+
return () => mesh?.skeleton?.dispose();
|
|
1422
|
+
}, []);
|
|
1423
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1424
|
+
"skinnedMesh",
|
|
1425
|
+
{
|
|
1426
|
+
ref: meshRef,
|
|
1427
|
+
geometry,
|
|
1428
|
+
frustumCulled: false,
|
|
1429
|
+
castShadow: node.castShadow ?? true,
|
|
1430
|
+
receiveShadow: node.receiveShadow ?? true,
|
|
1431
|
+
children: meshMaterial(node.material, opacity)
|
|
1432
|
+
}
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1163
1435
|
function Mesh3D({
|
|
1164
1436
|
node,
|
|
1165
1437
|
projector,
|
|
@@ -1172,6 +1444,10 @@ function Mesh3D({
|
|
|
1172
1444
|
const validPos = isValidScenePos(node.position);
|
|
1173
1445
|
const baseWorld = validPos ? projector.toWorld(node.position) : [0, 0, 0];
|
|
1174
1446
|
const geo = React3.useMemo(() => meshGeometry(node, projector.cellSize), [node, projector.cellSize]);
|
|
1447
|
+
React3.useEffect(() => {
|
|
1448
|
+
const g = geo?.geometry;
|
|
1449
|
+
return () => g?.dispose();
|
|
1450
|
+
}, [geo]);
|
|
1175
1451
|
fiber.useFrame(({ clock }) => {
|
|
1176
1452
|
if (!animated || !groupRef.current) return;
|
|
1177
1453
|
const state = applyMeshAnimation(node, clock.elapsedTime * 1e3);
|
|
@@ -1184,8 +1460,13 @@ function Mesh3D({
|
|
|
1184
1460
|
);
|
|
1185
1461
|
groupRef.current.scale.setScalar(state.scale);
|
|
1186
1462
|
if (meshRef.current) {
|
|
1463
|
+
const shapeRot = geo?.baseRotation ?? [0, 0, 0];
|
|
1187
1464
|
const base = node.rotation ?? [0, 0, 0];
|
|
1188
|
-
meshRef.current.rotation.set(
|
|
1465
|
+
meshRef.current.rotation.set(
|
|
1466
|
+
shapeRot[0] + base[0] + state.rotate[0],
|
|
1467
|
+
shapeRot[1] + base[1] + state.rotate[1],
|
|
1468
|
+
shapeRot[2] + base[2] + state.rotate[2]
|
|
1469
|
+
);
|
|
1189
1470
|
}
|
|
1190
1471
|
const mat = materialRef.current;
|
|
1191
1472
|
if (mat) {
|
|
@@ -1202,13 +1483,28 @@ function Mesh3D({
|
|
|
1202
1483
|
if (!validPos || !geo) return null;
|
|
1203
1484
|
const lift = (node.pivot ?? "bottom") === "bottom" ? geo.lift : 0;
|
|
1204
1485
|
const opacity = (node.opacity ?? 1) * (node.material?.opacity ?? 1) * groupOpacity;
|
|
1205
|
-
|
|
1486
|
+
if (node.skin && geo.geometry) {
|
|
1487
|
+
return /* @__PURE__ */ jsxRuntime.jsx("group", { position: baseWorld, children: /* @__PURE__ */ jsxRuntime.jsx(SkinnedPolyhedron3D, { node, skin: node.skin, geometry: geo.geometry, cellSize: projector.cellSize, opacity }) });
|
|
1488
|
+
}
|
|
1489
|
+
const nodeRotation = node.rotation ?? [0, 0, 0];
|
|
1490
|
+
const shapeRotation = geo.baseRotation ?? [0, 0, 0];
|
|
1491
|
+
const rotation = [
|
|
1492
|
+
shapeRotation[0] + nodeRotation[0],
|
|
1493
|
+
shapeRotation[1] + nodeRotation[1],
|
|
1494
|
+
shapeRotation[2] + nodeRotation[2]
|
|
1495
|
+
];
|
|
1206
1496
|
const outlineScale = geo.size > 0 ? 1 + (node.outline?.width ?? 0.05) * projector.cellSize / geo.size : 1;
|
|
1497
|
+
if (node.outline && geo.geometry && !warnedPolyhedronOutline) {
|
|
1498
|
+
warnedPolyhedronOutline = true;
|
|
1499
|
+
console.warn('[draw-mesh] outline is not yet supported on shape "polyhedron" \u2014 skipped');
|
|
1500
|
+
}
|
|
1501
|
+
const geometryProp = geo.geometry ? { geometry: geo.geometry } : {};
|
|
1207
1502
|
return /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, position: baseWorld, children: [
|
|
1208
1503
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1209
1504
|
"mesh",
|
|
1210
1505
|
{
|
|
1211
1506
|
ref: meshRef,
|
|
1507
|
+
...geometryProp,
|
|
1212
1508
|
position: [0, lift, 0],
|
|
1213
1509
|
rotation,
|
|
1214
1510
|
castShadow: node.castShadow ?? true,
|
|
@@ -1219,13 +1515,13 @@ function Mesh3D({
|
|
|
1219
1515
|
]
|
|
1220
1516
|
}
|
|
1221
1517
|
),
|
|
1222
|
-
node.outline && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, lift, 0], rotation, scale: outlineScale, children: [
|
|
1518
|
+
node.outline && !geo.geometry && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, lift, 0], rotation, scale: outlineScale, children: [
|
|
1223
1519
|
geo.element,
|
|
1224
1520
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1225
1521
|
"meshBasicMaterial",
|
|
1226
1522
|
{
|
|
1227
1523
|
color: node.outline.color ?? "#101014",
|
|
1228
|
-
side:
|
|
1524
|
+
side: THREE11__namespace.BackSide,
|
|
1229
1525
|
transparent: opacity < 1,
|
|
1230
1526
|
opacity
|
|
1231
1527
|
}
|
|
@@ -1240,7 +1536,7 @@ function Drawable3D({ node, projector, groupOpacity = 1 }) {
|
|
|
1240
1536
|
case "draw-shape":
|
|
1241
1537
|
return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector, groupOpacity });
|
|
1242
1538
|
case "draw-text":
|
|
1243
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector });
|
|
1539
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector, groupOpacity });
|
|
1244
1540
|
case "draw-mesh":
|
|
1245
1541
|
return /* @__PURE__ */ jsxRuntime.jsx(Mesh3D, { node, projector, groupOpacity });
|
|
1246
1542
|
case "draw-sprite-layer":
|
|
@@ -1248,18 +1544,57 @@ function Drawable3D({ node, projector, groupOpacity = 1 }) {
|
|
|
1248
1544
|
case "draw-shape-layer":
|
|
1249
1545
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
|
|
1250
1546
|
case "draw-text-layer":
|
|
1251
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector }, i)) });
|
|
1547
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector, groupOpacity }, i)) });
|
|
1252
1548
|
case "draw-group": {
|
|
1253
1549
|
if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
|
|
1254
1550
|
if (node.clip) warnUnsupported3d("draw-group:clip");
|
|
1255
|
-
|
|
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)) });
|
|
1551
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Group3D, { node, projector, groupOpacity });
|
|
1260
1552
|
}
|
|
1261
1553
|
}
|
|
1262
1554
|
}
|
|
1555
|
+
function Group3D({
|
|
1556
|
+
node,
|
|
1557
|
+
projector,
|
|
1558
|
+
groupOpacity
|
|
1559
|
+
}) {
|
|
1560
|
+
const ref = React3.useRef(null);
|
|
1561
|
+
const animated = isAnimatedGroup(node);
|
|
1562
|
+
const world = projector.toWorld(node.position);
|
|
1563
|
+
const inner = create3DProjector({ cellSize: projector.cellSize });
|
|
1564
|
+
const opacity = (node.opacity ?? 1) * groupOpacity;
|
|
1565
|
+
const s = node.scale ?? 1;
|
|
1566
|
+
const baseRotation = node.rotation ?? [0, -(node.rotate ?? 0), 0];
|
|
1567
|
+
const parentStore = React3.useContext(BoneRegistryContext);
|
|
1568
|
+
const scopedStore = React3.useMemo(() => node.skeleton ? new BoneStore() : null, [node.skeleton]);
|
|
1569
|
+
const boneStore = scopedStore ?? parentStore;
|
|
1570
|
+
const boneObject = React3.useMemo(() => node.bone ? new THREE11__namespace.Bone() : null, [node.bone]);
|
|
1571
|
+
React3.useEffect(() => {
|
|
1572
|
+
if (!node.bone || !boneStore || !boneObject) return;
|
|
1573
|
+
return boneStore.register(node.bone, boneObject);
|
|
1574
|
+
}, [node.bone, boneStore, boneObject]);
|
|
1575
|
+
fiber.useFrame(({ clock }) => {
|
|
1576
|
+
if (!animated || !ref.current) return;
|
|
1577
|
+
const state = applyMeshAnimation(node, clock.elapsedTime * 1e3);
|
|
1578
|
+
if (!state) return;
|
|
1579
|
+
const cell = projector.cellSize;
|
|
1580
|
+
ref.current.position.set(
|
|
1581
|
+
world[0] + state.offset[0] * cell,
|
|
1582
|
+
world[1] + state.offset[2] * cell,
|
|
1583
|
+
world[2] + state.offset[1] * cell
|
|
1584
|
+
);
|
|
1585
|
+
ref.current.rotation.set(
|
|
1586
|
+
baseRotation[0] + state.rotate[0],
|
|
1587
|
+
baseRotation[1] + state.rotate[1],
|
|
1588
|
+
baseRotation[2] + state.rotate[2]
|
|
1589
|
+
);
|
|
1590
|
+
ref.current.scale.setScalar(s * state.scale);
|
|
1591
|
+
});
|
|
1592
|
+
const children = /* @__PURE__ */ jsxRuntime.jsxs("group", { ref, position: world, rotation: baseRotation, scale: [s, s, s], children: [
|
|
1593
|
+
boneObject && /* @__PURE__ */ jsxRuntime.jsx("primitive", { object: boneObject }),
|
|
1594
|
+
node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node: item, projector: inner, groupOpacity: opacity }, i))
|
|
1595
|
+
] });
|
|
1596
|
+
return scopedStore ? /* @__PURE__ */ jsxRuntime.jsx(BoneRegistryContext.Provider, { value: scopedStore, children }) : children;
|
|
1597
|
+
}
|
|
1263
1598
|
|
|
1264
1599
|
// lib/drawable/three/game3dTheme.ts
|
|
1265
1600
|
var GRID_COLORS_3D = {
|
|
@@ -1272,6 +1607,20 @@ function cn(...inputs) {
|
|
|
1272
1607
|
}
|
|
1273
1608
|
var DEFAULT_GRID_CONFIG = {
|
|
1274
1609
|
cellSize: 1};
|
|
1610
|
+
function RoomEnvironment3D() {
|
|
1611
|
+
const { gl, scene } = fiber.useThree(({ gl: gl2, scene: scene2 }) => ({ gl: gl2, scene: scene2 }));
|
|
1612
|
+
React3.useEffect(() => {
|
|
1613
|
+
const pmremGenerator = new THREE11__namespace.PMREMGenerator(gl);
|
|
1614
|
+
const envTexture = pmremGenerator.fromScene(new RoomEnvironment_js.RoomEnvironment(), 0.04).texture;
|
|
1615
|
+
scene.environment = envTexture;
|
|
1616
|
+
return () => {
|
|
1617
|
+
scene.environment = null;
|
|
1618
|
+
envTexture.dispose();
|
|
1619
|
+
pmremGenerator.dispose();
|
|
1620
|
+
};
|
|
1621
|
+
}, [gl, scene]);
|
|
1622
|
+
return null;
|
|
1623
|
+
}
|
|
1275
1624
|
var Canvas3DHost = React3.forwardRef(
|
|
1276
1625
|
({
|
|
1277
1626
|
cameraMode = "isometric",
|
|
@@ -1297,6 +1646,8 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1297
1646
|
keyUpMap,
|
|
1298
1647
|
pixelsPerUnit,
|
|
1299
1648
|
fov,
|
|
1649
|
+
lighting,
|
|
1650
|
+
post,
|
|
1300
1651
|
children,
|
|
1301
1652
|
drawables
|
|
1302
1653
|
}, ref) => {
|
|
@@ -1305,6 +1656,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1305
1656
|
const [internalError, setInternalError] = React3.useState(null);
|
|
1306
1657
|
const eventBus = useEventBus();
|
|
1307
1658
|
const keysRef = React3.useRef(/* @__PURE__ */ new Set());
|
|
1659
|
+
const allDrawables = React3.useMemo(() => drawables ?? [], [drawables]);
|
|
1308
1660
|
React3.useEffect(() => {
|
|
1309
1661
|
if (!keyMap && !keyUpMap) return;
|
|
1310
1662
|
const down = (e) => {
|
|
@@ -1338,7 +1690,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1338
1690
|
unitAnimationEvent,
|
|
1339
1691
|
cameraChangeEvent
|
|
1340
1692
|
});
|
|
1341
|
-
const drawnItems = React3.useMemo(() => collectDrawnItems(
|
|
1693
|
+
const drawnItems = React3.useMemo(() => collectDrawnItems(allDrawables), [allDrawables]);
|
|
1342
1694
|
const scenePositions = React3.useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
|
|
1343
1695
|
const hitIndex = React3.useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
|
|
1344
1696
|
const gridBounds = React3.useMemo(() => {
|
|
@@ -1374,6 +1726,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1374
1726
|
}),
|
|
1375
1727
|
[gridBounds, cellSize]
|
|
1376
1728
|
);
|
|
1729
|
+
const boneStore = React3.useMemo(() => new BoneStore(), []);
|
|
1377
1730
|
const drawableProjector = React3.useMemo(
|
|
1378
1731
|
() => create3DProjector({
|
|
1379
1732
|
cellSize: gridConfig.cellSize,
|
|
@@ -1386,7 +1739,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1386
1739
|
getCameraPosition: () => {
|
|
1387
1740
|
if (controlsRef.current) {
|
|
1388
1741
|
const pos = controlsRef.current.object.position;
|
|
1389
|
-
return new
|
|
1742
|
+
return new THREE11__namespace.Vector3(pos.x, pos.y, pos.z);
|
|
1390
1743
|
}
|
|
1391
1744
|
return null;
|
|
1392
1745
|
},
|
|
@@ -1431,6 +1784,8 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1431
1784
|
return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
|
|
1432
1785
|
case "top-down":
|
|
1433
1786
|
return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
|
|
1787
|
+
case "front":
|
|
1788
|
+
return { position: [cx, d * 0.32, cz + d * 1.15], fov: fovDeg };
|
|
1434
1789
|
case "follow":
|
|
1435
1790
|
return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
|
|
1436
1791
|
case "perspective":
|
|
@@ -1497,6 +1852,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1497
1852
|
fiber.Canvas,
|
|
1498
1853
|
{
|
|
1499
1854
|
shadows,
|
|
1855
|
+
flat: lighting?.toneMapping === "none",
|
|
1500
1856
|
camera: {
|
|
1501
1857
|
position: cameraConfig.position,
|
|
1502
1858
|
fov: cameraConfig.fov,
|
|
@@ -1520,9 +1876,19 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1520
1876
|
shadowNormalBias: 0.04,
|
|
1521
1877
|
shadowCameraSize: 5,
|
|
1522
1878
|
shadowCameraNear: 0.5,
|
|
1523
|
-
shadowCameraFar: 500
|
|
1879
|
+
shadowCameraFar: 500,
|
|
1880
|
+
ambientIntensity: lighting?.ambient?.intensity,
|
|
1881
|
+
ambientColor: lighting?.ambient?.color,
|
|
1882
|
+
directionalIntensity: lighting?.directional?.intensity,
|
|
1883
|
+
directionalColor: lighting?.directional?.color,
|
|
1884
|
+
directionalPosition: lighting?.directional?.position,
|
|
1885
|
+
hemisphereIntensity: lighting?.hemisphere?.intensity,
|
|
1886
|
+
hemisphereColor: lighting?.hemisphere?.color,
|
|
1887
|
+
hemisphereGroundColor: lighting?.hemisphere?.groundColor,
|
|
1888
|
+
points: lighting?.points
|
|
1524
1889
|
}
|
|
1525
1890
|
),
|
|
1891
|
+
lighting?.environment === "room" && /* @__PURE__ */ jsxRuntime.jsx(RoomEnvironment3D, {}),
|
|
1526
1892
|
showGrid && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1527
1893
|
drei.Grid,
|
|
1528
1894
|
{
|
|
@@ -1545,7 +1911,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1545
1911
|
fadeStrength: 1
|
|
1546
1912
|
}
|
|
1547
1913
|
),
|
|
1548
|
-
|
|
1914
|
+
allDrawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(BoneRegistryContext.Provider, { value: boneStore, children: /* @__PURE__ */ jsxRuntime.jsx("group", { children: allDrawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }) }),
|
|
1549
1915
|
(tileClickEvent || unitClickEvent) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1550
1916
|
"mesh",
|
|
1551
1917
|
{
|
|
@@ -1570,7 +1936,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1570
1936
|
]
|
|
1571
1937
|
}
|
|
1572
1938
|
),
|
|
1573
|
-
|
|
1939
|
+
post && (post.bloom || post.vignette) ? /* @__PURE__ */ jsxRuntime.jsx(Effects3D, { post }) : null,
|
|
1574
1940
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1575
1941
|
drei.OrbitControls,
|
|
1576
1942
|
{
|
|
@@ -1581,7 +1947,7 @@ var Canvas3DHost = React3.forwardRef(
|
|
|
1581
1947
|
dampingFactor: 0.05,
|
|
1582
1948
|
enableZoom: true,
|
|
1583
1949
|
enablePan: true,
|
|
1584
|
-
touches: { ONE:
|
|
1950
|
+
touches: { ONE: THREE11__namespace.TOUCH.ROTATE, TWO: THREE11__namespace.TOUCH.DOLLY_PAN },
|
|
1585
1951
|
minDistance: 2,
|
|
1586
1952
|
maxDistance: 100,
|
|
1587
1953
|
maxPolarAngle: Math.PI / 2 - 0.1
|
|
@@ -1604,15 +1970,15 @@ function Scene3D({ background = "#1a1a2e", fog, children }) {
|
|
|
1604
1970
|
if (initializedRef.current) return;
|
|
1605
1971
|
initializedRef.current = true;
|
|
1606
1972
|
if (background.startsWith("#") || background.startsWith("rgb")) {
|
|
1607
|
-
scene.background = new
|
|
1973
|
+
scene.background = new THREE11__namespace.Color(background);
|
|
1608
1974
|
} else {
|
|
1609
|
-
const loader = new
|
|
1975
|
+
const loader = new THREE11__namespace.TextureLoader();
|
|
1610
1976
|
loader.load(background, (texture) => {
|
|
1611
1977
|
scene.background = texture;
|
|
1612
1978
|
});
|
|
1613
1979
|
}
|
|
1614
1980
|
if (fog) {
|
|
1615
|
-
scene.fog = new
|
|
1981
|
+
scene.fog = new THREE11__namespace.Fog(fog.color, fog.near, fog.far);
|
|
1616
1982
|
}
|
|
1617
1983
|
return () => {
|
|
1618
1984
|
scene.background = null;
|
|
@@ -1635,14 +2001,14 @@ var Camera3D = React3.forwardRef(
|
|
|
1635
2001
|
}, ref) => {
|
|
1636
2002
|
const { camera, set, viewport } = fiber.useThree();
|
|
1637
2003
|
const controlsRef = React3.useRef(null);
|
|
1638
|
-
const initialPosition = React3.useRef(new
|
|
1639
|
-
const initialTarget = React3.useRef(new
|
|
2004
|
+
const initialPosition = React3.useRef(new THREE11__namespace.Vector3(...position));
|
|
2005
|
+
const initialTarget = React3.useRef(new THREE11__namespace.Vector3(...target));
|
|
1640
2006
|
React3.useEffect(() => {
|
|
1641
2007
|
let newCamera;
|
|
1642
2008
|
if (mode === "isometric") {
|
|
1643
2009
|
const aspect = viewport.aspect;
|
|
1644
2010
|
const size = 10 / zoom;
|
|
1645
|
-
newCamera = new
|
|
2011
|
+
newCamera = new THREE11__namespace.OrthographicCamera(
|
|
1646
2012
|
-size * aspect,
|
|
1647
2013
|
size * aspect,
|
|
1648
2014
|
size,
|
|
@@ -1651,7 +2017,7 @@ var Camera3D = React3.forwardRef(
|
|
|
1651
2017
|
1e3
|
|
1652
2018
|
);
|
|
1653
2019
|
} else {
|
|
1654
|
-
newCamera = new
|
|
2020
|
+
newCamera = new THREE11__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
|
|
1655
2021
|
}
|
|
1656
2022
|
newCamera.position.copy(initialPosition.current);
|
|
1657
2023
|
newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
|
|
@@ -1692,8 +2058,8 @@ var Camera3D = React3.forwardRef(
|
|
|
1692
2058
|
}
|
|
1693
2059
|
},
|
|
1694
2060
|
getViewBounds: () => {
|
|
1695
|
-
const min = new
|
|
1696
|
-
const max = new
|
|
2061
|
+
const min = new THREE11__namespace.Vector3(-10, -10, -10);
|
|
2062
|
+
const max = new THREE11__namespace.Vector3(10, 10, 10);
|
|
1697
2063
|
return { min, max };
|
|
1698
2064
|
}
|
|
1699
2065
|
}));
|
|
@@ -1735,7 +2101,7 @@ var AssetLoader = class {
|
|
|
1735
2101
|
__publicField(this, "textureCache");
|
|
1736
2102
|
__publicField(this, "loadingPromises");
|
|
1737
2103
|
this.objLoader = new OBJLoader_js.OBJLoader();
|
|
1738
|
-
this.textureLoader = new
|
|
2104
|
+
this.textureLoader = new THREE11__namespace.TextureLoader();
|
|
1739
2105
|
this.modelCache = /* @__PURE__ */ new Map();
|
|
1740
2106
|
this.textureCache = /* @__PURE__ */ new Map();
|
|
1741
2107
|
this.loadingPromises = /* @__PURE__ */ new Map();
|
|
@@ -1809,7 +2175,7 @@ var AssetLoader = class {
|
|
|
1809
2175
|
return this.loadingPromises.get(`texture:${url}`);
|
|
1810
2176
|
}
|
|
1811
2177
|
const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
|
|
1812
|
-
texture.colorSpace =
|
|
2178
|
+
texture.colorSpace = THREE11__namespace.SRGBColorSpace;
|
|
1813
2179
|
this.textureCache.set(url, texture);
|
|
1814
2180
|
this.loadingPromises.delete(`texture:${url}`);
|
|
1815
2181
|
return texture;
|
|
@@ -1883,7 +2249,7 @@ var AssetLoader = class {
|
|
|
1883
2249
|
});
|
|
1884
2250
|
this.modelCache.forEach((model) => {
|
|
1885
2251
|
model.scene.traverse((child) => {
|
|
1886
|
-
if (child instanceof
|
|
2252
|
+
if (child instanceof THREE11__namespace.Mesh) {
|
|
1887
2253
|
child.geometry.dispose();
|
|
1888
2254
|
if (Array.isArray(child.material)) {
|
|
1889
2255
|
child.material.forEach((m) => m.dispose());
|
|
@@ -1920,7 +2286,7 @@ var DEFAULT_OPTIONS = {
|
|
|
1920
2286
|
gridSize: 20,
|
|
1921
2287
|
assetLoader: new AssetLoader()
|
|
1922
2288
|
};
|
|
1923
|
-
function
|
|
2289
|
+
function useThree5(options = {}) {
|
|
1924
2290
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
1925
2291
|
const containerRef = React3.useRef(null);
|
|
1926
2292
|
const canvasRef = React3.useRef(null);
|
|
@@ -1933,21 +2299,21 @@ function useThree4(options = {}) {
|
|
|
1933
2299
|
const [isReady, setIsReady] = React3.useState(false);
|
|
1934
2300
|
const [dimensions, setDimensions] = React3.useState({ width: 0, height: 0 });
|
|
1935
2301
|
const initialCameraPosition = React3.useMemo(
|
|
1936
|
-
() => new
|
|
2302
|
+
() => new THREE11__namespace.Vector3(...opts.cameraPosition),
|
|
1937
2303
|
[]
|
|
1938
2304
|
);
|
|
1939
2305
|
React3.useEffect(() => {
|
|
1940
2306
|
if (!containerRef.current) return;
|
|
1941
2307
|
const container = containerRef.current;
|
|
1942
2308
|
const { clientWidth, clientHeight } = container;
|
|
1943
|
-
const scene = new
|
|
1944
|
-
scene.background = new
|
|
2309
|
+
const scene = new THREE11__namespace.Scene();
|
|
2310
|
+
scene.background = new THREE11__namespace.Color(opts.backgroundColor);
|
|
1945
2311
|
sceneRef.current = scene;
|
|
1946
2312
|
let camera;
|
|
1947
2313
|
const aspect = clientWidth / clientHeight;
|
|
1948
2314
|
if (opts.cameraMode === "isometric") {
|
|
1949
2315
|
const size = 10;
|
|
1950
|
-
camera = new
|
|
2316
|
+
camera = new THREE11__namespace.OrthographicCamera(
|
|
1951
2317
|
-size * aspect,
|
|
1952
2318
|
size * aspect,
|
|
1953
2319
|
size,
|
|
@@ -1956,11 +2322,11 @@ function useThree4(options = {}) {
|
|
|
1956
2322
|
1e3
|
|
1957
2323
|
);
|
|
1958
2324
|
} else {
|
|
1959
|
-
camera = new
|
|
2325
|
+
camera = new THREE11__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
|
|
1960
2326
|
}
|
|
1961
2327
|
camera.position.copy(initialCameraPosition);
|
|
1962
2328
|
cameraRef.current = camera;
|
|
1963
|
-
const renderer = new
|
|
2329
|
+
const renderer = new THREE11__namespace.WebGLRenderer({
|
|
1964
2330
|
antialias: true,
|
|
1965
2331
|
alpha: true,
|
|
1966
2332
|
canvas: canvasRef.current || void 0
|
|
@@ -1968,7 +2334,7 @@ function useThree4(options = {}) {
|
|
|
1968
2334
|
renderer.setSize(clientWidth, clientHeight);
|
|
1969
2335
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
1970
2336
|
renderer.shadowMap.enabled = opts.shadows;
|
|
1971
|
-
renderer.shadowMap.type =
|
|
2337
|
+
renderer.shadowMap.type = THREE11__namespace.PCFSoftShadowMap;
|
|
1972
2338
|
rendererRef.current = renderer;
|
|
1973
2339
|
const controls = new OrbitControls_js.OrbitControls(camera, renderer.domElement);
|
|
1974
2340
|
controls.enableDamping = true;
|
|
@@ -1977,16 +2343,16 @@ function useThree4(options = {}) {
|
|
|
1977
2343
|
controls.maxDistance = 100;
|
|
1978
2344
|
controls.maxPolarAngle = Math.PI / 2 - 0.1;
|
|
1979
2345
|
controlsRef.current = controls;
|
|
1980
|
-
const ambientLight = new
|
|
2346
|
+
const ambientLight = new THREE11__namespace.AmbientLight(16777215, 0.6);
|
|
1981
2347
|
scene.add(ambientLight);
|
|
1982
|
-
const directionalLight = new
|
|
2348
|
+
const directionalLight = new THREE11__namespace.DirectionalLight(16777215, 0.8);
|
|
1983
2349
|
directionalLight.position.set(10, 20, 10);
|
|
1984
2350
|
directionalLight.castShadow = opts.shadows;
|
|
1985
2351
|
directionalLight.shadow.mapSize.width = 2048;
|
|
1986
2352
|
directionalLight.shadow.mapSize.height = 2048;
|
|
1987
2353
|
scene.add(directionalLight);
|
|
1988
2354
|
if (opts.showGrid) {
|
|
1989
|
-
const gridHelper = new
|
|
2355
|
+
const gridHelper = new THREE11__namespace.GridHelper(
|
|
1990
2356
|
opts.gridSize,
|
|
1991
2357
|
opts.gridSize,
|
|
1992
2358
|
4473924,
|
|
@@ -2004,10 +2370,10 @@ function useThree4(options = {}) {
|
|
|
2004
2370
|
const handleResize = () => {
|
|
2005
2371
|
const { clientWidth: width, clientHeight: height } = container;
|
|
2006
2372
|
setDimensions({ width, height });
|
|
2007
|
-
if (camera instanceof
|
|
2373
|
+
if (camera instanceof THREE11__namespace.PerspectiveCamera) {
|
|
2008
2374
|
camera.aspect = width / height;
|
|
2009
2375
|
camera.updateProjectionMatrix();
|
|
2010
|
-
} else if (camera instanceof
|
|
2376
|
+
} else if (camera instanceof THREE11__namespace.OrthographicCamera) {
|
|
2011
2377
|
const aspect2 = width / height;
|
|
2012
2378
|
const size = 10;
|
|
2013
2379
|
camera.left = -size * aspect2;
|
|
@@ -2038,7 +2404,7 @@ function useThree4(options = {}) {
|
|
|
2038
2404
|
let newCamera;
|
|
2039
2405
|
if (opts.cameraMode === "isometric") {
|
|
2040
2406
|
const size = 10;
|
|
2041
|
-
newCamera = new
|
|
2407
|
+
newCamera = new THREE11__namespace.OrthographicCamera(
|
|
2042
2408
|
-size * aspect,
|
|
2043
2409
|
size * aspect,
|
|
2044
2410
|
size,
|
|
@@ -2047,7 +2413,7 @@ function useThree4(options = {}) {
|
|
|
2047
2413
|
1e3
|
|
2048
2414
|
);
|
|
2049
2415
|
} else {
|
|
2050
|
-
newCamera = new
|
|
2416
|
+
newCamera = new THREE11__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
|
|
2051
2417
|
}
|
|
2052
2418
|
newCamera.position.copy(currentPos);
|
|
2053
2419
|
cameraRef.current = newCamera;
|
|
@@ -2377,8 +2743,8 @@ function useSceneGraph() {
|
|
|
2377
2743
|
}
|
|
2378
2744
|
function useRaycaster(options) {
|
|
2379
2745
|
const { camera, canvas, cellSize = 1, offsetX = 0, offsetZ = 0 } = options;
|
|
2380
|
-
const raycaster = React3.useRef(new
|
|
2381
|
-
const mouse = React3.useRef(new
|
|
2746
|
+
const raycaster = React3.useRef(new THREE11__namespace.Raycaster());
|
|
2747
|
+
const mouse = React3.useRef(new THREE11__namespace.Vector2());
|
|
2382
2748
|
const clientToNDC = React3.useCallback(
|
|
2383
2749
|
(clientX, clientY) => {
|
|
2384
2750
|
if (!canvas) {
|
|
@@ -2448,8 +2814,8 @@ function useRaycaster(options) {
|
|
|
2448
2814
|
const ndc = clientToNDC(clientX, clientY);
|
|
2449
2815
|
mouse.current.set(ndc.x, ndc.y);
|
|
2450
2816
|
raycaster.current.setFromCamera(mouse.current, camera);
|
|
2451
|
-
const plane = new
|
|
2452
|
-
const target = new
|
|
2817
|
+
const plane = new THREE11__namespace.Plane(new THREE11__namespace.Vector3(0, 1, 0), 0);
|
|
2818
|
+
const target = new THREE11__namespace.Vector3();
|
|
2453
2819
|
const intersection = raycaster.current.ray.intersectPlane(plane, target);
|
|
2454
2820
|
if (intersection) {
|
|
2455
2821
|
const gridX = Math.round((target.x - offsetX) / cellSize);
|
|
@@ -2487,7 +2853,7 @@ function useRaycaster(options) {
|
|
|
2487
2853
|
return {
|
|
2488
2854
|
gridX: gridCoords.x,
|
|
2489
2855
|
gridZ: gridCoords.z,
|
|
2490
|
-
worldPosition: new
|
|
2856
|
+
worldPosition: new THREE11__namespace.Vector3(
|
|
2491
2857
|
gridCoords.x * cellSize + offsetX,
|
|
2492
2858
|
0,
|
|
2493
2859
|
gridCoords.z * cellSize + offsetZ
|
|
@@ -2517,7 +2883,7 @@ var DEFAULT_CONFIG = {
|
|
|
2517
2883
|
};
|
|
2518
2884
|
function gridToWorld(gridX, gridZ, config = DEFAULT_CONFIG) {
|
|
2519
2885
|
const opts = { ...DEFAULT_CONFIG, ...config };
|
|
2520
|
-
return new
|
|
2886
|
+
return new THREE11__namespace.Vector3(
|
|
2521
2887
|
gridX * opts.cellSize + opts.offsetX,
|
|
2522
2888
|
opts.elevation,
|
|
2523
2889
|
gridZ * opts.cellSize + opts.offsetZ
|
|
@@ -2531,17 +2897,17 @@ function worldToGrid(worldX, worldZ, config = DEFAULT_CONFIG) {
|
|
|
2531
2897
|
};
|
|
2532
2898
|
}
|
|
2533
2899
|
function raycastToPlane(camera, mouseX, mouseY, planeY = 0) {
|
|
2534
|
-
const raycaster = new
|
|
2535
|
-
const mouse = new
|
|
2900
|
+
const raycaster = new THREE11__namespace.Raycaster();
|
|
2901
|
+
const mouse = new THREE11__namespace.Vector2(mouseX, mouseY);
|
|
2536
2902
|
raycaster.setFromCamera(mouse, camera);
|
|
2537
|
-
const plane = new
|
|
2538
|
-
const target = new
|
|
2903
|
+
const plane = new THREE11__namespace.Plane(new THREE11__namespace.Vector3(0, 1, 0), -planeY);
|
|
2904
|
+
const target = new THREE11__namespace.Vector3();
|
|
2539
2905
|
const intersection = raycaster.ray.intersectPlane(plane, target);
|
|
2540
2906
|
return intersection ? target : null;
|
|
2541
2907
|
}
|
|
2542
2908
|
function raycastToObjects(camera, mouseX, mouseY, objects) {
|
|
2543
|
-
const raycaster = new
|
|
2544
|
-
const mouse = new
|
|
2909
|
+
const raycaster = new THREE11__namespace.Raycaster();
|
|
2910
|
+
const mouse = new THREE11__namespace.Vector2(mouseX, mouseY);
|
|
2545
2911
|
raycaster.setFromCamera(mouse, camera);
|
|
2546
2912
|
const intersects = raycaster.intersectObjects(objects, true);
|
|
2547
2913
|
return intersects.length > 0 ? intersects[0] : null;
|
|
@@ -2593,14 +2959,14 @@ function getCellsInRadius(centerX, centerZ, radius) {
|
|
|
2593
2959
|
return cells;
|
|
2594
2960
|
}
|
|
2595
2961
|
function createGridHighlight(color = 16776960, opacity = 0.3) {
|
|
2596
|
-
const geometry = new
|
|
2597
|
-
const material = new
|
|
2962
|
+
const geometry = new THREE11__namespace.PlaneGeometry(0.95, 0.95);
|
|
2963
|
+
const material = new THREE11__namespace.MeshBasicMaterial({
|
|
2598
2964
|
color,
|
|
2599
2965
|
transparent: true,
|
|
2600
2966
|
opacity,
|
|
2601
|
-
side:
|
|
2967
|
+
side: THREE11__namespace.DoubleSide
|
|
2602
2968
|
});
|
|
2603
|
-
const mesh = new
|
|
2969
|
+
const mesh = new THREE11__namespace.Mesh(geometry, material);
|
|
2604
2970
|
mesh.rotation.x = -Math.PI / 2;
|
|
2605
2971
|
mesh.position.y = 0.01;
|
|
2606
2972
|
return mesh;
|
|
@@ -2613,31 +2979,31 @@ function normalizeMouseCoordinates(clientX, clientY, element) {
|
|
|
2613
2979
|
};
|
|
2614
2980
|
}
|
|
2615
2981
|
function isInFrustum(position, camera, padding = 0) {
|
|
2616
|
-
const frustum = new
|
|
2617
|
-
const projScreenMatrix = new
|
|
2982
|
+
const frustum = new THREE11__namespace.Frustum();
|
|
2983
|
+
const projScreenMatrix = new THREE11__namespace.Matrix4();
|
|
2618
2984
|
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
2619
2985
|
frustum.setFromProjectionMatrix(projScreenMatrix);
|
|
2620
|
-
const sphere = new
|
|
2986
|
+
const sphere = new THREE11__namespace.Sphere(position, padding);
|
|
2621
2987
|
return frustum.intersectsSphere(sphere);
|
|
2622
2988
|
}
|
|
2623
2989
|
function filterByFrustum(positions, camera, padding = 0) {
|
|
2624
|
-
const frustum = new
|
|
2625
|
-
const projScreenMatrix = new
|
|
2990
|
+
const frustum = new THREE11__namespace.Frustum();
|
|
2991
|
+
const projScreenMatrix = new THREE11__namespace.Matrix4();
|
|
2626
2992
|
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
2627
2993
|
frustum.setFromProjectionMatrix(projScreenMatrix);
|
|
2628
2994
|
return positions.filter((position) => {
|
|
2629
|
-
const sphere = new
|
|
2995
|
+
const sphere = new THREE11__namespace.Sphere(position, padding);
|
|
2630
2996
|
return frustum.intersectsSphere(sphere);
|
|
2631
2997
|
});
|
|
2632
2998
|
}
|
|
2633
2999
|
function getVisibleIndices(positions, camera, padding = 0) {
|
|
2634
|
-
const frustum = new
|
|
2635
|
-
const projScreenMatrix = new
|
|
3000
|
+
const frustum = new THREE11__namespace.Frustum();
|
|
3001
|
+
const projScreenMatrix = new THREE11__namespace.Matrix4();
|
|
2636
3002
|
const visible = /* @__PURE__ */ new Set();
|
|
2637
3003
|
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
|
2638
3004
|
frustum.setFromProjectionMatrix(projScreenMatrix);
|
|
2639
3005
|
positions.forEach((position, index) => {
|
|
2640
|
-
const sphere = new
|
|
3006
|
+
const sphere = new THREE11__namespace.Sphere(position, padding);
|
|
2641
3007
|
if (frustum.intersectsSphere(sphere)) {
|
|
2642
3008
|
visible.add(index);
|
|
2643
3009
|
}
|
|
@@ -2661,7 +3027,7 @@ function updateInstanceLOD(instancedMesh, positions, camera, lodDistances) {
|
|
|
2661
3027
|
return lodIndices;
|
|
2662
3028
|
}
|
|
2663
3029
|
function cullInstancedMesh(instancedMesh, positions, visibleIndices) {
|
|
2664
|
-
const dummy = new
|
|
3030
|
+
const dummy = new THREE11__namespace.Object3D();
|
|
2665
3031
|
let visibleCount = 0;
|
|
2666
3032
|
positions.forEach((position, index) => {
|
|
2667
3033
|
if (visibleIndices.has(index)) {
|
|
@@ -3828,25 +4194,25 @@ function orbitRingPositions(count, radius, tilt) {
|
|
|
3828
4194
|
return positions;
|
|
3829
4195
|
}
|
|
3830
4196
|
function arcCurve3D(from, to, offset) {
|
|
3831
|
-
const start = new
|
|
3832
|
-
const end = new
|
|
3833
|
-
const mid = new
|
|
3834
|
-
const dir = new
|
|
3835
|
-
const up = new
|
|
3836
|
-
const perp = new
|
|
4197
|
+
const start = new THREE11.Vector3(...from);
|
|
4198
|
+
const end = new THREE11.Vector3(...to);
|
|
4199
|
+
const mid = new THREE11.Vector3().addVectors(start, end).multiplyScalar(0.5);
|
|
4200
|
+
const dir = new THREE11.Vector3().subVectors(end, start).normalize();
|
|
4201
|
+
const up = new THREE11.Vector3(0, 1, 0);
|
|
4202
|
+
const perp = new THREE11.Vector3().crossVectors(dir, up).normalize();
|
|
3837
4203
|
if (perp.length() < 1e-3) {
|
|
3838
|
-
perp.crossVectors(dir, new
|
|
4204
|
+
perp.crossVectors(dir, new THREE11.Vector3(1, 0, 0)).normalize();
|
|
3839
4205
|
}
|
|
3840
4206
|
const control = mid.clone().add(perp.multiplyScalar(offset));
|
|
3841
4207
|
control.y += Math.abs(offset) * 0.3;
|
|
3842
|
-
return new
|
|
4208
|
+
return new THREE11.QuadraticBezierCurve3(start, control, end);
|
|
3843
4209
|
}
|
|
3844
4210
|
function selfLoopCurve3D(position, loopRadius) {
|
|
3845
|
-
const base = new
|
|
3846
|
-
const start = base.clone().add(new
|
|
3847
|
-
const end = base.clone().add(new
|
|
3848
|
-
const control = base.clone().add(new
|
|
3849
|
-
return new
|
|
4211
|
+
const base = new THREE11.Vector3(...position);
|
|
4212
|
+
const start = base.clone().add(new THREE11.Vector3(-loopRadius * 0.3, 0, 0));
|
|
4213
|
+
const end = base.clone().add(new THREE11.Vector3(loopRadius * 0.3, 0, 0));
|
|
4214
|
+
const control = base.clone().add(new THREE11.Vector3(0, loopRadius, 0));
|
|
4215
|
+
return new THREE11.QuadraticBezierCurve3(start, control, end);
|
|
3850
4216
|
}
|
|
3851
4217
|
function treeLayout3D(node, origin, horizontalSpacing, verticalSpacing = 2) {
|
|
3852
4218
|
const results = [];
|
|
@@ -4013,7 +4379,7 @@ var Avl3DOrbitalNode = ({
|
|
|
4013
4379
|
if (!groupRef.current) return;
|
|
4014
4380
|
groupRef.current.rotation.y += delta * (hovered ? 0.4 : 0.2);
|
|
4015
4381
|
groupRef.current.rotation.x += delta * 0.05;
|
|
4016
|
-
currentScale.current =
|
|
4382
|
+
currentScale.current = THREE11.MathUtils.damp(currentScale.current, targetScale, 6, delta);
|
|
4017
4383
|
});
|
|
4018
4384
|
const baseBrightness = 0.3 + Math.min(pageCount, 5) * 0.05;
|
|
4019
4385
|
const emissiveIntensity = hovered ? 0.8 : baseBrightness;
|
|
@@ -4655,7 +5021,7 @@ var Avl3DStateNode = ({
|
|
|
4655
5021
|
const targetScale = hovered ? 1.08 : 1;
|
|
4656
5022
|
const currentScale = React3.useRef(1);
|
|
4657
5023
|
fiber.useFrame((_, delta) => {
|
|
4658
|
-
currentScale.current =
|
|
5024
|
+
currentScale.current = THREE11.MathUtils.damp(currentScale.current, targetScale, 6, delta);
|
|
4659
5025
|
});
|
|
4660
5026
|
const scale = currentScale.current;
|
|
4661
5027
|
return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
|
|
@@ -4835,9 +5201,9 @@ var Avl3DTransitionArc = ({
|
|
|
4835
5201
|
const guardPt = curve.getPoint(0.3);
|
|
4836
5202
|
const arrowPt = curve.getPoint(0.9);
|
|
4837
5203
|
const arrowTangent = curve.getTangent(0.9);
|
|
4838
|
-
const upVec = new
|
|
4839
|
-
const tangentVec = new
|
|
4840
|
-
const quat = new
|
|
5204
|
+
const upVec = new THREE11.Vector3(0, 1, 0);
|
|
5205
|
+
const tangentVec = new THREE11.Vector3(arrowTangent.x, arrowTangent.y, arrowTangent.z).normalize();
|
|
5206
|
+
const quat = new THREE11.Quaternion().setFromUnitVectors(upVec, tangentVec);
|
|
4841
5207
|
const effectPositions2 = [];
|
|
4842
5208
|
for (let ei = 0; ei < 4; ei++) {
|
|
4843
5209
|
const t = 0.7 + ei * 0.05;
|
|
@@ -5061,14 +5427,14 @@ function operatorColor(label) {
|
|
|
5061
5427
|
return "#4A90D9";
|
|
5062
5428
|
}
|
|
5063
5429
|
function edgeGeometry(parent, child) {
|
|
5064
|
-
const p = new
|
|
5065
|
-
const c = new
|
|
5066
|
-
const mid = new
|
|
5067
|
-
const dir = new
|
|
5430
|
+
const p = new THREE11.Vector3(parent.x, parent.y, parent.z);
|
|
5431
|
+
const c = new THREE11.Vector3(child.x, child.y, child.z);
|
|
5432
|
+
const mid = new THREE11.Vector3().addVectors(p, c).multiplyScalar(0.5);
|
|
5433
|
+
const dir = new THREE11.Vector3().subVectors(c, p);
|
|
5068
5434
|
const length = dir.length();
|
|
5069
|
-
const yAxis = new
|
|
5435
|
+
const yAxis = new THREE11.Vector3(0, 1, 0);
|
|
5070
5436
|
const angle = yAxis.angleTo(dir.normalize());
|
|
5071
|
-
const axis = new
|
|
5437
|
+
const axis = new THREE11.Vector3().crossVectors(yAxis, dir).normalize();
|
|
5072
5438
|
if (axis.length() < 1e-3) {
|
|
5073
5439
|
return {
|
|
5074
5440
|
position: [mid.x, mid.y, mid.z],
|
|
@@ -5444,12 +5810,12 @@ function useAvl3DConfig() {
|
|
|
5444
5810
|
}
|
|
5445
5811
|
function CameraController({ targetPosition, targetLookAt, animated }) {
|
|
5446
5812
|
const { camera } = fiber.useThree();
|
|
5447
|
-
const targetPosVec = React3.useRef(new
|
|
5448
|
-
const targetLookVec = React3.useRef(new
|
|
5813
|
+
const targetPosVec = React3.useRef(new THREE11__namespace.Vector3(...targetPosition));
|
|
5814
|
+
const targetLookVec = React3.useRef(new THREE11__namespace.Vector3(...targetLookAt));
|
|
5449
5815
|
const isAnimating = React3.useRef(false);
|
|
5450
5816
|
React3.useEffect(() => {
|
|
5451
|
-
const newTarget = new
|
|
5452
|
-
const newLookAt = new
|
|
5817
|
+
const newTarget = new THREE11__namespace.Vector3(...targetPosition);
|
|
5818
|
+
const newLookAt = new THREE11__namespace.Vector3(...targetLookAt);
|
|
5453
5819
|
if (!newTarget.equals(targetPosVec.current) || !newLookAt.equals(targetLookVec.current)) {
|
|
5454
5820
|
targetPosVec.current.copy(newTarget);
|
|
5455
5821
|
targetLookVec.current.copy(newLookAt);
|
|
@@ -5464,9 +5830,9 @@ function CameraController({ targetPosition, targetLookAt, animated }) {
|
|
|
5464
5830
|
fiber.useFrame((_, delta) => {
|
|
5465
5831
|
if (!isAnimating.current) return;
|
|
5466
5832
|
const speed = 3;
|
|
5467
|
-
camera.position.x =
|
|
5468
|
-
camera.position.y =
|
|
5469
|
-
camera.position.z =
|
|
5833
|
+
camera.position.x = THREE11__namespace.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
|
|
5834
|
+
camera.position.y = THREE11__namespace.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
|
|
5835
|
+
camera.position.z = THREE11__namespace.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
|
|
5470
5836
|
camera.lookAt(targetLookVec.current);
|
|
5471
5837
|
const dist = camera.position.distanceTo(targetPosVec.current);
|
|
5472
5838
|
if (dist < 0.05) {
|
|
@@ -5481,7 +5847,7 @@ function SceneFade({ animating, children }) {
|
|
|
5481
5847
|
fiber.useFrame((_, delta) => {
|
|
5482
5848
|
if (!groupRef.current) return;
|
|
5483
5849
|
const target = animating ? 0 : 1;
|
|
5484
|
-
opacityRef.current =
|
|
5850
|
+
opacityRef.current = THREE11__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
|
|
5485
5851
|
groupRef.current.visible = opacityRef.current > 0.05;
|
|
5486
5852
|
const s = 0.9 + opacityRef.current * 0.1;
|
|
5487
5853
|
groupRef.current.scale.setScalar(s);
|
|
@@ -5781,5 +6147,5 @@ exports.useAvl3DConfig = useAvl3DConfig;
|
|
|
5781
6147
|
exports.useGameCanvas3DEvents = useGameCanvas3DEvents;
|
|
5782
6148
|
exports.useRaycaster = useRaycaster;
|
|
5783
6149
|
exports.useSceneGraph = useSceneGraph;
|
|
5784
|
-
exports.useThree =
|
|
6150
|
+
exports.useThree = useThree5;
|
|
5785
6151
|
exports.worldToGrid = worldToGrid;
|