From 78f6b92bdc5fb811d2595ca7b46b9b353e435066 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 6 Jun 2025 17:34:32 -0700 Subject: [PATCH 01/52] Update Cargo.toml --- Cargo.toml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 82c80488..0eb4a39c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,18 @@ repository = "https://github.com/rewin123/space_editor" homepage = "https://github.com/rewin123/space_editor" [workspace.dependencies] -bevy = { version = "0.16.0"} +bevy = { version = "0.16.0", features = [ + "bevy_gltf", + "bevy_log", + "bevy_window", + "bevy_state", + "bevy_sprite", + "reflect_documentation", + "reflect_functions", + "bevy_gizmos", + "bevy_picking", + "bevy_mesh_picking_backend", +] } # Editor Crates space_prefab = { version = "0.8.0", path = "crates/prefab" } From ea644cd3752f87a80f1518f4c89b4be362284006 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 6 Jun 2025 17:43:49 -0700 Subject: [PATCH 02/52] Update lib.rs --- crates/undo/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/undo/src/lib.rs b/crates/undo/src/lib.rs index ef3265c5..867fc7b3 100644 --- a/crates/undo/src/lib.rs +++ b/crates/undo/src/lib.rs @@ -821,10 +821,8 @@ fn apply_for_every_typed_field( } bevy::reflect::ReflectMut::Set(_s) => {} bevy::reflect::ReflectMut::Opaque(_s) => {} - // bevy::reflect::ReflectMut::Function(_s) => {}, - //bevy::reflect::ReflectMut::Value(_v) => { - //do nothing. Value was checked before - //} + bevy::reflect::ReflectMut::Function(_s) => {}, + bevy::reflect::ReflectMut::Value(_v) => {} } } } From f33a759723f0734bc37fa6b5f8b3781ed8295d4a Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 6 Jun 2025 17:51:03 -0700 Subject: [PATCH 03/52] Update lib.rs --- crates/undo/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/undo/src/lib.rs b/crates/undo/src/lib.rs index 867fc7b3..b73cbe41 100644 --- a/crates/undo/src/lib.rs +++ b/crates/undo/src/lib.rs @@ -822,7 +822,7 @@ fn apply_for_every_typed_field( bevy::reflect::ReflectMut::Set(_s) => {} bevy::reflect::ReflectMut::Opaque(_s) => {} bevy::reflect::ReflectMut::Function(_s) => {}, - bevy::reflect::ReflectMut::Value(_v) => {} + //bevy::reflect::ReflectMut::Value(_v) => {} } } } From 6ce7d389551e55c1837cdfe457bec82536bce19b Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 19:52:05 -0700 Subject: [PATCH 04/52] Update camera_view.rs --- crates/editor_ui/src/camera_view.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/camera_view.rs b/crates/editor_ui/src/camera_view.rs index 3ed71fbb..d53cb511 100644 --- a/crates/editor_ui/src/camera_view.rs +++ b/crates/editor_ui/src/camera_view.rs @@ -123,7 +123,7 @@ impl EditorTab for CameraViewTab { let mut camera_query = world.query_filtered::, With, - Without, + //Without, )>(); if camera_query.iter(world).count() == 1 { From 699664ccfa6498613fd962efb402682027de742a Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:14:59 -0700 Subject: [PATCH 05/52] Update camera_view.rs --- crates/editor_ui/src/camera_view.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/editor_ui/src/camera_view.rs b/crates/editor_ui/src/camera_view.rs index d53cb511..482506ac 100644 --- a/crates/editor_ui/src/camera_view.rs +++ b/crates/editor_ui/src/camera_view.rs @@ -267,7 +267,7 @@ impl EditorTab for CameraViewTab { fn clean_camera_view_tab( mut ui_state: ResMut, - mut cameras: Query<(&mut Camera, &mut GlobalTransform), Without>, + mut cameras: Query<(&mut Camera, &mut GlobalTransform) /*, Without */ >, ) { let Some(real_cam_entity) = ui_state.real_camera else { return; @@ -296,7 +296,7 @@ fn set_camera_viewport( primary_window: Query<&mut Window, With>, mut cameras: Query< (&mut Camera, &mut GlobalTransform, &mut Transform), - Without, + //Without, >, mut ctxs: EguiContexts, images: Res>, From 32da890dc417fc7cb0e9e853616b91a102992ab1 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:45:55 -0700 Subject: [PATCH 06/52] Update camera_plugin.rs --- crates/editor_ui/src/camera_plugin.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/editor_ui/src/camera_plugin.rs b/crates/editor_ui/src/camera_plugin.rs index f8db156f..8c4f79be 100644 --- a/crates/editor_ui/src/camera_plugin.rs +++ b/crates/editor_ui/src/camera_plugin.rs @@ -81,18 +81,20 @@ pub fn update_pan_orbit( } } -type PlayModeCameraFilter = (Without, With); -type EditorModeCameraFilter = (With, Without); +//type PlayModeCameraFilter = (Without, With); +//type EditorModeCameraFilter = (With, Without); /// System to change camera from editor camera to game play camera (if exist) pub fn change_camera_in_play( - mut editor_cameras: Query<&mut Camera, EditorModeCameraFilter>, - mut play_cameras: Query<&mut Camera, PlayModeCameraFilter>, + //mut editor_cameras: Query<&mut Camera, EditorModeCameraFilter>, + //mut play_cameras: Query<&mut Camera, PlayModeCameraFilter>, + mut editor_only_cameras: Query<&mut Camera, (With, Without)>, + mut play_cameras: Query<&mut Camera, With>, primary_window: Query<&mut Window, With>, mut toast: EventWriter, ) { if !play_cameras.is_empty() { - editor_cameras.iter_mut().for_each(|mut cam| { + editor_only_cameras.iter_mut().for_each(|mut cam| { cam.is_active = false; }); play_cameras.iter_mut().for_each(|mut cam| { @@ -131,8 +133,8 @@ pub fn change_camera_in_play( /// System to change camera from game camera to editor camera (if exist) pub fn change_camera_in_editor( - mut editor_cameras: Query<&mut Camera, EditorModeCameraFilter>, - mut play_cameras: Query<&mut Camera, PlayModeCameraFilter>, + mut editor_cameras: Query<&mut Camera, With>, + mut play_only_cameras: Query<&mut Camera, (With, Without)>, ) { for mut ecam in editor_cameras.iter_mut() { ecam.is_active = true; @@ -164,7 +166,7 @@ pub fn draw_camera_gizmo( (&GlobalTransform, &Projection), ( With, - Without, + //Without, Without, Without, ), @@ -177,7 +179,7 @@ pub fn draw_camera_gizmo( let cuboid_transform = transform.with_scale(Vec3::new(1.0, 1.0, 2.0)); gizmos.cuboid(cuboid_transform, pink); - let scale = 1.5; + let scale = 0.25; gizmos.line( transform.translation, From a8b1f2a6b777fa69ebb0134d58ef18b19f6ebb9a Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 20:46:56 -0700 Subject: [PATCH 07/52] Update camera_plugin.rs --- crates/editor_ui/src/camera_plugin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/camera_plugin.rs b/crates/editor_ui/src/camera_plugin.rs index 8c4f79be..ba092514 100644 --- a/crates/editor_ui/src/camera_plugin.rs +++ b/crates/editor_ui/src/camera_plugin.rs @@ -140,7 +140,7 @@ pub fn change_camera_in_editor( ecam.is_active = true; } - for mut play_cam in play_cameras.iter_mut() { + for mut play_cam in play_only_cameras.iter_mut() { play_cam.is_active = false; } } From 54b3f080fd5918c7767467322f50c6bc6a9cbbb5 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:02:19 -0700 Subject: [PATCH 08/52] Update camera_plugin.rs --- crates/editor_ui/src/camera_plugin.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/editor_ui/src/camera_plugin.rs b/crates/editor_ui/src/camera_plugin.rs index ba092514..a3ca4959 100644 --- a/crates/editor_ui/src/camera_plugin.rs +++ b/crates/editor_ui/src/camera_plugin.rs @@ -175,11 +175,14 @@ pub fn draw_camera_gizmo( for (transform, _projection) in cameras.iter() { let pink = Color::srgb(1.0, 0.41, 0.71); + let scale = 0.4; + let scale2 = 0.4 / 1.5; + let transform = transform.compute_transform(); - let cuboid_transform = transform.with_scale(Vec3::new(1.0, 1.0, 2.0)); + let cuboid_transform = transform.with_scale(Vec3::new(1.0 * scale2, 1.0 * scale2, 2.0 * scale2)); gizmos.cuboid(cuboid_transform, pink); - let scale = 0.25; + gizmos.line( transform.translation, From 7a7de6f1a285b929c8650630fb0be250e8078bb8 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:07:18 -0700 Subject: [PATCH 09/52] Update ui_plugin.rs --- crates/editor_ui/src/ui_plugin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/ui_plugin.rs b/crates/editor_ui/src/ui_plugin.rs index c995590d..f569fc49 100644 --- a/crates/editor_ui/src/ui_plugin.rs +++ b/crates/editor_ui/src/ui_plugin.rs @@ -181,7 +181,7 @@ impl Plugin for EditorUiCore { app.add_systems( Update, ( - draw_camera_gizmo, + //draw_camera_gizmo, //draw_light_gizmo, //selection::delete_selected, ) From e707a6685b6fc6506b238dece53e48adedb78701 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 12 Jun 2025 21:09:39 -0700 Subject: [PATCH 10/52] Update ui_plugin.rs --- crates/editor_ui/src/ui_plugin.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/editor_ui/src/ui_plugin.rs b/crates/editor_ui/src/ui_plugin.rs index f569fc49..f83eafca 100644 --- a/crates/editor_ui/src/ui_plugin.rs +++ b/crates/editor_ui/src/ui_plugin.rs @@ -178,15 +178,15 @@ impl Plugin for EditorUiCore { clear_and_load_on_start, ); - app.add_systems( - Update, - ( + //app.add_systems( + // Update, + // ( //draw_camera_gizmo, //draw_light_gizmo, //selection::delete_selected, - ) - .run_if(in_state(EditorState::Editor).and(in_state(ShowEditorUi::Show))), - ); + // ) + // .run_if(in_state(EditorState::Editor).and(in_state(ShowEditorUi::Show))), + //); if self.disable_no_editor_cams { app.add_systems( From af146bf9a589e4e1c0b0286e7f8ca0dbefaf24cd Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Mon, 23 Jun 2025 11:59:57 -0700 Subject: [PATCH 11/52] Update Cargo.toml --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0eb4a39c..1ae04b37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,8 +93,9 @@ bevy-inspector-egui = {version = "0.31.0", features = [ #] } bevy_mod_billboard = { branch = "dev-0.16", git = "https://github.com/MiniMinerX/bevy_mod_billboard.git"} bevy_asset_loader = "0.23.0-rc.3" -bevy_panorbit_camera = "0.26" -# bevy_panorbit_camera = { branch = "reflect_component", git = "https://github.com/MiniMinerX/bevy_panorbit_camera.git"} +# bevy_panorbit_camera = "0.26" +bevy_panorbit_camera = { branch = "dev-0.16-reflect-cam-2", git = "https://github.com/MiniMinerX/bevy_panorbit_camera.git"} + bevy_mod_outline = {git = "https://github.com/komadori/bevy_mod_outline.git", branch = "bevy-0.16"} # below has not been updated to bevy 0.16 From 80067ea52e60a45977738bc33c25975ebfb640c1 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Mon, 23 Jun 2025 12:02:41 -0700 Subject: [PATCH 12/52] Update Cargo.toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1ae04b37..d9e80b43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,8 +93,8 @@ bevy-inspector-egui = {version = "0.31.0", features = [ #] } bevy_mod_billboard = { branch = "dev-0.16", git = "https://github.com/MiniMinerX/bevy_mod_billboard.git"} bevy_asset_loader = "0.23.0-rc.3" -# bevy_panorbit_camera = "0.26" -bevy_panorbit_camera = { branch = "dev-0.16-reflect-cam-2", git = "https://github.com/MiniMinerX/bevy_panorbit_camera.git"} +bevy_panorbit_camera = "0.26" +# bevy_panorbit_camera = { branch = "dev-0.16-reflect-cam-2", git = "https://github.com/MiniMinerX/bevy_panorbit_camera.git"} bevy_mod_outline = {git = "https://github.com/komadori/bevy_mod_outline.git", branch = "bevy-0.16"} From 40aa4aa6165c6f5209142ab48c447030ce23c136 Mon Sep 17 00:00:00 2001 From: MiniMinerX Date: Mon, 23 Jun 2025 13:24:36 -0700 Subject: [PATCH 13/52] gltf parenting test --- crates/editor_core/src/gltf_unpack.rs | 32 ++++++++++++++++++--------- crates/editor_core/src/lib.rs | 7 ++++-- crates/editor_ui/src/menu_toolbars.rs | 5 ++++- crates/shared/src/lib.rs | 5 ++++- examples/gltf_unpack_example.rs | 20 +++++++++++++---- 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/crates/editor_core/src/gltf_unpack.rs b/crates/editor_core/src/gltf_unpack.rs index 6b0deb45..0fec2a83 100644 --- a/crates/editor_core/src/gltf_unpack.rs +++ b/crates/editor_core/src/gltf_unpack.rs @@ -11,10 +11,14 @@ use super::{BackgroundTask, BackgroundTaskStorage}; /// Event to handle GLTF path pub struct EditorUnpackGltf { pub path: String, + pub parent: Option, } #[derive(Event, Clone)] -struct GltfLoaded(Handle); +struct GltfLoaded { + handle: Handle, + parent: Option, +} pub struct UnpackGltfPlugin; @@ -34,8 +38,8 @@ impl Plugin for UnpackGltfPlugin { #[reflect(Component)] struct GltfHolder(Handle); -#[derive(Resource, Default)] -struct GltfSceneQueue(Vec>); +#[derive(Resource, Default)] // Handle then parent +struct GltfSceneQueue(Vec<(Handle, Option)>); fn unpack_gltf_event( mut events: EventReader, @@ -49,7 +53,7 @@ fn unpack_gltf_event( event.path.clone(), handle.clone().untyped(), )); - queue.0.push(handle); + queue.0.push((handle, event.parent)); } events.clear(); } @@ -60,9 +64,11 @@ fn queue_push( mut events: EventWriter, assets: Res, ) { - if !queue.0.is_empty() && matches!(assets.get_load_state(&queue.0[0]), Some(LoadState::Loaded)) - { - events.write(GltfLoaded(queue.0.remove(0))); + if let Some((handle, parent)) = queue.0.first().cloned() { + if matches!(assets.get_load_state(&handle), Some(LoadState::Loaded)) { + events.write(GltfLoaded { handle, parent }); + queue.0.remove(0); + } } } @@ -86,8 +92,8 @@ fn unpack_gltf(world: &mut World) { }; let mut command_queue = CommandQueue::default(); - for gltf in loaded_scenes.iter() { - let handle: Handle = gltf.0.clone(); + for gltf_loaded in loaded_scenes.iter() { + let handle: Handle = gltf_loaded.handle.clone(); let gltf_path = if let Some(path) = handle.path() { path.clone() } else { @@ -97,7 +103,7 @@ fn unpack_gltf(world: &mut World) { let Some(gltf) = world .get_resource::>() - .and_then(|gltfs| gltfs.get(&gltf.0)) + .and_then(|gltfs| gltfs.get(&gltf_loaded.handle)) else { world.send_event(space_shared::toast::ToastMessage::new( "Gltf asset not found or empty", @@ -175,7 +181,11 @@ fn unpack_gltf(world: &mut World) { }; for root in roots.iter() { - spawn_node(&mut commands, root, gltf, &ctx); + let entity = spawn_node(&mut commands, root, gltf, &ctx); + + if let Some(parent) = gltf_loaded.parent { + commands.entity(parent).add_child(entity); + } } } diff --git a/crates/editor_core/src/lib.rs b/crates/editor_core/src/lib.rs index 640b5faa..cf714625 100644 --- a/crates/editor_core/src/lib.rs +++ b/crates/editor_core/src/lib.rs @@ -100,8 +100,11 @@ fn editor_event_listener( EditorEvent::StartGame => { start_game_state.set(EditorState::GamePrepare); } - EditorEvent::LoadGltfAsPrefab(path) => { - gltf_events.write(gltf_unpack::EditorUnpackGltf { path: path.clone() }); + EditorEvent::LoadGltfAsPrefab{path, parent} => { + gltf_events.write(gltf_unpack::EditorUnpackGltf { + path: path.clone(), + parent: *parent, + }); } } } diff --git a/crates/editor_ui/src/menu_toolbars.rs b/crates/editor_ui/src/menu_toolbars.rs index 9d53285e..8da763ad 100644 --- a/crates/editor_ui/src/menu_toolbars.rs +++ b/crates/editor_ui/src/menu_toolbars.rs @@ -479,7 +479,10 @@ pub fn top_menu( if path.starts_with("assets/") { path = path.replace("assets/", ""); - editor_events.write(EditorEvent::LoadGltfAsPrefab(path)); + editor_events.write(EditorEvent::LoadGltfAsPrefab{ + path: path, + parent: None, + }); } } } else { diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index a53bb425..e98a44bc 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -66,7 +66,10 @@ pub enum EditorPrefabPath { pub enum EditorEvent { Load(EditorPrefabPath), Save(EditorPrefabPath), - LoadGltfAsPrefab(String), + LoadGltfAsPrefab{ + path: String, + parent: Option, + }, StartGame, } diff --git a/examples/gltf_unpack_example.rs b/examples/gltf_unpack_example.rs index 085c4f40..412fa5d3 100644 --- a/examples/gltf_unpack_example.rs +++ b/examples/gltf_unpack_example.rs @@ -9,8 +9,20 @@ fn main() { .run(); } -fn setup(mut editor_events: EventWriter) { - editor_events.send(EditorEvent::LoadGltfAsPrefab( - "models/low_poly_fighter_2.gltf".to_string(), - )); +fn setup( + mut editor_events: EventWriter, + mut commands: Commands, +) { + + let test_parent = commands.spawn(( + Name::from("Test Parent"), + PrefabMarker, + Transform::default(), + Visibility::default() + )).id(); + + editor_events.write(EditorEvent::LoadGltfAsPrefab{ + path: "models/colone.glb".to_string(), + parent: Some(test_parent) + }); } From ec8cda07c1871a45e7803f03f6b770624b0bc852 Mon Sep 17 00:00:00 2001 From: MiniMinerX Date: Mon, 23 Jun 2025 21:59:12 -0700 Subject: [PATCH 14/52] fix scene filter --- assets/scenes/Scene0.scn.ron | 4 ++-- crates/prefab/src/load.rs | 25 +++++++++++++++---------- crates/prefab/src/save.rs | 7 +++++++ examples/gltf_unpack_example.rs | 5 +++++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/assets/scenes/Scene0.scn.ron b/assets/scenes/Scene0.scn.ron index 2b8b9638..4a7c9f10 100644 --- a/assets/scenes/Scene0.scn.ron +++ b/assets/scenes/Scene0.scn.ron @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ca5bc50a0083a10b30a31f79b93e57de1a6b4a4b5f1e9b2e14bd6f41fd57609 -size 3386 +oid sha256:962310783245107b44f8dbe1a1cb46e16b53d715eef8c3a3639e2df43c262e97 +size 935 diff --git a/crates/prefab/src/load.rs b/crates/prefab/src/load.rs index 04a04aee..e14b0247 100644 --- a/crates/prefab/src/load.rs +++ b/crates/prefab/src/load.rs @@ -1,4 +1,4 @@ -use bevy::prelude::*; +use bevy::{platform::collections::HashSet, prelude::*}; use bevy_scene_hook::SceneHook; use space_shared::PrefabMarker; @@ -48,15 +48,16 @@ impl Plugin for LoadPlugin { app.add_systems( Update, - load_prefab.after(bevy_scene_hook::Systems::SceneHookRunner), + ( + conflict_resolve, + load_prefab, + ApplyDeferred, + // Use the new debug system + auto_children, + ) + .chain() + .after(bevy_scene_hook::Systems::SceneHookRunner), ); - app.add_systems( - Update, - conflict_resolve - .after(bevy_scene_hook::Systems::SceneHookRunner) - .before(load_prefab), - ); - app.add_systems(Update, auto_children); } } @@ -108,7 +109,7 @@ fn load_prefab( let id = commands .spawn(DynamicSceneRoot(scene)) .insert(SceneHook::new(move |_e, cmd| { - cmd.insert(PrefabAutoChild); + cmd.insert((PrefabAutoChild)); })) .insert(PrefabAutoChild) .id(); @@ -126,6 +127,7 @@ fn conflict_resolve( } } + fn auto_children( mut commands: Commands, query: Query<(Entity, &ChildrenPrefab)>, @@ -136,12 +138,15 @@ fn auto_children( for child in children.0.iter() { if existing_entity.contains(*child) { cmds.add_child(*child); + } else { + println!("nonexistent entity"); } } cmds.remove::(); } } + #[cfg(test)] mod test { use super::*; diff --git a/crates/prefab/src/save.rs b/crates/prefab/src/save.rs index 38dacf77..d3488168 100644 --- a/crates/prefab/src/save.rs +++ b/crates/prefab/src/save.rs @@ -139,6 +139,13 @@ pub fn serialize_scene(world: &mut World) { .with_resource_filter(SceneFilter::Allowlist(HashSet::from_iter( allow_types.iter().cloned(), ))) + .with_component_filter(SceneFilter::Allowlist(HashSet::from_iter( + allow_types.iter().cloned(), + ))) + // Deny test for standard material + //.deny_component::>() + //.deny_component:: + .extract_entities(entities.iter().copied()); let scene = builder.build(); diff --git a/examples/gltf_unpack_example.rs b/examples/gltf_unpack_example.rs index 412fa5d3..6eeb7e05 100644 --- a/examples/gltf_unpack_example.rs +++ b/examples/gltf_unpack_example.rs @@ -6,6 +6,11 @@ fn main() { .add_plugins((DefaultPlugins, SpaceEditorPlugin)) .add_systems(Startup, simple_editor_setup) .add_systems(Startup, setup) + .register_type::() + //.register_type::() + //.editor_registry::() + //.editor_registry::() + .run(); } From 9710ee31580be580e6b19fec30087bc7373f96c8 Mon Sep 17 00:00:00 2001 From: MiniMinerX Date: Tue, 24 Jun 2025 12:45:38 -0700 Subject: [PATCH 15/52] MAPPING EVERYONE --- assets/scenes/Scene0.scn.ron | 4 ++-- crates/prefab/src/load.rs | 11 +++++++---- crates/prefab/src/save.rs | 33 ++++++++++++++++++++----------- crates/prefab/src/spawn_system.rs | 2 +- examples/gltf_unpack_example.rs | 4 +--- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/assets/scenes/Scene0.scn.ron b/assets/scenes/Scene0.scn.ron index 4a7c9f10..d77da3b3 100644 --- a/assets/scenes/Scene0.scn.ron +++ b/assets/scenes/Scene0.scn.ron @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:962310783245107b44f8dbe1a1cb46e16b53d715eef8c3a3639e2df43c262e97 -size 935 +oid sha256:66a681b43b6ad13a656517110cdc18ac1ddec035844dbf43f0e629fbbbf1c9fd +size 1461 diff --git a/crates/prefab/src/load.rs b/crates/prefab/src/load.rs index e14b0247..e29bdf40 100644 --- a/crates/prefab/src/load.rs +++ b/crates/prefab/src/load.rs @@ -52,7 +52,6 @@ impl Plugin for LoadPlugin { conflict_resolve, load_prefab, ApplyDeferred, - // Use the new debug system auto_children, ) .chain() @@ -103,7 +102,7 @@ fn load_prefab( } commands.entity(e).remove::(); } - + let scene: Handle = assets.load(&l.path); let id = commands @@ -115,6 +114,8 @@ fn load_prefab( .id(); commands.entity(e).add_children(&[id]); + + } } @@ -127,7 +128,7 @@ fn conflict_resolve( } } - + fn auto_children( mut commands: Commands, query: Query<(Entity, &ChildrenPrefab)>, @@ -135,7 +136,8 @@ fn auto_children( ) { for (e, children) in query.iter() { let mut cmds = commands.entity(e); - for child in children.0.iter() { + for child in children.entities.iter() { + println!("Adding child: {:?}", child); if existing_entity.contains(*child) { cmds.add_child(*child); } else { @@ -147,6 +149,7 @@ fn auto_children( } + #[cfg(test)] mod test { use super::*; diff --git a/crates/prefab/src/save.rs b/crates/prefab/src/save.rs index d3488168..14589892 100644 --- a/crates/prefab/src/save.rs +++ b/crates/prefab/src/save.rs @@ -6,28 +6,39 @@ use std::{any::TypeId, fs, io::Write}; use crate::prelude::{EditorRegistry, EditorRegistryExt, SceneAutoChild}; -#[derive(Reflect, Default, Component, Clone)] +#[derive(Reflect, Default, Component, Clone, MapEntities)] #[reflect(Component, MapEntities)] /// Component that holds children entity/prefab information /// that should be serialized -pub struct ChildrenPrefab(pub Vec); +pub struct ChildrenPrefab{ + #[entities] + pub entities: Vec, +} impl ChildrenPrefab { pub fn from_children(children: &Children) -> Self { - Self(children.to_vec()) + ChildrenPrefab { + entities: children.to_vec(), + } } } +/* impl MapEntities for ChildrenPrefab { #[cfg(not(tarpaulin_include))] fn map_entities(&mut self, entity_mapper: &mut M) { - self.0 = self - .0 - .iter() - .map(|e| entity_mapper.get_mapped(*e)) - .collect(); + // ================================================================================= + // DIAGNOSTIC LOGS: Check your console for these messages when loading a prefab. + // ================================================================================= + warn!("ChildrenPrefab::map_entities CALLED. This is a good sign!"); + for entity in self.0.iter_mut() { + let old_id = *entity; + *entity = entity_mapper.get_mapped(old_id); + info!(" Mapping child {:?} -> {:?}", old_id, *entity); + } } } + */ struct SaveResourcesPrefabPlugin; @@ -319,11 +330,11 @@ mod tests { let child_id = commands.spawn_empty().id(); commands .spawn(PrefabMarker) - .insert(ChildrenPrefab(vec![child_id])); + .insert(ChildrenPrefab{entities: vec![child_id]}); let child_id = commands.spawn_empty().id(); commands .spawn(PrefabMarker) - .insert(ChildrenPrefab(vec![child_id])); + .insert(ChildrenPrefab{entities: vec![child_id]}); commands.spawn(PrefabMarker); }) .add_systems(Update, delete_prepared_children); @@ -345,7 +356,7 @@ mod tests { let children = query.single(&world).unwrap(); let prefab = ChildrenPrefab::from_children(children); - assert_eq!(prefab.0.len(), 1); + assert_eq!(prefab.entities.len(), 1); } #[test] diff --git a/crates/prefab/src/spawn_system.rs b/crates/prefab/src/spawn_system.rs index a98bb3fa..c33b6522 100644 --- a/crates/prefab/src/spawn_system.rs +++ b/crates/prefab/src/spawn_system.rs @@ -85,7 +85,7 @@ fn recursive_path( entity: Entity, path: Vec, ) { - // commands.entity(entity).insert(ChildPath(path.clone())); + //commands.entity(entity).insert(ChildPath(path.clone())); if let Ok(children) = q_children.get(entity) { for (i, child_entity) in children.iter().enumerate() { diff --git a/examples/gltf_unpack_example.rs b/examples/gltf_unpack_example.rs index 6eeb7e05..7fe361f6 100644 --- a/examples/gltf_unpack_example.rs +++ b/examples/gltf_unpack_example.rs @@ -7,9 +7,7 @@ fn main() { .add_systems(Startup, simple_editor_setup) .add_systems(Startup, setup) .register_type::() - //.register_type::() - //.editor_registry::() - //.editor_registry::() + .run(); } From fb309a29aeab81815e77f741d58ecfd2b632f67e Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 24 Jun 2025 23:31:23 -0700 Subject: [PATCH 16/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 447362db..64cec584 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -130,9 +130,9 @@ impl Plugin for BasePrefabPlugin { app.register_type::(); //camera - app.editor_registry::(); - app.editor_registry::(); - app.editor_registry::(); + //app.editor_registry::(); + //app.editor_registry::(); + //app.editor_registry::(); app.editor_registry::(); //app.editor_registry::(); app.editor_registry::(); From 3709002124c7a0db6f3824516feb9231e121c9ff Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:44:35 -0700 Subject: [PATCH 17/52] Update hierarchy.rs --- crates/editor_ui/src/hierarchy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/hierarchy.rs b/crates/editor_ui/src/hierarchy.rs index 4f46ce9a..151a70db 100644 --- a/crates/editor_ui/src/hierarchy.rs +++ b/crates/editor_ui/src/hierarchy.rs @@ -162,7 +162,7 @@ fn draw_entity( CollapsingState::load_with_default_open( ui.ctx(), ui.make_persistent_id(entity_name.clone()), - true, + false, ) .show_header(ui, |ui| { let mut entity_name = egui::RichText::new(entity_name.clone()); From 2168995bf406ba6a4ab3c5352a02c2d664a7c907 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 25 Jun 2025 16:45:34 -0700 Subject: [PATCH 18/52] Update Cargo.toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d9e80b43..e63592fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,8 +100,8 @@ bevy_mod_outline = {git = "https://github.com/komadori/bevy_mod_outline.git", br # below has not been updated to bevy 0.16 -transform-gizmo-bevy = {git = "https://github.com/jakobhellermann/transform-gizmo.git", branch = "bevy-0.16", package = "transform-gizmo-bevy"} -transform-gizmo-egui = {git = "https://github.com/jakobhellermann/transform-gizmo.git", branch = "bevy-0.16", package = "transform-gizmo-egui"} +#transform-gizmo-bevy = {git = "https://github.com/jakobhellermann/transform-gizmo.git", branch = "bevy-0.16", package = "transform-gizmo-bevy"} +#transform-gizmo-egui = {git = "https://github.com/jakobhellermann/transform-gizmo.git", branch = "bevy-0.16", package = "transform-gizmo-egui"} #transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo.git"} From b8e75084cd184acf85aca65a7f094c759b47a4b2 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 25 Jun 2025 16:49:39 -0700 Subject: [PATCH 19/52] Update Cargo.toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e63592fd..2e1a5c54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,8 +100,8 @@ bevy_mod_outline = {git = "https://github.com/komadori/bevy_mod_outline.git", br # below has not been updated to bevy 0.16 -#transform-gizmo-bevy = {git = "https://github.com/jakobhellermann/transform-gizmo.git", branch = "bevy-0.16", package = "transform-gizmo-bevy"} -#transform-gizmo-egui = {git = "https://github.com/jakobhellermann/transform-gizmo.git", branch = "bevy-0.16", package = "transform-gizmo-egui"} +transform-gizmo-bevy = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-bevy-0.16"} +transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-bevy-0.16"} #transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo.git"} From 26777ad6e4f2bc5a6373cd121c54ad57bbd70733 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 25 Jun 2025 22:08:29 -0700 Subject: [PATCH 20/52] Update Cargo.toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2e1a5c54..3cb77310 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,8 +100,8 @@ bevy_mod_outline = {git = "https://github.com/komadori/bevy_mod_outline.git", br # below has not been updated to bevy 0.16 -transform-gizmo-bevy = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-bevy-0.16"} -transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-bevy-0.16"} +transform-gizmo-bevy = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-0.16-2"} +transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-0.16-2"} #transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo.git"} From ac52ec2df59a191b885cc5b5cdab95a8b3ae36ff Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:53:22 -0700 Subject: [PATCH 21/52] Update Cargo.toml --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3cb77310..8c7f686a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,8 +100,8 @@ bevy_mod_outline = {git = "https://github.com/komadori/bevy_mod_outline.git", br # below has not been updated to bevy 0.16 -transform-gizmo-bevy = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-0.16-2"} -transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-0.16-2"} +transform-gizmo-bevy = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-0.16-3"} +transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo", branch = "dev-0.16-3"} #transform-gizmo-egui = {git = "https://github.com/MiniMinerX/transform-gizmo.git"} From 85e92eb29733a78c5b0357c6c5119f5570724313 Mon Sep 17 00:00:00 2001 From: MiniMinerX Date: Mon, 30 Jun 2025 15:45:34 -0700 Subject: [PATCH 22/52] some picking stuff --- Cargo.lock | 13 +++++----- Cargo.toml | 1 + crates/editor_game_view/src/lib.rs | 8 +++---- crates/editor_ui/src/selection.rs | 7 ++++++ examples/space_example.rs | 38 +++++++++++++++++++++++++++++- 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a68f36cc..49d54cad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5270,6 +5270,7 @@ dependencies = [ "space_editor_game_view", "space_editor_ui", "space_prefab", + "transform-gizmo-bevy", "workspace-hakari", ] @@ -5821,8 +5822,8 @@ dependencies = [ [[package]] name = "transform-gizmo" -version = "0.5.0" -source = "git+https://github.com/jakobhellermann/transform-gizmo.git?branch=bevy-0.16#a1fbba9c06f8817f4cf041104dadf55c801c9fcc" +version = "0.6.0" +source = "git+https://github.com/MiniMinerX/transform-gizmo?branch=dev-0.16-3#55559e6dfcf02a54e4a06c2d9ff873fbcbd2f5cd" dependencies = [ "ahash", "ecolor", @@ -5836,8 +5837,8 @@ dependencies = [ [[package]] name = "transform-gizmo-bevy" -version = "0.5.0" -source = "git+https://github.com/jakobhellermann/transform-gizmo.git?branch=bevy-0.16#a1fbba9c06f8817f4cf041104dadf55c801c9fcc" +version = "0.6.0" +source = "git+https://github.com/MiniMinerX/transform-gizmo?branch=dev-0.16-3#55559e6dfcf02a54e4a06c2d9ff873fbcbd2f5cd" dependencies = [ "bevy_app", "bevy_asset", @@ -5863,8 +5864,8 @@ dependencies = [ [[package]] name = "transform-gizmo-egui" -version = "0.5.0" -source = "git+https://github.com/jakobhellermann/transform-gizmo.git?branch=bevy-0.16#a1fbba9c06f8817f4cf041104dadf55c801c9fcc" +version = "0.6.0" +source = "git+https://github.com/MiniMinerX/transform-gizmo?branch=dev-0.16-3#55559e6dfcf02a54e4a06c2d9ff873fbcbd2f5cd" dependencies = [ "egui", "transform-gizmo", diff --git a/Cargo.toml b/Cargo.toml index 8c7f686a..fae1a794 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,6 +118,7 @@ bevy.workspace = true space_editor_ui.workspace = true space_prefab.workspace = true game_app.workspace = true +transform-gizmo-bevy.workspace = true # Tabs space_editor_game_view.workspace = true diff --git a/crates/editor_game_view/src/lib.rs b/crates/editor_game_view/src/lib.rs index b45667c6..1165dd5e 100644 --- a/crates/editor_game_view/src/lib.rs +++ b/crates/editor_game_view/src/lib.rs @@ -214,10 +214,10 @@ pub fn set_camera_viewport( local.0 = Some(viewport_rect); let scale_factor = window.scale_factor(); - debug!( - "Window scale factor: {} egui scale factor: {}", - scale_factor, context_settings.scale_factor - ); + //debug!( + // "Window scale factor: {} egui scale factor: {}", + // scale_factor, context_settings.scale_factor + //); let mut viewport_pos = viewport_rect.left_top().to_vec2() * scale_factor; let mut viewport_size = viewport_rect.size() * scale_factor; diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index a21d2b46..3b45d704 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -1,5 +1,6 @@ use crate::*; use bevy::{color::palettes::tailwind::{PINK_100, RED_500}, picking::pointer::PointerInteraction, prelude::*}; +use transform_gizmo_bevy::GizmoTarget; @@ -119,7 +120,11 @@ pub fn select_listener( parents: Query<&ChildOf>, pan_orbit_state: ResMut, keyboard: Res>, + gizmo_query: Query<&GizmoTarget>, ) { + if gizmo_query.iter().any(|gizmo| gizmo.is_active()) { + return; + } if !pan_orbit_state.0 { trigger.propagate(false); @@ -142,6 +147,8 @@ pub fn select_listener( } + + /// This event used for selecting entities #[derive(Event, Clone)] pub struct SelectEvent; diff --git a/examples/space_example.rs b/examples/space_example.rs index 56afbb67..7aec31c0 100644 --- a/examples/space_example.rs +++ b/examples/space_example.rs @@ -5,13 +5,49 @@ use bevy::{ use ext::bevy_inspector_egui::quick::WorldInspectorPlugin; use space_editor::prelude::*; +use space_editor_game_view::gizmo_tool; +use space_editor_ui::ext::bevy_panorbit_camera::PanOrbitCamera; +use transform_gizmo_bevy::{mouse_interact::MouseGizmoInteractionPlugin, picking::TransformGizmoPickingPlugin, GizmoCamera, GizmoTarget, TransformGizmoPlugin}; + fn main() { App::default() .add_plugins(DefaultPlugins.set(LogPlugin { - level: Level::TRACE, + level: Level::DEBUG, ..default() })) .add_plugins(SpaceEditorPlugin) .add_systems(Startup, simple_editor_setup) + + .add_plugins(TransformGizmoPlugin) + + .add_systems( + Update, + disable_pan_orbit_on_gizmo + .after(update_pan_orbit) + .in_set(EditorSet::Editor), + ) + + .register_type::() + .register_type::() + .editor_registry::() + .editor_registry::() + .register_type::() + .run(); } + + +fn disable_pan_orbit_on_gizmo( + mut pan_orbit_cams: Query<&mut PanOrbitCamera, With>, + gizmo_targets: Query<&GizmoTarget>, +) { + for mut cam in pan_orbit_cams.iter_mut() { + for gizmo_target in gizmo_targets.iter() { + if gizmo_target.is_active() { + cam.enabled = false; + //debug!("Disabling PanOrbitCamera for GizmoTarget: {:?}", gizmo_target); + return; + } + } + } +} From 079bef4573486416e6eea3ddc481f20c2c68b650 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:41:44 -0700 Subject: [PATCH 23/52] Update lib.rs --- crates/editor_ui/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/editor_ui/src/lib.rs b/crates/editor_ui/src/lib.rs index 8eee1913..ef0e2b48 100644 --- a/crates/editor_ui/src/lib.rs +++ b/crates/editor_ui/src/lib.rs @@ -139,6 +139,9 @@ pub mod prelude { pub use crate::EditorPlugin; pub use crate::editor_tab_name::*; + + // Game editor tab egui editing + pub use space_edtior_game_view::GameViewTab; } /// External dependencies for editor crate From 25660b916f41a8bf7e798861f01d8f926a2e0f7e Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 1 Aug 2025 13:59:21 -0700 Subject: [PATCH 24/52] Update lib.rs --- crates/editor_ui/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/lib.rs b/crates/editor_ui/src/lib.rs index ef0e2b48..45decc1a 100644 --- a/crates/editor_ui/src/lib.rs +++ b/crates/editor_ui/src/lib.rs @@ -141,7 +141,7 @@ pub mod prelude { pub use crate::editor_tab_name::*; // Game editor tab egui editing - pub use space_edtior_game_view::GameViewTab; + pub use space_editor_game_view::GameViewTab; } /// External dependencies for editor crate From 4bd855299297b491afff0b463af5898a78bd1f36 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 1 Aug 2025 14:01:34 -0700 Subject: [PATCH 25/52] Update lib.rs --- crates/editor_ui/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/editor_ui/src/lib.rs b/crates/editor_ui/src/lib.rs index 45decc1a..95809c56 100644 --- a/crates/editor_ui/src/lib.rs +++ b/crates/editor_ui/src/lib.rs @@ -140,8 +140,7 @@ pub mod prelude { pub use crate::editor_tab_name::*; - // Game editor tab egui editing - pub use space_editor_game_view::GameViewTab; + } /// External dependencies for editor crate From 969a550e15adc2f0e403c0dcb7e25288c4c68941 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Fri, 1 Aug 2025 14:01:44 -0700 Subject: [PATCH 26/52] Update lib.rs --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ded18708..9d3b085a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,8 @@ pub mod prelude { pub use crate::SpaceEditorPlugin; pub use space_editor_ui::prelude::*; + // Game editor tab egui editing + pub use space_editor_game_view::GameViewTab; } pub use space_editor_ui; From 80728d74ef5175de3e314e8fc027b6fd553ede3a Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sat, 9 Aug 2025 19:13:57 -0700 Subject: [PATCH 27/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index 3b45d704..7cbe74f8 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -26,7 +26,7 @@ pub fn plugin(app: &mut App) { app.add_event::(); app.add_observer(select_listener); - app.add_observer(recursive_add_markers); + //app.add_observer(recursive_add_markers); app.insert_resource(MeshPickingSettings { require_markers: false, From c3a8b033cb4aca8fe3c189431aa6479e274eb69d Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sat, 9 Aug 2025 19:44:40 -0700 Subject: [PATCH 28/52] Update lib.rs --- crates/undo/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/undo/src/lib.rs b/crates/undo/src/lib.rs index b73cbe41..d5a7f5e7 100644 --- a/crates/undo/src/lib.rs +++ b/crates/undo/src/lib.rs @@ -26,6 +26,7 @@ impl Plugin for UndoPlugin { app.add_event::(); app.add_event::(); + /* app.configure_sets( PostUpdate, (UndoSet::PerType, UndoSet::UpdateAll, UndoSet::Remapping) @@ -44,6 +45,7 @@ impl Plugin for UndoPlugin { .chain() .in_set(UndoSet::UpdateAll), ); + */ } } From d9330f54f4f53877f1a9a9071ce12cbd57a6d1f2 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sat, 9 Aug 2025 19:59:15 -0700 Subject: [PATCH 29/52] Update lib.rs --- crates/editor_core/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/editor_core/src/lib.rs b/crates/editor_core/src/lib.rs index cf714625..36511577 100644 --- a/crates/editor_core/src/lib.rs +++ b/crates/editor_core/src/lib.rs @@ -51,8 +51,8 @@ impl Plugin for EditorCore { app.add_systems(Update, editor_event_listener); //app.auto_reflected_undo::(); - app.auto_reflected_undo::(); - app.auto_undo::(); + //app.auto_reflected_undo::(); + //app.auto_undo::(); } } From 8db69dfceb04b492c7ae476bde540487255cdb3c Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sat, 9 Aug 2025 20:00:06 -0700 Subject: [PATCH 30/52] Update mod.rs --- crates/prefab/src/editor_registry/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/prefab/src/editor_registry/mod.rs b/crates/prefab/src/editor_registry/mod.rs index 5c8dfdc8..60908bf9 100644 --- a/crates/prefab/src/editor_registry/mod.rs +++ b/crates/prefab/src/editor_registry/mod.rs @@ -309,7 +309,7 @@ impl EditorRegistryExt for App { self.world_mut().register_component::(); self.register_type::(); - self.auto_reflected_undo::(); + //self.auto_reflected_undo::(); self } From eeaac36eb80798327dc40110f931cecdc786e2dd Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 13:03:54 -0700 Subject: [PATCH 31/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index 7cbe74f8..d76a5d40 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -15,7 +15,7 @@ pub fn plugin(app: &mut App) { app.add_systems( Update, - (delete_selected, reemit_pointer_click, auto_add_markers) + (delete_selected, reemit_pointer_click) //, auto_add_markers) ); app.add_systems( From 6bedd1becd0b78e4f39d96f1d8b8f0d0eabf312b Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:10:21 -0700 Subject: [PATCH 32/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index d76a5d40..7cbe74f8 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -15,7 +15,7 @@ pub fn plugin(app: &mut App) { app.add_systems( Update, - (delete_selected, reemit_pointer_click) //, auto_add_markers) + (delete_selected, reemit_pointer_click, auto_add_markers) ); app.add_systems( From c8786a232bba45bc460a1bc70ec0a9a9dd66bc48 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:12:13 -0700 Subject: [PATCH 33/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index 7cbe74f8..bb1de6c6 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -10,7 +10,7 @@ pub fn plugin(app: &mut App) { app.add_plugins(MeshPickingPlugin); } - app.add_observer(on_pointer_click); + //app.add_observer(on_pointer_click); app.add_systems( From 4bed95bce6a1d7296552f405eab4f1ee8ceb8d10 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:13:18 -0700 Subject: [PATCH 34/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index bb1de6c6..112f460e 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -25,7 +25,7 @@ pub fn plugin(app: &mut App) { app.add_event::(); - app.add_observer(select_listener); + //app.add_observer(select_listener); //app.add_observer(recursive_add_markers); app.insert_resource(MeshPickingSettings { From c893b1dd846173d05929edaac662e5ebe1059a02 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:57:56 -0700 Subject: [PATCH 35/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index 112f460e..32151187 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -29,7 +29,7 @@ pub fn plugin(app: &mut App) { //app.add_observer(recursive_add_markers); app.insert_resource(MeshPickingSettings { - require_markers: false, + require_markers: true, ray_cast_visibility: RayCastVisibility::Any }); } From 39e76eb667b02727796562a90f727c1a027fe543 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 17:59:52 -0700 Subject: [PATCH 36/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index 32151187..724474f9 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -30,7 +30,7 @@ pub fn plugin(app: &mut App) { app.insert_resource(MeshPickingSettings { require_markers: true, - ray_cast_visibility: RayCastVisibility::Any + ray_cast_visibility: RayCastVisibility::VisibleInView }); } From 8120cee23811244a685c46ab3463959afa0fccf2 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Sun, 10 Aug 2025 22:31:59 -0700 Subject: [PATCH 37/52] Update selection.rs --- crates/editor_ui/src/selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/editor_ui/src/selection.rs b/crates/editor_ui/src/selection.rs index 724474f9..9fa1eb0f 100644 --- a/crates/editor_ui/src/selection.rs +++ b/crates/editor_ui/src/selection.rs @@ -15,7 +15,7 @@ pub fn plugin(app: &mut App) { app.add_systems( Update, - (delete_selected, reemit_pointer_click, auto_add_markers) + (delete_selected, reemit_pointer_click)// auto_add_markers) ); app.add_systems( From 63f38adbc513fca08e221ee2cc43b6b5e4b763f5 Mon Sep 17 00:00:00 2001 From: MiniMinerX Date: Tue, 12 Aug 2025 15:48:20 -0700 Subject: [PATCH 38/52] hierarchies --- .gitignore | 3 +- assets/scenes/Scene0.scn.ron | 4 +- crates/editor_ui/src/hierarchy.rs | 83 +++++++++++++++++-------------- 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index fa4b5bde..92422ca1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ docs/.obsidian/* editor.ron .idea/* crates/prefab/test*.ron -**/.DS_Store \ No newline at end of file +**/.DS_Store +assets/models/TrackATest1_sp.glb \ No newline at end of file diff --git a/assets/scenes/Scene0.scn.ron b/assets/scenes/Scene0.scn.ron index d77da3b3..048c18c8 100644 --- a/assets/scenes/Scene0.scn.ron +++ b/assets/scenes/Scene0.scn.ron @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:66a681b43b6ad13a656517110cdc18ac1ddec035844dbf43f0e629fbbbf1c9fd -size 1461 +oid sha256:979ff68eb678794704172be125d51654943d87b65a8f03e67a8c58c98d88dd48 +size 40067 diff --git a/crates/editor_ui/src/hierarchy.rs b/crates/editor_ui/src/hierarchy.rs index 151a70db..0a667c2c 100644 --- a/crates/editor_ui/src/hierarchy.rs +++ b/crates/editor_ui/src/hierarchy.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use bevy::{ecs::query::QueryFilter, platform::collections::HashMap, prelude::*}; use bevy_egui::{ - egui::{collapsing_header::CollapsingState, TextEdit}, + egui::{collapsing_header::CollapsingState, TextEdit, TextStyle}, *, }; use space_editor_core::prelude::*; @@ -70,12 +70,6 @@ pub fn show_hierarchy( mut state: ResMut, auto_children: Query<(), With>, ) { - let mut all: Vec<_> = if state.show_editor_entities { - all_entities.iter().collect() - } else { - query.iter().collect() - }; - all.sort_by_key(|a| a.0); let ui = &mut ui.0; ui.horizontal(|ui| { let button_size = ui @@ -95,41 +89,58 @@ pub fn show_hierarchy( ui.spacing(); let lower_filter = state.entity_filter.to_lowercase(); - egui::ScrollArea::vertical().show(ui, |ui| { - for (entity, _name, _children, parent) in all.iter().filter(|(_, name, _, _)| { + // Collect and filter entities once + let filtered_entities: Vec<_> = if state.show_editor_entities { + all_entities.iter().filter(|(_, name, _, parent)| { + parent.is_none() && // Only root entities name.map(|n| n.to_lowercase()) .unwrap_or_else(|| "entity".to_string()) .contains(&lower_filter) - }) { - if parent.is_none() { - if state.show_editor_entities { - draw_entity::<()>( - &mut commands, - ui, - &all_entities, - *entity, - &mut selected, - &mut clone_events, - &mut changes, - &auto_children, - ); - } else { - draw_entity::>( - &mut commands, - ui, - &query, - *entity, - &mut selected, - &mut clone_events, - &mut changes, - &auto_children, - ); + }).collect() + } else { + query.iter().filter(|(_, name, _, parent)| { + parent.is_none() && // Only root entities + name.map(|n| n.to_lowercase()) + .unwrap_or_else(|| "entity".to_string()) + .contains(&lower_filter) + }).collect() + }; + // Use virtual scrolling for performance + let text_style = TextStyle::Body; + let row_height = ui.text_style_height(&text_style); + + egui::ScrollArea::vertical() + .auto_shrink(false) + .show_rows(ui, row_height, filtered_entities.len(), |ui, row_range| { + for row in row_range { + if let Some((entity, _name, _children, _parent)) = filtered_entities.get(row) { + if state.show_editor_entities { + draw_entity::<()>( + &mut commands, + ui, + &all_entities, + *entity, + &mut selected, + &mut clone_events, + &mut changes, + &auto_children, + ); + } else { + draw_entity::>( + &mut commands, + ui, + &query, + *entity, + &mut selected, + &mut clone_events, + &mut changes, + &auto_children, + ); + } } } - } - }); + }); } - type DrawIter<'a> = ( Entity, Option<&'a Name>, From d75a929b9dd640f0cb63733d3327ed856829e136 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:44:59 -0700 Subject: [PATCH 39/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 102 ++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 8 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 64cec584..deb32a6d 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -113,16 +113,22 @@ impl Plugin for BasePrefabPlugin { app.register_type::(); app.editor_registry::(); - app.add_systems( - Update, - sync_asset_mesh.in_set(PrefabSet::DetectPrefabChange), - ); + //app.add_systems( + // Update, + // sync_asset_mesh.in_set(PrefabSet::DetectPrefabChange), + //); + app.add_observer(on_asset_mesh_added); + //app.add_observer(on_asset_mesh_changed); + app.add_observer(on_asset_mesh_removed); app.editor_registry::(); - app.add_systems( - Update, - sync_asset_material.in_set(PrefabSet::DetectPrefabChange), - ); + //app.add_systems( + // Update, + // sync_asset_material.in_set(PrefabSet::DetectPrefabChange), + //); + app.add_observer(on_asset_material_added); + //app.add_observer(on_asset_material_changed); + app.add_observer(on_asset_material_removed); //material registration app.register_type::(); @@ -350,6 +356,86 @@ fn sync_asset_material( } } +// AssetMesh observers +fn on_asset_mesh_added( + trigger: Trigger, + mut commands: Commands, + query: Query<&AssetMesh>, + assets: Res, +) { + let entity = trigger.target(); + if let Ok(asset_mesh) = query.get(entity) { + info!("Loading mesh for entity {:?}: {}", entity, asset_mesh.path); + commands.entity(entity).insert(assets.load::(&asset_mesh.path)); + } +} + +/* +fn on_asset_mesh_changed( + trigger: Trigger, + mut commands: Commands, + query: Query<&AssetMesh>, + assets: Res, +) { + let entity = trigger.target(); + if let Ok(asset_mesh) = query.get(entity) { + info!("Updating mesh for entity {:?}: {}", entity, asset_mesh.path); + commands.entity(entity).insert(assets.load::(&asset_mesh.path)); + } +} +*/ + +fn on_asset_mesh_removed( + trigger: Trigger, + mut commands: Commands, +) { + let entity = trigger.target(); + if let Some(mut cmd) = commands.get_entity(entity) { + cmd.remove::>(); + info!("Removed mesh handle for entity {:?}", entity); + } +} + +// AssetMaterial observers +fn on_asset_material_added( + trigger: Trigger, + mut commands: Commands, + query: Query<&AssetMaterial>, + assets: Res, +) { + let entity = trigger.target(); + if let Ok(asset_material) = query.get(entity) { + info!("Loading material for entity {:?}: {}", entity, asset_material.path); + commands.entity(entity).insert(assets.load::(&asset_material.path)); + } +} + +/* +fn on_asset_material_changed( + trigger: Trigger, + mut commands: Commands, + query: Query<&AssetMaterial>, + assets: Res, +) { + let entity = trigger.entity(); + if let Ok(asset_material) = query.get(entity) { + info!("Updating material for entity {:?}: {}", entity, asset_material.path); + commands.entity(entity).insert(assets.load::(&asset_material.path)); + } +} +*/ + +fn on_asset_material_removed( + trigger: Trigger, + mut commands: Commands, +) { + let entity = trigger.target(); + if let Some(mut cmd) = commands.get_entity(entity) { + cmd.remove::>(); + info!("Removed material handle for entity {:?}", entity); + } +} + #[cfg(test)] mod test { use super::*; From 2f6ed819d4e13c4b8b9e51748f6a2e9157bcdbdd Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:49:24 -0700 Subject: [PATCH 40/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index deb32a6d..4ac58aba 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -366,11 +366,10 @@ fn on_asset_mesh_added( let entity = trigger.target(); if let Ok(asset_mesh) = query.get(entity) { info!("Loading mesh for entity {:?}: {}", entity, asset_mesh.path); - commands.entity(entity).insert(assets.load::(&asset_mesh.path)); + commands.entity(entity).insert(Mesh3d(assets.load::(&asset_mesh.path))); } } -/* fn on_asset_mesh_changed( trigger: Trigger, mut commands: Commands, @@ -380,10 +379,9 @@ fn on_asset_mesh_changed( let entity = trigger.target(); if let Ok(asset_mesh) = query.get(entity) { info!("Updating mesh for entity {:?}: {}", entity, asset_mesh.path); - commands.entity(entity).insert(assets.load::(&asset_mesh.path)); + commands.entity(entity).insert(Mesh3d(assets.load::(&asset_mesh.path))); } } -*/ fn on_asset_mesh_removed( trigger: Trigger, @@ -391,7 +389,7 @@ fn on_asset_mesh_removed( ) { let entity = trigger.target(); if let Some(mut cmd) = commands.get_entity(entity) { - cmd.remove::>(); + cmd.remove::(); info!("Removed mesh handle for entity {:?}", entity); } } @@ -406,24 +404,26 @@ fn on_asset_material_added( let entity = trigger.target(); if let Ok(asset_material) = query.get(entity) { info!("Loading material for entity {:?}: {}", entity, asset_material.path); - commands.entity(entity).insert(assets.load::(&asset_material.path)); + commands.entity(entity).insert(MeshMaterial3d( + assets.load::(&asset_material.path), + )); } } -/* fn on_asset_material_changed( trigger: Trigger, mut commands: Commands, query: Query<&AssetMaterial>, assets: Res, ) { - let entity = trigger.entity(); + let entity = trigger.target(); if let Ok(asset_material) = query.get(entity) { info!("Updating material for entity {:?}: {}", entity, asset_material.path); - commands.entity(entity).insert(assets.load::(&asset_material.path)); + commands.entity(entity).insert(MeshMaterial3d( + assets.load::(&asset_material.path), + )); } } -*/ fn on_asset_material_removed( trigger: Trigger, @@ -431,7 +431,7 @@ fn on_asset_material_removed( ) { let entity = trigger.target(); if let Some(mut cmd) = commands.get_entity(entity) { - cmd.remove::>(); + cmd.remove::>(); info!("Removed material handle for entity {:?}", entity); } } From 2bb0142a20b12ccbadc6d4a18aab17b7a362a5e6 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:50:16 -0700 Subject: [PATCH 41/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 4ac58aba..ee34b61b 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -388,7 +388,7 @@ fn on_asset_mesh_removed( mut commands: Commands, ) { let entity = trigger.target(); - if let Some(mut cmd) = commands.get_entity(entity) { + if let Ok(mut cmd) = commands.get_entity(entity) { cmd.remove::(); info!("Removed mesh handle for entity {:?}", entity); } @@ -430,7 +430,7 @@ fn on_asset_material_removed( mut commands: Commands, ) { let entity = trigger.target(); - if let Some(mut cmd) = commands.get_entity(entity) { + if let Ok(mut cmd) = commands.get_entity(entity) { cmd.remove::>(); info!("Removed material handle for entity {:?}", entity); } From 38ec0218f26f6205cc88cf9af705efa363ebee8f Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:13:47 -0700 Subject: [PATCH 42/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 52 +++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index ee34b61b..9419e5ac 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -17,6 +17,12 @@ use load::*; use save::*; use spawn_system::*; +#[derive(Resource, Default)] +pub struct AssetCache { + meshes: HashMap>, + materials: HashMap>, +} + /// This plugin contains all components and logic of prefabs pub struct PrefabPlugin; @@ -33,6 +39,7 @@ impl Plugin for BasePrefabPlugin { #[cfg(not(tarpaulin_include))] fn build(&self, app: &mut App) { app.init_state::(); + app.insert_resource(AssetCache::Default()); if !app.is_plugin_added::() { app.add_plugins(HookPlugin); @@ -356,17 +363,29 @@ fn sync_asset_material( } } -// AssetMesh observers fn on_asset_mesh_added( trigger: Trigger, mut commands: Commands, - query: Query<&AssetMesh>, + query: Query<(&AssetMesh, Option<&Mesh3d>)>, assets: Res, + mut cache: ResMut, ) { let entity = trigger.target(); - if let Ok(asset_mesh) = query.get(entity) { - info!("Loading mesh for entity {:?}: {}", entity, asset_mesh.path); - commands.entity(entity).insert(Mesh3d(assets.load::(&asset_mesh.path))); + if let Ok((asset_mesh, existing_mesh)) = query.get(entity) { + // Don't reload if already has a mesh + if existing_mesh.is_some() { + return; + } + + // Use cached handle or create new one + let handle = cache.meshes.entry(asset_mesh.path.clone()) + .or_insert_with(|| { + info!("Loading NEW mesh: {}", asset_mesh.path); + assets.load::(&asset_mesh.path) + }) + .clone(); + + commands.entity(entity).insert(Mesh3d(handle)); } } @@ -394,19 +413,28 @@ fn on_asset_mesh_removed( } } -// AssetMaterial observers fn on_asset_material_added( trigger: Trigger, mut commands: Commands, - query: Query<&AssetMaterial>, + query: Query<(&AssetMaterial, Option<&MeshMaterial3d>)>, assets: Res, + mut cache: ResMut, ) { let entity = trigger.target(); - if let Ok(asset_material) = query.get(entity) { - info!("Loading material for entity {:?}: {}", entity, asset_material.path); - commands.entity(entity).insert(MeshMaterial3d( - assets.load::(&asset_material.path), - )); + if let Ok((asset_material, existing_material)) = query.get(entity) { + // Don't reload if already has a material + if existing_material.is_some() { + return; + } + + let handle = cache.materials.entry(asset_material.path.clone()) + .or_insert_with(|| { + info!("Loading NEW material: {}", asset_material.path); + assets.load::(&asset_material.path) + }) + .clone(); + + commands.entity(entity).insert(MeshMaterial3d(handle)); } } From ac659ae86a76b5101224aa0c4064ff17a9ba725b Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:14:29 -0700 Subject: [PATCH 43/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 9419e5ac..d004f090 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -6,6 +6,7 @@ use bevy::{ use bevy_scene_hook::HookPlugin; use space_shared::toast::ToastMessage; use space_shared::{LightAreaToggle, PrefabMarker}; +use std::collections::HashMap; use crate::{ component, editor_registry::EditorRegistryExt, load, prelude::EditorRegistryPlugin, save, @@ -39,7 +40,7 @@ impl Plugin for BasePrefabPlugin { #[cfg(not(tarpaulin_include))] fn build(&self, app: &mut App) { app.init_state::(); - app.insert_resource(AssetCache::Default()); + app.insert_resource(AssetCache::default()); if !app.is_plugin_added::() { app.add_plugins(HookPlugin); From 1cd968ba0727ddde3566db113a4bc9a896c06c0e Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:20:06 -0700 Subject: [PATCH 44/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 53 ++++++++---------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index d004f090..ee34b61b 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -6,7 +6,6 @@ use bevy::{ use bevy_scene_hook::HookPlugin; use space_shared::toast::ToastMessage; use space_shared::{LightAreaToggle, PrefabMarker}; -use std::collections::HashMap; use crate::{ component, editor_registry::EditorRegistryExt, load, prelude::EditorRegistryPlugin, save, @@ -18,12 +17,6 @@ use load::*; use save::*; use spawn_system::*; -#[derive(Resource, Default)] -pub struct AssetCache { - meshes: HashMap>, - materials: HashMap>, -} - /// This plugin contains all components and logic of prefabs pub struct PrefabPlugin; @@ -40,7 +33,6 @@ impl Plugin for BasePrefabPlugin { #[cfg(not(tarpaulin_include))] fn build(&self, app: &mut App) { app.init_state::(); - app.insert_resource(AssetCache::default()); if !app.is_plugin_added::() { app.add_plugins(HookPlugin); @@ -364,29 +356,17 @@ fn sync_asset_material( } } +// AssetMesh observers fn on_asset_mesh_added( trigger: Trigger, mut commands: Commands, - query: Query<(&AssetMesh, Option<&Mesh3d>)>, + query: Query<&AssetMesh>, assets: Res, - mut cache: ResMut, ) { let entity = trigger.target(); - if let Ok((asset_mesh, existing_mesh)) = query.get(entity) { - // Don't reload if already has a mesh - if existing_mesh.is_some() { - return; - } - - // Use cached handle or create new one - let handle = cache.meshes.entry(asset_mesh.path.clone()) - .or_insert_with(|| { - info!("Loading NEW mesh: {}", asset_mesh.path); - assets.load::(&asset_mesh.path) - }) - .clone(); - - commands.entity(entity).insert(Mesh3d(handle)); + if let Ok(asset_mesh) = query.get(entity) { + info!("Loading mesh for entity {:?}: {}", entity, asset_mesh.path); + commands.entity(entity).insert(Mesh3d(assets.load::(&asset_mesh.path))); } } @@ -414,28 +394,19 @@ fn on_asset_mesh_removed( } } +// AssetMaterial observers fn on_asset_material_added( trigger: Trigger, mut commands: Commands, - query: Query<(&AssetMaterial, Option<&MeshMaterial3d>)>, + query: Query<&AssetMaterial>, assets: Res, - mut cache: ResMut, ) { let entity = trigger.target(); - if let Ok((asset_material, existing_material)) = query.get(entity) { - // Don't reload if already has a material - if existing_material.is_some() { - return; - } - - let handle = cache.materials.entry(asset_material.path.clone()) - .or_insert_with(|| { - info!("Loading NEW material: {}", asset_material.path); - assets.load::(&asset_material.path) - }) - .clone(); - - commands.entity(entity).insert(MeshMaterial3d(handle)); + if let Ok(asset_material) = query.get(entity) { + info!("Loading material for entity {:?}: {}", entity, asset_material.path); + commands.entity(entity).insert(MeshMaterial3d( + assets.load::(&asset_material.path), + )); } } From 2efd5ee4483cbeb99b07bc1317085de19a19cfde Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:58:25 -0700 Subject: [PATCH 45/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 166 +++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index ee34b61b..5cf2d986 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -17,6 +17,18 @@ use load::*; use save::*; use spawn_system::*; +// Resource to track entities that need mesh loading +#[derive(Resource, Default)] +pub struct PendingMeshLoads { + pub entities: HashSet, +} + +// Resource to track entities that need material loading +#[derive(Resource, Default)] +pub struct PendingMaterialLoads { + pub entities: HashSet, +} + /// This plugin contains all components and logic of prefabs pub struct PrefabPlugin; @@ -33,6 +45,8 @@ impl Plugin for BasePrefabPlugin { #[cfg(not(tarpaulin_include))] fn build(&self, app: &mut App) { app.init_state::(); + app.init_resource::(); + app.init_resource::(); if !app.is_plugin_added::() { app.add_plugins(HookPlugin); @@ -317,6 +331,7 @@ fn remove_computed_visibility( } } +/* fn sync_asset_mesh( mut commands: Commands, changed: Query<(Entity, &AssetMesh), Changed>, @@ -435,6 +450,157 @@ fn on_asset_material_removed( info!("Removed material handle for entity {:?}", entity); } } +*/ + +// Modified observer - just tracks the entity, doesn't load immediately +fn on_asset_mesh_added_tracker( + trigger: Trigger, + mut pending_loads: ResMut, + query: Query<&AssetMesh>, +) { + let entity = trigger.target(); + if query.get(entity).is_ok() { + info!("Queuing mesh load for entity {:?}", entity); + pending_loads.entities.insert(entity); + } +} + +// Batched sync system - processes all pending loads at once +fn batched_sync_asset_mesh( + mut commands: Commands, + mut pending_loads: ResMut, + query: Query<&AssetMesh>, + assets: Res, +) { + if pending_loads.entities.is_empty() { + return; + } + + // Group entities by their mesh path to avoid duplicate handles + let mut path_to_entities: std::collections::HashMap> = std::collections::HashMap::new(); + + // Collect valid entities and group by path + let mut valid_entities = Vec::new(); + for &entity in &pending_loads.entities { + if let Ok(asset_mesh) = query.get(entity) { + path_to_entities + .entry(asset_mesh.path.clone()) + .or_default() + .push(entity); + valid_entities.push(entity); + } + } + + // Load each unique mesh path once and apply to all entities that need it + for (path, entities) in path_to_entities { + info!("Loading mesh '{}' for {} entities", path, entities.len()); + let mesh_handle = assets.load::(&path); + + for entity in entities { + commands.entity(entity).insert(Mesh3d(mesh_handle.clone())); + } + } + + // Clear the pending loads + pending_loads.entities.clear(); + + info!("Batched mesh loading completed for {} entities", valid_entities.len()); +} + +// Keep the removal observer as-is since it's immediate +fn on_asset_mesh_removed( + trigger: Trigger, + mut commands: Commands, +) { + let entity = trigger.target(); + if let Ok(mut cmd) = commands.get_entity(entity) { + cmd.remove::(); + info!("Removed mesh handle for entity {:?}", entity); + } +} + +// Similar pattern for materials +fn on_asset_material_added_tracker( + trigger: Trigger, + mut pending_loads: ResMut, + query: Query<&AssetMaterial>, +) { + let entity = trigger.target(); + if query.get(entity).is_ok() { + info!("Queuing material load for entity {:?}", entity); + pending_loads.entities.insert(entity); + } +} + +fn batched_sync_asset_material( + mut commands: Commands, + mut pending_loads: ResMut, + query: Query<&AssetMaterial>, + assets: Res, +) { + if pending_loads.entities.is_empty() { + return; + } + + // Group entities by their material path + let mut path_to_entities: std::collections::HashMap> = std::collections::HashMap::new(); + + let mut valid_entities = Vec::new(); + for &entity in &pending_loads.entities { + if let Ok(asset_material) = query.get(entity) { + path_to_entities + .entry(asset_material.path.clone()) + .or_default() + .push(entity); + valid_entities.push(entity); + } + } + + // Load each unique material path once and apply to all entities + for (path, entities) in path_to_entities { + info!("Loading material '{}' for {} entities", path, entities.len()); + let material_handle = assets.load::(&path); + + for entity in entities { + commands.entity(entity).insert(MeshMaterial3d(material_handle.clone())); + } + } + + // Clear the pending loads + pending_loads.entities.clear(); + + info!("Batched material loading completed for {} entities", valid_entities.len()); +} + +fn on_asset_material_removed( + trigger: Trigger, + mut commands: Commands, +) { + let entity = trigger.target(); + if let Ok(mut cmd) = commands.get_entity(entity) { + cmd.remove::>(); + info!("Removed material handle for entity {:?}", entity); + } +} + +// Optional: Add a system to handle changes to existing AssetMesh components +fn on_asset_mesh_changed_tracker( + trigger: Trigger, + mut pending_loads: ResMut, +) { + let entity = trigger.target(); + info!("Queuing mesh update for entity {:?}", entity); + pending_loads.entities.insert(entity); +} + +fn on_asset_material_changed_tracker( + trigger: Trigger, + mut pending_loads: ResMut, +) { + let entity = trigger.target(); + info!("Queuing material update for entity {:?}", entity); + pending_loads.entities.insert(entity); +} #[cfg(test)] mod test { From dce685a64e81b386f9b6b53760274448cf739169 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:59:29 -0700 Subject: [PATCH 46/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 5cf2d986..07865e84 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -131,7 +131,7 @@ impl Plugin for BasePrefabPlugin { // Update, // sync_asset_mesh.in_set(PrefabSet::DetectPrefabChange), //); - app.add_observer(on_asset_mesh_added); + app.add_observer(on_asset_mesh_added_tracker); //app.add_observer(on_asset_mesh_changed); app.add_observer(on_asset_mesh_removed); @@ -140,7 +140,7 @@ impl Plugin for BasePrefabPlugin { // Update, // sync_asset_material.in_set(PrefabSet::DetectPrefabChange), //); - app.add_observer(on_asset_material_added); + app.add_observer(on_asset_material_added_tracker); //app.add_observer(on_asset_material_changed); app.add_observer(on_asset_material_removed); From 2845d965f7052ffe59e300a6b08d3270d8d26068 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:59:46 -0700 Subject: [PATCH 47/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 07865e84..3baa3bd9 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -6,6 +6,7 @@ use bevy::{ use bevy_scene_hook::HookPlugin; use space_shared::toast::ToastMessage; use space_shared::{LightAreaToggle, PrefabMarker}; +use std::collections::HashSet; use crate::{ component, editor_registry::EditorRegistryExt, load, prelude::EditorRegistryPlugin, save, From 0f8bc58bf2a24d17b239c4e34d3d3cc1d4ceac0a Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:03:42 -0700 Subject: [PATCH 48/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 3baa3bd9..f89ef19d 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -145,6 +145,11 @@ impl Plugin for BasePrefabPlugin { //app.add_observer(on_asset_material_changed); app.add_observer(on_asset_material_removed); + app.add_systems( + Update, + (batched_sync_asset_mesh, batched_sync_asset_material).in_set(PrefabSet::DetectPrefabChange), + ); + //material registration app.register_type::(); app.register_type::(); From 9f529aaeb7207a0571754d56d7180c351e605e36 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:16:44 -0700 Subject: [PATCH 49/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index f89ef19d..83684e6b 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -500,7 +500,7 @@ fn batched_sync_asset_mesh( // Load each unique mesh path once and apply to all entities that need it for (path, entities) in path_to_entities { info!("Loading mesh '{}' for {} entities", path, entities.len()); - let mesh_handle = assets.load::(&path); + let mesh_handle = assets.load(&path); for entity in entities { commands.entity(entity).insert(Mesh3d(mesh_handle.clone())); @@ -565,7 +565,7 @@ fn batched_sync_asset_material( // Load each unique material path once and apply to all entities for (path, entities) in path_to_entities { info!("Loading material '{}' for {} entities", path, entities.len()); - let material_handle = assets.load::(&path); + let material_handle = assets.load(&path); for entity in entities { commands.entity(entity).insert(MeshMaterial3d(material_handle.clone())); From 786a3ee3c2a653ddecc6d20430e448455c025f1f Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:19:38 -0700 Subject: [PATCH 50/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 83684e6b..8d0e9e8a 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -500,7 +500,7 @@ fn batched_sync_asset_mesh( // Load each unique mesh path once and apply to all entities that need it for (path, entities) in path_to_entities { info!("Loading mesh '{}' for {} entities", path, entities.len()); - let mesh_handle = assets.load(&path); + let mesh_handle = assets.load::(&path); for entity in entities { commands.entity(entity).insert(Mesh3d(mesh_handle.clone())); @@ -565,7 +565,7 @@ fn batched_sync_asset_material( // Load each unique material path once and apply to all entities for (path, entities) in path_to_entities { info!("Loading material '{}' for {} entities", path, entities.len()); - let material_handle = assets.load(&path); + let material_handle = assets.load(&path); for entity in entities { commands.entity(entity).insert(MeshMaterial3d(material_handle.clone())); From 51d615b5b5efe76725fc7167dd4072ca41d5a731 Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:26:01 -0700 Subject: [PATCH 51/52] Update plugins.rs --- crates/prefab/src/plugins.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/prefab/src/plugins.rs b/crates/prefab/src/plugins.rs index 8d0e9e8a..f89ef19d 100644 --- a/crates/prefab/src/plugins.rs +++ b/crates/prefab/src/plugins.rs @@ -565,7 +565,7 @@ fn batched_sync_asset_material( // Load each unique material path once and apply to all entities for (path, entities) in path_to_entities { info!("Loading material '{}' for {} entities", path, entities.len()); - let material_handle = assets.load(&path); + let material_handle = assets.load::(&path); for entity in entities { commands.entity(entity).insert(MeshMaterial3d(material_handle.clone())); From 6b39c99a3abcfb98485e4d3a59395ec26e93235a Mon Sep 17 00:00:00 2001 From: MiniMinerX <111392588+MiniMinerX@users.noreply.github.com> Date: Thu, 14 Aug 2025 12:41:28 -0700 Subject: [PATCH 52/52] Update lib.rs --- crates/editor_game_view/src/lib.rs | 38 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/crates/editor_game_view/src/lib.rs b/crates/editor_game_view/src/lib.rs index 1165dd5e..71991499 100644 --- a/crates/editor_game_view/src/lib.rs +++ b/crates/editor_game_view/src/lib.rs @@ -214,27 +214,39 @@ pub fn set_camera_viewport( local.0 = Some(viewport_rect); let scale_factor = window.scale_factor(); - //debug!( - // "Window scale factor: {} egui scale factor: {}", - // scale_factor, context_settings.scale_factor - //); let mut viewport_pos = viewport_rect.left_top().to_vec2() * scale_factor; let mut viewport_size = viewport_rect.size() * scale_factor; + // Ensure position is non-negative viewport_pos.x = viewport_pos.x.max(0.0); viewport_pos.y = viewport_pos.y.max(0.0); - viewport_size.x = viewport_size - .x - .min(window.width().mul_add(scale_factor, -viewport_pos.x)); - viewport_size.y = viewport_size - .y - .min(window.height().mul_add(scale_factor, -viewport_pos.y)); - - if (viewport_size.x <= 0.0) || (viewport_size.y <= 0.0) { + // Calculate maximum allowed size based on window dimensions and position + let window_width = window.width() * scale_factor; + let window_height = window.height() * scale_factor; + + // IMPORTANT: Ensure viewport fits WITHIN the render target + // Subtract 1 pixel to ensure it's contained, not equal + let max_width = (window_width - viewport_pos.x - 1.0).max(0.0); + let max_height = (window_height - viewport_pos.y - 1.0).max(0.0); + + viewport_size.x = viewport_size.x.min(max_width); + viewport_size.y = viewport_size.y.min(max_height); + + // Ensure minimum size of 1x1 + if viewport_size.x < 1.0 || viewport_size.y < 1.0 { return; } + + // Additional safety check: ensure the viewport is fully contained + if viewport_pos.x + viewport_size.x >= window_width || + viewport_pos.y + viewport_size.y >= window_height { + // Adjust size to fit + viewport_size.x = (window_width - viewport_pos.x - 1.0).max(1.0); + viewport_size.y = (window_height - viewport_pos.y - 1.0).max(1.0); + } + cam.viewport = Some(bevy::render::camera::Viewport { physical_position: UVec2::new(viewport_pos.x as u32, viewport_pos.y as u32), physical_size: UVec2::new(viewport_size.x as u32, viewport_size.y as u32), @@ -251,4 +263,4 @@ fn set_non_ui_areas( if let Some(viewport_rect) = game_view.viewport_rect { non_ui_areas.areas.push(viewport_rect); } -} \ No newline at end of file +}