From ba19b6342ea93182a5cb84be53fe631df3b03a24 Mon Sep 17 00:00:00 2001 From: "Elijah C. Voigt" Date: Mon, 10 Jun 2024 20:44:43 -0700 Subject: [PATCH] Proof of concept for textured dice Now to integrate with the game. Also need to figure out best way to do multiple dice. Probably multiple cameras + textures. But we can probably share one mesh. --- examples/.gitkeep | 0 examples/minimal_2d.rs | 2 +- examples/text_image.rs | 190 +++++++++++++++++++++++++++++++++++++++++ src/game/dice.rs | 114 +++++++++++++++---------- src/prelude.rs | 4 +- 5 files changed, 264 insertions(+), 46 deletions(-) delete mode 100644 examples/.gitkeep create mode 100644 examples/text_image.rs diff --git a/examples/.gitkeep b/examples/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/examples/minimal_2d.rs b/examples/minimal_2d.rs index 0f45bee..06c60af 100644 --- a/examples/minimal_2d.rs +++ b/examples/minimal_2d.rs @@ -28,4 +28,4 @@ fn setup( }, PickableBundle::default(), // <- Makes the mesh pickable. )); -} \ No newline at end of file +} diff --git a/examples/text_image.rs b/examples/text_image.rs new file mode 100644 index 0000000..7cf3c72 --- /dev/null +++ b/examples/text_image.rs @@ -0,0 +1,190 @@ +use std::f32::consts::PI; + +use bevy::{ + prelude::*, + render::{ + camera::RenderTarget, + render_resource::{ + Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, + }, + }, +}; + +fn main() { + App::new() + .add_plugins(DefaultPlugins) + .add_systems(Startup, add_texture) + .add_systems(Update, rotate_mesh.run_if(|keys: Res>| -> bool { + keys.pressed(KeyCode::Space) + })) + .run(); +} + +fn add_texture( + mut images: ResMut>, + mut materials: ResMut>, + mut meshes: ResMut>, + mut commands: Commands, +) { + let image_handle = { + let size = Extent3d { + width: 256, + height: 256 * 6, + ..default() + }; + let mut image = Image { + texture_descriptor: TextureDescriptor { + label: None, + size, + dimension: TextureDimension::D2, + format: TextureFormat::Bgra8UnormSrgb, + mip_level_count: 1, + sample_count: 1, + usage: TextureUsages::TEXTURE_BINDING + | TextureUsages::COPY_DST + | TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }, + ..default() + }; + image.resize(size); + + images.add(image) + }; + + let texture_camera = commands + .spawn(Camera2dBundle { + camera: Camera { + order: -1, + target: RenderTarget::Image(image_handle.clone()), + ..default() + }, + ..default() + }) + .id(); + + commands + .spawn(( + NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + flex_direction: FlexDirection::Column, + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + ..default() + }, + background_color: BackgroundColor(Color::GOLD), + ..default() + }, + TargetCamera(texture_camera), + )) + .with_children(|parent| { + ["Up", "Down", "Left", "Right", "Top", "Bottom"] + .into_iter() + .for_each(|text| { + parent.spawn(NodeBundle { + style: Style { + height: Val::Percent(100.0 / 6.0), + width: Val::Percent(100.0), + justify_content: JustifyContent::Center, + justify_items: JustifyItems::Center, + align_items: AlignItems::Center, + align_content: AlignContent::Center, + ..default() + }, + ..default() + }).with_children(|parent| { + parent.spawn(TextBundle { + text: Text::from_section( + text, + TextStyle { + color: Color::BLACK, + font_size: 64.0, + ..default() + }, + ), + ..default() + }); + }); + }); + }); + + commands.spawn(DirectionalLightBundle { ..default() }); + + { + commands.spawn(ImageBundle { + style: Style { + top: Val::Px(0.0), + left: Val::Px(0.0), + position_type: PositionType::Absolute, + max_height: Val::Percent(100.0), + ..default() + }, + image: UiImage { + texture: image_handle.clone(), + ..default() + }, + ..default() + }); + } + + { + let cube_size = 4.0; + let a = 1.0 / 6.0; + let b = 2.0 * a; + let c = 3.0 * a; + let d = 4.0 * a; + let e = 5.0 * a; + let f = 1.0; + let cuboid = Mesh::from(Cuboid::new(cube_size, cube_size, cube_size)) + .with_inserted_attribute( + Mesh::ATTRIBUTE_UV_0, + vec![ + // Top side + [1.0, 0.0], [0.0, 0.0], [0.0, a], [1.0, a], + // Bottom side + [1.0, a], [0.0, a], [0.0, b], [1.0, b], + // Right side + [1.0, b], [0.0, b], [0.0, c], [1.0, c], + // Left side + [1.0, c], [0.0, c], [0.0, d], [1.0, d], + // Back side + [1.0, d], [0.0, d], [0.0, e], [1.0, e], + // Front side + [1.0, e], [0.0, e], [0.0, f], [1.0, f], + ]); + let mesh = meshes.add(cuboid); + let material = materials.add(StandardMaterial { + base_color_texture: Some(image_handle), + ..default() + }); + let transform = + Transform::from_xyz(0.0, 0.0, 1.5).with_rotation(Quat::from_rotation_x(-PI / 5.0)); + commands.spawn(PbrBundle { + mesh, + material, + transform, + ..default() + }); + } + + { + let transform = Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y); + commands.spawn(Camera3dBundle { + transform, + ..default() + }); + } +} + +fn rotate_mesh( + mut query: Query<&mut Transform, With>>, + time: Res