Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Transform.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef Transform_INCLUDE_ONCE
33 #define Transform_INCLUDE_ONCE
34 
35 #include <vlCore/vlnamespace.hpp>
36 #include <vlCore/Object.hpp>
37 #include <vlCore/Matrix4.hpp>
38 #include <vector>
39 #include <set>
40 #include <algorithm>
41 
42 namespace vl
43 {
44  class Camera;
45 
46  //------------------------------------------------------------------------------
47  // Transform
48  //------------------------------------------------------------------------------
73  {
75 
76  public:
78  Transform(): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false), mParent(NULL)
79  {
80  VL_DEBUG_SET_OBJECT_NAME()
81 
82  #ifdef VL_USER_DATA_TRANSFORM
83  mTransformUserData = NULL;
84  #endif
85  }
86 
88  Transform(const mat4& matrix): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false), mParent(NULL)
89  {
90  VL_DEBUG_SET_OBJECT_NAME()
91 
92  #ifdef VL_USER_DATA_TRANSFORM
93  mTransformUserData = NULL;
94  #endif
95 
96  setLocalMatrix(matrix);
97  setWorldMatrix(matrix);
98  }
99 
101  ~Transform();
102 
104  const Transform* parent() const { return mParent; }
105 
107  Transform* parent() { return mParent; }
108 
111  void translate(real x, real y, real z);
112 
115  void translate(const vec3& t);
116 
119  void scale(real x, real y, real z);
120 
123  void rotate(real degrees, real x, real y, real z);
124 
127  void rotate(const vec3& from, const vec3& to);
128 
131  void preMultiply(const mat4& m);
132 
135  void postMultiply(const mat4& m);
136 
139  void setLocalMatrix(const mat4& m)
140  {
141  mLocalMatrix = m;
142  }
143 
145  const mat4& localMatrix() const
146  {
147  return mLocalMatrix;
148  }
149 
154  {
155  return mLocalMatrix;
156  }
157 
161  void setWorldMatrix(const mat4& matrix)
162  {
163  mWorldMatrix = matrix;
164  ++mWorldMatrixUpdateTick;
165  }
166 
168  const mat4& worldMatrix() const
169  {
170  return mWorldMatrix;
171  }
172 
176  void setLocalAndWorldMatrix(const mat4& matrix)
177  {
178  mLocalMatrix = matrix;
179  setWorldMatrix(matrix);
180  }
181 
184  long long worldMatrixUpdateTick() const { return mWorldMatrixUpdateTick; }
185 
188  void setAssumeIdentityWorldMatrix(bool assume_I) { mAssumeIdentityWorldMatrix = assume_I; }
189 
192  bool assumeIdentityWorldMatrix() { return mAssumeIdentityWorldMatrix; }
193 
195  virtual void computeWorldMatrix(Camera* /*camera*/ = NULL)
196  {
197  if( assumeIdentityWorldMatrix() )
198  {
199  setWorldMatrix(mat4());
200  }
201  else
202  /* top Transforms are usually assumeIdentityWorldMatrix() == true for performance reasons */
203  if( parent() && !parent()->assumeIdentityWorldMatrix() )
204  {
205  setWorldMatrix( parent()->worldMatrix() * localMatrix() );
206  }
207  else
208  {
209  setWorldMatrix( localMatrix() );
210  }
211  }
212 
215  {
216  computeWorldMatrix(camera);
217  for(size_t i=0; i<mChildren.size(); ++i)
218  mChildren[i]->computeWorldMatrixRecursive(camera);
219  }
220 
223  {
224  mat4 world = localMatrix();
225  Transform* par = parent();
226  while(par)
227  {
228  world = par->localMatrix() * world;
229  par = par->parent();
230  }
231  return world;
232  }
233 
234  // --- --- children management --- ---
235 
237  const ref<Transform>* children() const { if (mChildren.empty()) return NULL; else return &mChildren[0]; }
238 
240  ref<Transform>* children() { if (mChildren.empty()) return NULL; else return &mChildren[0]; }
241 
243  size_t childrenCount() const { return mChildren.size(); }
244 
246  void addChild(Transform* child)
247  {
248  VL_CHECK(child != NULL)
249  VL_CHECK(child->mParent == NULL)
250 
251  mChildren.push_back(child);
252  child->mParent = this;
253  }
254 
256  void addChildren(Transform*const* children, size_t count)
257  {
258  VL_CHECK(children != NULL)
259 
260  if (count)
261  {
262  size_t insert_point = mChildren.size();
263  mChildren.resize(mChildren.size() + count);
264  vl::ref<Transform>* ptr = &mChildren[insert_point];
265  for(size_t i=0; i<count; ++i, ++ptr)
266  {
267  VL_CHECK(children[i]->mParent == NULL);
268  children[i]->mParent = this;
269  (*ptr) = children[i];
270  }
271  }
272  }
273 
274  void addChildren(const ref<Transform>* children, size_t count)
275  {
276  VL_CHECK(children != NULL)
277 
278  if (count)
279  {
280  size_t insert_point = mChildren.size();
281  mChildren.resize(mChildren.size() + count);
282  vl::ref<Transform>* ptr = &mChildren[insert_point];
283  for(size_t i=0; i<count; ++i)
284  {
285  VL_CHECK(children[i]->mParent == NULL);
286  ptr[i] = children[i];
287  ptr[i]->mParent = this;
288  }
289  }
290  }
291 
292  void addChildren(const std::vector< ref<Transform> >& children)
293  {
294  if (children.size())
295  addChildren( &children[0], children.size() );
296  }
297 
299  void addChildren(const std::vector< Transform* >& children)
300  {
301  if (children.size())
302  addChildren( &children[0], children.size() );
303  }
304 
306  void setChild(int index, Transform* child)
307  {
308  VL_CHECK(child)
309  VL_CHECK( index < (int)mChildren.size() )
310  mChildren[index]->mParent = NULL;
311  mChildren[index] = child;
312  mChildren[index]->mParent = this;
313  }
314 
316  const Transform* lastChild() const { return mChildren.back().get(); }
317 
319  Transform* lastChild() { return mChildren.back().get(); }
320 
322  void eraseChild(const Transform* child)
323  {
324  VL_CHECK(child != NULL)
325  std::vector< ref<Transform> >::iterator it;
326  it = std::find(mChildren.begin(), mChildren.end(), child);
327  VL_CHECK(it != mChildren.end())
328  if (it != mChildren.end())
329  {
330  (*it)->mParent = NULL;
331  mChildren.erase(it);
332  }
333  }
334 
336  void eraseChildren(int index, int count)
337  {
338  VL_CHECK( index + count <= (int)mChildren.size() );
339 
340  for(int j=index; j<index+count; ++j)
341  mChildren[j]->mParent = NULL;
342 
343  for(int i=index+count, j=index; i<(int)mChildren.size(); ++i, ++j)
344  mChildren[j] = mChildren[i];
345 
346  mChildren.resize( mChildren.size() - count );
347  }
348 
351  {
352  for(int i=0; i<(int)mChildren.size(); ++i)
353  mChildren[i]->mParent = NULL;
354  mChildren.clear();
355  }
356 
359  {
360  for(int i=0; i<(int)mChildren.size(); ++i)
361  {
362  mChildren[i]->eraseAllChildrenRecursive();
363  mChildren[i]->mParent = NULL;
364  }
365  mChildren.clear();
366  }
367 
370  {
371  for(int i=0; i<(int)mChildren.size(); ++i)
372  {
373  mChildren[i]->setLocalAndWorldMatrix( mChildren[i]->worldMatrix() );
374  mChildren[i]->eraseAllChildrenRecursive();
375  mChildren[i]->mParent = NULL;
376  }
377  mChildren.clear();
378  }
379 
382  {
383  if (parent())
384  {
385  mParent->eraseChild(this);
386  setLocalMatrix( worldMatrix() );
387  }
388  }
389 
391  void shrink()
392  {
393  std::vector< ref<Transform> > tmp (mChildren);
394  mChildren.swap(tmp);
395  }
396 
399  {
400  shrink();
401  for(size_t i=0; i<mChildren.size(); ++i)
402  mChildren[i]->shrinkRecursive();
403  }
404 
409  void reserveChildren(size_t count) { mChildren.reserve(count); }
410 
413  {
414  std::set<const Transform*> tr_set;
415  for(size_t i=0; i<mChildren.size(); ++i)
416  tr_set.insert( mChildren[i].get() );
417  return tr_set.size() != mChildren.size();
418  }
419 
420 #ifdef VL_USER_DATA_TRANSFORM
421  public:
422  const Object* transformUserData() const { return mTransformUserData.get(); }
423  Object* transformUserData() { return mTransformUserData.get(); }
424  void setTransformUserData(Object* data) { mTransformUserData = data; }
425 
426  private:
427  ref<Object> mTransformUserData;
428 #endif
429 
430  protected:
435  std::vector< ref<Transform> > mChildren;
437  };
438 
439 }
440 
441 #endif
void addChildren(const ref< Transform > *children, size_t count)
Definition: Transform.hpp:274
void eraseChild(const Transform *child)
Removes the given child Transform.
Definition: Transform.hpp:322
std::vector< ref< Transform > > mChildren
Definition: Transform.hpp:435
Implements a 4x4 matrix transform used to define the position and orientation of an Actor...
Definition: Transform.hpp:72
void shrink()
Minimizes the amount of memory used to store the children Transforms.
Definition: Transform.hpp:391
void setLocalMatrix(const mat4 &m)
The matrix representing the transform&#39;s local space.
Definition: Transform.hpp:139
void setWorldMatrix(const mat4 &matrix)
Normally you should not use directly this function, call it only if you are sure you cannot do otherw...
Definition: Transform.hpp:161
mat4 & localMatrix()
The matrix representing the transform&#39;s local space.
Definition: Transform.hpp:153
T degrees(T radians)
Definition: glsl_math.hpp:173
void eraseAllChildrenRecursive()
Removes all the children of a Transform recursively descending the hierarchy.
Definition: Transform.hpp:358
void reserveChildren(size_t count)
Reserves space for count children.
Definition: Transform.hpp:409
long long worldMatrixUpdateTick() const
Returns the internal update tick used to avoid unnecessary computations.
Definition: Transform.hpp:184
void flattenHierarchy()
Disassembles a hierarchy of Transforms like eraseAllChildrenRecursive() does plus assigns the local m...
Definition: Transform.hpp:369
void addChildren(const std::vector< ref< Transform > > &children)
Definition: Transform.hpp:292
const Transform * lastChild() const
Returns the last child.
Definition: Transform.hpp:316
const mat4 & localMatrix() const
The matrix representing the transform&#39;s local space.
Definition: Transform.hpp:145
void setLocalAndWorldMatrix(const mat4 &matrix)
Sets both the local and the world matrices.
Definition: Transform.hpp:176
void addChildren(const std::vector< Transform * > &children)
Adds the specified children transforms.
Definition: Transform.hpp:299
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
void addChildren(Transform *const *children, size_t count)
Adds count children transforms.
Definition: Transform.hpp:256
Visualization Library main namespace.
void setChild(int index, Transform *child)
Sets the index-th child.
Definition: Transform.hpp:306
Transform * mParent
Definition: Transform.hpp:436
size_t childrenCount() const
Returns the number of child Transform.
Definition: Transform.hpp:243
virtual void computeWorldMatrix(Camera *=NULL)
Computes the world matrix by concatenating the parent&#39;s world matrix with its own local matrix...
Definition: Transform.hpp:195
The base class for all the reference counted objects.
Definition: Object.hpp:158
void shrinkRecursive()
Minimizes recursively the amount of memory used to store the children Transforms. ...
Definition: Transform.hpp:398
const Transform * parent() const
Returns the parent Transform.
Definition: Transform.hpp:104
void computeWorldMatrixRecursive(Camera *camera=NULL)
Computes the world matrix by concatenating the parent&#39;s world matrix with its local matrix...
Definition: Transform.hpp:214
bool mAssumeIdentityWorldMatrix
Definition: Transform.hpp:434
Transform()
Constructor.
Definition: Transform.hpp:78
ref< Transform > * children()
Returns the array containing the child Transforms.
Definition: Transform.hpp:240
mat4 getComputedWorldMatrix()
Returns the matrix computed concatenating this Transform&#39;s local matrix with the local matrices of al...
Definition: Transform.hpp:222
#define NULL
Definition: OpenGLDefs.hpp:81
const mat4 & worldMatrix() const
Returns the world matrix used for rendering.
Definition: Transform.hpp:168
const ref< Transform > * children() const
Returns the array containing the child Transforms.
Definition: Transform.hpp:237
Transform * lastChild()
Returns the last child.
Definition: Transform.hpp:319
bool assumeIdentityWorldMatrix()
If set to true the world matrix of this transform will always be considered and identity.
Definition: Transform.hpp:192
Transform(const mat4 &matrix)
Constructor.
Definition: Transform.hpp:88
bool hasDuplicatedChildren() const
Checks whether there are duplicated entries in the Transform&#39;s children list.
Definition: Transform.hpp:412
void eraseChildren(int index, int count)
Removes count children Transforms starting at position index.
Definition: Transform.hpp:336
fmat4 mat4
Defined as: &#39;typedef fmat4 mat4&#39;. See also VL_PIPELINE_PRECISION.
Definition: Matrix4.hpp:1240
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
void removeFromParent()
Erases a Transform from it&#39;s parent and sets the local matrix to be equal to the world matrix...
Definition: Transform.hpp:381
void setAssumeIdentityWorldMatrix(bool assume_I)
If set to true the world matrix of this transform will always be considered and identity.
Definition: Transform.hpp:188
long long mWorldMatrixUpdateTick
Definition: Transform.hpp:433
#define VL_CHECK(expr)
Definition: checks.hpp:73
Visualization Library&#39;s enums in the &#39;vl&#39; namespace.
void addChild(Transform *child)
Adds a child transform.
Definition: Transform.hpp:246
void eraseAllChildren()
Removes all the children of a Transform.
Definition: Transform.hpp:350
Transform * parent()
Returns the parent Transform.
Definition: Transform.hpp:107