save scene camera settings

- saving previous camera position is useful when doing multiple iterations that require to restart the editor
- instead of using default position and orientation, the editor will try to load previous one, this should save some time during iterative development
This commit is contained in:
Dmitry
2022-09-12 17:47:07 +03:00
parent 2be837f06b
commit 52effcc9dc
4 changed files with 79 additions and 12 deletions
+18 -8
View File
@@ -1,4 +1,4 @@
use crate::{settings::camera::CameraSettings, utils::built_in_skybox};
use crate::{settings::camera::CameraSettings, utils::built_in_skybox, SceneCameraSettings};
use fyrox::{
core::{
algebra::{Matrix4, Point3, UnitQuaternion, Vector2, Vector3},
@@ -26,13 +26,13 @@ use std::{
hash::{Hash, Hasher},
};
const DEFAULT_Z_OFFSET: f32 = -3.0;
pub const DEFAULT_Z_OFFSET: f32 = -3.0;
pub struct CameraController {
pub pivot: Handle<Node>,
pub camera: Handle<Node>,
yaw: f32,
pitch: f32,
pub yaw: f32,
pub pitch: f32,
rotate: bool,
drag_side: f32,
drag_up: f32,
@@ -78,7 +78,13 @@ where
}
impl CameraController {
pub fn new(graph: &mut Graph, root: Handle<Node>) -> Self {
pub fn new(
graph: &mut Graph,
root: Handle<Node>,
settings: Option<&SceneCameraSettings>,
) -> Self {
let settings = settings.cloned().unwrap_or_default();
let camera;
let pivot = PivotBuilder::new(
BaseBuilder::new()
@@ -97,7 +103,7 @@ impl CameraController {
.with_name("EditorCameraPivot")
.with_local_transform(
TransformBuilder::new()
.with_local_position(Vector3::new(0.0, 1.0, DEFAULT_Z_OFFSET))
.with_local_position(settings.position)
.build(),
),
)
@@ -108,8 +114,8 @@ impl CameraController {
Self {
pivot,
camera,
yaw: 0.0,
pitch: 0.0,
yaw: settings.yaw,
pitch: settings.pitch,
rotate: false,
drag_side: 0.0,
drag_up: 0.0,
@@ -270,6 +276,10 @@ impl CameraController {
}
}
pub fn position(&self, graph: &Graph) -> Vector3<f32> {
graph[self.pivot].global_position()
}
pub fn update(&mut self, graph: &mut Graph, settings: &CameraSettings, dt: f32) {
let camera = graph[self.camera].as_camera_mut();
+25 -1
View File
@@ -33,6 +33,7 @@ mod settings;
mod utils;
mod world;
use crate::settings::camera::SceneCameraSettings;
use crate::{
absm::AbsmEditor,
asset::{item::AssetItem, item::AssetKind, AssetBrowser},
@@ -839,7 +840,8 @@ impl Editor {
self.scene_viewer
.set_render_target(&self.engine.user_interface, scene.render_target.clone());
let editor_scene = EditorScene::from_native_scene(scene, &mut self.engine, path.clone());
let editor_scene =
EditorScene::from_native_scene(scene, &mut self.engine, path.clone(), &self.settings);
self.interaction_modes = vec![
Box::new(SelectInteractionMode::new(
@@ -1790,6 +1792,25 @@ impl Editor {
.camera_controller
.update(graph, &self.settings.camera, dt);
// Save camera current camera settings for current scene to be able to load them
// on next launch.
if let Some(path) = editor_scene.path.as_ref() {
let last_settings = SceneCameraSettings {
position: editor_scene.camera_controller.position(&scene.graph),
yaw: editor_scene.camera_controller.yaw,
pitch: editor_scene.camera_controller.pitch,
};
if let Some(entry) = self.settings.camera.camera_settings.get_mut(path) {
*entry = last_settings;
} else {
self.settings
.camera
.camera_settings
.insert(path.clone(), last_settings);
}
}
if let Some(mode) = self.current_interaction_mode {
self.interaction_modes[mode as usize].update(
editor_scene,
@@ -1946,6 +1967,9 @@ impl Editor {
self.engine.user_interface.process_os_event(&os_event);
}
}
Event::LoopDestroyed => {
Log::verify(self.settings.save());
}
_ => *control_flow = ControlFlow::Poll,
});
}
+12 -2
View File
@@ -63,9 +63,19 @@ pub fn is_scene_needs_to_be_saved(editor_scene: Option<&EditorScene>) -> bool {
}
impl EditorScene {
pub fn from_native_scene(mut scene: Scene, engine: &mut Engine, path: Option<PathBuf>) -> Self {
pub fn from_native_scene(
mut scene: Scene,
engine: &mut Engine,
path: Option<PathBuf>,
settings: &Settings,
) -> Self {
let root = PivotBuilder::new(BaseBuilder::new()).build(&mut scene.graph);
let camera_controller = CameraController::new(&mut scene.graph, root);
let camera_controller = CameraController::new(
&mut scene.graph,
root,
path.as_ref()
.and_then(|p| settings.camera.camera_settings.get(p)),
);
// Freeze physics simulation in while editing scene by setting time step to zero.
scene.graph.physics.integration_parameters.dt = 0.0;
+24 -1
View File
@@ -1,11 +1,33 @@
use fyrox::core::{inspect::prelude::*, reflect::Reflect};
use crate::camera;
use fyrox::core::{algebra::Vector3, inspect::prelude::*, reflect::Reflect};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};
#[derive(Deserialize, Serialize, PartialEq, Clone, Debug)]
pub struct SceneCameraSettings {
pub position: Vector3<f32>,
pub yaw: f32,
pub pitch: f32,
}
impl Default for SceneCameraSettings {
fn default() -> Self {
Self {
position: Vector3::new(0.0, 1.0, camera::DEFAULT_Z_OFFSET),
yaw: 0.0,
pitch: 0.0,
}
}
}
#[derive(Deserialize, Serialize, PartialEq, Clone, Debug, Inspect, Reflect)]
pub struct CameraSettings {
pub speed: f32,
pub invert_dragging: bool,
pub drag_speed: f32,
#[inspect(skip)]
#[reflect(hidden)]
pub camera_settings: HashMap<PathBuf, SceneCameraSettings>,
}
impl Default for CameraSettings {
@@ -14,6 +36,7 @@ impl Default for CameraSettings {
speed: 10.0,
invert_dragging: false,
drag_speed: 0.01,
camera_settings: Default::default(),
}
}
}