Lugdunum  0.1.0
Node.cpp
Go to the documentation of this file.
1 #include <lug/Graphics/Node.hpp>
3 
4 namespace lug {
5 namespace Graphics {
6 
7 Node::Node(const std::string& name) : _name(name) {}
8 
9 Node* Node::getNode(const std::string& name) {
10  if (name == _name) {
11  return this;
12  }
13 
14  for (auto& child : _children) {
15  Node* tmp = child->getNode(name);
16 
17  if (tmp) {
18  return tmp;
19  }
20  }
21 
22  return nullptr;
23 }
24 
25 const Node* Node::getNode(const std::string& name) const {
26  if (name == _name) {
27  return this;
28  }
29 
30  for (const auto& child : _children) {
31  const Node* tmp = child->getNode(name);
32 
33  if (tmp) {
34  return tmp;
35  }
36  }
37 
38  return nullptr;
39 }
40 
41 void Node::attachChild(Node& child) {
42  child._parent = this;
43  _children.push_back(&child);
44 }
45 
46 void Node::translate(const Math::Vec3f& direction, TransformSpace space) {
47  if (space == TransformSpace::Local) {
48  _position += _rotation.transform() * direction;
49  } else if (space == TransformSpace::Parent) {
50  _position += direction;
51  } else if (space == TransformSpace::World) {
52  if (_parent) {
53  _position += (Math::inverse(_parent->getAbsoluteRotation()).transform() * direction) / _parent->getAbsoluteScale();
54  } else {
55  _position += direction;
56  }
57  }
58 
59  needUpdate();
60 }
61 
62 void Node::rotate(float angle, const Math::Vec3f& axis, TransformSpace space) {
63  rotate(Math::Quatf(angle, axis), space);
64 }
65 
66 void Node::rotate(const Math::Quatf& quat, TransformSpace space) {
67  if (space == TransformSpace::Local) {
68  _rotation = _rotation * quat;
69  } else if (space == TransformSpace::Parent) {
70  _rotation = quat * _rotation;
71  } else if (space == TransformSpace::World) {
73  }
74 
75  needUpdate();
76 }
77 
78 void Node::scale(const Math::Vec3f& scale) {
79  _scale *= scale;
80  needUpdate();
81 }
82 
83 void Node::setPosition(const Math::Vec3f& position, TransformSpace space) {
84  if (space == TransformSpace::Local) {
85  _position = _rotation.transform() * position;
86  } else if (space == TransformSpace::Parent) {
87  _position = position;
88  } else if (space == TransformSpace::World) {
89  if (_parent) {
91  } else {
92  _position = position;
93  }
94  }
95 
96  needUpdate();
97 }
98 
99 void Node::setRotation(const Math::Quatf& rotation, TransformSpace space) {
100  if (space == TransformSpace::Local) {
101  // TODO: Use the current local rotation to compute the new rotation
102  _rotation = rotation;
103  } else if (space == TransformSpace::Parent) {
104  _rotation = rotation;
105  } else if (space == TransformSpace::World) {
106  if (_parent) {
108  } else {
109  _rotation = rotation;
110  }
111  }
112 
113  needUpdate();
114 }
115 
116 void Node::setRotation(float angle, const Math::Vec3f& axis, TransformSpace space) {
117  setRotation(Math::Quatf(angle, axis), space);
118 }
119 
120 void Node::setDirection(const Math::Vec3f& spaceTargetDirection, const Math::Vec3f& localDirectionVector, const Math::Vec3f& localUpVector, TransformSpace space) {
121  if (spaceTargetDirection.length() == 0.0f) {
122  return;
123  }
124 
125  // The direction we want the local direction point to
126  Math::Vec3f targetDirection = Math::normalize(spaceTargetDirection);
127 
128  // Transform target direction to world space
129  if (space == TransformSpace::Local) {
130  targetDirection = getAbsoluteRotation().transform() * targetDirection;
131  } else if (space == TransformSpace::Parent) {
132  if (_parent) {
133  targetDirection = _parent->getAbsoluteRotation().transform() * targetDirection;
134  }
135  } else if (space == TransformSpace::World) {
136  // Nothing to do here
137  }
138 
139  Math::Vec3f xVec = Math::normalize(cross(localUpVector, targetDirection));
140  Math::Vec3f yVec = Math::normalize(cross(targetDirection, xVec));
141  Math::Quatf unitZToTarget = Math::Quatf::fromAxes(xVec, yVec, targetDirection);
142 
143  Math::Quatf targetOrientation;
144 
145  if (localDirectionVector == Math::Vec3f{0.0f, 0.0f, -1.0f}) {
146  targetOrientation = Math::Quatf(-unitZToTarget.y(), -unitZToTarget.z(), unitZToTarget.w(), unitZToTarget.x());
147  } else {
148  targetOrientation = unitZToTarget * directionTo(localDirectionVector, Math::Vec3f{0.0f, 0.0f, 1.0f});
149  }
150 
151  setRotation(targetOrientation, TransformSpace::Parent);
152 }
153 
154 void Node::lookAt(const Math::Vec3f& targetPosition, const Math::Vec3f& localDirectionVector, const Math::Vec3f& localUpVector, TransformSpace space) {
155  Math::Vec3f origin;
156 
157  if (space == TransformSpace::Local) {
158  origin = Math::Vec3f(0.0f);
159  } else if (space == TransformSpace::Parent) {
160  origin = _position;
161  } else if (space == TransformSpace::World) {
162  origin = getAbsolutePosition();
163  }
164 
165  setDirection(targetPosition - origin, localDirectionVector, localUpVector, space);
166 }
167 
169  _needUpdate = true;
170 
171  for (auto& child : _children) {
172  child->needUpdate();
173  }
174 }
175 
176 void Node::update() {
177  if (_parent) {
181  } else {
185  }
186 
187  _absoluteRotation.normalize();
188 
190 
191  _needUpdate = false;
192 }
193 
194 } // Graphics
195 } // lug
Quaternion< T > directionTo(const Vector< 3, T > &original, const Vector< 3, T > &expected)
Definition: Quaternion.inl:210
Math::Vec3f _absoluteScale
Definition: Node.hpp:96
void attachChild(Node &child)
Definition: Node.cpp:41
std::vector< Node * > _children
Definition: Node.hpp:87
void scale(const Math::Vec3f &scale)
Definition: Node.cpp:78
Math::Quatf _rotation
Definition: Node.hpp:91
Matrix< 4, 4, T > translate(const Vector< 3, T > &direction)
void setRotation(float angle, const Math::Vec3f &axis, TransformSpace space=TransformSpace::Local)
Definition: Node.cpp:116
std::string _name
Definition: Node.hpp:86
void translate(const Math::Vec3f &direction, TransformSpace space=TransformSpace::Local)
Definition: Node.cpp:46
const Math::Vec3f & getAbsolutePosition()
Definition: Node.inl:14
constexpr Vector< 3, T > cross(const Vector< 3, T > &lhs, const Vector< 3, T > &rhs)
Definition: Vector.inl:72
Math::Vec3f _scale
Definition: Node.hpp:92
Math::Vec3f _absolutePosition
Definition: Node.hpp:94
Math::Mat4x4f _transform
Definition: Node.hpp:98
void rotate(float angle, const Math::Vec3f &axis, TransformSpace space=TransformSpace::Local)
Definition: Node.cpp:62
const Math::Quatf & getAbsoluteRotation()
Definition: Node.inl:22
void setDirection(const Math::Vec3f &spaceTargetDirection, const Math::Vec3f &localDirectionVector, const Math::Vec3f &localUpVector, TransformSpace space=TransformSpace::Local)
Rotates the node according to the direction given in parameter.
Definition: Node.cpp:120
Quaternion< T > inverse(const Quaternion< T > &lhs)
Node(const std::string &name)
Definition: Node.cpp:7
Node * getNode(const std::string &name)
Definition: Node.cpp:9
Quaternion< T > normalize(const Quaternion< T > &lhs)
void setPosition(const Math::Vec3f &position, TransformSpace space=TransformSpace::Local)
Definition: Node.cpp:83
const Math::Vec3f & getAbsoluteScale()
Definition: Node.inl:30
Math::Vec3f _position
Definition: Node.hpp:90
Node * _parent
Definition: Node.hpp:84
void lookAt(const Math::Vec3f &targetPosition, const Math::Vec3f &localDirectionVector, const Math::Vec3f &localUpVector, TransformSpace space=TransformSpace::Local)
Rotates the node in order to look at the target position.
Definition: Node.cpp:154
Math::Quatf _absoluteRotation
Definition: Node.hpp:95
Matrix< 4, 4, T > scale(const Vector< 3, T > &factors)
virtual void needUpdate()
Definition: Node.cpp:168
Quaternion< float > Quatf
Definition: Quaternion.hpp:75