Formalize object id encoding contract
This commit is contained in:
@@ -1,18 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Core/Types.h>
|
||||
#include <XCEngine/Core/Math/Vector4.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
inline uint32_t EncodeObjectIdToUInt32(uint64_t objectId) {
|
||||
return static_cast<uint32_t>(objectId & 0xFFFFFFFFull);
|
||||
using EncodedObjectId = Core::uint32;
|
||||
|
||||
// Object-id render targets store only the low 32 bits of a runtime object id.
|
||||
// This codec is for editor/runtime picking surfaces, not for persistent ids.
|
||||
inline bool CanEncodeObjectIdWithoutLoss(Core::uint64 objectId) {
|
||||
return (objectId & 0xFFFFFFFF00000000ull) == 0ull;
|
||||
}
|
||||
|
||||
inline Math::Vector4 EncodeObjectIdToColor(uint64_t objectId) {
|
||||
const uint32_t encodedId = EncodeObjectIdToUInt32(objectId);
|
||||
inline EncodedObjectId EncodeObjectIdToEncodedId(Core::uint64 objectId) {
|
||||
return static_cast<EncodedObjectId>(objectId & 0xFFFFFFFFull);
|
||||
}
|
||||
|
||||
inline EncodedObjectId EncodeObjectIdToUInt32(Core::uint64 objectId) {
|
||||
return EncodeObjectIdToEncodedId(objectId);
|
||||
}
|
||||
|
||||
inline Math::Vector4 EncodeObjectIdToColor(Core::uint64 objectId) {
|
||||
const EncodedObjectId encodedId = EncodeObjectIdToEncodedId(objectId);
|
||||
constexpr float kInv255 = 1.0f / 255.0f;
|
||||
return Math::Vector4(
|
||||
static_cast<float>((encodedId >> 0) & 0xFFu) * kInv255,
|
||||
@@ -21,11 +32,23 @@ inline Math::Vector4 EncodeObjectIdToColor(uint64_t objectId) {
|
||||
static_cast<float>((encodedId >> 24) & 0xFFu) * kInv255);
|
||||
}
|
||||
|
||||
inline uint32_t DecodeObjectIdFromColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
||||
return static_cast<uint32_t>(r) |
|
||||
(static_cast<uint32_t>(g) << 8u) |
|
||||
(static_cast<uint32_t>(b) << 16u) |
|
||||
(static_cast<uint32_t>(a) << 24u);
|
||||
inline EncodedObjectId DecodeEncodedObjectIdFromColor(
|
||||
Core::uint8 r,
|
||||
Core::uint8 g,
|
||||
Core::uint8 b,
|
||||
Core::uint8 a) {
|
||||
return static_cast<EncodedObjectId>(r) |
|
||||
(static_cast<EncodedObjectId>(g) << 8u) |
|
||||
(static_cast<EncodedObjectId>(b) << 16u) |
|
||||
(static_cast<EncodedObjectId>(a) << 24u);
|
||||
}
|
||||
|
||||
inline Core::uint64 DecodeObjectIdFromColor(
|
||||
Core::uint8 r,
|
||||
Core::uint8 g,
|
||||
Core::uint8 b,
|
||||
Core::uint8 a) {
|
||||
return static_cast<Core::uint64>(DecodeEncodedObjectIdFromColor(r, g, b, a));
|
||||
}
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -4,9 +4,8 @@ project(XCEngine_RenderingUnitTests)
|
||||
|
||||
set(RENDERING_UNIT_TEST_SOURCES
|
||||
test_render_pass.cpp
|
||||
test_object_id_encoding.cpp
|
||||
test_builtin_forward_pipeline.cpp
|
||||
test_builtin_post_process_pass_plan.cpp
|
||||
test_builtin_post_process_pass_sequence_builder.cpp
|
||||
test_camera_scene_renderer.cpp
|
||||
test_scene_render_request_planner.cpp
|
||||
test_scene_render_request_utils.cpp
|
||||
|
||||
33
tests/Rendering/unit/test_object_id_encoding.cpp
Normal file
33
tests/Rendering/unit/test_object_id_encoding.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEngine/Rendering/ObjectIdEncoding.h>
|
||||
|
||||
using namespace XCEngine::Rendering;
|
||||
|
||||
TEST(ObjectIdEncoding_Test, EncodesOnlyLow32BitsIntoPickingId) {
|
||||
constexpr uint64_t objectId = 0x123456789ABCDEF0ull;
|
||||
|
||||
EXPECT_FALSE(CanEncodeObjectIdWithoutLoss(objectId));
|
||||
EXPECT_EQ(EncodeObjectIdToEncodedId(objectId), 0x9ABCDEF0u);
|
||||
EXPECT_EQ(EncodeObjectIdToUInt32(objectId), 0x9ABCDEF0u);
|
||||
}
|
||||
|
||||
TEST(ObjectIdEncoding_Test, DecodesColorBackToWidenedRuntimeId) {
|
||||
constexpr uint8_t r = 0x12u;
|
||||
constexpr uint8_t g = 0x34u;
|
||||
constexpr uint8_t b = 0x56u;
|
||||
constexpr uint8_t a = 0x78u;
|
||||
|
||||
EXPECT_EQ(DecodeEncodedObjectIdFromColor(r, g, b, a), 0x78563412u);
|
||||
EXPECT_EQ(DecodeObjectIdFromColor(r, g, b, a), 0x78563412ull);
|
||||
}
|
||||
|
||||
TEST(ObjectIdEncoding_Test, EncodesColorChannelsFromLow32Bits) {
|
||||
const auto encodedColor = EncodeObjectIdToColor(0x78563412ull);
|
||||
constexpr float kInv255 = 1.0f / 255.0f;
|
||||
|
||||
EXPECT_FLOAT_EQ(encodedColor.x, 0x12u * kInv255);
|
||||
EXPECT_FLOAT_EQ(encodedColor.y, 0x34u * kInv255);
|
||||
EXPECT_FLOAT_EQ(encodedColor.z, 0x56u * kInv255);
|
||||
EXPECT_FLOAT_EQ(encodedColor.w, 0x78u * kInv255);
|
||||
}
|
||||
Reference in New Issue
Block a user