feat: expand editor scripting asset and viewport flow

This commit is contained in:
2026-04-03 13:22:30 +08:00
parent ed8c27fde2
commit a05d0b80a2
124 changed files with 10397 additions and 1737 deletions

View File

@@ -130,7 +130,7 @@ float ComputeVisualScaleFactor(float current, float start) {
void SceneViewportScaleGizmo::Update(const SceneViewportScaleGizmoContext& context) {
BuildDrawData(context);
if (m_activeHandle == SceneViewportScaleGizmoHandle::None && IsMouseInsideViewport(context)) {
m_hoveredHandle = HitTestHandle(context.mousePosition);
m_hoveredHandle = EvaluateHit(context.mousePosition).handle;
} else if (m_activeHandle == SceneViewportScaleGizmoHandle::None) {
m_hoveredHandle = SceneViewportScaleGizmoHandle::None;
} else {
@@ -158,7 +158,7 @@ bool SceneViewportScaleGizmo::TryBeginDrag(const SceneViewportScaleGizmoContext&
activeScreenDirection = handle->end - handle->start;
if (activeScreenDirection.SqrMagnitude() <= Math::EPSILON) {
const Math::Vector3 pivotWorldPosition = context.selectedObject->GetTransform()->GetPosition();
const Math::Vector3 pivotWorldPosition = context.pivotWorldPosition;
if (!ProjectSceneViewportAxisDirectionAtPoint(
context.overlay,
context.viewportSize.x,
@@ -310,6 +310,68 @@ const SceneViewportScaleGizmoDrawData& SceneViewportScaleGizmo::GetDrawData() co
return m_drawData;
}
SceneViewportScaleGizmoHitResult SceneViewportScaleGizmo::EvaluateHit(const Math::Vector2& mousePosition) const {
SceneViewportScaleGizmoHitResult result = {};
if (!m_drawData.visible) {
return result;
}
if (m_drawData.centerHandle.visible &&
IsPointInsideSquare(
mousePosition,
m_drawData.centerHandle.center,
m_drawData.centerHandle.halfSize + 2.0f)) {
result.handle = SceneViewportScaleGizmoHandle::Uniform;
result.distanceSq = (m_drawData.centerHandle.center - mousePosition).SqrMagnitude();
return result;
}
for (const SceneViewportScaleGizmoAxisHandleDrawData& handle : m_drawData.axisHandles) {
if (!handle.visible ||
!IsPointInsideSquare(mousePosition, handle.capCenter, handle.capHalfSize + 2.0f)) {
continue;
}
const float distanceSq = (handle.capCenter - mousePosition).SqrMagnitude();
if (distanceSq >= result.distanceSq) {
continue;
}
result.handle = handle.handle;
result.distanceSq = distanceSq;
}
if (result.handle != SceneViewportScaleGizmoHandle::None) {
return result;
}
const float hoverThresholdSq = kScaleGizmoHoverThresholdPixels * kScaleGizmoHoverThresholdPixels;
for (const SceneViewportScaleGizmoAxisHandleDrawData& handle : m_drawData.axisHandles) {
if (!handle.visible) {
continue;
}
const float distanceSq = DistanceToSegmentSquared(mousePosition, handle.start, handle.end);
if (distanceSq > result.distanceSq || distanceSq > hoverThresholdSq) {
continue;
}
result.handle = handle.handle;
result.distanceSq = distanceSq;
}
return result;
}
void SceneViewportScaleGizmo::SetHoveredHandle(SceneViewportScaleGizmoHandle handle) {
if (m_activeHandle != SceneViewportScaleGizmoHandle::None) {
return;
}
m_hoveredHandle = handle;
RefreshHandleState();
}
void SceneViewportScaleGizmo::BuildDrawData(const SceneViewportScaleGizmoContext& context) {
m_drawData = {};
@@ -321,7 +383,7 @@ void SceneViewportScaleGizmo::BuildDrawData(const SceneViewportScaleGizmoContext
return;
}
const Math::Vector3 pivotWorldPosition = selectedObject->GetTransform()->GetPosition();
const Math::Vector3 pivotWorldPosition = context.pivotWorldPosition;
const SceneViewportProjectedPoint projectedPivot = ProjectSceneViewportWorldPoint(
context.overlay,
context.viewportSize.x,
@@ -435,58 +497,6 @@ void SceneViewportScaleGizmo::RefreshHandleState() {
m_drawData.centerHandle.active ? 1.0f : (m_drawData.centerHandle.hovered ? 0.96f : 0.88f));
}
SceneViewportScaleGizmoHandle SceneViewportScaleGizmo::HitTestHandle(const Math::Vector2& mousePosition) const {
if (!m_drawData.visible) {
return SceneViewportScaleGizmoHandle::None;
}
if (m_drawData.centerHandle.visible &&
IsPointInsideSquare(
mousePosition,
m_drawData.centerHandle.center,
m_drawData.centerHandle.halfSize + 2.0f)) {
return SceneViewportScaleGizmoHandle::Uniform;
}
SceneViewportScaleGizmoHandle bestHandle = SceneViewportScaleGizmoHandle::None;
float bestDistanceSq = Math::FLOAT_MAX;
for (const SceneViewportScaleGizmoAxisHandleDrawData& handle : m_drawData.axisHandles) {
if (!handle.visible ||
!IsPointInsideSquare(mousePosition, handle.capCenter, handle.capHalfSize + 2.0f)) {
continue;
}
const float distanceSq = (handle.capCenter - mousePosition).SqrMagnitude();
if (distanceSq >= bestDistanceSq) {
continue;
}
bestDistanceSq = distanceSq;
bestHandle = handle.handle;
}
if (bestHandle != SceneViewportScaleGizmoHandle::None) {
return bestHandle;
}
bestDistanceSq = kScaleGizmoHoverThresholdPixels * kScaleGizmoHoverThresholdPixels;
for (const SceneViewportScaleGizmoAxisHandleDrawData& handle : m_drawData.axisHandles) {
if (!handle.visible) {
continue;
}
const float distanceSq = DistanceToSegmentSquared(mousePosition, handle.start, handle.end);
if (distanceSq > bestDistanceSq) {
continue;
}
bestDistanceSq = distanceSq;
bestHandle = handle.handle;
}
return bestHandle;
}
const SceneViewportScaleGizmoAxisHandleDrawData* SceneViewportScaleGizmo::FindAxisHandleDrawData(
SceneViewportScaleGizmoHandle handle) const {
for (const SceneViewportScaleGizmoAxisHandleDrawData& drawHandle : m_drawData.axisHandles) {