MathLib
Loading...
Searching...
No Matches
SceneNode.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <memory>
5#include <vector>
6#include <algorithm>
7#include <string>
8#include <string_view>
9
10
18template <class T> class SceneNode;
19
24template <class T>
25using SceneNodeList = std::vector< std::shared_ptr<SceneNode<T>> >;
26
27
39template <class Type>
40class SceneNode : public std::enable_shared_from_this<SceneNode<Type>>
41{
42 struct Private { explicit Private() = default; };
43
44public:
51 SceneNode(Private) { }
52
59 SceneNode(Private ,
60 std::weak_ptr<SceneNode> parent,
61 const Math::BasicVector3D<Type> &translation,
62 const Math::BasicQuaternion<Type> &rotation,
63 std::string_view name)
64 :
65 _coordinate_system{ Math::BasicDualQuaternion<Type>::make_coordinate_system(rotation, translation.x, translation.y, translation.z) },
66 _parent{parent},
67 _name{name}
68 {
69 }
70 ~SceneNode() = default;
71
79 static std::shared_ptr<SceneNode<Type>> make()
80 {
81 return std::make_shared<SceneNode<Type>>(Private{});
82 }
84
85 std::weak_ptr<SceneNode<Type>> parent() const { return _parent; }
86
87 const SceneNodeList<Type> &children() const { return _children; }
88
89 const Math::BasicDualQuaternion<Type> &coordinate_system() const { return _coordinate_system; }
90 Math::BasicDualQuaternion<Type> &coordinate_system() { return _coordinate_system; }
91
92 std::string_view name() const { return _name; }
93
94 std::weak_ptr<SceneNode<Type>> createChildNode(const Math::BasicVector3D<Type> &translation = Math::BasicVector3D<Type>::zero(),
96 std::string_view name = std::string_view())
97 {
98 std::shared_ptr<SceneNode<Type>> new_node = make( this->weak_from_this(), translation, rotation, name );
99
100 _children.push_back( new_node );
101 return new_node;
102 }
103
105 void detachChild(std::shared_ptr<SceneNode<Type>> item_to_detach)
106 {
107 auto iter = std::ranges::find(_children, item_to_detach);
108
109 if (iter != _children.end())
110 {
111 // Found!
112 (*iter)->_parent.reset();
113 _children.erase(iter);
114 }
115 }
116
117 void attachChild(std::shared_ptr<SceneNode<Type>> node)
118 {
119 assert( std::ranges::find(_children, node) == _children.end() ); // It is currently not in the list of children!
120
121 _children.push_back( node );
122 node->_parent = this->weak_from_this();
123 }
124
126 {
127#if 1
128 using namespace Math;
129
130 BasicDualQuaternion<Type> transforms_to_parent{ concatenatedTransforms() };
131
132 // NOTE: From here on out, we cuse the algebraically-simplified form of multiplying it out with DualQuaternions...
133 BasicQuaternion<Type> encoded_point{ BasicQuaternion<Type>::encode_point( local_coordinate ) };
134 BasicQuaternion<Type> encoded_translation{ BasicQuaternion<Type>::encode_point( transforms_to_parent.translation() ) };
135 BasicDualQuaternion<Type> result{ BasicQuaternion<Type>::identity(), transforms_to_parent.real() * encoded_point * transforms_to_parent.real().conjugate() + encoded_translation };
136
137 return result.dual().imaginary();
138#else
139 // General case using only BasicDualQuaternion operations.
140 // TODO: Why doesn't this work?
141 BasicDualQuaternion<Type> transforms_to_parent{ concatenatedTransforms() };
143 BasicDualQuaternion<Type> result{ transforms_to_parent * encoded_point * transforms_to_parent.conjugate() };
144
145 return result.translation();
146#endif
147 }
148
150 {
151 if (_parent.expired())
152 return _coordinate_system;
153 else
154 return _parent.lock()->concatenatedTransforms() * _coordinate_system;
155 }
156private:
157 Math::BasicDualQuaternion<Type> _coordinate_system;
158 std::weak_ptr<SceneNode<Type>> _parent;
159 SceneNodeList<Type> _children;
160 std::string _name;
161
162 static std::shared_ptr<SceneNode<Type>> make(std::weak_ptr<SceneNode<Type>> parent,
163 const Math::BasicVector3D<Type> &translation,
164 const Math::BasicQuaternion<Type> &rotation,
165 std::string_view name)
166 {
167 return std::make_shared<SceneNode<Type>>(Private{}, parent, translation, rotation, name);
168 }
169};
170
171
constexpr BasicDualQuaternion< T > conjugate() const
constexpr const T & real() const
const SceneNodeList< Type > & children() const
Definition SceneNode.hpp:87
void attachChild(std::shared_ptr< SceneNode< Type > > node)
~SceneNode()=default
std::string_view name() const
Definition SceneNode.hpp:92
const Math::BasicDualQuaternion< Type > & coordinate_system() const
Definition SceneNode.hpp:89
std::weak_ptr< SceneNode< Type > > parent() const
Definition SceneNode.hpp:85
Math::BasicDualQuaternion< Type > & coordinate_system()
Definition SceneNode.hpp:90
Math::BasicDualQuaternion< Type > concatenatedTransforms() const
SceneNode(Private)
Definition SceneNode.hpp:51
std::vector< std::shared_ptr< SceneNode< T > > > SceneNodeList
Definition SceneNode.hpp:25
static std::shared_ptr< SceneNode< Type > > make()
Definition SceneNode.hpp:79
void detachChild(std::shared_ptr< SceneNode< Type > > item_to_detach)
SceneNode(Private, std::weak_ptr< SceneNode > parent, const Math::BasicVector3D< Type > &translation, const Math::BasicQuaternion< Type > &rotation, std::string_view name)
Definition SceneNode.hpp:59
Math::BasicVector3D< Type > localToWorld(const Math::BasicVector3D< Type > &local_coordinate) const
std::weak_ptr< SceneNode< Type > > createChildNode(const Math::BasicVector3D< Type > &translation=Math::BasicVector3D< Type >::zero(), const Math::BasicQuaternion< Type > &rotation=Math::BasicQuaternion< Type >::identity(), std::string_view name=std::string_view())
Definition SceneNode.hpp:94
Definition Angle.hpp:16