diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e155eb4 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'steadyum'", + "cargo": { + "args": [ + "build", + "--bin=steadyum", + "--package=steadyum", + "--features=dim3", + ], + "filter": { + "name": "steadyum", + "kind": "bin" + } + }, + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'steadyum'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=steadyum", + "--package=steadyum" + ], + "filter": { + "name": "steadyum", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5565aca --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.cargo.features": [ + "dim3" + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 4c5b65c..1635f26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,30 +23,40 @@ parallel = ["bevy_rapier2d?/parallel", "bevy_rapier3d?/parallel"] simd-stable = ["bevy_rapier2d?/simd-stable", "bevy_rapier3d?/simd-stable"] wasm-bindgen = ["bevy_rapier2d?/wasm-bindgen", "bevy_rapier3d?/wasm-bindgen"] simd-nightly = ["bevy_rapier2d?/simd-nightly", "bevy_rapier3d?/simd-nightly"] -serde-serialize = ["bevy_rapier2d?/serde-serialize", "bevy_rapier3d?/serde-serialize"] -enhanced-determinism = ["bevy_rapier2d?/enhanced-determinism", "bevy_rapier3d?/enhanced-determinism"] +serde-serialize = [ + "bevy_rapier2d?/serde-serialize", + "bevy_rapier3d?/serde-serialize", +] +enhanced-determinism = [ + "bevy_rapier2d?/enhanced-determinism", + "bevy_rapier3d?/enhanced-determinism", +] voxels = ["dot_vox"] [dependencies] -nalgebra = { version = "0.32", features = ["convert-glam020"] } +nalgebra = { version = "0.33", features = ["convert-glam027"] } # Don't enable the default features because we don't need the ColliderSet/RigidBodySet -rapier3d = { version = "0.19", optional = true, features = ["profiler"] } -bevy_rapier3d = { version = "0.26", optional = true, features = ["serde-serialize"] } -rapier2d = { version = "0.19", optional = true, features = ["profiler"] } -bevy_rapier2d = { version = "0.26", optional = true, features = ["serde-serialize"] } +rapier3d = { version = "0.21", optional = true, features = ["profiler"] } +bevy_rapier3d = { version = "0.27", optional = true, features = [ + "serde-serialize", +] } +rapier2d = { version = "0.21", optional = true, features = ["profiler"] } +bevy_rapier2d = { version = "0.27", optional = true, features = [ + "serde-serialize", +] } bitflags = "1" -strum = "0.24" -strum_macros = "0.24" +strum = "0.26" +strum_macros = "0.26" image = "0.24" -winit = "0.28" +winit = "0.30" log = "0.4" oorandom = "11" bytemuck = "1" serde = "1" bincode = "1" serde_json = "1" -noise = "0.8" +noise = "0.9" sled = "0.34" clap = { version = "4", features = ["derive"] } anyhow = "1" @@ -55,17 +65,17 @@ uuid = "1" dot_vox = { version = "5", optional = true } instant = "0.1" -bevy = { version = "0.13", features = ["serialize"] } -bevy_egui = "0.27" +bevy = { version = "0.14", features = ["serialize"] } +bevy_egui = "0.28" #bevy_stl = "0.7" -bevy_obj = "0.13" -bevy_polyline = { git = "https://github.com/nsabovic/bevy_polyline", branch = "bevy-13" } -bevy_prototype_lyon = "0.11" -bevy_infinite_grid = "0.12" +bevy_obj = "0.14" +bevy_polyline = "0.10" +bevy_prototype_lyon = "0.12" +bevy_infinite_grid = "0.13" # Not compatible with WASM [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -native-dialog = "0.6" # For opening mesh files. +native-dialog = "0.7" # For opening mesh files. [profile.release] debug = true @@ -83,4 +93,3 @@ debug = true #bevy_rapier3d = { path = "../bevy_rapier/bevy_rapier3d" } #bevy_rapier2d = { git = "https://github.com/dimforge/bevy_rapier", branch = "gosim" } #bevy_rapier3d = { git = "https://github.com/dimforge/bevy_rapier", branch = "gosim" } - diff --git a/src/floor/mod.rs b/src/floor/mod.rs index 8f1b37d..f01a09e 100644 --- a/src/floor/mod.rs +++ b/src/floor/mod.rs @@ -14,13 +14,15 @@ impl Plugin for FloorPlugin { } fn setup_floor(mut commands: Commands, _meshes: ResMut>) { - commands.spawn(InfiniteGridBundle { - settings: InfiniteGridSettings { - // shadow_color: None, - fadeout_distance: 500.0, - dot_fadeout_strength: 0.1, + commands + .spawn(InfiniteGridBundle { + settings: InfiniteGridSettings { + // shadow_color: None, + fadeout_distance: 500.0, + dot_fadeout_strength: 0.1, + ..Default::default() + }, ..Default::default() - }, - ..Default::default() - }); + }) + .insert(Name::new("Infinite Grid")); } diff --git a/src/insertion/mod.rs b/src/insertion/mod.rs index 1d8f844..1ecef8a 100644 --- a/src/insertion/mod.rs +++ b/src/insertion/mod.rs @@ -262,7 +262,8 @@ fn spawn_preview_entity(mut commands: Commands) { commands .spawn(preview_shape_bundle(Vect::ONE, Color::WHITE)) .insert(InsertionPreview) - .insert(Visibility::Hidden); + .insert(Visibility::Hidden) + .insert(Name::new("Preview")); } #[cfg(feature = "dim2")] diff --git a/src/layers.rs b/src/layers.rs index 3c1cad5..881bb52 100644 --- a/src/layers.rs +++ b/src/layers.rs @@ -1 +1 @@ -pub const GIZMO_LAYER: u8 = 1; +pub const GIZMO_LAYER: usize = 1; diff --git a/src/main.rs b/src/main.rs index 53e9424..2283cf8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,7 +74,7 @@ fn main() { title, ..Default::default() })*/ - .insert_resource(ClearColor(Color::rgb(0.55, 0.55, 0.55))) + .insert_resource(ClearColor(Color::srgb(0.55, 0.55, 0.55))) .insert_resource(args) .insert_resource(PhysicsProgress::default()) .add_plugins(DefaultPlugins) @@ -191,19 +191,21 @@ fn setup_graphics(mut commands: Commands) { #[cfg(feature = "dim3")] fn setup_graphics(mut commands: Commands) { - commands.spawn(DirectionalLightBundle { - directional_light: DirectionalLight { - illuminance: 10_000.0, - shadows_enabled: true, - ..Default::default() - }, - transform: Transform { - translation: Vec3::new(10.0, 2.0, 10.0), - rotation: Quat::from_rotation_x(-std::f32::consts::FRAC_PI_4), + commands + .spawn(DirectionalLightBundle { + directional_light: DirectionalLight { + illuminance: 10_000.0, + shadows_enabled: true, + ..Default::default() + }, + transform: Transform { + translation: Vec3::new(10.0, 2.0, 10.0), + rotation: Quat::from_rotation_x(-std::f32::consts::FRAC_PI_4), + ..Default::default() + }, ..Default::default() - }, - ..Default::default() - }); + }) + .insert(Name::new("Light")); let mut orbit = OrbitCamera { pan_sensitivity: 4.0, @@ -227,6 +229,7 @@ fn setup_graphics(mut commands: Commands) { }), ..Default::default() }) + .insert(Name::new("3D Camera")) // .insert(UnrealCameraBundle::new( // UnrealCameraController { ..default() }, // Vec3::new(-2.0, 25.0, 5.0), @@ -251,6 +254,7 @@ fn setup_graphics(mut commands: Commands) { }, ..default() }) + .insert(Name::new("Gizmos Camera")) .insert(GizmoCamera) .insert(RenderLayers::layer(GIZMO_LAYER)); } diff --git a/src/operation/add_collision_shape.rs b/src/operation/add_collision_shape.rs index 79c1144..3e8f715 100644 --- a/src/operation/add_collision_shape.rs +++ b/src/operation/add_collision_shape.rs @@ -13,6 +13,7 @@ pub fn add_collision_shape( commands .spawn(collider.clone()) .insert(rigid_body.clone()) + .insert(Name::new("Collision Shape")) .insert(TransformBundle::from_transform(*transform)) .insert(ColliderRenderBundle::new(&mut colors)); } diff --git a/src/render/collision_shape_outline_render3d.rs b/src/render/collision_shape_outline_render3d.rs index e67f786..c74ae67 100644 --- a/src/render/collision_shape_outline_render3d.rs +++ b/src/render/collision_shape_outline_render3d.rs @@ -49,7 +49,10 @@ pub fn create_collider_outline_renders_system( } } else { let target = commands.entity(entity).with_children(|cmd| { - let target = cmd.spawn(bundle).id(); + let target = cmd + .spawn(bundle) + .insert(Name::new("Collider Outlines")) + .id(); render_target.outline_target = Some(target); }); } diff --git a/src/render/components.rs b/src/render/components.rs index 982822e..0435104 100644 --- a/src/render/components.rs +++ b/src/render/components.rs @@ -1,19 +1,19 @@ use bevy::prelude::Color; use bevy::prelude::*; -pub const DEFAULT_COLOR: Color = Color::BEIGE; +pub const DEFAULT_COLOR: Color = Color::Srgba(bevy::color::palettes::css::BEIGE); pub const DEFAULT_PALETTE: [Color; 3] = [ - Color::rgb( + Color::srgb( 0x98 as f32 / 255.0, 0xC1 as f32 / 255.0, 0xD9 as f32 / 255.0, ), - Color::rgb( + Color::srgb( 0x05 as f32 / 255.0, 0x3C as f32 / 255.0, 0x5E as f32 / 255.0, ), - Color::rgb( + Color::srgb( 0x1F as f32 / 255.0, 0x7A as f32 / 255.0, 0x8C as f32 / 255.0, @@ -91,8 +91,8 @@ impl ColliderOutlineRender { /* * Joint rendering. */ -pub const DEFAULT_JOINT_ANCHOR_COLOR: Color = Color::rgb(0.0, 0.0, 1.0); -pub const DEFAULT_JOINT_SEPARATION_COLOR: Color = Color::rgb(1.0, 0.0, 1.0); +pub const DEFAULT_JOINT_ANCHOR_COLOR: Color = Color::srgb(0.0, 0.0, 1.0); +pub const DEFAULT_JOINT_SEPARATION_COLOR: Color = Color::srgb(1.0, 0.0, 1.0); #[derive(Copy, Clone, Component)] pub struct JointRender { diff --git a/src/selection/mod.rs b/src/selection/mod.rs index ff0a23b..88e2183 100644 --- a/src/selection/mod.rs +++ b/src/selection/mod.rs @@ -1,5 +1,6 @@ use bevy::app::PluginGroupBuilder; use bevy::prelude::*; +use bevy::render::view::{check_visibility, VisibilitySystems}; use bevy_rapier::prelude::*; pub use self::selection_shape::SelectionShape; @@ -50,7 +51,11 @@ impl Plugin for SelectionPlugin { fn build(&self, app: &mut App) { app.insert_resource(SelectionState::default()) .insert_resource(SceneMouse::default()) - .add_systems(Update, add_missing_selection_components); + .add_systems(Update, add_missing_selection_components) + .add_systems( + PostUpdate, + check_visibility::>.in_set(VisibilitySystems::CheckVisibility), + ); } } diff --git a/src/selection/mouse/track.rs b/src/selection/mouse/track.rs index a0544f9..53df140 100644 --- a/src/selection/mouse/track.rs +++ b/src/selection/mouse/track.rs @@ -16,7 +16,7 @@ pub fn track_mouse_state( - Vec2::ONE) * Vec2::new(1.0, -1.0); let ndc_to_world = - camera_transform.compute_matrix() * camera.projection_matrix().inverse(); + camera_transform.compute_matrix() * camera.clip_from_view().inverse(); let ray_pt1 = ndc_to_world.project_point3(Vec3::new(ndc_cursor.x, ndc_cursor.y, -1.0)); diff --git a/src/selection/transform_gizmo/assets/gizmo_material.wgsl b/src/selection/transform_gizmo/assets/gizmo_material.wgsl index 0ca7e78..3c868af 100644 --- a/src/selection/transform_gizmo/assets/gizmo_material.wgsl +++ b/src/selection/transform_gizmo/assets/gizmo_material.wgsl @@ -1,4 +1,4 @@ -#import bevy_pbr::mesh_functions::{get_model_matrix, mesh_position_local_to_clip} +#import bevy_pbr::mesh_functions::{get_world_from_local, mesh_position_local_to_clip} struct GizmoMaterial { color: vec4, @@ -20,7 +20,7 @@ struct VertexOutput { fn vertex(vertex: Vertex) -> VertexOutput { var out: VertexOutput; out.clip_position = mesh_position_local_to_clip( - get_model_matrix(vertex.instance_index), + get_world_from_local(vertex.instance_index), vec4(vertex.position, 1.0), ); return out; diff --git a/src/selection/transform_gizmo/gizmo_material.rs b/src/selection/transform_gizmo/gizmo_material.rs index 2420d19..4d246bf 100644 --- a/src/selection/transform_gizmo/gizmo_material.rs +++ b/src/selection/transform_gizmo/gizmo_material.rs @@ -3,7 +3,7 @@ use bevy::{ prelude::*, reflect::TypePath, render::{ - mesh::MeshVertexBufferLayout, + mesh::{MeshVertexBufferLayout, MeshVertexBufferLayoutRef}, render_resource::{ AsBindGroup, RenderPipelineDescriptor, ShaderRef, SpecializedMeshPipelineError, }, @@ -15,12 +15,14 @@ pub const GIZMO_SHADER_HANDLE: Handle = Handle::weak_from_u128(139538002 #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct GizmoMaterial { #[uniform(0)] - pub color: Color, + pub color: LinearRgba, } impl From for GizmoMaterial { fn from(color: Color) -> Self { - GizmoMaterial { color } + GizmoMaterial { + color: color.into(), + } } } @@ -40,7 +42,7 @@ impl Material for GizmoMaterial { fn specialize( _pipeline: &MaterialPipeline, descriptor: &mut RenderPipelineDescriptor, - _layout: &MeshVertexBufferLayout, + _layout: &MeshVertexBufferLayoutRef, _key: MaterialPipelineKey, ) -> Result<(), SpecializedMeshPipelineError> { descriptor.primitive.cull_mode = None; diff --git a/src/selection/transform_gizmo/mesh/mod.rs b/src/selection/transform_gizmo/mesh/mod.rs index 7a3238f..03c6a8a 100644 --- a/src/selection/transform_gizmo/mesh/mod.rs +++ b/src/selection/transform_gizmo/mesh/mod.rs @@ -46,7 +46,7 @@ pub fn build_gizmo( shape: Collider::ball(arc_radius), }; - let cube_mesh = meshes.add(Mesh::from(shape::Cube { size: 0.1 })); + let cube_mesh = meshes.add(Mesh::from(Cuboid::from_size(Vec3::splat(0.1)))); // Define gizmo materials let (s, l, a) = (0.45, 0.59, 1.0); @@ -195,7 +195,7 @@ pub fn build_gizmo( shape: Collider::cuboid(arc_radius / 1.5, ring_radius * 2.0, arc_radius / 1.5), }; - let cube_mesh = meshes.add(Mesh::from(shape::Cube { size: 0.1 })); + let cube_mesh = meshes.add(Mesh::from(Cuboid::from_size(Vec3::splat(0.1)))); // Define gizmo materials let (s, l, a) = (0.45, 0.59, 1.0); @@ -223,12 +223,13 @@ pub fn build_gizmo( /*let gizmo_matl_origin = materials.add(StandardMaterial { unlit: true, - base_color: Color::rgb(0.7, 0.7, 0.7), + base_color: Color::srgb(0.7, 0.7, 0.7), ..Default::default() });*/ // Build the gizmo using the variables above. commands .spawn(TransformGizmoBundle::default()) + .insert(Name::new("Transform Gizmo")) .with_children(|parent| { // Translation Handles parent @@ -310,6 +311,7 @@ pub fn build_gizmo( material: gizmo_matl_y.clone(), ..Default::default() }) + .insert(Name::new("RotateAxis")) .insert(rotation_selection.clone()) .insert(matls_y.clone()) .insert(TransformGizmoInteraction::RotateAxis { diff --git a/src/selection/transform_gizmo/mod.rs b/src/selection/transform_gizmo/mod.rs index 679425b..a2f2a94 100644 --- a/src/selection/transform_gizmo/mod.rs +++ b/src/selection/transform_gizmo/mod.rs @@ -4,6 +4,7 @@ use super::{SceneMouse, SelectableSceneObject, Selection}; use crate::parry::query; use bevy::asset::load_internal_asset; +use bevy::render::view::{check_visibility, VisibilitySystems}; use bevy::{input::InputSystem, prelude::*, transform::TransformSystem}; use bevy_rapier::dynamics::ReadMassProperties; use gizmo_material::{GizmoMaterial, GizmoStateMaterials}; @@ -140,7 +141,11 @@ impl Plugin for TransformGizmoPlugin { ) .add_systems(Startup, mesh::build_gizmo) .add_systems(PostStartup, place_gizmo) - .add_systems(Update, sync_gizmo_camera); + .add_systems(Update, sync_gizmo_camera) + .add_systems( + PostUpdate, + check_visibility::>.in_set(VisibilitySystems::CheckVisibility), + ); } } diff --git a/src/styling/color_generator.rs b/src/styling/color_generator.rs index 7088f42..46153de 100644 --- a/src/styling/color_generator.rs +++ b/src/styling/color_generator.rs @@ -17,7 +17,7 @@ impl Default for ColorGenerator { impl ColorGenerator { pub fn gen_color(&mut self) -> Color { - Color::rgb( + Color::srgb( self.rng.rand_float(), self.rng.rand_float(), self.rng.rand_float(), @@ -26,7 +26,7 @@ impl ColorGenerator { pub fn outline_color(color: Color) -> Color { if cfg!(feature = "dim2") { - let [h, s, l, a] = color.as_hsla_f32(); + let [h, s, l, a] = Hsla::from(color).to_f32_array(); Color::hsla(h, s, l * 1.2, a) } else { color @@ -42,7 +42,7 @@ impl ColorGenerator { let color = &mut self.region_colors[region]; if color.is_none() { - *color = Some(Color::rgb( + *color = Some(Color::srgb( seeded_rng.rand_float(), seeded_rng.rand_float(), seeded_rng.rand_float(), diff --git a/src/styling/plugin.rs b/src/styling/plugin.rs index 7550d3d..887b335 100644 --- a/src/styling/plugin.rs +++ b/src/styling/plugin.rs @@ -1,5 +1,5 @@ use crate::styling::ColorGenerator; -use bevy::prelude::*; +use bevy::{color::palettes, prelude::*}; use bevy_egui::egui::Visuals; pub struct StylingPlugin; @@ -26,7 +26,7 @@ impl Theme { pub fn background_color(&self) -> Color { if self.dark_mode { - Color::DARK_GRAY + palettes::css::DARK_GRAY.into() } else { Color::WHITE } @@ -42,17 +42,17 @@ impl Theme { pub fn floor_minor_line_color(&self) -> Color { if self.dark_mode { - Color::rgb(0.1, 0.1, 0.1) + Color::srgb(0.1, 0.1, 0.1) } else { - Color::rgb(0.7, 0.7, 0.7) + Color::srgb(0.7, 0.7, 0.7) } } pub fn floor_major_line_color(&self) -> Color { if self.dark_mode { - Color::rgb(0.25, 0.25, 0.25) + Color::srgb(0.25, 0.25, 0.25) } else { - Color::rgb(0.25, 0.25, 0.25) + Color::srgb(0.25, 0.25, 0.25) } } } diff --git a/src/ui/main_menu.rs b/src/ui/main_menu.rs index 8287e46..cef0c02 100644 --- a/src/ui/main_menu.rs +++ b/src/ui/main_menu.rs @@ -76,7 +76,7 @@ pub(super) fn ui( operations.push(Operation::ClearScene) } if ui.button("🚪 Exit").clicked() { - exit.send(AppExit); + exit.send(AppExit::Success); } }); }) diff --git a/src/ui/right_panel.rs b/src/ui/right_panel.rs index ba5da34..c37992f 100644 --- a/src/ui/right_panel.rs +++ b/src/ui/right_panel.rs @@ -97,7 +97,7 @@ fn scene_explorer( let is_visible = visibility .get(entity) - .map(|v| v.1 == Visibility::Visible) + .map(|v| v.1 != Visibility::Hidden) .unwrap_or(true); let visibility_icon = if is_visible { "🌑" } else { "🌕" }; if ui.button(visibility_icon).clicked() {