refactor: formalize scene viewport object-id picking

This commit is contained in:
2026-04-02 15:23:25 +08:00
parent 617b11f801
commit a5d2058818
3 changed files with 119 additions and 31 deletions

View File

@@ -9,6 +9,7 @@
#include <array>
#include <cstdint>
#include <utility>
namespace XCEngine {
namespace Editor {
@@ -32,6 +33,21 @@ struct ViewportObjectIdReadbackRequest {
uint32_t pixelY = 0;
};
enum class ViewportObjectIdPickStatus : uint8_t {
Unavailable = 0,
Success,
ReadbackFailed
};
struct ViewportObjectIdPickResult {
ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable;
uint64_t entityId = 0;
bool HasResolvedSample() const {
return status == ViewportObjectIdPickStatus::Success;
}
};
inline bool CanPickViewportObjectId(const ViewportObjectIdPickContext& context) {
return context.commandQueue != nullptr &&
context.texture != nullptr &&
@@ -67,28 +83,40 @@ inline bool BuildViewportObjectIdReadbackRequest(
}
template <typename ReadPixelFn>
bool TryPickViewportObjectIdEntity(
ViewportObjectIdPickResult PickViewportObjectIdEntity(
const ViewportObjectIdPickContext& context,
ReadPixelFn&& readPixel,
uint64_t& outEntityId) {
outEntityId = 0;
ReadPixelFn&& readPixel) {
ViewportObjectIdPickResult result = {};
ViewportObjectIdReadbackRequest request = {};
if (!BuildViewportObjectIdReadbackRequest(context, request)) {
return false;
return result;
}
std::array<uint8_t, 4> rgba = {};
if (!readPixel(request, rgba)) {
return false;
result.status = ViewportObjectIdPickStatus::ReadbackFailed;
return result;
}
outEntityId = static_cast<uint64_t>(Rendering::DecodeObjectIdFromColor(
result.status = ViewportObjectIdPickStatus::Success;
result.entityId = static_cast<uint64_t>(Rendering::DecodeObjectIdFromColor(
rgba[0],
rgba[1],
rgba[2],
rgba[3]));
return true;
return result;
}
template <typename ReadPixelFn>
bool TryPickViewportObjectIdEntity(
const ViewportObjectIdPickContext& context,
ReadPixelFn&& readPixel,
uint64_t& outEntityId) {
const ViewportObjectIdPickResult result =
PickViewportObjectIdEntity(context, std::forward<ReadPixelFn>(readPixel));
outEntityId = result.entityId;
return result.HasResolvedSample();
}
} // namespace Editor