Refactor Studio entry-points (#54)

This PR heavily refactors the entry-point functions in
`studio/src/lib.rs` to simplify and consolidate. Additionally, the
frontend application should now be configurable as expected with any
valid combination of the following URL parameters:

* `objectId` : A pre-bundled library object to load (e.g., "couch.gltf")
* `bvh` : Any resolvable path to a BVH animation with a MocapNET
skeleton (e.g., "mocap/shuffle.bvh")
* `mixamo` : Any resolvable path to a glTF animation with the Mixamo
skeleton (e.g., "mocap/hip-hop-dancing.gltf")
* `sceneImport` : Any resolvable path to an arbitrary glTF scene
(untested, but should theoretically work)
* `scene` : Any resolvable path to a previously saved Storyteller Studio
scene in `*.scn.ron` format
* `skybox` : The ID of a pre-bundled skybox asset. Valid options are:
  - "gum_trees_4k"
  - "kloofenfal_28d_misty_4k"
  - "meadow_4k"
  - "promenade_de_vidy_4k"
  - "scythian_tombs_4k"
  - "test_scene" (this is the default if not specified)
* `mode` : One of "studio" or "viewer" (the default if not specified)

"Validity" rules are as follows:

* `objectId`, `bvh`, `mixamo`, `sceneImport` and `scene` are mutually
exclusive
* `skybox` is not supported for `scene` (the skybox should be saved and
loaded as part of the scene description, though this is not currently
working)
* Both `mode` options are valid for all other parameters
This commit is contained in:
Danny McGee
2024-02-27 12:22:00 -05:00
committed by GitHub
parent d51eec52c3
commit c788bcf6b7
21 changed files with 564 additions and 554 deletions
+164
View File
@@ -0,0 +1,164 @@
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
use crate::{InitAsset, InitParams, StudioMode, ViewportSize};
#[wasm_bindgen(typescript_custom_section)]
const WASM_ENTRY_POINTS: &str = r#"
export type SkyboxId
= "gum_trees_4k"
| "kloofenfal_28d_misty_4k"
| "meadow_4k"
| "promenade_de_vidy_4k"
| "scythian_tombs_4k"
| "test_scene"
;
export interface InitOptions {
mode: StudioMode;
/** Required for all entry-points except `initFromStorytellerScene()` */
skyboxId?: SkyboxId;
canvasSelector: string;
canvasAlt: string;
viewportSize: ViewportSize;
}
export function initFromLibrary(objectId: string, options: InitOptions): void;
export function initFromBvh(animPath: string, options: InitOptions): void;
export function initFromMixamo(animPath: string, options: InitOptions): void;
export function initFromSceneImport(scenePath: string, options: InitOptions): void;
export function initFromStorytellerScene(scenePath: string, options: InitOptions): void;
"#;
#[derive(Serialize, Deserialize)]
struct WasmInitOptions {
#[serde(rename = "skyboxId")]
skybox_id: Option<String>,
mode: StudioMode,
#[serde(rename = "canvasSelector")]
canvas_selector: String,
#[serde(rename = "canvasAlt")]
canvas_alt: String,
#[serde(rename = "viewportSize")]
viewport_size: ViewportSize,
}
#[wasm_bindgen(skip_typescript, js_name = initFromLibrary)]
pub fn init_from_library(object_id: String, options: JsValue) -> Result<(), JsValue> {
let options = serde_wasm_bindgen::from_value::<WasmInitOptions>(options)?;
let skybox_id = options
.skybox_id
.expect("`skyboxId` is required for `initFromLibrary`");
crate::start(
InitParams::FromAsset {
asset: InitAsset::LibraryObject(object_id),
skybox_id,
},
options.mode,
Some(Window {
resolution: options.viewport_size.into(),
title: options.canvas_alt,
canvas: Some(options.canvas_selector),
..default()
}),
)
.run();
Ok(())
}
#[wasm_bindgen(skip_typescript, js_name = initFromBvh)]
pub fn init_from_bvh(anim_path: String, options: JsValue) -> Result<(), JsValue> {
let options = serde_wasm_bindgen::from_value::<WasmInitOptions>(options)?;
let skybox_id = options
.skybox_id
.expect("`skyboxId` is required for `initFromBvh`");
crate::start(
InitParams::FromAsset {
asset: InitAsset::BvhAnim(anim_path),
skybox_id,
},
options.mode,
Some(Window {
resolution: options.viewport_size.into(),
title: options.canvas_alt,
canvas: Some(options.canvas_selector),
..default()
}),
)
.run();
Ok(())
}
#[wasm_bindgen(skip_typescript, js_name = initFromMixamo)]
pub fn init_from_mixamo(anim_path: String, options: JsValue) -> Result<(), JsValue> {
let options = serde_wasm_bindgen::from_value::<WasmInitOptions>(options)?;
let skybox_id = options
.skybox_id
.expect("`skyboxId` is required for `initFromMixamo`");
crate::start(
InitParams::FromAsset {
asset: InitAsset::MixamoAnim(anim_path),
skybox_id,
},
options.mode,
Some(Window {
resolution: options.viewport_size.into(),
title: options.canvas_alt,
canvas: Some(options.canvas_selector),
..default()
}),
)
.run();
Ok(())
}
#[wasm_bindgen(skip_typescript, js_name = initFromSceneImport)]
pub fn init_from_scene_import(scene_path: String, options: JsValue) -> Result<(), JsValue> {
let options = serde_wasm_bindgen::from_value::<WasmInitOptions>(options)?;
let skybox_id = options
.skybox_id
.expect("`skyboxId` is required for `initFromSceneImport`");
crate::start(
InitParams::FromAsset {
asset: InitAsset::ImportedScene(scene_path),
skybox_id,
},
options.mode,
Some(Window {
resolution: options.viewport_size.into(),
title: options.canvas_alt,
canvas: Some(options.canvas_selector),
..default()
}),
)
.run();
Ok(())
}
#[wasm_bindgen(skip_typescript, js_name = initFromStorytellerScene)]
pub fn init_from_storyteller_scene(scene_path: String, options: JsValue) -> Result<(), JsValue> {
let options = serde_wasm_bindgen::from_value::<WasmInitOptions>(options)?;
crate::start(
InitParams::FromScene(scene_path),
options.mode,
Some(Window {
resolution: options.viewport_size.into(),
title: options.canvas_alt,
canvas: Some(options.canvas_selector),
..default()
}),
)
.run();
Ok(())
}
+1
View File
@@ -4,6 +4,7 @@ use parking_lot::ReentrantMutex;
use wasm_bindgen::prelude::wasm_bindgen;
mod conv;
mod init;
#[cfg(feature = "wasm_screenshot")]
mod screenshot;
mod util;