feat: expand editor scripting asset and viewport flow
This commit is contained in:
543
editor/src/Viewport/SceneViewportOverlayHandleBuilder.h
Normal file
543
editor/src/Viewport/SceneViewportOverlayHandleBuilder.h
Normal file
@@ -0,0 +1,543 @@
|
||||
#pragma once
|
||||
|
||||
#include "SceneViewportEditorOverlayData.h"
|
||||
#include "SceneViewportMoveGizmo.h"
|
||||
#include "SceneViewportRotateGizmo.h"
|
||||
#include "SceneViewportScaleGizmo.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
struct SceneViewportTransformGizmoHandleBuildInputs {
|
||||
const SceneViewportMoveGizmoDrawData* moveGizmo = nullptr;
|
||||
uint64_t moveEntityId = 0;
|
||||
const SceneViewportRotateGizmoDrawData* rotateGizmo = nullptr;
|
||||
uint64_t rotateEntityId = 0;
|
||||
const SceneViewportScaleGizmoDrawData* scaleGizmo = nullptr;
|
||||
uint64_t scaleEntityId = 0;
|
||||
};
|
||||
|
||||
inline SceneViewportTransformGizmoHandleBuildInputs BuildSceneViewportTransformGizmoHandleBuildInputs(
|
||||
bool showingMoveGizmo,
|
||||
const SceneViewportMoveGizmo& moveGizmo,
|
||||
const SceneViewportMoveGizmoContext& moveGizmoContext,
|
||||
bool showingRotateGizmo,
|
||||
const SceneViewportRotateGizmo& rotateGizmo,
|
||||
const SceneViewportRotateGizmoContext& rotateGizmoContext,
|
||||
bool showingScaleGizmo,
|
||||
const SceneViewportScaleGizmo& scaleGizmo,
|
||||
const SceneViewportScaleGizmoContext& scaleGizmoContext) {
|
||||
SceneViewportTransformGizmoHandleBuildInputs inputs = {};
|
||||
if (showingMoveGizmo && moveGizmoContext.selectedObject != nullptr) {
|
||||
inputs.moveGizmo = &moveGizmo.GetDrawData();
|
||||
inputs.moveEntityId = moveGizmoContext.selectedObject->GetID();
|
||||
}
|
||||
if (showingRotateGizmo && rotateGizmoContext.selectedObject != nullptr) {
|
||||
inputs.rotateGizmo = &rotateGizmo.GetDrawData();
|
||||
inputs.rotateEntityId = rotateGizmoContext.selectedObject->GetID();
|
||||
}
|
||||
if (showingScaleGizmo && scaleGizmoContext.selectedObject != nullptr) {
|
||||
inputs.scaleGizmo = &scaleGizmo.GetDrawData();
|
||||
inputs.scaleEntityId = scaleGizmoContext.selectedObject->GetID();
|
||||
}
|
||||
|
||||
return inputs;
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
|
||||
inline constexpr int kSceneViewportHandlePrioritySceneIcon = 100;
|
||||
inline constexpr int kSceneViewportHandlePriorityRotateAxis = 311;
|
||||
inline constexpr int kSceneViewportHandlePriorityMovePlane = 321;
|
||||
inline constexpr int kSceneViewportHandlePriorityMoveAxis = 322;
|
||||
inline constexpr int kSceneViewportHandlePriorityScaleAxisLine = 331;
|
||||
inline constexpr int kSceneViewportHandlePriorityScaleAxisCap = 332;
|
||||
inline constexpr int kSceneViewportHandlePriorityScaleUniform = 333;
|
||||
|
||||
inline constexpr float kSceneViewportMoveAxisHitThicknessPixels = 10.0f;
|
||||
inline constexpr float kSceneViewportRotateAxisHitThicknessPixels = 9.0f;
|
||||
inline constexpr float kSceneViewportScaleAxisHitThicknessPixels = 10.0f;
|
||||
inline constexpr float kSceneViewportScaleCapHitPaddingPixels = 2.0f;
|
||||
|
||||
inline constexpr float kSceneViewportMoveArrowLengthPixels = 14.0f;
|
||||
inline constexpr float kSceneViewportMoveArrowHalfWidthPixels = 7.0f;
|
||||
|
||||
inline Math::Color WithAlpha(const Math::Color& color, float alpha) {
|
||||
return Math::Color(color.r, color.g, color.b, alpha);
|
||||
}
|
||||
|
||||
inline Math::Color LerpColor(const Math::Color& a, const Math::Color& b, float t) {
|
||||
return Math::Color(
|
||||
a.r + (b.r - a.r) * t,
|
||||
a.g + (b.g - a.g) * t,
|
||||
a.b + (b.b - a.b) * t,
|
||||
a.a + (b.a - a.a) * t);
|
||||
}
|
||||
|
||||
inline Math::Vector2 NormalizeVector2(
|
||||
const Math::Vector2& value,
|
||||
const Math::Vector2& fallback = Math::Vector2(1.0f, 0.0f)) {
|
||||
const float lengthSq = value.SqrMagnitude();
|
||||
if (lengthSq <= Math::EPSILON) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
return value / std::sqrt(lengthSq);
|
||||
}
|
||||
|
||||
inline void AppendScreenTriangle(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const Math::Vector2& a,
|
||||
const Math::Vector2& b,
|
||||
const Math::Vector2& c,
|
||||
const Math::Color& color,
|
||||
SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop) {
|
||||
SceneViewportOverlayScreenTrianglePrimitive& triangle = frameData.screenTriangles.emplace_back();
|
||||
triangle.vertices[0].screenPosition = a;
|
||||
triangle.vertices[0].color = color;
|
||||
triangle.vertices[1].screenPosition = b;
|
||||
triangle.vertices[1].color = color;
|
||||
triangle.vertices[2].screenPosition = c;
|
||||
triangle.vertices[2].color = color;
|
||||
triangle.depthMode = depthMode;
|
||||
}
|
||||
|
||||
inline void AppendScreenQuad(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const Math::Vector2& a,
|
||||
const Math::Vector2& b,
|
||||
const Math::Vector2& c,
|
||||
const Math::Vector2& d,
|
||||
const Math::Color& color,
|
||||
SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop) {
|
||||
AppendScreenTriangle(frameData, a, b, c, color, depthMode);
|
||||
AppendScreenTriangle(frameData, a, c, d, color, depthMode);
|
||||
}
|
||||
|
||||
inline void AppendScreenRect(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const Math::Vector2& center,
|
||||
const Math::Vector2& halfSize,
|
||||
const Math::Color& color,
|
||||
SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop) {
|
||||
AppendScreenQuad(
|
||||
frameData,
|
||||
Math::Vector2(center.x - halfSize.x, center.y - halfSize.y),
|
||||
Math::Vector2(center.x + halfSize.x, center.y - halfSize.y),
|
||||
Math::Vector2(center.x + halfSize.x, center.y + halfSize.y),
|
||||
Math::Vector2(center.x - halfSize.x, center.y + halfSize.y),
|
||||
color,
|
||||
depthMode);
|
||||
}
|
||||
|
||||
inline void AppendScreenSegmentQuad(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const Math::Vector2& start,
|
||||
const Math::Vector2& end,
|
||||
float thicknessPixels,
|
||||
const Math::Color& color,
|
||||
SceneViewportOverlayDepthMode depthMode = SceneViewportOverlayDepthMode::AlwaysOnTop) {
|
||||
const Math::Vector2 delta = end - start;
|
||||
if (delta.SqrMagnitude() <= Math::EPSILON || thicknessPixels <= Math::EPSILON) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Math::Vector2 direction = NormalizeVector2(delta);
|
||||
const Math::Vector2 normal(-direction.y, direction.x);
|
||||
const Math::Vector2 offset = normal * (thicknessPixels * 0.5f);
|
||||
AppendScreenQuad(
|
||||
frameData,
|
||||
start + offset,
|
||||
start - offset,
|
||||
end - offset,
|
||||
end + offset,
|
||||
color,
|
||||
depthMode);
|
||||
}
|
||||
|
||||
inline void AppendScreenQuadOutline(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const std::array<Math::Vector2, 4>& corners,
|
||||
float thicknessPixels,
|
||||
const Math::Color& color) {
|
||||
for (size_t index = 0; index < corners.size(); ++index) {
|
||||
AppendScreenSegmentQuad(
|
||||
frameData,
|
||||
corners[index],
|
||||
corners[(index + 1u) % corners.size()],
|
||||
thicknessPixels,
|
||||
color);
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendScreenRectOutline(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const Math::Vector2& center,
|
||||
const Math::Vector2& halfSize,
|
||||
float thicknessPixels,
|
||||
const Math::Color& color) {
|
||||
const std::array<Math::Vector2, 4> corners = {{
|
||||
Math::Vector2(center.x - halfSize.x, center.y - halfSize.y),
|
||||
Math::Vector2(center.x + halfSize.x, center.y - halfSize.y),
|
||||
Math::Vector2(center.x + halfSize.x, center.y + halfSize.y),
|
||||
Math::Vector2(center.x - halfSize.x, center.y + halfSize.y)
|
||||
}};
|
||||
AppendScreenQuadOutline(frameData, corners, thicknessPixels, color);
|
||||
}
|
||||
|
||||
inline void AppendMoveGizmoHandleRecords(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportMoveGizmoDrawData& drawData,
|
||||
uint64_t entityId) {
|
||||
if (!drawData.visible || entityId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const SceneViewportMoveGizmoHandleDrawData& handle : drawData.handles) {
|
||||
if (!handle.visible || handle.axis == SceneViewportGizmoAxis::None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SceneViewportOverlayHandleRecord& record = frameData.handleRecords.emplace_back();
|
||||
record.kind = SceneViewportOverlayHandleKind::MoveAxis;
|
||||
record.handleId = static_cast<uint64_t>(handle.axis);
|
||||
record.entityId = entityId;
|
||||
record.shape = SceneViewportOverlayHandleShape::ScreenSegment;
|
||||
record.priority = kSceneViewportHandlePriorityMoveAxis;
|
||||
record.screenStart = handle.start;
|
||||
record.screenEnd = handle.end;
|
||||
record.hitThicknessPixels = kSceneViewportMoveAxisHitThicknessPixels;
|
||||
}
|
||||
|
||||
for (const SceneViewportMoveGizmoPlaneDrawData& plane : drawData.planes) {
|
||||
if (!plane.visible || plane.plane == SceneViewportGizmoPlane::None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SceneViewportOverlayHandleRecord& record = frameData.handleRecords.emplace_back();
|
||||
record.kind = SceneViewportOverlayHandleKind::MovePlane;
|
||||
record.handleId = static_cast<uint64_t>(plane.plane);
|
||||
record.entityId = entityId;
|
||||
record.shape = SceneViewportOverlayHandleShape::ScreenQuad;
|
||||
record.priority = kSceneViewportHandlePriorityMovePlane;
|
||||
record.screenQuad = plane.corners;
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendRotateGizmoHandleRecords(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportRotateGizmoDrawData& drawData,
|
||||
uint64_t entityId) {
|
||||
if (!drawData.visible || entityId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const SceneViewportRotateGizmoHandleDrawData& handle : drawData.handles) {
|
||||
if (!handle.visible || handle.axis == SceneViewportRotateGizmoAxis::None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const SceneViewportRotateGizmoSegmentDrawData& segment : handle.segments) {
|
||||
if (!segment.visible ||
|
||||
(handle.axis != SceneViewportRotateGizmoAxis::View && !segment.frontFacing)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SceneViewportOverlayHandleRecord& record = frameData.handleRecords.emplace_back();
|
||||
record.kind = SceneViewportOverlayHandleKind::RotateAxis;
|
||||
record.handleId = static_cast<uint64_t>(handle.axis);
|
||||
record.entityId = entityId;
|
||||
record.shape = SceneViewportOverlayHandleShape::ScreenSegment;
|
||||
record.priority = kSceneViewportHandlePriorityRotateAxis;
|
||||
record.screenStart = segment.start;
|
||||
record.screenEnd = segment.end;
|
||||
record.hitThicknessPixels = kSceneViewportRotateAxisHitThicknessPixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendScaleGizmoHandleRecords(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportScaleGizmoDrawData& drawData,
|
||||
uint64_t entityId) {
|
||||
if (!drawData.visible || entityId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawData.centerHandle.visible) {
|
||||
SceneViewportOverlayHandleRecord& uniformRecord = frameData.handleRecords.emplace_back();
|
||||
uniformRecord.kind = SceneViewportOverlayHandleKind::ScaleUniform;
|
||||
uniformRecord.handleId = static_cast<uint64_t>(SceneViewportScaleGizmoHandle::Uniform);
|
||||
uniformRecord.entityId = entityId;
|
||||
uniformRecord.shape = SceneViewportOverlayHandleShape::ScreenRect;
|
||||
uniformRecord.priority = kSceneViewportHandlePriorityScaleUniform;
|
||||
uniformRecord.screenCenter = drawData.centerHandle.center;
|
||||
uniformRecord.screenHalfSize = Math::Vector2(
|
||||
drawData.centerHandle.halfSize + kSceneViewportScaleCapHitPaddingPixels,
|
||||
drawData.centerHandle.halfSize + kSceneViewportScaleCapHitPaddingPixels);
|
||||
}
|
||||
|
||||
for (const SceneViewportScaleGizmoAxisHandleDrawData& handle : drawData.axisHandles) {
|
||||
if (!handle.visible || handle.handle == SceneViewportScaleGizmoHandle::None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SceneViewportOverlayHandleRecord& capRecord = frameData.handleRecords.emplace_back();
|
||||
capRecord.kind = SceneViewportOverlayHandleKind::ScaleAxis;
|
||||
capRecord.handleId = static_cast<uint64_t>(handle.handle);
|
||||
capRecord.entityId = entityId;
|
||||
capRecord.shape = SceneViewportOverlayHandleShape::ScreenRect;
|
||||
capRecord.priority = kSceneViewportHandlePriorityScaleAxisCap;
|
||||
capRecord.screenCenter = handle.capCenter;
|
||||
capRecord.screenHalfSize = Math::Vector2(
|
||||
handle.capHalfSize + kSceneViewportScaleCapHitPaddingPixels,
|
||||
handle.capHalfSize + kSceneViewportScaleCapHitPaddingPixels);
|
||||
|
||||
SceneViewportOverlayHandleRecord& lineRecord = frameData.handleRecords.emplace_back();
|
||||
lineRecord.kind = SceneViewportOverlayHandleKind::ScaleAxis;
|
||||
lineRecord.handleId = static_cast<uint64_t>(handle.handle);
|
||||
lineRecord.entityId = entityId;
|
||||
lineRecord.shape = SceneViewportOverlayHandleShape::ScreenSegment;
|
||||
lineRecord.priority = kSceneViewportHandlePriorityScaleAxisLine;
|
||||
lineRecord.screenStart = handle.start;
|
||||
lineRecord.screenEnd = handle.end;
|
||||
lineRecord.hitThicknessPixels = kSceneViewportScaleAxisHitThicknessPixels;
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendMoveGizmoScreenTriangles(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportMoveGizmoDrawData& drawData) {
|
||||
if (!drawData.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const SceneViewportMoveGizmoPlaneDrawData& plane : drawData.planes) {
|
||||
if (!plane.visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AppendScreenQuad(
|
||||
frameData,
|
||||
plane.corners[0],
|
||||
plane.corners[1],
|
||||
plane.corners[2],
|
||||
plane.corners[3],
|
||||
plane.fillColor);
|
||||
AppendScreenQuadOutline(
|
||||
frameData,
|
||||
plane.corners,
|
||||
plane.active ? 2.6f : (plane.hovered ? 2.0f : 1.4f),
|
||||
plane.outlineColor);
|
||||
}
|
||||
|
||||
for (const SceneViewportMoveGizmoHandleDrawData& handle : drawData.handles) {
|
||||
if (!handle.visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const float thickness = handle.active ? 4.0f : (handle.hovered ? 3.0f : 2.0f);
|
||||
const Math::Vector2 direction = NormalizeVector2(handle.end - handle.start);
|
||||
const float arrowLength =
|
||||
(std::min)(kSceneViewportMoveArrowLengthPixels, (handle.end - handle.start).Magnitude());
|
||||
const Math::Vector2 normal(-direction.y, direction.x);
|
||||
const Math::Vector2 arrowBase = handle.end - direction * arrowLength;
|
||||
const Math::Vector2 arrowLeft = arrowBase + normal * kSceneViewportMoveArrowHalfWidthPixels;
|
||||
const Math::Vector2 arrowRight = arrowBase - normal * kSceneViewportMoveArrowHalfWidthPixels;
|
||||
|
||||
AppendScreenSegmentQuad(frameData, handle.start, arrowBase, thickness, handle.color);
|
||||
AppendScreenTriangle(frameData, handle.end, arrowLeft, arrowRight, handle.color);
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendRotateGizmoHandleScreenTriangles(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportRotateGizmoHandleDrawData& handle,
|
||||
bool frontPass) {
|
||||
if (!handle.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isViewHandle = handle.axis == SceneViewportRotateGizmoAxis::View;
|
||||
if (isViewHandle && !frontPass) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float thickness = handle.active ? 3.6f : (handle.hovered ? 3.0f : 2.1f);
|
||||
for (const SceneViewportRotateGizmoSegmentDrawData& segment : handle.segments) {
|
||||
if (!segment.visible || (!isViewHandle && segment.frontFacing != frontPass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Math::Color drawColor = handle.color;
|
||||
if (!isViewHandle && !frontPass) {
|
||||
drawColor = LerpColor(handle.color, Math::Color(0.72f, 0.72f, 0.72f, 1.0f), 0.78f);
|
||||
drawColor = WithAlpha(drawColor, handle.active ? 0.55f : 0.38f);
|
||||
} else if (isViewHandle) {
|
||||
drawColor = WithAlpha(drawColor, handle.active ? 0.95f : (handle.hovered ? 0.88f : 0.78f));
|
||||
}
|
||||
|
||||
AppendScreenSegmentQuad(frameData, segment.start, segment.end, thickness, drawColor);
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendRotateGizmoAngleFillScreenTriangles(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportRotateGizmoAngleFillDrawData& angleFill) {
|
||||
if (!angleFill.visible || angleFill.arcPointCount < 2u) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t index = 0; index + 1u < angleFill.arcPointCount; ++index) {
|
||||
AppendScreenTriangle(
|
||||
frameData,
|
||||
angleFill.pivot,
|
||||
angleFill.arcPoints[index],
|
||||
angleFill.arcPoints[index + 1u],
|
||||
angleFill.fillColor);
|
||||
}
|
||||
|
||||
for (size_t index = 0; index + 1u < angleFill.arcPointCount; ++index) {
|
||||
AppendScreenSegmentQuad(
|
||||
frameData,
|
||||
angleFill.arcPoints[index],
|
||||
angleFill.arcPoints[index + 1u],
|
||||
2.0f,
|
||||
angleFill.outlineColor);
|
||||
}
|
||||
|
||||
AppendScreenSegmentQuad(
|
||||
frameData,
|
||||
angleFill.pivot,
|
||||
angleFill.arcPoints[0],
|
||||
1.6f,
|
||||
angleFill.outlineColor);
|
||||
AppendScreenSegmentQuad(
|
||||
frameData,
|
||||
angleFill.pivot,
|
||||
angleFill.arcPoints[angleFill.arcPointCount - 1u],
|
||||
1.6f,
|
||||
angleFill.outlineColor);
|
||||
}
|
||||
|
||||
inline void AppendRotateGizmoScreenTriangles(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportRotateGizmoDrawData& drawData) {
|
||||
if (!drawData.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const SceneViewportRotateGizmoHandleDrawData& handle : drawData.handles) {
|
||||
if (handle.axis == SceneViewportRotateGizmoAxis::View) {
|
||||
AppendRotateGizmoHandleScreenTriangles(frameData, handle, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (const SceneViewportRotateGizmoHandleDrawData& handle : drawData.handles) {
|
||||
if (handle.axis != SceneViewportRotateGizmoAxis::View) {
|
||||
AppendRotateGizmoHandleScreenTriangles(frameData, handle, false);
|
||||
}
|
||||
}
|
||||
|
||||
AppendRotateGizmoAngleFillScreenTriangles(frameData, drawData.angleFill);
|
||||
|
||||
for (const SceneViewportRotateGizmoHandleDrawData& handle : drawData.handles) {
|
||||
if (handle.axis != SceneViewportRotateGizmoAxis::View) {
|
||||
AppendRotateGizmoHandleScreenTriangles(frameData, handle, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendScaleGizmoScreenTriangles(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportScaleGizmoDrawData& drawData) {
|
||||
if (!drawData.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
constexpr Math::Color kScaleCapOutlineColor(24.0f / 255.0f, 24.0f / 255.0f, 24.0f / 255.0f, 220.0f / 255.0f);
|
||||
|
||||
for (const SceneViewportScaleGizmoAxisHandleDrawData& handle : drawData.axisHandles) {
|
||||
if (!handle.visible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const float thickness = handle.active ? 4.0f : (handle.hovered ? 3.0f : 2.2f);
|
||||
const Math::Vector2 direction = NormalizeVector2(handle.capCenter - handle.start);
|
||||
const Math::Vector2 lineEnd = handle.capCenter - direction * handle.capHalfSize;
|
||||
const Math::Vector2 capHalfSize(handle.capHalfSize, handle.capHalfSize);
|
||||
AppendScreenSegmentQuad(frameData, handle.start, lineEnd, thickness, handle.color);
|
||||
AppendScreenRect(frameData, handle.capCenter, capHalfSize, handle.color);
|
||||
AppendScreenRectOutline(
|
||||
frameData,
|
||||
handle.capCenter,
|
||||
capHalfSize,
|
||||
handle.active ? 2.0f : 1.0f,
|
||||
kScaleCapOutlineColor);
|
||||
}
|
||||
|
||||
if (drawData.centerHandle.visible) {
|
||||
const Math::Vector2 halfSize(drawData.centerHandle.halfSize, drawData.centerHandle.halfSize);
|
||||
AppendScreenRect(
|
||||
frameData,
|
||||
drawData.centerHandle.center,
|
||||
halfSize,
|
||||
drawData.centerHandle.fillColor);
|
||||
AppendScreenRectOutline(
|
||||
frameData,
|
||||
drawData.centerHandle.center,
|
||||
halfSize,
|
||||
drawData.centerHandle.active ? 2.0f : 1.0f,
|
||||
drawData.centerHandle.outlineColor);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Detail
|
||||
|
||||
inline void AppendTransformGizmoHandleRecords(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportTransformGizmoHandleBuildInputs& inputs) {
|
||||
if (inputs.moveGizmo != nullptr) {
|
||||
Detail::AppendMoveGizmoHandleRecords(frameData, *inputs.moveGizmo, inputs.moveEntityId);
|
||||
}
|
||||
|
||||
if (inputs.rotateGizmo != nullptr) {
|
||||
Detail::AppendRotateGizmoHandleRecords(frameData, *inputs.rotateGizmo, inputs.rotateEntityId);
|
||||
}
|
||||
|
||||
if (inputs.scaleGizmo != nullptr) {
|
||||
Detail::AppendScaleGizmoHandleRecords(frameData, *inputs.scaleGizmo, inputs.scaleEntityId);
|
||||
}
|
||||
}
|
||||
|
||||
inline void AppendTransformGizmoScreenTriangles(
|
||||
SceneViewportOverlayFrameData& frameData,
|
||||
const SceneViewportTransformGizmoHandleBuildInputs& inputs) {
|
||||
if (inputs.moveGizmo != nullptr) {
|
||||
Detail::AppendMoveGizmoScreenTriangles(frameData, *inputs.moveGizmo);
|
||||
}
|
||||
|
||||
if (inputs.rotateGizmo != nullptr) {
|
||||
Detail::AppendRotateGizmoScreenTriangles(frameData, *inputs.rotateGizmo);
|
||||
}
|
||||
|
||||
if (inputs.scaleGizmo != nullptr) {
|
||||
Detail::AppendScaleGizmoScreenTriangles(frameData, *inputs.scaleGizmo);
|
||||
}
|
||||
}
|
||||
|
||||
inline SceneViewportOverlayFrameData BuildSceneViewportTransformGizmoOverlayFrameData(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const SceneViewportTransformGizmoHandleBuildInputs& inputs) {
|
||||
SceneViewportOverlayFrameData frameData = {};
|
||||
frameData.overlay = overlay;
|
||||
AppendTransformGizmoScreenTriangles(frameData, inputs);
|
||||
AppendTransformGizmoHandleRecords(frameData, inputs);
|
||||
return frameData;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user