Skip to content

Commit 44d9834

Browse files
committed
Load BVH skeleton
1 parent 7f55483 commit 44d9834

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

editor/src/editor/layout/assets-browser.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import { FileInspectorObject } from "./inspector/file";
6565
import { AssetBrowserGUIItem } from "./assets-browser/items/gui-item";
6666
import { AssetBrowserHDRItem } from "./assets-browser/items/hdr-item";
6767
import { AssetBrowserMeshItem } from "./assets-browser/items/mesh-item";
68+
import { AssetBrowserSkeletonItem } from "./assets-browser/items/skeleton-item";
6869
import { AssetBrowserSceneItem } from "./assets-browser/items/scene-item";
6970
import { AssetBrowserImageItem } from "./assets-browser/items/image-item";
7071
import { AssetBrowserMaterialItem } from "./assets-browser/items/material-item";
@@ -90,6 +91,7 @@ const ImageSelectable = createSelectable(AssetBrowserImageItem);
9091
const SceneSelectable = createSelectable(AssetBrowserSceneItem);
9192
const MaterialSelectable = createSelectable(AssetBrowserMaterialItem);
9293
const CinematicSelectable = createSelectable(AssetBrowserCinematicItem);
94+
const SkeletonSelectable = createSelectable(AssetBrowserSkeletonItem);
9395

9496
export interface IEditorAssetsBrowserProps {
9597
/**
@@ -791,6 +793,10 @@ export class EditorAssetsBrowser extends Component<IEditorAssetsBrowserProps, IE
791793
case ".babylon":
792794
return <MeshSelectable {...props} />;
793795

796+
case ".bvh":
797+
case ".BVH":
798+
return <SkeletonSelectable {...props} />;
799+
794800
case ".material":
795801
return <MaterialSelectable {...props} />;
796802

editor/src/editor/layout/assets-browser/items/item.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { toast } from "sonner";
1515
import { VscJson } from "react-icons/vsc";
1616
import { ImFinder } from "react-icons/im";
1717
import { BiSolidFileCss } from "react-icons/bi";
18-
import { GiCeilingLight } from "react-icons/gi";
18+
import { GiCeilingLight, GiSkeletonInside } from "react-icons/gi";
1919
import { GrStatusUnknown } from "react-icons/gr";
2020
import { BsFiletypeMp3, BsFiletypeWav } from "react-icons/bs";
2121
import { AiFillFileMarkdown, AiOutlineClose } from "react-icons/ai";
@@ -455,6 +455,10 @@ export class AssetsBrowserItem extends Component<IAssetsBrowserItemProps, IAsset
455455
case ".bjseditor":
456456
return <SiBabylondotjs size="64px" />;
457457

458+
case ".bvh":
459+
case ".BVH":
460+
return <GiSkeletonInside size="64px" />;
461+
458462
case ".ies":
459463
return <GiCeilingLight size="64px" />;
460464

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { ReactNode } from "react";
2+
3+
import { GiSkeletonInside } from "react-icons/gi";
4+
5+
import { SceneLoader, Debug } from "babylonjs";
6+
7+
import { AssetsBrowserItem } from "./item";
8+
import { ContextMenuItem } from "../../../../ui/shadcn/ui/context-menu";
9+
10+
export class AssetBrowserSkeletonItem extends AssetsBrowserItem {
11+
/**
12+
* @override
13+
*/
14+
protected getContextMenuContent(): ReactNode {
15+
return (
16+
<>
17+
<ContextMenuItem className="flex items-center gap-2" onClick={() => this._handleLoadSkeletonToScene()}>
18+
<GiSkeletonInside className="w-5 h-5" /> Load to Scene
19+
</ContextMenuItem>
20+
</>
21+
);
22+
}
23+
24+
/**
25+
* @override
26+
*/
27+
protected getIcon(): ReactNode {
28+
return <GiSkeletonInside size="64px" />;
29+
}
30+
31+
/**
32+
* @override
33+
*/
34+
protected async onDoubleClick(): Promise<void> {
35+
await this._handleLoadSkeletonToScene();
36+
}
37+
38+
private async _handleLoadSkeletonToScene(): Promise<void> {
39+
const scene = this.props.editor.layout.preview.scene;
40+
if (!scene) {
41+
return;
42+
}
43+
44+
try {
45+
// Load the BVH file using SceneLoader
46+
const result = await SceneLoader.ImportMeshAsync("", "", this.props.absolutePath, scene);
47+
48+
// Get the skeleton from the result
49+
const skeleton = result.skeletons[0];
50+
51+
if (skeleton) {
52+
// Create a skeleton viewer to visualize the skeleton
53+
const viewer = new Debug.SkeletonViewer(skeleton, null, scene, false, 1, {
54+
displayMode: Debug.SkeletonViewer.DISPLAY_SPHERE_AND_SPURS,
55+
});
56+
viewer.isEnabled = true;
57+
58+
// Start the animation if available
59+
const highestFrame = skeleton.bones[0]?.animations[0]?.getHighestFrame() ?? 60;
60+
scene.beginAnimation(skeleton, 0, highestFrame, true);
61+
62+
// Notify the user
63+
this.props.editor.layout.console.log(`Loaded skeleton: ${skeleton.name} with ${skeleton.bones.length} bones`);
64+
} else {
65+
this.props.editor.layout.console.warn("No skeleton found in the BVH file");
66+
}
67+
} catch (error) {
68+
console.error("Failed to load BVH file:", error);
69+
this.props.editor.layout.console.error(`Failed to load BVH file: ${error}`);
70+
}
71+
}
72+
}

editor/src/editor/layout/preview.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,8 @@ export class EditorPreview extends Component<IEditorPreviewProps, IEditorPreview
10991099

11001100
const extension = extname(absolutePath).toLowerCase();
11011101
switch (extension) {
1102+
case ".bvh":
1103+
case ".BVH":
11021104
case ".x":
11031105
case ".b3d":
11041106
case ".dae":

0 commit comments

Comments
 (0)