Files
storyteller-bevy/studio/src/world_grid.rs
T
Danny McGee cba70a62ae 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.
2023-12-07 15:46:32 -05:00

84 lines
2.2 KiB
Rust

use bevy::{
pbr::NotShadowCaster,
prelude::*,
render::render_resource::{AsBindGroup, ShaderRef},
};
use crate::camera_controller::{CameraController, CameraMotionSystem};
pub struct WorldGridPlugin;
impl Plugin for WorldGridPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(MaterialPlugin::<ProceduralGridMaterial>::default())
.add_systems(Startup, spawn_world_grid)
.add_systems(PostUpdate, move_plane_with_camera.after(CameraMotionSystem));
}
}
#[derive(Component)]
struct WorldGridPlane;
#[derive(Asset, AsBindGroup, TypePath, Clone)]
struct ProceduralGridMaterial {}
impl Material for ProceduralGridMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/procedural_grid.wgsl".into()
}
fn alpha_mode(&self) -> AlphaMode {
AlphaMode::Blend
}
}
fn spawn_world_grid(
mut cmd: Commands,
mut ra_meshes: ResMut<Assets<Mesh>>,
mut ra_mat_proc_grid: ResMut<Assets<ProceduralGridMaterial>>,
) {
let plane = ra_meshes.add(Mesh::from(shape::Plane {
size: 200.0,
subdivisions: 0,
}));
let proc_grid = ra_mat_proc_grid.add(ProceduralGridMaterial {});
cmd.spawn((
Name::new("World Grid"),
SpatialBundle::from_transform(Transform::IDENTITY),
WorldGridPlane,
))
.with_children(|parent| {
parent.spawn((
MaterialMeshBundle {
mesh: plane.clone(),
material: proc_grid.clone(),
transform: Transform::IDENTITY,
..default()
},
NotShadowCaster,
));
parent.spawn((
MaterialMeshBundle {
mesh: plane,
material: proc_grid,
transform: Transform::IDENTITY.looking_to(Vec3::Z, Vec3::NEG_Y),
..default()
},
NotShadowCaster,
));
});
}
fn move_plane_with_camera(
mut plane: Query<(&WorldGridPlane, &mut Transform)>,
camera: Query<&CameraController, Changed<CameraController>>,
) {
if let Ok(&CameraController { focus, .. }) = camera.get_single() {
let (_, mut xform) = plane.single_mut();
xform.translation.x = focus.x;
xform.translation.z = focus.z;
}
}