Files
XCEngine/tests/editor/test_viewport_object_id_picker.cpp

179 lines
6.3 KiB
C++

#include <gtest/gtest.h>
#include "Viewport/ViewportObjectIdPicker.h"
#include <cstdint>
namespace {
using XCEngine::Editor::BuildViewportObjectIdReadbackRequest;
using XCEngine::Editor::CanPickViewportObjectId;
using XCEngine::Editor::PickViewportObjectIdEntity;
using XCEngine::Editor::TryPickViewportObjectIdEntity;
using XCEngine::Editor::ViewportObjectIdPickContext;
using XCEngine::Editor::ViewportObjectIdPickResult;
using XCEngine::Editor::ViewportObjectIdPickStatus;
using XCEngine::Editor::ViewportObjectIdReadbackRequest;
using XCEngine::RHI::RHICommandQueue;
using XCEngine::RHI::RHITexture;
using XCEngine::RHI::ResourceStates;
using XCEngine::Rendering::kInvalidRenderObjectId;
using XCEngine::UI::UIPoint;
using XCEngine::UI::UISize;
RHICommandQueue* MakeDummyQueue() {
return reinterpret_cast<RHICommandQueue*>(static_cast<uintptr_t>(0x1));
}
RHITexture* MakeDummyTexture() {
return reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0x2));
}
ViewportObjectIdPickContext CreateValidContext() {
ViewportObjectIdPickContext context = {};
context.commandQueue = MakeDummyQueue();
context.texture = MakeDummyTexture();
context.textureState = ResourceStates::PixelShaderResource;
context.textureWidth = 1280;
context.textureHeight = 720;
context.hasValidFrame = true;
context.viewportSize = UISize(1280.0f, 720.0f);
context.viewportMousePosition = UIPoint(640.0f, 360.0f);
return context;
}
TEST(ViewportObjectIdPickerTest, CanPickRejectsMissingOrOutOfBoundsInputs) {
ViewportObjectIdPickContext context = CreateValidContext();
EXPECT_TRUE(CanPickViewportObjectId(context));
context.commandQueue = nullptr;
EXPECT_FALSE(CanPickViewportObjectId(context));
context = CreateValidContext();
context.texture = nullptr;
EXPECT_FALSE(CanPickViewportObjectId(context));
context = CreateValidContext();
context.hasValidFrame = false;
EXPECT_FALSE(CanPickViewportObjectId(context));
context = CreateValidContext();
context.textureWidth = 0;
EXPECT_FALSE(CanPickViewportObjectId(context));
context = CreateValidContext();
context.viewportMousePosition = UIPoint(-1.0f, 10.0f);
EXPECT_FALSE(CanPickViewportObjectId(context));
context = CreateValidContext();
context.viewportMousePosition = UIPoint(10.0f, 721.0f);
EXPECT_FALSE(CanPickViewportObjectId(context));
}
TEST(ViewportObjectIdPickerTest, BuildReadbackRequestMapsViewportCoordinatesToTexturePixels) {
ViewportObjectIdPickContext context = CreateValidContext();
context.viewportMousePosition = UIPoint(1280.0f, 720.0f);
ViewportObjectIdReadbackRequest request = {};
ASSERT_TRUE(BuildViewportObjectIdReadbackRequest(context, request));
EXPECT_EQ(request.commandQueue, context.commandQueue);
EXPECT_EQ(request.texture, context.texture);
EXPECT_EQ(request.textureState, ResourceStates::PixelShaderResource);
EXPECT_EQ(request.pixelX, 1279u);
EXPECT_EQ(request.pixelY, 719u);
}
TEST(ViewportObjectIdPickerTest, TryPickViewportObjectIdEntityDecodesReadbackColor) {
const ViewportObjectIdPickContext context = CreateValidContext();
const ViewportObjectIdPickResult result = PickViewportObjectIdEntity(
context,
[](const ViewportObjectIdReadbackRequest&, std::array<uint8_t, 4>& outRgba) {
outRgba = { 0x78, 0x56, 0x34, 0x12 };
return true;
});
EXPECT_EQ(result.renderObjectId, 0x12345678u);
EXPECT_EQ(result.entityId, 0x12345678ull);
EXPECT_TRUE(result.HasResolvedSample());
uint64_t entityId = 0;
ViewportObjectIdReadbackRequest capturedRequest = {};
const bool picked = TryPickViewportObjectIdEntity(
context,
[&capturedRequest](const ViewportObjectIdReadbackRequest& request, std::array<uint8_t, 4>& outRgba) {
capturedRequest = request;
outRgba = { 0x78, 0x56, 0x34, 0x12 };
return true;
},
entityId);
EXPECT_TRUE(picked);
EXPECT_EQ(entityId, 0x12345678ull);
EXPECT_EQ(capturedRequest.pixelX, 640u);
EXPECT_EQ(capturedRequest.pixelY, 360u);
}
TEST(ViewportObjectIdPickerTest, PickViewportObjectIdEntityReturnsSuccessForZeroObjectId) {
const ViewportObjectIdPickContext context = CreateValidContext();
const ViewportObjectIdPickResult result = PickViewportObjectIdEntity(
context,
[](const ViewportObjectIdReadbackRequest&, std::array<uint8_t, 4>& outRgba) {
outRgba = { 0u, 0u, 0u, 0u };
return true;
});
EXPECT_EQ(result.status, ViewportObjectIdPickStatus::Success);
EXPECT_EQ(result.renderObjectId, kInvalidRenderObjectId);
EXPECT_EQ(result.entityId, 0u);
EXPECT_TRUE(result.HasResolvedSample());
}
TEST(ViewportObjectIdPickerTest, PickViewportObjectIdEntityReturnsUnavailableWhenContextIsInvalid) {
ViewportObjectIdPickContext context = CreateValidContext();
context.hasValidFrame = false;
const ViewportObjectIdPickResult result = PickViewportObjectIdEntity(
context,
[](const ViewportObjectIdReadbackRequest&, std::array<uint8_t, 4>&) {
return true;
});
EXPECT_EQ(result.status, ViewportObjectIdPickStatus::Unavailable);
EXPECT_EQ(result.renderObjectId, kInvalidRenderObjectId);
EXPECT_EQ(result.entityId, 0u);
EXPECT_FALSE(result.HasResolvedSample());
}
TEST(ViewportObjectIdPickerTest, TryPickViewportObjectIdEntityFailsWhenReadbackFails) {
const ViewportObjectIdPickContext context = CreateValidContext();
uint64_t entityId = 99;
const bool picked = TryPickViewportObjectIdEntity(
context,
[](const ViewportObjectIdReadbackRequest&, std::array<uint8_t, 4>&) {
return false;
},
entityId);
EXPECT_FALSE(picked);
EXPECT_EQ(entityId, 0u);
}
TEST(ViewportObjectIdPickerTest, PickViewportObjectIdEntityReportsReadbackFailure) {
const ViewportObjectIdPickContext context = CreateValidContext();
const ViewportObjectIdPickResult result = PickViewportObjectIdEntity(
context,
[](const ViewportObjectIdReadbackRequest&, std::array<uint8_t, 4>&) {
return false;
});
EXPECT_EQ(result.status, ViewportObjectIdPickStatus::ReadbackFailed);
EXPECT_EQ(result.renderObjectId, kInvalidRenderObjectId);
EXPECT_EQ(result.entityId, 0u);
EXPECT_FALSE(result.HasResolvedSample());
}
} // namespace