Files
Aethera/render_3D/tests/Visual_Tests.cpp
T
2026-09-03 16:57:18 +08:00

99 lines
4.7 KiB
C++

#include <render_3D/Render_3D.hpp>
#include <cmath>
#include <gtest/gtest.h>
#include <type_traits>
namespace aethera::render_3d {
namespace {
template <typename Visual, typename Item>
void verify_visual(Item valid, Item invalid) {
EXPECT_TRUE(Visual::Specification::valid(valid));
EXPECT_FALSE(Visual::Specification::valid(invalid));
typename Visual::Builder builder;
builder
.template set<typename Visual::Frame_Tag>([&](typename Visual::Frame& frame) { frame.items = {valid}; });
auto object = builder.build();
ASSERT_TRUE(object);
ASSERT_TRUE(object->model_initialized());
object->template get<typename Visual::Frame_Tag>([&](const typename Visual::Frame& frame) {
ASSERT_EQ(frame.items.size(), 1U);
EXPECT_EQ(frame.items.front(), valid);
});
auto renderable = model_proxy_view<scene::Renderable>(*object);
ASSERT_TRUE(renderable);
EXPECT_NO_THROW(renderable->advance());
EXPECT_TRUE(renderable->taskflow());
EXPECT_EQ(std::addressof(renderable->use()), std::addressof(Visual::Specification::datoviz_operations()));
}
} // namespace
TEST(Render_3D_Visual, Migrated_Families_Use_Current_Model_And_Validate) {
verify_visual<Point_Visual>(Point{}, Point{.diameter_px = 0.0F});
verify_visual<Splat_Visual>(Splat{}, Splat{.sigma = {0.0F, 0.0F}});
verify_visual<Pixel_Visual>(Pixel{}, Pixel{.size_px = 0.0F});
verify_visual<Marker_Visual>(Marker{}, Marker{.diameter_px = 0.0F});
verify_visual<Sphere_Visual>(Sphere{}, Sphere{.radius = 0.0F});
verify_visual<Segment_Visual>(Segment{}, Segment{.width_px = 0.0F});
verify_visual<Vector_Visual>(Vector_Glyph{}, Vector_Glyph{.width_px = 0.0F});
verify_visual<Primitive_Visual>(Primitive_Vertex{}, Primitive_Vertex{.position = {NAN, 0.0F, 0.0F}});
verify_visual<Mesh_Visual>(Mesh_Vertex{}, Mesh_Vertex{.normal = {NAN, 0.0F, 0.0F}});
verify_visual<Path_Visual>(Path_Vertex{}, Path_Vertex{.width_px = 0.0F});
verify_visual<Image_Visual>(Image{}, Image{.extent = {0.0F, 0.0F}});
verify_visual<Labels_Visual>(Label{}, Label{.extent = {0.0F, 0.0F}});
verify_visual<Glyph_Visual>(Glyph{}, Glyph{.angle = NAN});
verify_visual<Text_Visual>(Text_Label{.text = "A"}, Text_Label{});
verify_visual<Volume_Visual>(Voxel{}, Voxel{.value = NAN});
}
TEST(Render_3D_Scene, Builder_Owns_Current_Renderable_Dag) {
auto camera = Camera_3D::Builder{}.build();
auto axes = Axes_3D::Builder{}.build();
ASSERT_TRUE(camera);
ASSERT_TRUE(axes);
Dag_Relation<scene::Renderable>::Builder dag_builder;
dag_builder
.add({1}, make_model_proxy<scene::Renderable, Point_Visual>());
auto dag = dag_builder.build();
ASSERT_TRUE(dag.has_value());
Render_Scene_3D::Builder scene_builder(*camera, *axes);
scene_builder
.relation<aethera::scene::Renderable>([graph = std::move(*dag)](auto& relation) mutable { relation = std::move(graph); });
static_assert(std::same_as<decltype(scene_builder.build()), std::unique_ptr<Render_Scene_3D>>);
auto scene = scene_builder.build();
ASSERT_TRUE(scene);
EXPECT_TRUE(scene->model_initialized());
auto& relation = aethera::detail::model_private(*scene).relation<aethera::scene::Renderable>();
static_assert(std::same_as<typename std::remove_reference_t<decltype(relation)>::Node, scene::Renderable>);
std::size_t node_count{};
relation.for_each_topological([&](auto, auto&) { ++node_count; });
EXPECT_EQ(node_count, 1U);
}
TEST(Render_3D_Visual, Prepared_Data_Preserves_Datoviz_Attributes) {
detail::Mesh_Prepared_Data mesh;
detail::Mesh_Spec::prepare(std::vector<Mesh_Vertex>{{.texture_coordinate = {0.25F, 0.75F}}}, mesh);
ASSERT_EQ(mesh.texture_coordinates.size(), 1U);
EXPECT_EQ(mesh.texture_coordinates.front(), (std::array<float, 2>{0.25F, 0.75F}));
detail::Image_Prepared_Data image;
detail::Image_Spec::prepare(std::vector<Image>{{.texture_rectangle = {0.1F, 0.2F, 0.8F, 0.9F}}}, image);
EXPECT_EQ(image.texture_rectangles.front(), (std::array<float, 4>{0.1F, 0.2F, 0.8F, 0.9F}));
detail::Glyph_Prepared_Data glyph;
detail::Glyph_Spec::prepare(std::vector<Glyph>{{.bounds = {-1.0F, -2.0F, 3.0F, 4.0F}, .texture_coordinates = {0.0F, 0.1F, 0.9F, 1.0F}, .angle = 0.5F}}, glyph);
EXPECT_EQ(glyph.bounds.front(), (std::array<float, 4>{-1.0F, -2.0F, 3.0F, 4.0F}));
EXPECT_EQ(glyph.texture_coordinates.front(), (std::array<float, 4>{0.0F, 0.1F, 0.9F, 1.0F}));
detail::Text_Prepared_Data text;
detail::Text_Spec::prepare(std::vector<Text_Label>{{.text = "dynamic", .size_px = 23.0F}}, text);
ASSERT_EQ(text.strings.size(), 1U);
EXPECT_EQ(text.strings.front(), "dynamic");
EXPECT_FLOAT_EQ(text.sizes.front(), 23.0F);
}
} // namespace aethera::render_3d