refactor: extract viewport object id picker
This commit is contained in:
95
editor/src/Viewport/ViewportObjectIdPicker.h
Normal file
95
editor/src/Viewport/ViewportObjectIdPicker.h
Normal file
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include "ViewportHostSurfaceUtils.h"
|
||||
|
||||
#include <XCEngine/RHI/RHICommandQueue.h>
|
||||
#include <XCEngine/RHI/RHIEnums.h>
|
||||
#include <XCEngine/RHI/RHITexture.h>
|
||||
#include <XCEngine/Rendering/ObjectIdEncoding.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
struct ViewportObjectIdPickContext {
|
||||
RHI::RHICommandQueue* commandQueue = nullptr;
|
||||
RHI::RHITexture* texture = nullptr;
|
||||
RHI::ResourceStates textureState = RHI::ResourceStates::Common;
|
||||
uint32_t textureWidth = 0;
|
||||
uint32_t textureHeight = 0;
|
||||
bool hasValidFrame = false;
|
||||
ImVec2 viewportSize = ImVec2(0.0f, 0.0f);
|
||||
ImVec2 viewportMousePosition = ImVec2(0.0f, 0.0f);
|
||||
};
|
||||
|
||||
struct ViewportObjectIdReadbackRequest {
|
||||
RHI::RHICommandQueue* commandQueue = nullptr;
|
||||
RHI::RHITexture* texture = nullptr;
|
||||
RHI::ResourceStates textureState = RHI::ResourceStates::Common;
|
||||
uint32_t pixelX = 0;
|
||||
uint32_t pixelY = 0;
|
||||
};
|
||||
|
||||
inline bool CanPickViewportObjectId(const ViewportObjectIdPickContext& context) {
|
||||
return context.commandQueue != nullptr &&
|
||||
context.texture != nullptr &&
|
||||
context.textureWidth > 0 &&
|
||||
context.textureHeight > 0 &&
|
||||
context.hasValidFrame &&
|
||||
context.viewportSize.x > 1.0f &&
|
||||
context.viewportSize.y > 1.0f &&
|
||||
context.viewportMousePosition.x >= 0.0f &&
|
||||
context.viewportMousePosition.y >= 0.0f &&
|
||||
context.viewportMousePosition.x <= context.viewportSize.x &&
|
||||
context.viewportMousePosition.y <= context.viewportSize.y;
|
||||
}
|
||||
|
||||
inline bool BuildViewportObjectIdReadbackRequest(
|
||||
const ViewportObjectIdPickContext& context,
|
||||
ViewportObjectIdReadbackRequest& outRequest) {
|
||||
outRequest = {};
|
||||
if (!CanPickViewportObjectId(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outRequest.commandQueue = context.commandQueue;
|
||||
outRequest.texture = context.texture;
|
||||
outRequest.textureState = context.textureState;
|
||||
outRequest.pixelX = ClampViewportPixelCoordinate(
|
||||
context.viewportMousePosition.x,
|
||||
context.textureWidth);
|
||||
outRequest.pixelY = ClampViewportPixelCoordinate(
|
||||
context.viewportMousePosition.y,
|
||||
context.textureHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ReadPixelFn>
|
||||
bool TryPickViewportObjectIdEntity(
|
||||
const ViewportObjectIdPickContext& context,
|
||||
ReadPixelFn&& readPixel,
|
||||
uint64_t& outEntityId) {
|
||||
outEntityId = 0;
|
||||
|
||||
ViewportObjectIdReadbackRequest request = {};
|
||||
if (!BuildViewportObjectIdReadbackRequest(context, request)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::array<uint8_t, 4> rgba = {};
|
||||
if (!readPixel(request, rgba)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outEntityId = static_cast<uint64_t>(Rendering::DecodeObjectIdFromColor(
|
||||
rgba[0],
|
||||
rgba[1],
|
||||
rgba[2],
|
||||
rgba[3]));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user