MathLib
Loading...
Searching...
No Matches
TestHierarchicalCoordinateSystem.cpp
Go to the documentation of this file.
3#include <cassert>
4#include <iostream>
5#include <format>
6#include <cstdlib>
7
8
23using namespace Math;
24using namespace Math::Literals;
25
26static std::shared_ptr<SceneNodef> GenerateHierarchicalSkeleton(HierarchicalCoordinateSystemf &world)
27{
28 std::shared_ptr<SceneNodef> waist{ world.root().createChildNode( Vector3Df::zero(), Quaternionf::identity(), "waist" ) };
29
30 // Lower parts
31 std::shared_ptr<SceneNodef> left_upper_leg{ waist->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "left_upper_leg" ) };
32 std::shared_ptr<SceneNodef> right_upper_leg{ waist->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "right_upper_leg" ) };
33
34 std::shared_ptr<SceneNodef> left_lower_leg{ left_upper_leg->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "left_lower_leg" ) };
35 std::shared_ptr<SceneNodef> right_lower_leg{ right_upper_leg->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "right_lower_leg" ) };
36
37 std::shared_ptr<SceneNodef> left_foot{ left_lower_leg->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "left_foot" ) };
38 std::shared_ptr<SceneNodef> right_foot{ right_lower_leg->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "right_foot" ) };
39
40 // Upper parts
41 std::shared_ptr<SceneNodef> torso_1{ waist->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "torso_1" ) };
42 std::shared_ptr<SceneNodef> torso_2{ torso_1->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "torso_2" ) };
43 std::shared_ptr<SceneNodef> torso_3{ torso_2->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "torso_3" ) };
44
45 std::shared_ptr<SceneNodef> left_upper_arm{ torso_3->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "left_upper_arm" ) };
46 std::shared_ptr<SceneNodef> right_upper_arm{ torso_3->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "right_upper_arm" ) };
47
48 std::shared_ptr<SceneNodef> left_lower_arm{ left_upper_arm->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "left_lower_arm" ) };
49 std::shared_ptr<SceneNodef> right_lower_arm{ right_upper_arm->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "right_lower_arm" ) };
50
51 std::shared_ptr<SceneNodef> left_hand{ left_lower_arm->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "left_hand" ) };
52 std::shared_ptr<SceneNodef> right_hand{ right_lower_arm->createChildNode( Vector3Df::zero(), Quaternionf::identity(), "right_hand" ) };
53
54 return waist;
55}
56
57int NumParents(std::shared_ptr<SceneNodef> node, std::shared_ptr<SceneNodef> relative_to)
58{
59 if (node == relative_to)
60 return 0; // We are relative to this, so 0 by definition!
61
62 if (node->parent().use_count() == 0)
63 return 0; // No parent!
64
65 return NumParents(node->parent().lock(), relative_to) + 1;
66}
67
68void PrintNode(std::shared_ptr<SceneNodef> node, std::shared_ptr<SceneNodef> relative_to)
69{
70 int num_parents = NumParents(node, relative_to);
71
72 for (int i = 0; i < num_parents; ++i)
73 std::cout << '\t';
74
75 std::cout << std::format("{}", node->name()) << std::endl;
76}
77
78void PrintHierarchyRecursive(std::shared_ptr<SceneNodef> root, std::shared_ptr<SceneNodef> relative_to = nullptr)
79{
80 PrintNode(root, relative_to);
81 for (auto child : root->children())
82 PrintHierarchyRecursive(child, relative_to);
83}
84
85void PrintHierarchy(std::shared_ptr<SceneNodef> root)
86{
87 PrintHierarchyRecursive(root, root);
88}
89
94{
95
97{
98 std::cout << __func__ << std::endl;
99
100 HierarchicalCoordinateSystemf scene;
101
102 assert( scene.root().parent().expired() );
103 assert( scene.root().children().empty() );
104}
105
107{
108 std::cout << __func__ << std::endl;
109
110 HierarchicalCoordinateSystemf scene;
111
112 assert( scene.root().parent().expired() );
113 assert( scene.root().children().empty() );
114
115 auto wp = scene.root().createChildNode( { 1.0f, 2.0f, 3.0f }, Quaternionf::make_rotation( 120.0_deg_f, { 1.0f, 1.0f, 1.0f } ) );
116
117 assert( scene.root().children().size() == 1 );
118 assert( wp.lock() == scene.root().children().back() );
119 assert( scene.root().children().back()->parent().lock().get() == &scene.root() );
120}
121
123{
124 std::cout << __func__ << std::endl;
125
126 // One child node that has only a translation
127 {
128 HierarchicalCoordinateSystemf scene;
129
130 std::shared_ptr<SceneNodef> translation_only{ scene.root().createChildNode( { 2.0f, 0.0f, 0.0f } ) };
131 Vector3Df translation_only_test_point{ 0.0f, 2.0f, 3.0f };
132 Vector3Df translation_point_to_global_space{ translation_only->localToWorld(translation_only_test_point) };
133 Vector3Df expected_global_point{ 2.0f, 2.0f, 3.0f };
134
135 assert( translation_point_to_global_space != translation_only_test_point );
136 assert( translation_point_to_global_space == expected_global_point );
137 }
138
139 // One child node that has only a rotation
140 {
141 HierarchicalCoordinateSystemf scene;
142
143 Quaternionf rotation{ Quaternionf::make_rotation( 30.0_deg_f, Vector3Df::unit_x() ) };
144 std::shared_ptr<SceneNodef> rotation_only{ scene.root().createChildNode(Vector3Df::zero(), rotation ) };
145 Vector3Df test_point{ 0.0f, 2.0f, 3.0f };
146 Vector3Df point_to_global_space{ rotation_only->localToWorld(test_point) };
147 Vector3Df expected_global_point{ (rotation * Quaternionf::encode_point( test_point ) * rotation.conjugate()).imaginary() };
148
149 assert( point_to_global_space != test_point );
150 assert( point_to_global_space == expected_global_point );
151 }
152}
153
155{
156 std::cout << __func__ << std::endl;
157
158 HierarchicalCoordinateSystemf world;
159
160 std::shared_ptr<SceneNodef> skeleton{ GenerateHierarchicalSkeleton(world) };
161
162 PrintHierarchy(skeleton);
163}
164
168void Run()
169{
170 std::cout << "Running HierarchicalCoordinateSystem Tests..." << std::endl;
171
176
177 std::cout << "PASSED!" << std::endl;
178}
179}
181
182int main(void)
183{
185 return EXIT_SUCCESS;
186}
int NumParents(std::shared_ptr< SceneNodef > node, std::shared_ptr< SceneNodef > relative_to)
void PrintNode(std::shared_ptr< SceneNodef > node, std::shared_ptr< SceneNodef > relative_to)
void PrintHierarchyRecursive(std::shared_ptr< SceneNodef > root, std::shared_ptr< SceneNodef > relative_to=nullptr)
void PrintHierarchy(std::shared_ptr< SceneNodef > root)
static std::shared_ptr< SceneNodef > GenerateHierarchicalSkeleton(HierarchicalCoordinateSystemf &world)
Definition Angle.hpp:16