Merge branch 'develop' into feat/polish-mission-2
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled

This commit is contained in:
math-pixel
2026-06-03 01:52:20 +02:00
31 changed files with 661 additions and 857 deletions
+9 -9
View File
@@ -85,7 +85,7 @@ export class Debug {
fogEnabled: boolean;
handTrackingSource: HandTrackingSource;
showDebugOverlay: boolean;
showHandTrackingSvg: boolean;
showHandTrackingModel: boolean;
showInteractionSpheres: boolean;
showPerf: boolean;
sceneMode: SceneMode;
@@ -108,7 +108,7 @@ export class Debug {
fogEnabled: FOG_CONFIG.enabled,
handTrackingSource: storedControls.handTrackingSource ?? "browser",
showDebugOverlay: true,
showHandTrackingSvg: false,
showHandTrackingModel: false,
showInteractionSpheres: false,
showPerf: true,
sceneMode: storedControls.sceneMode ?? "game",
@@ -156,10 +156,10 @@ export class Debug {
const handTrackingFolder = this.createFolder("Hand Tracking");
handTrackingFolder
?.add(this.controls, "showHandTrackingSvg")
.name("Show SVG")
?.add(this.controls, "showHandTrackingModel")
.name("Show Model")
.onChange((value: boolean) => {
this.controls.showHandTrackingSvg = value;
this.controls.showHandTrackingModel = value;
this.emit();
});
@@ -281,12 +281,12 @@ export class Debug {
return this.controls.showInteractionSpheres;
}
getShowHandTrackingSvg(): boolean {
return this.controls.showHandTrackingSvg;
getShowHandTrackingModel(): boolean {
return this.controls.showHandTrackingModel;
}
setShowHandTrackingSvg(value: boolean): void {
this.controls.showHandTrackingSvg = value;
setShowHandTrackingModel(value: boolean): void {
this.controls.showHandTrackingModel = value;
this.emit();
}
+16 -6
View File
@@ -53,13 +53,23 @@ export class ExplodedModel {
}
private createParts(model: THREE.Object3D): ExplodedPart[] {
const root =
model.children.length === 1 && model.children[0]
? model.children[0]
: model;
const directChildren = root.children.filter((child) => hasMesh(child));
// Drill down through single-mesh-bearing branches until we find a node
// with multiple mesh-bearing children (the natural "explosion group" the
// modeler authored). Falls back to flat mesh list only if no such group
// exists. This avoids exploding leaves in local space when wrapper nodes
// (e.g. "Empty" + "Moto" > "Eclatement") sit above the actual group.
let current = model;
while (true) {
const meshChildren = current.children.filter((child) => hasMesh(child));
if (meshChildren.length === 1 && meshChildren[0]) {
current = meshChildren[0];
continue;
}
break;
}
const directChildren = current.children.filter((child) => hasMesh(child));
const sourceObjects =
directChildren.length > 1 ? directChildren : getMeshes(root);
directChildren.length > 1 ? directChildren : getMeshes(current);
if (sourceObjects.length === 0) return [];