diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 61b6eab63..1c26df0f7 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -669,8 +669,7 @@ void EditorComponent::Load() Scene& scene = GetCurrentScene(); PickResult pick; - XMFLOAT3 in_front_of_camera; - XMStoreFloat3(&in_front_of_camera, XMVectorAdd(camera.GetEye(), camera.GetAt() * 4)); + XMFLOAT3 in_front_of_camera = GetPositionInFrontOfCamera(); switch (args.userdata) { @@ -882,6 +881,27 @@ void EditorComponent::Load() } if (pick.entity != INVALID_ENTITY) { + // Place the entity in front of camera, if enabled + if (generalWnd.placeInFrontOfCameraCheckBox.GetCheck()) + { + TransformComponent* transform = scene.transforms.GetComponent(pick.entity); + if (transform != nullptr) + { + // Check if this entity type should spawn in front of camera + bool should_reposition = true; + if (args.userdata == NEW_DIRECTIONALLIGHT || args.userdata == NEW_CAMERA) + { + should_reposition = false; + } + + if (should_reposition) + { + transform->translation_local = in_front_of_camera; + transform->SetDirty(); + } + } + } + wi::Archive& archive = AdvanceHistory(); archive << EditorComponent::HISTORYOP_ADD; RecordSelection(archive); @@ -5231,13 +5251,31 @@ void EditorComponent::Open(std::string filename) { GetCurrentEditorScene().path = filename; } + + const size_t transform_count_prev = GetCurrentScene().transforms.GetCount(); GetCurrentScene().Merge(*scene); + // Place the imported model in front of the camera: + if (type != FileType::WISCENE && generalWnd.placeInFrontOfCameraCheckBox.GetCheck()) + { + // Imported models always have a root transform entity + if (transform_count_prev < GetCurrentScene().transforms.GetCount()) + { + const Entity rootEntity = GetCurrentScene().transforms.GetEntity(transform_count_prev); + TransformComponent* transform = GetCurrentScene().transforms.GetComponent(rootEntity); + if (transform != nullptr) + { + transform->translation_local = GetPositionInFrontOfCamera(); + transform->SetDirty(); + } + } + } + // Detect when the new scene contains a new camera, and snap the camera onto it: - size_t camera_count = GetCurrentScene().cameras.GetCount(); + const size_t camera_count = GetCurrentScene().cameras.GetCount(); if (camera_count > 0 && camera_count > camera_count_prev) { - Entity entity = GetCurrentScene().cameras.GetEntity(camera_count_prev); + const Entity entity = GetCurrentScene().cameras.GetEntity(camera_count_prev); if (entity != INVALID_ENTITY) { CameraComponent* cam = GetCurrentScene().cameras.GetComponent(entity); @@ -5257,7 +5295,7 @@ void EditorComponent::Open(std::string filename) editorscene.camera.width = (float)renderPath->GetInternalResolution().x; editorscene.camera.height = (float)renderPath->GetInternalResolution().y; - TransformComponent* camera_transform = GetCurrentScene().transforms.GetComponent(entity); + const TransformComponent* camera_transform = GetCurrentScene().transforms.GetComponent(entity); if (camera_transform != nullptr) { editorscene.camera_transform = *camera_transform; @@ -6297,6 +6335,15 @@ void EditorComponent::FocusCameraOnSelected() editorscene.cam_move = {}; } +XMFLOAT3 EditorComponent::GetPositionInFrontOfCamera() const +{ + const EditorScene& editorscene = GetCurrentEditorScene(); + const CameraComponent& camera = editorscene.camera; + XMFLOAT3 in_front_of_camera; + XMStoreFloat3(&in_front_of_camera, XMVectorAdd(camera.GetEye(), camera.GetAt() * 4)); + return in_front_of_camera; +} + void EditorComponent::ReloadTerrainProps() { Scene& scene = GetCurrentScene(); diff --git a/Editor/Editor.h b/Editor/Editor.h index 6059753cd..f372e9734 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -231,6 +231,8 @@ public: void ReloadTerrainProps(); + XMFLOAT3 GetPositionInFrontOfCamera() const; + wi::Localization default_localization; wi::Localization current_localization; void SetDefaultLocalization(); diff --git a/Editor/GeneralWindow.cpp b/Editor/GeneralWindow.cpp index 974074a31..f3284742c 100644 --- a/Editor/GeneralWindow.cpp +++ b/Editor/GeneralWindow.cpp @@ -396,6 +396,18 @@ void GeneralWindow::Create(EditorComponent* _editor) }); AddWidget(&localizationButton); + placeInFrontOfCameraCheckBox.Create("Place entities in front of camera: "); + placeInFrontOfCameraCheckBox.SetTooltip("When enabled, newly created entities and imported models will be positioned in front of the editor camera instead of at the origin."); + if (editor->main->config.GetSection("options").Has("place_entities_in_front_of_camera")) + { + placeInFrontOfCameraCheckBox.SetCheck(editor->main->config.GetSection("options").GetBool("place_entities_in_front_of_camera")); + } + placeInFrontOfCameraCheckBox.OnClick([this](wi::gui::EventArgs args) { + editor->main->config.GetSection("options").Set("place_entities_in_front_of_camera", args.bValue); + editor->main->config.Commit(); + }); + AddWidget(&placeInFrontOfCameraCheckBox); + wireFrameComboBox.Create("Render wireframe: "); wireFrameComboBox.SetTooltip("Choose wireframe rendering mode:\nDisabled: Normal rendering\nWireframe Only: Replace geometry with wireframe\nWireframe Overlay: Show wireframe on top of geometry"); wireFrameComboBox.AddItem("Disabled", wi::renderer::WIREFRAME_DISABLED); @@ -1512,6 +1524,8 @@ void GeneralWindow::ResizeLayout() layout.add_fullwidth(localizationButton); + layout.add_right(placeInFrontOfCameraCheckBox); + layout.add(wireFrameComboBox); layout.add_right(physicsDebugCheckBox); layout.add(physicsDebugMaxDistanceSlider); diff --git a/Editor/GeneralWindow.h b/Editor/GeneralWindow.h index 2d0a12a1f..0612d5823 100644 --- a/Editor/GeneralWindow.h +++ b/Editor/GeneralWindow.h @@ -27,6 +27,7 @@ public: wi::gui::CheckBox debugEmittersCheckBox; wi::gui::CheckBox debugForceFieldsCheckBox; wi::gui::CheckBox debugRaytraceBVHCheckBox; + wi::gui::CheckBox placeInFrontOfCameraCheckBox; wi::gui::ComboBox wireFrameComboBox; wi::gui::CheckBox envProbesCheckBox; wi::gui::CheckBox cameraVisCheckBox;