Single-object viewer POC (#14)

This commit implements a Sketchfab-style single-object viewer as a minimal
proof-of-concept.

### `@storyteller/studio-web`
This is a new package to house web components for interfacing with the
`@storyteller/studio` WASM library. It currently includes a single component,
`<sts-viewer />`, which is exported from `@storyteller/studio-web/viewer`.

### `react-frontend`
This is a new application intended as a proof-of-concept and testbed for React
interop with `@storyteller/studio-web`.

Web components are currently a little bit fiddly to use in a React application.
`react-frontend/src/app/studio-viewer.tsx` demonstrates how a React-idiomatic
component can be written as a thin wrapper around a web component, and
`react-frontend/src/app/app.tsx` demonstrates that wrapper component in use.
This commit is contained in:
Danny McGee
2023-12-07 15:46:32 -05:00
committed by GitHub
parent 155272a5ba
commit cba70a62ae
70 changed files with 71793 additions and 1157 deletions
+28 -2
View File
@@ -2,9 +2,12 @@ use bevy::prelude::*;
use bevy_mod_outline::{
AutoGenerateOutlineNormalsPlugin, OutlineBundle, OutlinePlugin, OutlineVolume,
};
use bevy_mod_picking::{prelude::Pointer, selection::Select};
use bevy_mod_picking::{prelude::Pointer, selection::Select, PickableBundle};
use crate::input::{self, Action, InputAction, Lifecycle};
use crate::{
input::{self, Action, InputAction, Lifecycle},
scene::{SceneElement, SceneSpawnerSystem, SceneState},
};
pub struct SelectionPlugin;
impl Plugin for SelectionPlugin {
@@ -14,6 +17,12 @@ impl Plugin for SelectionPlugin {
.add_systems(
PostUpdate,
draw_selection_outline.run_if(resource_changed_or_removed::<Selection>()),
)
.add_systems(
OnEnter(SceneState::Active),
(apply_deferred, tag_scene_elements)
.chain()
.after(SceneSpawnerSystem),
);
#[cfg(feature = "wasm")]
@@ -35,6 +44,23 @@ pub struct Selected;
#[derive(Resource, Deref, DerefMut, Debug)]
pub struct Selection(Entity);
fn tag_scene_elements(
mut cmd: Commands,
q_scene_elements: Query<(Entity, &Children), (With<SceneElement>, Without<Selectable>)>,
q_primitives: Query<&Handle<Mesh>>,
) {
for (ent, children) in q_scene_elements.iter() {
cmd.entity(ent).insert(Selectable);
for &ent_child in children
.iter()
.filter(|child| q_primitives.contains(**child))
{
cmd.entity(ent_child).insert(PickableBundle::default());
}
}
}
fn update_selection(
mut cmd: Commands,
// FIXME: These events aren't aware of our input actions, so we receive a
+7 -7
View File
@@ -88,7 +88,7 @@ mod wasm {
use bevy::prelude::*;
use wasm_bindgen::prelude::*;
use crate::wasm::{self, WasmMessageBuffer};
use crate::wasm::{StaticBuffer, WasmMessageBuffer};
use super::{TransformMode, TransformSpace, TransformType};
@@ -111,22 +111,22 @@ mod wasm {
#[wasm_bindgen(js_name = setTransformType)]
pub fn set_transform_type(flags: u8) {
wasm::write_message!(TRANSFORM_TYPE_BUF, flags.into());
TRANSFORM_TYPE_BUF.write_message(flags.into());
}
#[wasm_bindgen(js_name = setTransformSpace)]
pub fn set_transform_space(space: TransformSpace) {
wasm::write_message!(TRANSFORM_SPACE_BUF, space);
TRANSFORM_SPACE_BUF.write_message(space);
}
pub(super) fn update_transform_mode(mut xform_mode: ResMut<TransformMode>) {
wasm::read_buffer!(TRANSFORM_TYPE_BUF, |ttype| {
if let Some(ttype) = TRANSFORM_TYPE_BUF.take_message() {
info!("Setting transform type: {ttype:?}");
xform_mode.ttype = ttype;
});
wasm::read_buffer!(TRANSFORM_SPACE_BUF, |space| {
}
if let Some(space) = TRANSFORM_SPACE_BUF.take_message() {
info!("Setting transform space: {space:?}");
xform_mode.space = space;
});
}
}
}