#include #include #include using namespace XCEngine::Resources; using namespace XCEngine::Math; namespace { TEST(GaussianSplat, ResolvesSHOrderFromCoefficientCount) { EXPECT_EQ(ResolveGaussianSplatSHOrderFromCoefficientCount(0u), 0u); EXPECT_EQ(ResolveGaussianSplatSHOrderFromCoefficientCount(9u), 1u); EXPECT_EQ(ResolveGaussianSplatSHOrderFromCoefficientCount(24u), 2u); EXPECT_EQ(ResolveGaussianSplatSHOrderFromCoefficientCount(45u), 3u); EXPECT_EQ(ResolveGaussianSplatSHOrderFromCoefficientCount(46u), 0u); } TEST(GaussianSplat, CreateOwnedStoresMetadataSectionsAndPayload) { GaussianSplat gaussianSplat; GaussianSplatMetadata metadata; metadata.contentVersion = 7u; metadata.splatCount = 2u; metadata.bounds.SetMinMax(Vector3(-1.0f, -2.0f, -3.0f), Vector3(4.0f, 5.0f, 6.0f)); metadata.positionFormat = GaussianSplatSectionFormat::VectorFloat32; metadata.otherFormat = GaussianSplatSectionFormat::OtherFloat32; metadata.colorFormat = GaussianSplatSectionFormat::ColorRGBA32F; metadata.shFormat = GaussianSplatSectionFormat::SHFloat32; XCEngine::Containers::Array sections; sections.PushBack(GaussianSplatSection{ GaussianSplatSectionType::Positions, GaussianSplatSectionFormat::VectorFloat32, 0u, 24u, 2u, 12u }); XCEngine::Containers::Array payload; payload.Resize(24u); for (size_t index = 0; index < payload.Size(); ++index) { payload[index] = static_cast(index); } ASSERT_TRUE(gaussianSplat.CreateOwned(metadata, std::move(sections), std::move(payload))); EXPECT_TRUE(gaussianSplat.IsValid()); EXPECT_EQ(gaussianSplat.GetType(), ResourceType::GaussianSplat); EXPECT_EQ(gaussianSplat.GetContentVersion(), 7u); EXPECT_EQ(gaussianSplat.GetSplatCount(), 2u); EXPECT_EQ(gaussianSplat.GetBounds().GetMin(), Vector3(-1.0f, -2.0f, -3.0f)); EXPECT_EQ(gaussianSplat.GetBounds().GetMax(), Vector3(4.0f, 5.0f, 6.0f)); ASSERT_NE(gaussianSplat.FindSection(GaussianSplatSectionType::Positions), nullptr); EXPECT_EQ(gaussianSplat.GetPayloadSize(), 24u); EXPECT_NE(gaussianSplat.GetSectionData(GaussianSplatSectionType::Positions), nullptr); } TEST(GaussianSplat, GetSHOrderUsesSHSectionStride) { GaussianSplat gaussianSplat; GaussianSplatMetadata metadata; metadata.splatCount = 1u; XCEngine::Containers::Array sections; sections.PushBack(GaussianSplatSection{ GaussianSplatSectionType::SH, GaussianSplatSectionFormat::SHFloat32, 0u, 96u, 1u, 96u }); XCEngine::Containers::Array payload; payload.Resize(96u); ASSERT_TRUE(gaussianSplat.CreateOwned(metadata, std::move(sections), std::move(payload))); EXPECT_EQ(gaussianSplat.GetSHOrder(), 2u); } TEST(GaussianSplat, RejectsInvalidSectionLayout) { GaussianSplat gaussianSplat; GaussianSplatMetadata metadata; metadata.splatCount = 1u; XCEngine::Containers::Array sections; sections.PushBack(GaussianSplatSection{ GaussianSplatSectionType::Positions, GaussianSplatSectionFormat::VectorFloat32, 16u, 16u, 1u, 12u }); XCEngine::Containers::Array payload; payload.Resize(24u); EXPECT_FALSE(gaussianSplat.CreateOwned(metadata, std::move(sections), std::move(payload))); } } // namespace