Checkpoint workspace changes
This commit is contained in:
@@ -1,28 +1,14 @@
|
||||
#include "Scene/EditorSceneRuntime.h"
|
||||
|
||||
#include <XCEngine/Components/CameraComponent.h>
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Components/GameObject.h>
|
||||
#include <XCEngine/Scene/Scene.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::XCEngine::Components::GameObject;
|
||||
using ::XCEngine::Components::Scene;
|
||||
using ::XCEngine::Components::Component;
|
||||
using ::XCEngine::Math::Quaternion;
|
||||
using ::XCEngine::Math::Vector3;
|
||||
|
||||
std::string ResolveGameObjectDisplayName(const GameObject& gameObject) {
|
||||
return gameObject.GetName().empty()
|
||||
? std::string("GameObject")
|
||||
: gameObject.GetName();
|
||||
}
|
||||
|
||||
bool NearlyEqual(float lhs, float rhs, float epsilon = 0.0001f) {
|
||||
return std::abs(lhs - rhs) <= epsilon;
|
||||
}
|
||||
@@ -48,6 +34,16 @@ bool TransformSnapshotsMatch(
|
||||
NearlyEqual(lhs.scale, rhs.scale);
|
||||
}
|
||||
|
||||
std::uint64_t CombineSceneViewportRequestRevisions(
|
||||
std::uint64_t sceneContentRevision,
|
||||
std::uint64_t sceneViewCameraRevision) {
|
||||
constexpr std::uint64_t kRevisionMixConstant = 0x9e3779b97f4a7c15ull;
|
||||
return sceneContentRevision ^
|
||||
(sceneViewCameraRevision + kRevisionMixConstant +
|
||||
(sceneContentRevision << 6u) +
|
||||
(sceneContentRevision >> 2u));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string_view GetSceneToolModeName(SceneToolMode mode) {
|
||||
@@ -118,10 +114,12 @@ void EditorSceneRuntime::Reset() {
|
||||
m_startupSceneResult = {};
|
||||
m_ownedSelectionService.ClearSelection();
|
||||
m_selectionService = &m_ownedSelectionService;
|
||||
m_sceneViewCamera = {};
|
||||
m_sceneViewCameraController.Reset();
|
||||
m_toolState = {};
|
||||
ResetTransformEditHistory();
|
||||
m_inspectorRevision = 0u;
|
||||
m_sceneContentRevision = 0u;
|
||||
m_sceneViewCameraRevision = 0u;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetBackend(std::unique_ptr<EditorSceneBackend> backend) {
|
||||
@@ -136,7 +134,6 @@ bool EditorSceneRuntime::Initialize(const std::filesystem::path& projectRoot) {
|
||||
}
|
||||
m_projectRoot = projectRoot;
|
||||
m_startupSceneResult = m_backend->EnsureStartupScene(projectRoot);
|
||||
EnsureSceneViewCamera();
|
||||
RefreshScene();
|
||||
return m_startupSceneResult.ready;
|
||||
}
|
||||
@@ -174,58 +171,76 @@ const EditorStartupSceneResult& EditorSceneRuntime::GetStartupResult() const {
|
||||
return m_startupSceneResult;
|
||||
}
|
||||
|
||||
Scene* EditorSceneRuntime::GetActiveScene() const {
|
||||
return m_backend != nullptr ? m_backend->GetActiveScene() : nullptr;
|
||||
}
|
||||
|
||||
EditorSceneHierarchySnapshot EditorSceneRuntime::BuildHierarchySnapshot() const {
|
||||
return m_backend != nullptr
|
||||
? m_backend->BuildHierarchySnapshot()
|
||||
: EditorSceneHierarchySnapshot{};
|
||||
}
|
||||
|
||||
::XCEngine::Components::CameraComponent* EditorSceneRuntime::GetSceneViewCamera() {
|
||||
return EnsureSceneViewCamera() ? m_sceneViewCamera.camera : nullptr;
|
||||
}
|
||||
|
||||
const ::XCEngine::Components::CameraComponent* EditorSceneRuntime::GetSceneViewCamera() const {
|
||||
return m_sceneViewCamera.camera;
|
||||
}
|
||||
|
||||
float EditorSceneRuntime::GetSceneViewOrbitDistance() const {
|
||||
return m_sceneViewCamera.controller.GetDistance();
|
||||
return m_sceneViewCameraController.GetDistance();
|
||||
}
|
||||
|
||||
SceneViewportRenderRequest EditorSceneRuntime::BuildSceneViewportRenderRequest() {
|
||||
SceneViewportRenderRequest request = {};
|
||||
request.scene = GetActiveScene();
|
||||
request.camera = GetSceneViewCamera();
|
||||
request.orbitDistance = GetSceneViewOrbitDistance();
|
||||
if (const std::optional<GameObject::ID> selectedId = GetSelectedGameObjectId();
|
||||
request.camera = BuildSceneViewCameraSnapshot();
|
||||
request.requestRevision = BuildSceneViewportRequestRevision();
|
||||
if (const std::optional<EditorSceneObjectId> selectedId = GetSelectedObjectId();
|
||||
selectedId.has_value()) {
|
||||
request.selectedObjectIds.push_back(selectedId.value());
|
||||
if (m_backend != nullptr) {
|
||||
request.selectedHelpers =
|
||||
m_backend->BuildViewportHelperSnapshots(selectedId.value());
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ApplySceneViewportCameraInput(
|
||||
const SceneViewportCameraInputState& input) {
|
||||
if (!EnsureSceneViewCamera()) {
|
||||
return;
|
||||
EditorSceneCameraSnapshot EditorSceneRuntime::BuildSceneViewCameraSnapshot() const {
|
||||
EditorSceneCameraSnapshot snapshot = {};
|
||||
snapshot.valid = true;
|
||||
snapshot.position = m_sceneViewCameraController.GetPosition();
|
||||
snapshot.forward = m_sceneViewCameraController.GetForward();
|
||||
snapshot.right = m_sceneViewCameraController.GetRight();
|
||||
snapshot.up = m_sceneViewCameraController.GetUp();
|
||||
snapshot.verticalFovDegrees = 60.0f;
|
||||
snapshot.nearClipPlane = 0.03f;
|
||||
snapshot.farClipPlane = 2000.0f;
|
||||
snapshot.orbitDistance = GetSceneViewOrbitDistance();
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
std::vector<EditorSceneViewportIconSnapshot>
|
||||
EditorSceneRuntime::BuildSceneViewportIconSnapshots() const {
|
||||
return m_backend != nullptr
|
||||
? m_backend->BuildViewportIconSnapshots()
|
||||
: std::vector<EditorSceneViewportIconSnapshot>{};
|
||||
}
|
||||
|
||||
std::optional<EditorSceneViewportSelectionSnapshot>
|
||||
EditorSceneRuntime::BuildSceneViewportSelectionSnapshot() const {
|
||||
const std::optional<EditorSceneObjectId> selectedId = GetSelectedObjectId();
|
||||
if (!selectedId.has_value() || m_backend == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
m_sceneViewCamera.controller.ApplyInput(input);
|
||||
ApplySceneViewCameraController();
|
||||
return m_backend->BuildViewportSelectionSnapshot(selectedId.value());
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ApplySceneViewportCameraInput(
|
||||
const SceneViewportCameraInputState& input) {
|
||||
m_sceneViewCameraController.ApplyInput(input);
|
||||
IncrementSceneViewCameraRevision();
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::FocusSceneSelection() {
|
||||
SceneTransformSnapshot snapshot = {};
|
||||
if (!CaptureSelectedTransformSnapshot(snapshot) || !EnsureSceneViewCamera()) {
|
||||
if (!CaptureSelectedTransformSnapshot(snapshot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sceneViewCamera.controller.Focus(snapshot.position);
|
||||
ApplySceneViewCameraController();
|
||||
m_sceneViewCameraController.Focus(snapshot.position);
|
||||
IncrementSceneViewCameraRevision();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -233,7 +248,7 @@ bool EditorSceneRuntime::HasSceneSelection() const {
|
||||
return HasValidSelection();
|
||||
}
|
||||
|
||||
std::optional<GameObject::ID> EditorSceneRuntime::GetSelectedGameObjectId() const {
|
||||
std::optional<EditorSceneObjectId> EditorSceneRuntime::GetSelectedObjectId() const {
|
||||
if (!HasHierarchySelection()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -242,27 +257,26 @@ std::optional<GameObject::ID> EditorSceneRuntime::GetSelectedGameObjectId() cons
|
||||
}
|
||||
|
||||
std::string EditorSceneRuntime::GetSelectedItemId() const {
|
||||
const std::optional<GameObject::ID> selectedId = GetSelectedGameObjectId();
|
||||
const std::optional<EditorSceneObjectId> selectedId = GetSelectedObjectId();
|
||||
return selectedId.has_value()
|
||||
? MakeEditorGameObjectItemId(selectedId.value())
|
||||
: std::string();
|
||||
}
|
||||
|
||||
std::string EditorSceneRuntime::GetSelectedDisplayName() const {
|
||||
const GameObject* gameObject = GetSelectedGameObject();
|
||||
return gameObject != nullptr
|
||||
? ResolveGameObjectDisplayName(*gameObject)
|
||||
const std::optional<EditorSceneObjectSnapshot> snapshot =
|
||||
GetSelectedObjectSnapshot();
|
||||
return snapshot.has_value()
|
||||
? snapshot->displayName
|
||||
: std::string();
|
||||
}
|
||||
|
||||
const GameObject* EditorSceneRuntime::GetSelectedGameObject() const {
|
||||
const std::optional<GameObject::ID> selectedId = GetSelectedGameObjectId();
|
||||
if (!selectedId.has_value()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Scene* scene = GetActiveScene();
|
||||
return scene != nullptr ? scene->FindByID(selectedId.value()) : nullptr;
|
||||
std::optional<EditorSceneObjectSnapshot>
|
||||
EditorSceneRuntime::GetSelectedObjectSnapshot() const {
|
||||
const std::string itemId = GetSelectedItemId();
|
||||
return itemId.empty()
|
||||
? std::nullopt
|
||||
: GetObjectSnapshot(itemId);
|
||||
}
|
||||
|
||||
std::vector<EditorSceneComponentDescriptor> EditorSceneRuntime::GetSelectedComponents() const {
|
||||
@@ -281,7 +295,7 @@ std::uint64_t EditorSceneRuntime::GetInspectorRevision() const {
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::SetSelection(std::string_view itemId) {
|
||||
const std::optional<GameObject::ID> gameObjectId =
|
||||
const std::optional<EditorSceneObjectId> gameObjectId =
|
||||
ParseEditorGameObjectItemId(itemId);
|
||||
if (!gameObjectId.has_value()) {
|
||||
return false;
|
||||
@@ -290,18 +304,18 @@ bool EditorSceneRuntime::SetSelection(std::string_view itemId) {
|
||||
return SetSelection(gameObjectId.value());
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::SetSelection(GameObject::ID id) {
|
||||
if (id == GameObject::INVALID_ID) {
|
||||
bool EditorSceneRuntime::SetSelection(EditorSceneObjectId id) {
|
||||
if (id == kInvalidEditorSceneObjectId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Scene* scene = GetActiveScene();
|
||||
GameObject* gameObject = scene != nullptr ? scene->FindByID(id) : nullptr;
|
||||
if (gameObject == nullptr) {
|
||||
const std::optional<EditorSceneObjectSnapshot> snapshot =
|
||||
GetObjectSnapshot(MakeEditorGameObjectItemId(id));
|
||||
if (!snapshot.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::optional<GameObject::ID> previousId = GetSelectedGameObjectId();
|
||||
const std::optional<EditorSceneObjectId> previousId = GetSelectedObjectId();
|
||||
const bool changed =
|
||||
!previousId.has_value() ||
|
||||
previousId.value() != id ||
|
||||
@@ -311,7 +325,7 @@ bool EditorSceneRuntime::SetSelection(GameObject::ID id) {
|
||||
}
|
||||
SelectionService().SetHierarchySelection(
|
||||
MakeEditorGameObjectItemId(id),
|
||||
ResolveGameObjectDisplayName(*gameObject));
|
||||
snapshot->displayName);
|
||||
ClearInvalidToolInteractionState();
|
||||
return changed;
|
||||
}
|
||||
@@ -329,26 +343,18 @@ bool EditorSceneRuntime::OpenSceneAsset(const std::filesystem::path& scenePath)
|
||||
m_startupSceneResult.ready = true;
|
||||
m_startupSceneResult.loadedFromDisk = true;
|
||||
m_startupSceneResult.scenePath = scenePath;
|
||||
if (Scene* activeScene = GetActiveScene();
|
||||
activeScene != nullptr) {
|
||||
m_startupSceneResult.sceneName = activeScene->GetName();
|
||||
} else {
|
||||
m_startupSceneResult.sceneName = scenePath.stem().string();
|
||||
}
|
||||
m_startupSceneResult.sceneName = scenePath.stem().string();
|
||||
|
||||
ResetTransformEditHistory();
|
||||
ResetToolInteractionState();
|
||||
SelectionService().ClearSelection();
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
RefreshScene();
|
||||
EnsureSceneSelection();
|
||||
return true;
|
||||
}
|
||||
|
||||
GameObject* EditorSceneRuntime::FindGameObject(std::string_view itemId) const {
|
||||
return m_backend != nullptr ? m_backend->FindGameObject(itemId) : nullptr;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::RenameGameObject(
|
||||
std::string_view itemId,
|
||||
std::string_view newName) {
|
||||
@@ -357,6 +363,7 @@ bool EditorSceneRuntime::RenameGameObject(
|
||||
m_backend->RenameGameObject(itemId, newName);
|
||||
if (renamed) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
return renamed;
|
||||
@@ -369,6 +376,7 @@ bool EditorSceneRuntime::DeleteGameObject(std::string_view itemId) {
|
||||
m_backend->DeleteGameObject(itemId);
|
||||
if (deleted) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
EnsureSceneSelection();
|
||||
@@ -383,6 +391,7 @@ std::string EditorSceneRuntime::DuplicateGameObject(std::string_view itemId) {
|
||||
: std::string();
|
||||
if (!duplicatedItemId.empty()) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
SetSelection(duplicatedItemId);
|
||||
} else {
|
||||
RefreshScene();
|
||||
@@ -399,6 +408,7 @@ bool EditorSceneRuntime::ReparentGameObject(
|
||||
m_backend->ReparentGameObject(itemId, parentItemId);
|
||||
if (reparented) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
return reparented;
|
||||
@@ -413,6 +423,7 @@ bool EditorSceneRuntime::MoveGameObjectBefore(
|
||||
m_backend->MoveGameObjectBefore(itemId, targetItemId);
|
||||
if (moved) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
return moved;
|
||||
@@ -427,6 +438,7 @@ bool EditorSceneRuntime::MoveGameObjectAfter(
|
||||
m_backend->MoveGameObjectAfter(itemId, targetItemId);
|
||||
if (moved) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
return moved;
|
||||
@@ -439,6 +451,7 @@ bool EditorSceneRuntime::MoveGameObjectToRoot(std::string_view itemId) {
|
||||
m_backend->MoveGameObjectToRoot(itemId);
|
||||
if (moved) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
return moved;
|
||||
@@ -458,6 +471,7 @@ bool EditorSceneRuntime::AddComponentToSelectedGameObject(
|
||||
}
|
||||
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
RefreshScene();
|
||||
return true;
|
||||
}
|
||||
@@ -482,6 +496,7 @@ bool EditorSceneRuntime::RemoveSelectedComponent(std::string_view componentId) {
|
||||
m_backend->RemoveComponent(GetSelectedItemId(), componentId);
|
||||
if (removed) {
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
RefreshScene();
|
||||
return removed;
|
||||
@@ -513,6 +528,7 @@ bool EditorSceneRuntime::SetSelectedTransformLocalPosition(
|
||||
if (!TransformSnapshotsMatch(beforeSnapshot, afterSnapshot)) {
|
||||
RecordTransformEdit(beforeSnapshot, afterSnapshot);
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -543,6 +559,7 @@ bool EditorSceneRuntime::SetSelectedTransformLocalEulerAngles(
|
||||
if (!TransformSnapshotsMatch(beforeSnapshot, afterSnapshot)) {
|
||||
RecordTransformEdit(beforeSnapshot, afterSnapshot);
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -573,30 +590,27 @@ bool EditorSceneRuntime::SetSelectedTransformLocalScale(
|
||||
if (!TransformSnapshotsMatch(beforeSnapshot, afterSnapshot)) {
|
||||
RecordTransformEdit(beforeSnapshot, afterSnapshot);
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::ApplySelectedComponentMutation(
|
||||
std::string_view componentId,
|
||||
const std::function<bool(Component&)>& mutation) {
|
||||
if (!mutation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const EditorSceneComponentMutation& mutation) {
|
||||
if (m_backend == nullptr ||
|
||||
!ResolveSelectedComponentDescriptor(componentId).IsValid()) {
|
||||
!mutation.IsValid() ||
|
||||
!ResolveSelectedComponentDescriptor(mutation.componentId).IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_backend->MutateComponent(
|
||||
if (!m_backend->ApplyComponentMutation(
|
||||
GetSelectedItemId(),
|
||||
componentId,
|
||||
mutation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -666,7 +680,7 @@ void EditorSceneRuntime::ResetToolInteractionState() {
|
||||
|
||||
bool EditorSceneRuntime::CaptureSelectedTransformSnapshot(
|
||||
SceneTransformSnapshot& outSnapshot) const {
|
||||
const std::optional<GameObject::ID> selectedId = GetSelectedGameObjectId();
|
||||
const std::optional<EditorSceneObjectId> selectedId = GetSelectedObjectId();
|
||||
if (!selectedId.has_value() || m_backend == nullptr) {
|
||||
outSnapshot = {};
|
||||
return false;
|
||||
@@ -702,6 +716,7 @@ bool EditorSceneRuntime::ApplyTransformSnapshot(
|
||||
}
|
||||
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -781,6 +796,7 @@ bool EditorSceneRuntime::ApplyTransformToolWorldPreview(
|
||||
}
|
||||
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -799,6 +815,7 @@ bool EditorSceneRuntime::ApplyTransformToolLocalScalePreview(
|
||||
}
|
||||
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -873,45 +890,6 @@ bool EditorSceneRuntime::RedoTransformEdit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::EnsureSceneViewCamera() {
|
||||
if (m_sceneViewCamera.gameObject != nullptr &&
|
||||
m_sceneViewCamera.camera != nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_sceneViewCamera = {};
|
||||
m_sceneViewCamera.gameObject =
|
||||
std::make_unique<GameObject>("EditorSceneCamera");
|
||||
m_sceneViewCamera.camera =
|
||||
m_sceneViewCamera.gameObject->AddComponent<
|
||||
::XCEngine::Components::CameraComponent>();
|
||||
if (m_sceneViewCamera.camera == nullptr) {
|
||||
m_sceneViewCamera.gameObject.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_sceneViewCamera.camera->SetPrimary(false);
|
||||
m_sceneViewCamera.camera->SetProjectionType(
|
||||
::XCEngine::Components::CameraProjectionType::Perspective);
|
||||
m_sceneViewCamera.camera->SetFieldOfView(60.0f);
|
||||
m_sceneViewCamera.camera->SetNearClipPlane(0.03f);
|
||||
m_sceneViewCamera.camera->SetFarClipPlane(2000.0f);
|
||||
m_sceneViewCamera.controller.Reset();
|
||||
ApplySceneViewCameraController();
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ApplySceneViewCameraController() {
|
||||
if (m_sceneViewCamera.gameObject == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto* transform = m_sceneViewCamera.gameObject->GetTransform();
|
||||
transform != nullptr) {
|
||||
m_sceneViewCamera.controller.ApplyTo(*transform);
|
||||
}
|
||||
}
|
||||
|
||||
EditorSelectionService& EditorSceneRuntime::SelectionService() {
|
||||
return *m_selectionService;
|
||||
}
|
||||
@@ -925,18 +903,26 @@ bool EditorSceneRuntime::HasHierarchySelection() const {
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::RevalidateSelection() {
|
||||
const GameObject* gameObject = GetSelectedGameObject();
|
||||
if (gameObject == nullptr) {
|
||||
const std::optional<EditorSceneObjectSnapshot> snapshot =
|
||||
GetSelectedObjectSnapshot();
|
||||
if (!snapshot.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SelectionService().SetHierarchySelection(
|
||||
MakeEditorGameObjectItemId(gameObject->GetID()),
|
||||
ResolveGameObjectDisplayName(*gameObject));
|
||||
snapshot->itemId,
|
||||
snapshot->displayName);
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::HasValidSelection() const {
|
||||
return GetSelectedGameObject() != nullptr;
|
||||
return GetSelectedObjectSnapshot().has_value();
|
||||
}
|
||||
|
||||
std::optional<EditorSceneObjectSnapshot> EditorSceneRuntime::GetObjectSnapshot(
|
||||
std::string_view itemId) const {
|
||||
return m_backend != nullptr
|
||||
? m_backend->GetObjectSnapshot(itemId)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
EditorSceneComponentDescriptor EditorSceneRuntime::ResolveSelectedComponentDescriptor(
|
||||
@@ -952,20 +938,13 @@ EditorSceneComponentDescriptor EditorSceneRuntime::ResolveSelectedComponentDescr
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::SelectFirstAvailableGameObject() {
|
||||
Scene* scene = GetActiveScene();
|
||||
if (scene == nullptr) {
|
||||
if (HasHierarchySelection()) {
|
||||
ClearSelection();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (GameObject* root : scene->GetRootGameObjects()) {
|
||||
if (root == nullptr) {
|
||||
const EditorSceneHierarchySnapshot snapshot = BuildHierarchySnapshot();
|
||||
for (const EditorSceneHierarchyNode& root : snapshot.roots) {
|
||||
if (root.itemId.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return SetSelection(root->GetID());
|
||||
return SetSelection(root.itemId);
|
||||
}
|
||||
|
||||
if (HasHierarchySelection()) {
|
||||
@@ -983,6 +962,20 @@ void EditorSceneRuntime::IncrementInspectorRevision() {
|
||||
++m_inspectorRevision;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::IncrementSceneContentRevision() {
|
||||
++m_sceneContentRevision;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::IncrementSceneViewCameraRevision() {
|
||||
++m_sceneViewCameraRevision;
|
||||
}
|
||||
|
||||
std::uint64_t EditorSceneRuntime::BuildSceneViewportRequestRevision() const {
|
||||
return CombineSceneViewportRequestRevisions(
|
||||
m_sceneContentRevision,
|
||||
m_sceneViewCameraRevision);
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ResetToolInteractionTransientState() {
|
||||
m_toolState.hoveredHandle = SceneToolHandle::None;
|
||||
m_toolState.activeHandle = SceneToolHandle::None;
|
||||
@@ -1001,10 +994,16 @@ void EditorSceneRuntime::ClearInvalidToolInteractionState() {
|
||||
}
|
||||
|
||||
const SceneTransformSnapshot snapshot = m_toolState.dragState.initialTransform;
|
||||
Scene* scene = GetActiveScene();
|
||||
if (scene == nullptr ||
|
||||
!snapshot.IsValid() ||
|
||||
scene->FindByID(snapshot.targetId) == nullptr) {
|
||||
if (!snapshot.IsValid()) {
|
||||
ResetToolInteractionTransientState();
|
||||
return;
|
||||
}
|
||||
|
||||
const std::optional<EditorSceneViewportSelectionSnapshot> selectionSnapshot =
|
||||
m_backend != nullptr
|
||||
? m_backend->BuildViewportSelectionSnapshot(snapshot.targetId)
|
||||
: std::nullopt;
|
||||
if (!selectionSnapshot.has_value() || !selectionSnapshot->IsValid()) {
|
||||
ResetToolInteractionTransientState();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user