Refactor scene viewport state into local sessions
This commit is contained in:
@@ -36,16 +36,6 @@ 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) {
|
||||
@@ -116,12 +106,9 @@ void EditorSceneRuntime::Reset() {
|
||||
m_startupSceneResult = {};
|
||||
m_ownedSelectionService.ClearSelection();
|
||||
m_selectionService = &m_ownedSelectionService;
|
||||
m_sceneViewCameraController.Reset();
|
||||
m_toolState = {};
|
||||
ResetTransformEditHistory();
|
||||
m_inspectorRevision = 0u;
|
||||
m_sceneContentRevision = 0u;
|
||||
m_sceneViewCameraRevision = 0u;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetBackend(std::unique_ptr<EditorSceneBackend> backend) {
|
||||
@@ -153,11 +140,7 @@ void EditorSceneRuntime::RefreshScene() {
|
||||
} else {
|
||||
RevalidateSelection();
|
||||
}
|
||||
} else if (m_toolState.dragState.active) {
|
||||
ResetToolInteractionState();
|
||||
}
|
||||
|
||||
ClearInvalidToolInteractionState();
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::EnsureSceneSelection() {
|
||||
@@ -179,39 +162,6 @@ EditorSceneHierarchySnapshot EditorSceneRuntime::BuildHierarchySnapshot() const
|
||||
: EditorSceneHierarchySnapshot{};
|
||||
}
|
||||
|
||||
float EditorSceneRuntime::GetSceneViewOrbitDistance() const {
|
||||
return m_sceneViewCameraController.GetDistance();
|
||||
}
|
||||
|
||||
SceneViewportRenderRequest EditorSceneRuntime::BuildSceneViewportRenderRequest() {
|
||||
SceneViewportRenderRequest request = {};
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -229,21 +179,14 @@ EditorSceneRuntime::BuildSceneViewportSelectionSnapshot() const {
|
||||
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)) {
|
||||
return false;
|
||||
std::vector<EditorSceneViewportHelperSnapshot>
|
||||
EditorSceneRuntime::BuildSelectedViewportHelperSnapshots() const {
|
||||
const std::optional<EditorSceneObjectId> selectedId = GetSelectedObjectId();
|
||||
if (!selectedId.has_value() || m_backend == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
m_sceneViewCameraController.Focus(snapshot.position);
|
||||
IncrementSceneViewCameraRevision();
|
||||
return true;
|
||||
return m_backend->BuildViewportHelperSnapshots(selectedId.value());
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::HasSceneSelection() const {
|
||||
@@ -326,18 +269,13 @@ bool EditorSceneRuntime::SetSelection(EditorSceneObjectId id) {
|
||||
!previousId.has_value() ||
|
||||
previousId.value() != id ||
|
||||
!HasHierarchySelection();
|
||||
if (changed) {
|
||||
ResetToolInteractionState();
|
||||
}
|
||||
SelectionService().SetHierarchySelection(
|
||||
MakeEditorGameObjectItemId(id),
|
||||
snapshot->displayName);
|
||||
ClearInvalidToolInteractionState();
|
||||
return changed;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ClearSelection() {
|
||||
ResetToolInteractionState();
|
||||
SelectionService().ClearSelection();
|
||||
}
|
||||
|
||||
@@ -359,7 +297,6 @@ bool EditorSceneRuntime::NewScene(std::string_view sceneName) {
|
||||
}
|
||||
|
||||
ResetTransformEditHistory();
|
||||
ResetToolInteractionState();
|
||||
SelectionService().ClearSelection();
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
@@ -379,7 +316,6 @@ bool EditorSceneRuntime::OpenSceneAsset(const std::filesystem::path& scenePath)
|
||||
m_startupSceneResult.sceneName = scenePath.stem().string();
|
||||
|
||||
ResetTransformEditHistory();
|
||||
ResetToolInteractionState();
|
||||
SelectionService().ClearSelection();
|
||||
IncrementInspectorRevision();
|
||||
IncrementSceneContentRevision();
|
||||
@@ -661,70 +597,6 @@ bool EditorSceneRuntime::ApplySelectedComponentMutation(
|
||||
return true;
|
||||
}
|
||||
|
||||
const SceneToolState& EditorSceneRuntime::GetToolState() const {
|
||||
return m_toolState;
|
||||
}
|
||||
|
||||
SceneToolMode EditorSceneRuntime::GetToolMode() const {
|
||||
return m_toolState.mode;
|
||||
}
|
||||
|
||||
SceneToolSpaceMode EditorSceneRuntime::GetToolSpaceMode() const {
|
||||
return m_toolState.spaceMode;
|
||||
}
|
||||
|
||||
SceneToolPivotMode EditorSceneRuntime::GetToolPivotMode() const {
|
||||
return m_toolState.pivotMode;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetToolMode(SceneToolMode mode) {
|
||||
if (m_toolState.mode == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResetToolInteractionState();
|
||||
m_toolState.mode = mode;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetToolSpaceMode(SceneToolSpaceMode mode) {
|
||||
if (m_toolState.spaceMode == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResetToolInteractionState();
|
||||
m_toolState.spaceMode = mode;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetToolPivotMode(SceneToolPivotMode mode) {
|
||||
if (m_toolState.pivotMode == mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResetToolInteractionState();
|
||||
m_toolState.pivotMode = mode;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetHoveredToolHandle(SceneToolHandle handle) {
|
||||
if (m_toolState.dragState.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_toolState.hoveredHandle = handle;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::SetToolInteractionLock(SceneToolInteractionLock lock) {
|
||||
m_toolState.interactionLock = lock;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ClearToolInteractionLock() {
|
||||
m_toolState.interactionLock = SceneToolInteractionLock::None;
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ResetToolInteractionState() {
|
||||
CancelTransformToolDrag();
|
||||
ResetToolInteractionTransientState();
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::CaptureSelectedTransformSnapshot(
|
||||
SceneTransformSnapshot& outSnapshot) const {
|
||||
const std::optional<EditorSceneObjectId> selectedId = GetSelectedObjectId();
|
||||
@@ -782,51 +654,6 @@ bool EditorSceneRuntime::RecordTransformEdit(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::BeginTransformToolDrag(
|
||||
SceneToolHandle handle,
|
||||
const ::XCEngine::UI::UIPoint& startPointerPosition) {
|
||||
if (handle == SceneToolHandle::None ||
|
||||
m_toolState.mode == SceneToolMode::View) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SceneTransformSnapshot snapshot = {};
|
||||
if (!CaptureSelectedTransformSnapshot(snapshot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CancelTransformToolDrag();
|
||||
m_toolState.dragState = {};
|
||||
m_toolState.dragState.active = true;
|
||||
m_toolState.dragState.mode = m_toolState.mode;
|
||||
m_toolState.dragState.handle = handle;
|
||||
m_toolState.dragState.startPointerPosition = startPointerPosition;
|
||||
m_toolState.dragState.initialTransform = snapshot;
|
||||
m_toolState.hoveredHandle = handle;
|
||||
m_toolState.activeHandle = handle;
|
||||
SetToolInteractionLock(SceneToolInteractionLock::TransformDrag);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::HasActiveTransformToolDrag() const {
|
||||
return m_toolState.dragState.active;
|
||||
}
|
||||
|
||||
const SceneToolDragState* EditorSceneRuntime::GetActiveTransformToolDrag() const {
|
||||
return m_toolState.dragState.active ? &m_toolState.dragState : nullptr;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::ApplyTransformToolPreview(
|
||||
const SceneTransformSnapshot& snapshot) {
|
||||
if (!m_toolState.dragState.active ||
|
||||
!snapshot.IsValid() ||
|
||||
snapshot.targetId != m_toolState.dragState.initialTransform.targetId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ApplyTransformSnapshot(snapshot);
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::ApplyTransformToolWorldPreview(
|
||||
EditorSceneObjectId targetId,
|
||||
const Vector3& position,
|
||||
@@ -836,9 +663,7 @@ bool EditorSceneRuntime::ApplyTransformToolWorldPreview(
|
||||
}
|
||||
|
||||
const EditorSceneObjectId activeTargetId =
|
||||
m_toolState.dragState.active
|
||||
? m_toolState.dragState.initialTransform.targetId
|
||||
: GetSelectedObjectId().value_or(kInvalidEditorSceneObjectId);
|
||||
GetSelectedObjectId().value_or(kInvalidEditorSceneObjectId);
|
||||
if (activeTargetId == kInvalidEditorSceneObjectId ||
|
||||
targetId != activeTargetId) {
|
||||
return false;
|
||||
@@ -862,9 +687,7 @@ bool EditorSceneRuntime::ApplyTransformToolLocalScalePreview(
|
||||
}
|
||||
|
||||
const EditorSceneObjectId activeTargetId =
|
||||
m_toolState.dragState.active
|
||||
? m_toolState.dragState.initialTransform.targetId
|
||||
: GetSelectedObjectId().value_or(kInvalidEditorSceneObjectId);
|
||||
GetSelectedObjectId().value_or(kInvalidEditorSceneObjectId);
|
||||
if (activeTargetId == kInvalidEditorSceneObjectId ||
|
||||
targetId != activeTargetId) {
|
||||
return false;
|
||||
@@ -880,37 +703,6 @@ bool EditorSceneRuntime::ApplyTransformToolLocalScalePreview(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::CommitTransformToolDrag() {
|
||||
if (!m_toolState.dragState.active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SceneTransformSnapshot afterSnapshot = {};
|
||||
const bool captured = CaptureSelectedTransformSnapshot(afterSnapshot);
|
||||
const SceneTransformSnapshot beforeSnapshot =
|
||||
m_toolState.dragState.initialTransform;
|
||||
ResetToolInteractionTransientState();
|
||||
|
||||
if (!captured || !afterSnapshot.IsValid() || !beforeSnapshot.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return RecordTransformEdit(beforeSnapshot, afterSnapshot);
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::CancelTransformToolDrag() {
|
||||
if (!m_toolState.dragState.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SceneTransformSnapshot snapshot = m_toolState.dragState.initialTransform;
|
||||
if (snapshot.IsValid()) {
|
||||
ApplyTransformSnapshot(snapshot);
|
||||
}
|
||||
|
||||
ResetToolInteractionTransientState();
|
||||
}
|
||||
|
||||
bool EditorSceneRuntime::CanUndoTransformEdit() const {
|
||||
return !m_transformUndoStack.empty();
|
||||
}
|
||||
@@ -1027,46 +819,4 @@ 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;
|
||||
ClearToolInteractionLock();
|
||||
m_toolState.dragState = {};
|
||||
}
|
||||
|
||||
void EditorSceneRuntime::ClearInvalidToolInteractionState() {
|
||||
if (!HasSceneSelection()) {
|
||||
ResetToolInteractionTransientState();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_toolState.dragState.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SceneTransformSnapshot snapshot = m_toolState.dragState.initialTransform;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
Reference in New Issue
Block a user