Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
78f6b92
Update Cargo.toml
MiniMinerX Jun 7, 2025
ea644cd
Update lib.rs
MiniMinerX Jun 7, 2025
f33a759
Update lib.rs
MiniMinerX Jun 7, 2025
6ce7d38
Update camera_view.rs
MiniMinerX Jun 13, 2025
699664c
Update camera_view.rs
MiniMinerX Jun 13, 2025
32da890
Update camera_plugin.rs
MiniMinerX Jun 13, 2025
a8b1f2a
Update camera_plugin.rs
MiniMinerX Jun 13, 2025
54b3f08
Update camera_plugin.rs
MiniMinerX Jun 13, 2025
7a7de6f
Update ui_plugin.rs
MiniMinerX Jun 13, 2025
e707a66
Update ui_plugin.rs
MiniMinerX Jun 13, 2025
af146bf
Update Cargo.toml
MiniMinerX Jun 23, 2025
80067ea
Update Cargo.toml
MiniMinerX Jun 23, 2025
40aa4aa
gltf parenting test
MiniMinerX Jun 23, 2025
e370bdd
Merge branch '0.16-reflect-functions' of https://github.com/MiniMiner…
MiniMinerX Jun 23, 2025
ec8cda0
fix scene filter
MiniMinerX Jun 24, 2025
9710ee3
MAPPING EVERYONE
MiniMinerX Jun 24, 2025
fb309a2
Update plugins.rs
MiniMinerX Jun 25, 2025
3709002
Update hierarchy.rs
MiniMinerX Jun 25, 2025
2168995
Update Cargo.toml
MiniMinerX Jun 25, 2025
b8e7508
Update Cargo.toml
MiniMinerX Jun 25, 2025
26777ad
Update Cargo.toml
MiniMinerX Jun 26, 2025
ac52ec2
Update Cargo.toml
MiniMinerX Jun 30, 2025
85e92eb
some picking stuff
MiniMinerX Jun 30, 2025
079bef4
Update lib.rs
MiniMinerX Aug 1, 2025
25660b9
Update lib.rs
MiniMinerX Aug 1, 2025
4bd8552
Update lib.rs
MiniMinerX Aug 1, 2025
969a550
Update lib.rs
MiniMinerX Aug 1, 2025
80728d7
Update selection.rs
MiniMinerX Aug 10, 2025
c3a8b03
Update lib.rs
MiniMinerX Aug 10, 2025
d9330f5
Update lib.rs
MiniMinerX Aug 10, 2025
8db69df
Update mod.rs
MiniMinerX Aug 10, 2025
eeaac36
Update selection.rs
MiniMinerX Aug 10, 2025
6bedd1b
Update selection.rs
MiniMinerX Aug 11, 2025
c8786a2
Update selection.rs
MiniMinerX Aug 11, 2025
4bed95b
Update selection.rs
MiniMinerX Aug 11, 2025
c893b1d
Update selection.rs
MiniMinerX Aug 11, 2025
39e76eb
Update selection.rs
MiniMinerX Aug 11, 2025
8120cee
Update selection.rs
MiniMinerX Aug 11, 2025
63f38ad
hierarchies
MiniMinerX Aug 12, 2025
d75a929
Update plugins.rs
MiniMinerX Aug 13, 2025
2f6ed81
Update plugins.rs
MiniMinerX Aug 13, 2025
2bb0142
Update plugins.rs
MiniMinerX Aug 13, 2025
38ec021
Update plugins.rs
MiniMinerX Aug 13, 2025
ac659ae
Update plugins.rs
MiniMinerX Aug 13, 2025
1cd968b
Update plugins.rs
MiniMinerX Aug 13, 2025
2efd5ee
Update plugins.rs
MiniMinerX Aug 13, 2025
dce685a
Update plugins.rs
MiniMinerX Aug 13, 2025
2845d96
Update plugins.rs
MiniMinerX Aug 13, 2025
0f8bc58
Update plugins.rs
MiniMinerX Aug 13, 2025
9f529aa
Update plugins.rs
MiniMinerX Aug 13, 2025
786a3ee
Update plugins.rs
MiniMinerX Aug 13, 2025
51d615b
Update plugins.rs
MiniMinerX Aug 13, 2025
6b39c99
Update lib.rs
MiniMinerX Aug 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ docs/.obsidian/*
editor.ron
.idea/*
crates/prefab/test*.ron
**/.DS_Store
**/.DS_Store
assets/models/TrackATest1_sp.glb
13 changes: 7 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 17 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down Expand Up @@ -83,13 +94,14 @@ 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 = { 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

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-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"}
Expand All @@ -106,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
Expand Down
4 changes: 2 additions & 2 deletions assets/scenes/Scene0.scn.ron
Git LFS file not shown
32 changes: 21 additions & 11 deletions crates/editor_core/src/gltf_unpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ use super::{BackgroundTask, BackgroundTaskStorage};
/// Event to handle GLTF path
pub struct EditorUnpackGltf {
pub path: String,
pub parent: Option<Entity>,
}

#[derive(Event, Clone)]
struct GltfLoaded(Handle<Gltf>);
struct GltfLoaded {
handle: Handle<Gltf>,
parent: Option<Entity>,
}

pub struct UnpackGltfPlugin;

Expand All @@ -34,8 +38,8 @@ impl Plugin for UnpackGltfPlugin {
#[reflect(Component)]
struct GltfHolder(Handle<Gltf>);

#[derive(Resource, Default)]
struct GltfSceneQueue(Vec<Handle<Gltf>>);
#[derive(Resource, Default)] // Handle then parent
struct GltfSceneQueue(Vec<(Handle<Gltf>, Option<Entity>)>);

fn unpack_gltf_event(
mut events: EventReader<EditorUnpackGltf>,
Expand All @@ -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();
}
Expand All @@ -60,9 +64,11 @@ fn queue_push(
mut events: EventWriter<GltfLoaded>,
assets: Res<AssetServer>,
) {
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);
}
}
}

Expand All @@ -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> = gltf.0.clone();
for gltf_loaded in loaded_scenes.iter() {
let handle: Handle<Gltf> = gltf_loaded.handle.clone();
let gltf_path = if let Some(path) = handle.path() {
path.clone()
} else {
Expand All @@ -97,7 +103,7 @@ fn unpack_gltf(world: &mut World) {

let Some(gltf) = world
.get_resource::<Assets<Gltf>>()
.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",
Expand Down Expand Up @@ -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);
}
}
}

Expand Down
11 changes: 7 additions & 4 deletions crates/editor_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ impl Plugin for EditorCore {
app.add_systems(Update, editor_event_listener);

//app.auto_reflected_undo::<ChildOf>();
app.auto_reflected_undo::<Children>();
app.auto_undo::<PrefabMarker>();
//app.auto_reflected_undo::<Children>();
//app.auto_undo::<PrefabMarker>();
}
}

Expand Down Expand Up @@ -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,
});
}
}
}
Expand Down
38 changes: 25 additions & 13 deletions crates/editor_game_view/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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);
}
}
}
27 changes: 16 additions & 11 deletions crates/editor_ui/src/camera_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,20 @@ pub fn update_pan_orbit(
}
}

type PlayModeCameraFilter = (Without<EditorCameraMarker>, With<PlaymodeCamera>);
type EditorModeCameraFilter = (With<EditorCameraMarker>, Without<PlaymodeCamera>);
//type PlayModeCameraFilter = (Without<EditorCameraMarker>, With<PlaymodeCamera>);
//type EditorModeCameraFilter = (With<EditorCameraMarker>, Without<PlaymodeCamera>);

/// 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<EditorCameraMarker>, Without<PlaymodeCamera>)>,
mut play_cameras: Query<&mut Camera, With<PlaymodeCamera>>,
primary_window: Query<&mut Window, With<PrimaryWindow>>,
mut toast: EventWriter<ToastMessage>,
) {
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| {
Expand Down Expand Up @@ -131,14 +133,14 @@ 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<EditorCameraMarker>>,
mut play_only_cameras: Query<&mut Camera, (With<PlaymodeCamera>, Without<EditorCameraMarker>)>,
) {
for mut ecam in editor_cameras.iter_mut() {
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;
}
}
Expand All @@ -164,7 +166,7 @@ pub fn draw_camera_gizmo(
(&GlobalTransform, &Projection),
(
With<Camera>,
Without<EditorCameraMarker>,
//Without<EditorCameraMarker>,
Without<DisableCameraSkip>,
Without<NotShowCamera>,
),
Expand All @@ -173,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 = 1.5;


gizmos.line(
transform.translation,
Expand Down
6 changes: 3 additions & 3 deletions crates/editor_ui/src/camera_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl EditorTab for CameraViewTab {
let mut camera_query = world.query_filtered::<Entity, (
With<Camera>,
With<PlaymodeCamera>,
Without<EditorCameraMarker>,
//Without<EditorCameraMarker>,
)>();

if camera_query.iter(world).count() == 1 {
Expand Down Expand Up @@ -267,7 +267,7 @@ impl EditorTab for CameraViewTab {

fn clean_camera_view_tab(
mut ui_state: ResMut<CameraViewTab>,
mut cameras: Query<(&mut Camera, &mut GlobalTransform), Without<EditorCameraMarker>>,
mut cameras: Query<(&mut Camera, &mut GlobalTransform) /*, Without<EditorCameraMarker> */ >,
) {
let Some(real_cam_entity) = ui_state.real_camera else {
return;
Expand Down Expand Up @@ -296,7 +296,7 @@ fn set_camera_viewport(
primary_window: Query<&mut Window, With<PrimaryWindow>>,
mut cameras: Query<
(&mut Camera, &mut GlobalTransform, &mut Transform),
Without<EditorCameraMarker>,
//Without<EditorCameraMarker>,
>,
mut ctxs: EguiContexts,
images: Res<Assets<Image>>,
Expand Down
Loading
Loading