@vizij/render 0.0.1 → 0.0.2
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/index.js +201 -4
- package/dist/index.mjs +201 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -428,6 +428,11 @@ function InnerRenderedGroup({
|
|
|
428
428
|
setReference(group.id, namespace, ref);
|
|
429
429
|
}
|
|
430
430
|
}, [group.id, namespace, ref, setReference, refIsNull]);
|
|
431
|
+
(0, import_react5.useEffect)(() => {
|
|
432
|
+
if (ref.current) {
|
|
433
|
+
ref.current.name = group.name;
|
|
434
|
+
}
|
|
435
|
+
}, [group.name]);
|
|
431
436
|
const handlePointerOver = (0, import_react5.useCallback)(
|
|
432
437
|
(event) => {
|
|
433
438
|
if (event.eventObject !== event.object) {
|
|
@@ -579,6 +584,9 @@ function InnerRenderedEllipse({
|
|
|
579
584
|
if ((0, import_utils4.instanceOfRawRGB)(color)) {
|
|
580
585
|
materialRef.current.color.setRGB(color.r, color.g, color.b);
|
|
581
586
|
materialRef.current.needsUpdate = true;
|
|
587
|
+
} else if ((0, import_utils4.instanceOfRawVector3)(color)) {
|
|
588
|
+
materialRef.current.color.setRGB(color.x, color.y, color.z);
|
|
589
|
+
materialRef.current.needsUpdate = true;
|
|
582
590
|
} else if ((0, import_utils4.instanceOfRawHSL)(color)) {
|
|
583
591
|
materialRef.current.color.setHSL(color.h, color.s, color.l);
|
|
584
592
|
materialRef.current.needsUpdate = true;
|
|
@@ -631,6 +639,13 @@ function InnerRenderedEllipse({
|
|
|
631
639
|
strokeColor.b
|
|
632
640
|
);
|
|
633
641
|
lineRef.current.material.needsUpdate = true;
|
|
642
|
+
} else if ((0, import_utils4.instanceOfRawVector3)(strokeColor)) {
|
|
643
|
+
lineRef.current.material.color.setRGB(
|
|
644
|
+
strokeColor.x,
|
|
645
|
+
strokeColor.y,
|
|
646
|
+
strokeColor.z
|
|
647
|
+
);
|
|
648
|
+
lineRef.current.material.needsUpdate = true;
|
|
634
649
|
} else if ((0, import_utils4.instanceOfRawHSL)(strokeColor)) {
|
|
635
650
|
lineRef.current.material.color.setHSL(
|
|
636
651
|
strokeColor.h,
|
|
@@ -854,6 +869,9 @@ function InnerRenderedRectangle({
|
|
|
854
869
|
if ((0, import_utils5.instanceOfRawRGB)(color)) {
|
|
855
870
|
materialRef.current.color.setRGB(color.r, color.g, color.b);
|
|
856
871
|
materialRef.current.needsUpdate = true;
|
|
872
|
+
} else if ((0, import_utils5.instanceOfRawVector3)(color)) {
|
|
873
|
+
materialRef.current.color.setRGB(color.x, color.y, color.z);
|
|
874
|
+
materialRef.current.needsUpdate = true;
|
|
857
875
|
} else if ((0, import_utils5.instanceOfRawHSL)(color)) {
|
|
858
876
|
materialRef.current.color.setHSL(color.h, color.s, color.l);
|
|
859
877
|
materialRef.current.needsUpdate = true;
|
|
@@ -906,6 +924,13 @@ function InnerRenderedRectangle({
|
|
|
906
924
|
strokeColor.b
|
|
907
925
|
);
|
|
908
926
|
lineRef.current.material.needsUpdate = true;
|
|
927
|
+
} else if ((0, import_utils5.instanceOfRawVector3)(strokeColor)) {
|
|
928
|
+
lineRef.current.material.color.setRGB(
|
|
929
|
+
strokeColor.x,
|
|
930
|
+
strokeColor.y,
|
|
931
|
+
strokeColor.z
|
|
932
|
+
);
|
|
933
|
+
lineRef.current.material.needsUpdate = true;
|
|
909
934
|
} else if ((0, import_utils5.instanceOfRawHSL)(strokeColor)) {
|
|
910
935
|
lineRef.current.material.color.setHSL(
|
|
911
936
|
strokeColor.h,
|
|
@@ -1049,7 +1074,17 @@ function InnerRenderedShape({
|
|
|
1049
1074
|
});
|
|
1050
1075
|
return av;
|
|
1051
1076
|
}, [shape.features, animatables]);
|
|
1052
|
-
const
|
|
1077
|
+
const materialName = (0, import_react8.useMemo)(
|
|
1078
|
+
() => deriveMaterialName(shape, animatableValues),
|
|
1079
|
+
[shape, animatableValues]
|
|
1080
|
+
);
|
|
1081
|
+
const geometry = (0, import_react8.useMemo)(() => {
|
|
1082
|
+
const cloned = shape.geometry.clone();
|
|
1083
|
+
if (shape.name) {
|
|
1084
|
+
cloned.name = shape.name;
|
|
1085
|
+
}
|
|
1086
|
+
return cloned;
|
|
1087
|
+
}, [shape.geometry, shape.name]);
|
|
1053
1088
|
const selectionData = (0, import_react8.useMemo)(
|
|
1054
1089
|
() => ({ id, namespace, type: "shape" }),
|
|
1055
1090
|
[id, namespace]
|
|
@@ -1139,9 +1174,14 @@ function InnerRenderedShape({
|
|
|
1139
1174
|
color.g,
|
|
1140
1175
|
color.b
|
|
1141
1176
|
);
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1177
|
+
material.current.needsUpdate = true;
|
|
1178
|
+
} else if ((material.current || void 0)?.color && (0, import_utils6.instanceOfRawVector3)(color)) {
|
|
1179
|
+
material.current.color.setRGB(
|
|
1180
|
+
color.x,
|
|
1181
|
+
color.y,
|
|
1182
|
+
color.z
|
|
1183
|
+
);
|
|
1184
|
+
material.current.needsUpdate = true;
|
|
1145
1185
|
} else if (material.current && (0, import_utils6.instanceOfRawHSL)(color)) {
|
|
1146
1186
|
material.current.color.setHSL(
|
|
1147
1187
|
color.h,
|
|
@@ -1164,6 +1204,21 @@ function InnerRenderedShape({
|
|
|
1164
1204
|
(0, import_react8.useEffect)(() => {
|
|
1165
1205
|
if (ref.current && refIsNull) setReference(shape.id, namespace, ref);
|
|
1166
1206
|
}, [shape.id, namespace, ref, setReference, refIsNull]);
|
|
1207
|
+
(0, import_react8.useEffect)(() => {
|
|
1208
|
+
if (ref.current) {
|
|
1209
|
+
ref.current.name = shape.name;
|
|
1210
|
+
}
|
|
1211
|
+
}, [shape.name]);
|
|
1212
|
+
(0, import_react8.useEffect)(() => {
|
|
1213
|
+
if (!material.current) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
if (materialName) {
|
|
1217
|
+
material.current.name = materialName;
|
|
1218
|
+
} else if (shape.name) {
|
|
1219
|
+
material.current.name = shape.name;
|
|
1220
|
+
}
|
|
1221
|
+
}, [materialName, shape.name]);
|
|
1167
1222
|
const handlePointerOver = (0, import_react8.useCallback)(
|
|
1168
1223
|
(event) => {
|
|
1169
1224
|
event.stopPropagation();
|
|
@@ -1250,6 +1305,51 @@ function InnerRenderedShape({
|
|
|
1250
1305
|
);
|
|
1251
1306
|
}
|
|
1252
1307
|
var RenderedShape = (0, import_react8.memo)(InnerRenderedShape);
|
|
1308
|
+
var MATERIAL_FEATURE_KEYS = [
|
|
1309
|
+
"color",
|
|
1310
|
+
"opacity",
|
|
1311
|
+
"roughness",
|
|
1312
|
+
"metalness",
|
|
1313
|
+
"shininess"
|
|
1314
|
+
];
|
|
1315
|
+
var MATERIAL_NAME_SUFFIXES = [
|
|
1316
|
+
" color",
|
|
1317
|
+
" colours",
|
|
1318
|
+
" colour",
|
|
1319
|
+
" opacity",
|
|
1320
|
+
" roughness",
|
|
1321
|
+
" metalness",
|
|
1322
|
+
" shininess"
|
|
1323
|
+
];
|
|
1324
|
+
function deriveMaterialName(shape, values) {
|
|
1325
|
+
for (const key of MATERIAL_FEATURE_KEYS) {
|
|
1326
|
+
const feature = shape.features[key];
|
|
1327
|
+
if (feature && feature.animated) {
|
|
1328
|
+
const animatable = values[feature.value];
|
|
1329
|
+
const candidate = extractMaterialName(animatable?.name);
|
|
1330
|
+
if (candidate) {
|
|
1331
|
+
return candidate;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
return void 0;
|
|
1336
|
+
}
|
|
1337
|
+
function extractMaterialName(name) {
|
|
1338
|
+
if (!name) {
|
|
1339
|
+
return void 0;
|
|
1340
|
+
}
|
|
1341
|
+
const trimmed = name.trim();
|
|
1342
|
+
if (!trimmed) {
|
|
1343
|
+
return void 0;
|
|
1344
|
+
}
|
|
1345
|
+
const lowered = trimmed.toLowerCase();
|
|
1346
|
+
for (const suffix of MATERIAL_NAME_SUFFIXES) {
|
|
1347
|
+
if (lowered.endsWith(suffix)) {
|
|
1348
|
+
return trimmed.slice(0, trimmed.length - suffix.length).trim();
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
return trimmed;
|
|
1352
|
+
}
|
|
1253
1353
|
|
|
1254
1354
|
// src/renderables/renderable.tsx
|
|
1255
1355
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
@@ -2424,6 +2524,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2424
2524
|
group.traverse((child) => {
|
|
2425
2525
|
if (child.userData?.gltfExtensions?.RobotData) {
|
|
2426
2526
|
const data = child.userData.gltfExtensions.RobotData;
|
|
2527
|
+
applyStoredRenderableNames(child, data);
|
|
2427
2528
|
let loadedData;
|
|
2428
2529
|
let mappedFeatures;
|
|
2429
2530
|
let animatableValues;
|
|
@@ -2505,6 +2606,94 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2505
2606
|
}
|
|
2506
2607
|
return [worldData, animatableData];
|
|
2507
2608
|
}
|
|
2609
|
+
var MATERIAL_NAME_FEATURE_KEYS = [
|
|
2610
|
+
"color",
|
|
2611
|
+
"opacity",
|
|
2612
|
+
"roughness",
|
|
2613
|
+
"metalness",
|
|
2614
|
+
"shininess"
|
|
2615
|
+
];
|
|
2616
|
+
var MATERIAL_NAME_SUFFIXES2 = [
|
|
2617
|
+
" color",
|
|
2618
|
+
" colours",
|
|
2619
|
+
" colour",
|
|
2620
|
+
" opacity",
|
|
2621
|
+
" roughness",
|
|
2622
|
+
" metalness",
|
|
2623
|
+
" shininess"
|
|
2624
|
+
];
|
|
2625
|
+
function applyStoredRenderableNames(object, data) {
|
|
2626
|
+
if (typeof data.name === "string" && data.name.length > 0) {
|
|
2627
|
+
object.name = data.name;
|
|
2628
|
+
}
|
|
2629
|
+
if (object.isGroup) {
|
|
2630
|
+
const group = object;
|
|
2631
|
+
if (typeof data.name === "string" && data.name.length > 0) {
|
|
2632
|
+
group.name = data.name;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
if (object.isMesh) {
|
|
2636
|
+
const mesh = object;
|
|
2637
|
+
if (typeof data.name === "string" && data.name.length > 0) {
|
|
2638
|
+
mesh.name = data.name;
|
|
2639
|
+
if (mesh.geometry) {
|
|
2640
|
+
mesh.geometry.name = data.name;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
const inferredName = inferMaterialNameFromStoredRenderable(data);
|
|
2644
|
+
if (inferredName) {
|
|
2645
|
+
assignMaterialName(mesh.material, inferredName);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
function assignMaterialName(material, name) {
|
|
2650
|
+
if (!material) {
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
if (Array.isArray(material)) {
|
|
2654
|
+
material.forEach((mat) => {
|
|
2655
|
+
mat.name = name;
|
|
2656
|
+
});
|
|
2657
|
+
} else {
|
|
2658
|
+
material.name = name;
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
function inferMaterialNameFromStoredRenderable(data) {
|
|
2662
|
+
if (data.type !== "shape") {
|
|
2663
|
+
return void 0;
|
|
2664
|
+
}
|
|
2665
|
+
const features = data.features;
|
|
2666
|
+
for (const key of MATERIAL_NAME_FEATURE_KEYS) {
|
|
2667
|
+
const candidate = extractMaterialNameFromFeature(features[key]);
|
|
2668
|
+
if (candidate) {
|
|
2669
|
+
return candidate;
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
return void 0;
|
|
2673
|
+
}
|
|
2674
|
+
function extractMaterialNameFromFeature(feature) {
|
|
2675
|
+
if (!isStoredAnimatedFeature(feature)) {
|
|
2676
|
+
return void 0;
|
|
2677
|
+
}
|
|
2678
|
+
const animatableName = feature.value.name;
|
|
2679
|
+
if (!animatableName) {
|
|
2680
|
+
return void 0;
|
|
2681
|
+
}
|
|
2682
|
+
return stripMaterialSuffixes(animatableName);
|
|
2683
|
+
}
|
|
2684
|
+
function stripMaterialSuffixes(name) {
|
|
2685
|
+
const trimmed = name.trim();
|
|
2686
|
+
const lowered = trimmed.toLowerCase();
|
|
2687
|
+
for (const suffix of MATERIAL_NAME_SUFFIXES2) {
|
|
2688
|
+
if (lowered.endsWith(suffix)) {
|
|
2689
|
+
return trimmed.slice(0, trimmed.length - suffix.length).trim();
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
return trimmed;
|
|
2693
|
+
}
|
|
2694
|
+
function isStoredAnimatedFeature(feature) {
|
|
2695
|
+
return Boolean(feature) && typeof feature === "object" && feature.animated === true && "value" in feature;
|
|
2696
|
+
}
|
|
2508
2697
|
function isGroupFeatures(value) {
|
|
2509
2698
|
if (!value || typeof value !== "object") {
|
|
2510
2699
|
throw new Error("Expected object");
|
|
@@ -2671,6 +2860,14 @@ var THREE6 = __toESM(require("three"));
|
|
|
2671
2860
|
THREE6.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2672
2861
|
function exportScene(data, fileName = "scene.glb") {
|
|
2673
2862
|
const exporter = new import_three_stdlib3.GLTFExporter();
|
|
2863
|
+
exporter.register(() => ({
|
|
2864
|
+
writeMesh(mesh, meshDef) {
|
|
2865
|
+
const meshName = mesh.name?.trim() || mesh.geometry?.name?.trim() || void 0;
|
|
2866
|
+
if (meshName) {
|
|
2867
|
+
meshDef.name = meshName;
|
|
2868
|
+
}
|
|
2869
|
+
}
|
|
2870
|
+
}));
|
|
2674
2871
|
exporter.parse(
|
|
2675
2872
|
data,
|
|
2676
2873
|
(gltf) => {
|
package/dist/index.mjs
CHANGED
|
@@ -393,6 +393,11 @@ function InnerRenderedGroup({
|
|
|
393
393
|
setReference(group.id, namespace, ref);
|
|
394
394
|
}
|
|
395
395
|
}, [group.id, namespace, ref, setReference, refIsNull]);
|
|
396
|
+
useEffect2(() => {
|
|
397
|
+
if (ref.current) {
|
|
398
|
+
ref.current.name = group.name;
|
|
399
|
+
}
|
|
400
|
+
}, [group.name]);
|
|
396
401
|
const handlePointerOver = useCallback(
|
|
397
402
|
(event) => {
|
|
398
403
|
if (event.eventObject !== event.object) {
|
|
@@ -557,6 +562,9 @@ function InnerRenderedEllipse({
|
|
|
557
562
|
if (instanceOfRawRGB(color)) {
|
|
558
563
|
materialRef.current.color.setRGB(color.r, color.g, color.b);
|
|
559
564
|
materialRef.current.needsUpdate = true;
|
|
565
|
+
} else if (instanceOfRawVector32(color)) {
|
|
566
|
+
materialRef.current.color.setRGB(color.x, color.y, color.z);
|
|
567
|
+
materialRef.current.needsUpdate = true;
|
|
560
568
|
} else if (instanceOfRawHSL(color)) {
|
|
561
569
|
materialRef.current.color.setHSL(color.h, color.s, color.l);
|
|
562
570
|
materialRef.current.needsUpdate = true;
|
|
@@ -609,6 +617,13 @@ function InnerRenderedEllipse({
|
|
|
609
617
|
strokeColor.b
|
|
610
618
|
);
|
|
611
619
|
lineRef.current.material.needsUpdate = true;
|
|
620
|
+
} else if (instanceOfRawVector32(strokeColor)) {
|
|
621
|
+
lineRef.current.material.color.setRGB(
|
|
622
|
+
strokeColor.x,
|
|
623
|
+
strokeColor.y,
|
|
624
|
+
strokeColor.z
|
|
625
|
+
);
|
|
626
|
+
lineRef.current.material.needsUpdate = true;
|
|
612
627
|
} else if (instanceOfRawHSL(strokeColor)) {
|
|
613
628
|
lineRef.current.material.color.setHSL(
|
|
614
629
|
strokeColor.h,
|
|
@@ -845,6 +860,9 @@ function InnerRenderedRectangle({
|
|
|
845
860
|
if (instanceOfRawRGB2(color)) {
|
|
846
861
|
materialRef.current.color.setRGB(color.r, color.g, color.b);
|
|
847
862
|
materialRef.current.needsUpdate = true;
|
|
863
|
+
} else if (instanceOfRawVector33(color)) {
|
|
864
|
+
materialRef.current.color.setRGB(color.x, color.y, color.z);
|
|
865
|
+
materialRef.current.needsUpdate = true;
|
|
848
866
|
} else if (instanceOfRawHSL2(color)) {
|
|
849
867
|
materialRef.current.color.setHSL(color.h, color.s, color.l);
|
|
850
868
|
materialRef.current.needsUpdate = true;
|
|
@@ -897,6 +915,13 @@ function InnerRenderedRectangle({
|
|
|
897
915
|
strokeColor.b
|
|
898
916
|
);
|
|
899
917
|
lineRef.current.material.needsUpdate = true;
|
|
918
|
+
} else if (instanceOfRawVector33(strokeColor)) {
|
|
919
|
+
lineRef.current.material.color.setRGB(
|
|
920
|
+
strokeColor.x,
|
|
921
|
+
strokeColor.y,
|
|
922
|
+
strokeColor.z
|
|
923
|
+
);
|
|
924
|
+
lineRef.current.material.needsUpdate = true;
|
|
900
925
|
} else if (instanceOfRawHSL2(strokeColor)) {
|
|
901
926
|
lineRef.current.material.color.setHSL(
|
|
902
927
|
strokeColor.h,
|
|
@@ -1052,7 +1077,17 @@ function InnerRenderedShape({
|
|
|
1052
1077
|
});
|
|
1053
1078
|
return av;
|
|
1054
1079
|
}, [shape.features, animatables]);
|
|
1055
|
-
const
|
|
1080
|
+
const materialName = useMemo4(
|
|
1081
|
+
() => deriveMaterialName(shape, animatableValues),
|
|
1082
|
+
[shape, animatableValues]
|
|
1083
|
+
);
|
|
1084
|
+
const geometry = useMemo4(() => {
|
|
1085
|
+
const cloned = shape.geometry.clone();
|
|
1086
|
+
if (shape.name) {
|
|
1087
|
+
cloned.name = shape.name;
|
|
1088
|
+
}
|
|
1089
|
+
return cloned;
|
|
1090
|
+
}, [shape.geometry, shape.name]);
|
|
1056
1091
|
const selectionData = useMemo4(
|
|
1057
1092
|
() => ({ id, namespace, type: "shape" }),
|
|
1058
1093
|
[id, namespace]
|
|
@@ -1142,9 +1177,14 @@ function InnerRenderedShape({
|
|
|
1142
1177
|
color.g,
|
|
1143
1178
|
color.b
|
|
1144
1179
|
);
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1180
|
+
material.current.needsUpdate = true;
|
|
1181
|
+
} else if ((material.current || void 0)?.color && instanceOfRawVector34(color)) {
|
|
1182
|
+
material.current.color.setRGB(
|
|
1183
|
+
color.x,
|
|
1184
|
+
color.y,
|
|
1185
|
+
color.z
|
|
1186
|
+
);
|
|
1187
|
+
material.current.needsUpdate = true;
|
|
1148
1188
|
} else if (material.current && instanceOfRawHSL3(color)) {
|
|
1149
1189
|
material.current.color.setHSL(
|
|
1150
1190
|
color.h,
|
|
@@ -1167,6 +1207,21 @@ function InnerRenderedShape({
|
|
|
1167
1207
|
useEffect5(() => {
|
|
1168
1208
|
if (ref.current && refIsNull) setReference(shape.id, namespace, ref);
|
|
1169
1209
|
}, [shape.id, namespace, ref, setReference, refIsNull]);
|
|
1210
|
+
useEffect5(() => {
|
|
1211
|
+
if (ref.current) {
|
|
1212
|
+
ref.current.name = shape.name;
|
|
1213
|
+
}
|
|
1214
|
+
}, [shape.name]);
|
|
1215
|
+
useEffect5(() => {
|
|
1216
|
+
if (!material.current) {
|
|
1217
|
+
return;
|
|
1218
|
+
}
|
|
1219
|
+
if (materialName) {
|
|
1220
|
+
material.current.name = materialName;
|
|
1221
|
+
} else if (shape.name) {
|
|
1222
|
+
material.current.name = shape.name;
|
|
1223
|
+
}
|
|
1224
|
+
}, [materialName, shape.name]);
|
|
1170
1225
|
const handlePointerOver = useCallback4(
|
|
1171
1226
|
(event) => {
|
|
1172
1227
|
event.stopPropagation();
|
|
@@ -1253,6 +1308,51 @@ function InnerRenderedShape({
|
|
|
1253
1308
|
);
|
|
1254
1309
|
}
|
|
1255
1310
|
var RenderedShape = memo5(InnerRenderedShape);
|
|
1311
|
+
var MATERIAL_FEATURE_KEYS = [
|
|
1312
|
+
"color",
|
|
1313
|
+
"opacity",
|
|
1314
|
+
"roughness",
|
|
1315
|
+
"metalness",
|
|
1316
|
+
"shininess"
|
|
1317
|
+
];
|
|
1318
|
+
var MATERIAL_NAME_SUFFIXES = [
|
|
1319
|
+
" color",
|
|
1320
|
+
" colours",
|
|
1321
|
+
" colour",
|
|
1322
|
+
" opacity",
|
|
1323
|
+
" roughness",
|
|
1324
|
+
" metalness",
|
|
1325
|
+
" shininess"
|
|
1326
|
+
];
|
|
1327
|
+
function deriveMaterialName(shape, values) {
|
|
1328
|
+
for (const key of MATERIAL_FEATURE_KEYS) {
|
|
1329
|
+
const feature = shape.features[key];
|
|
1330
|
+
if (feature && feature.animated) {
|
|
1331
|
+
const animatable = values[feature.value];
|
|
1332
|
+
const candidate = extractMaterialName(animatable?.name);
|
|
1333
|
+
if (candidate) {
|
|
1334
|
+
return candidate;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
return void 0;
|
|
1339
|
+
}
|
|
1340
|
+
function extractMaterialName(name) {
|
|
1341
|
+
if (!name) {
|
|
1342
|
+
return void 0;
|
|
1343
|
+
}
|
|
1344
|
+
const trimmed = name.trim();
|
|
1345
|
+
if (!trimmed) {
|
|
1346
|
+
return void 0;
|
|
1347
|
+
}
|
|
1348
|
+
const lowered = trimmed.toLowerCase();
|
|
1349
|
+
for (const suffix of MATERIAL_NAME_SUFFIXES) {
|
|
1350
|
+
if (lowered.endsWith(suffix)) {
|
|
1351
|
+
return trimmed.slice(0, trimmed.length - suffix.length).trim();
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
return trimmed;
|
|
1355
|
+
}
|
|
1256
1356
|
|
|
1257
1357
|
// src/renderables/renderable.tsx
|
|
1258
1358
|
import { Fragment as Fragment3, jsx as jsx6 } from "react/jsx-runtime";
|
|
@@ -2429,6 +2529,7 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2429
2529
|
group.traverse((child) => {
|
|
2430
2530
|
if (child.userData?.gltfExtensions?.RobotData) {
|
|
2431
2531
|
const data = child.userData.gltfExtensions.RobotData;
|
|
2532
|
+
applyStoredRenderableNames(child, data);
|
|
2432
2533
|
let loadedData;
|
|
2433
2534
|
let mappedFeatures;
|
|
2434
2535
|
let animatableValues;
|
|
@@ -2510,6 +2611,94 @@ function traverseThree(group, namespaces, aggressiveImport = false, rootBounds)
|
|
|
2510
2611
|
}
|
|
2511
2612
|
return [worldData, animatableData];
|
|
2512
2613
|
}
|
|
2614
|
+
var MATERIAL_NAME_FEATURE_KEYS = [
|
|
2615
|
+
"color",
|
|
2616
|
+
"opacity",
|
|
2617
|
+
"roughness",
|
|
2618
|
+
"metalness",
|
|
2619
|
+
"shininess"
|
|
2620
|
+
];
|
|
2621
|
+
var MATERIAL_NAME_SUFFIXES2 = [
|
|
2622
|
+
" color",
|
|
2623
|
+
" colours",
|
|
2624
|
+
" colour",
|
|
2625
|
+
" opacity",
|
|
2626
|
+
" roughness",
|
|
2627
|
+
" metalness",
|
|
2628
|
+
" shininess"
|
|
2629
|
+
];
|
|
2630
|
+
function applyStoredRenderableNames(object, data) {
|
|
2631
|
+
if (typeof data.name === "string" && data.name.length > 0) {
|
|
2632
|
+
object.name = data.name;
|
|
2633
|
+
}
|
|
2634
|
+
if (object.isGroup) {
|
|
2635
|
+
const group = object;
|
|
2636
|
+
if (typeof data.name === "string" && data.name.length > 0) {
|
|
2637
|
+
group.name = data.name;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
if (object.isMesh) {
|
|
2641
|
+
const mesh = object;
|
|
2642
|
+
if (typeof data.name === "string" && data.name.length > 0) {
|
|
2643
|
+
mesh.name = data.name;
|
|
2644
|
+
if (mesh.geometry) {
|
|
2645
|
+
mesh.geometry.name = data.name;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
const inferredName = inferMaterialNameFromStoredRenderable(data);
|
|
2649
|
+
if (inferredName) {
|
|
2650
|
+
assignMaterialName(mesh.material, inferredName);
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
function assignMaterialName(material, name) {
|
|
2655
|
+
if (!material) {
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
if (Array.isArray(material)) {
|
|
2659
|
+
material.forEach((mat) => {
|
|
2660
|
+
mat.name = name;
|
|
2661
|
+
});
|
|
2662
|
+
} else {
|
|
2663
|
+
material.name = name;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
function inferMaterialNameFromStoredRenderable(data) {
|
|
2667
|
+
if (data.type !== "shape") {
|
|
2668
|
+
return void 0;
|
|
2669
|
+
}
|
|
2670
|
+
const features = data.features;
|
|
2671
|
+
for (const key of MATERIAL_NAME_FEATURE_KEYS) {
|
|
2672
|
+
const candidate = extractMaterialNameFromFeature(features[key]);
|
|
2673
|
+
if (candidate) {
|
|
2674
|
+
return candidate;
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
return void 0;
|
|
2678
|
+
}
|
|
2679
|
+
function extractMaterialNameFromFeature(feature) {
|
|
2680
|
+
if (!isStoredAnimatedFeature(feature)) {
|
|
2681
|
+
return void 0;
|
|
2682
|
+
}
|
|
2683
|
+
const animatableName = feature.value.name;
|
|
2684
|
+
if (!animatableName) {
|
|
2685
|
+
return void 0;
|
|
2686
|
+
}
|
|
2687
|
+
return stripMaterialSuffixes(animatableName);
|
|
2688
|
+
}
|
|
2689
|
+
function stripMaterialSuffixes(name) {
|
|
2690
|
+
const trimmed = name.trim();
|
|
2691
|
+
const lowered = trimmed.toLowerCase();
|
|
2692
|
+
for (const suffix of MATERIAL_NAME_SUFFIXES2) {
|
|
2693
|
+
if (lowered.endsWith(suffix)) {
|
|
2694
|
+
return trimmed.slice(0, trimmed.length - suffix.length).trim();
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
return trimmed;
|
|
2698
|
+
}
|
|
2699
|
+
function isStoredAnimatedFeature(feature) {
|
|
2700
|
+
return Boolean(feature) && typeof feature === "object" && feature.animated === true && "value" in feature;
|
|
2701
|
+
}
|
|
2513
2702
|
function isGroupFeatures(value) {
|
|
2514
2703
|
if (!value || typeof value !== "object") {
|
|
2515
2704
|
throw new Error("Expected object");
|
|
@@ -2676,6 +2865,14 @@ import * as THREE6 from "three";
|
|
|
2676
2865
|
THREE6.Object3D.DEFAULT_UP.set(0, 0, 1);
|
|
2677
2866
|
function exportScene(data, fileName = "scene.glb") {
|
|
2678
2867
|
const exporter = new GLTFExporter();
|
|
2868
|
+
exporter.register(() => ({
|
|
2869
|
+
writeMesh(mesh, meshDef) {
|
|
2870
|
+
const meshName = mesh.name?.trim() || mesh.geometry?.name?.trim() || void 0;
|
|
2871
|
+
if (meshName) {
|
|
2872
|
+
meshDef.name = meshName;
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
}));
|
|
2679
2876
|
exporter.parse(
|
|
2680
2877
|
data,
|
|
2681
2878
|
(gltf) => {
|
package/package.json
CHANGED