CUGL
Cornell University Game Library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
CUNode.h
1 //
2 // CUNode.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module provides support for a (2d) scene graph node. It uses an anchor
6 // based approach, much like Cocos2d. However, it is much more streamlined
7 // and removes a lot of the Cocos2d nonsense when it comes to transforms.
8 //
9 // This class uses our standard shared-pointer architecture.
10 //
11 // 1. The constructor does not perform any initialization; it just sets all
12 // attributes to their defaults.
13 //
14 // 2. All initialization takes place via init methods, which can fail if an
15 // object is initialized more than once.
16 //
17 // 3. All allocation takes place via static constructors which return a shared
18 // pointer.
19 //
20 // CUGL zlib License:
21 // This software is provided 'as-is', without any express or implied
22 // warranty. In no event will the authors be held liable for any damages
23 // arising from the use of this software.
24 //
25 // Permission is granted to anyone to use this software for any purpose,
26 // including commercial applications, and to alter it and redistribute it
27 // freely, subject to the following restrictions:
28 //
29 // 1. The origin of this software must not be misrepresented; you must not
30 // claim that you wrote the original software. If you use this software
31 // in a product, an acknowledgment in the product documentation would be
32 // appreciated but is not required.
33 //
34 // 2. Altered source versions must be plainly marked as such, and must not
35 // be misrepresented as being the original software.
36 //
37 // 3. This notice may not be removed or altered from any source distribution.
38 //
39 // Author: Walker White
40 // Version: 6/27/16
41 
42 #ifndef __CU_NODE_H__
43 #define __CU_NODE_H__
44 
45 #include "../math/CUColor4.h"
46 #include "../math/CUVec2.h"
47 #include "../math/CUSize.h"
48 #include "../math/CUMat4.h"
49 #include "../renderer/CUSpriteBatch.h"
50 #include "../util/CUDebug.h"
51 #include <vector>
52 #include <string>
53 
54 namespace cugl {
55 
56 // Forward reference
57 class Scene;
58 
92 class Node {
93 #pragma mark Values
94 protected:
102 
110 
113 
120 
128 
137  float _angle;
138 
148 
151 
160 
162  std::vector<std::shared_ptr<Node>> _children;
163 
168 
171 
179  unsigned int _tag;
180 
187  std::string _name;
188 
194  size_t _hashOfName;
195 
197  int _zOrder;
199  bool _zDirty;
200 
201 #pragma mark -
202 #pragma mark Constructors
203 public:
212  Node();
213 
217  virtual ~Node() { removeAllChildren(); }
218 
228  virtual void dispose();
229 
237  virtual bool init() {
238  return initWithPosition(0, 0);
239  }
240 
241 
252  virtual bool initWithPosition(const Vec2& pos);
253 
265  bool initWithPosition(float x, float y) {
266  return initWithPosition(Vec2(x,y));
267  }
268 
281  virtual bool initWithBounds(const Size& size);
282 
296  bool initWithBounds(float width, float height) {
297  return initWithBounds(Size(width,height));
298  }
299 
315  virtual bool initWithBounds(const Rect& rect);
316 
335  bool initWithBounds(float x, float y, float width, float height) {
336  return initWithBounds(Rect(x,y,width,height));
337  }
338 
350  virtual Node* copy(Node* dst);
351 
352 
353 #pragma mark -
354 #pragma mark Static Constructors
355 
363  static std::shared_ptr<Node> alloc() {
364  std::shared_ptr<Node> result = std::make_shared<Node>();
365  return (result->init() ? result : nullptr);
366  }
367 
378  static std::shared_ptr<Node> allocWithPosition(const Vec2& pos) {
379  std::shared_ptr<Node> result = std::make_shared<Node>();
380  return (result->initWithPosition(pos) ? result : nullptr);
381  }
382 
394  static std::shared_ptr<Node> allocWithPosition(float x, float y) {
395  std::shared_ptr<Node> result = std::make_shared<Node>();
396  return (result->initWithPosition(x,y) ? result : nullptr);
397  }
398 
411  static std::shared_ptr<Node> allocWithBounds(const Size& size) {
412  std::shared_ptr<Node> result = std::make_shared<Node>();
413  return (result->initWithBounds(size) ? result : nullptr);
414  }
415 
429  static std::shared_ptr<Node> allocWithBounds(float width, float height) {
430  std::shared_ptr<Node> result = std::make_shared<Node>();
431  return (result->initWithBounds(width,height) ? result : nullptr);
432  }
433 
449  static std::shared_ptr<Node> allocWithBounds(const Rect& rect) {
450  std::shared_ptr<Node> result = std::make_shared<Node>();
451  return (result->initWithBounds(rect) ? result : nullptr);
452  }
453 
472  static std::shared_ptr<Node> allocWithBounds(float x, float y, float width, float height) {
473  std::shared_ptr<Node> result = std::make_shared<Node>();
474  return (result->initWithBounds(x,y,width,height) ? result : nullptr);
475  }
476 
477 #pragma mark -
478 #pragma mark Identifiers
479 
488  unsigned int getTag() const { return _tag; }
489 
499  void setTag(unsigned int tag) { _tag = tag; }
500 
510  const std::string& getName() const { return _name; }
511 
521  void setName(const std::string& name) {
522  _name = name;
523  _hashOfName = std::hash<std::string>()(_name);
524  }
525 
536  virtual std::string toString(bool verbose = false) const;
537 
539  operator std::string() const { return toString(); }
540 
541 
542 #pragma mark -
543 #pragma mark Position
544 
554  const Vec2& getPosition() const { return _position; }
555 
566  void setPosition(const Vec2 &position) { setPosition(position.x,position.y); }
567 
579  void setPosition(float x, float y);
580 
591  float getPositionX(void) const { return getPosition().x; }
592 
603  void setPositionX(float x) { setPosition(x,getPositionY()); }
604 
615  float getPositionY(void) const { return getPosition().y; }
616 
627  void setPositionY(float y) { setPosition(getPositionX(),y); }
628 
638  return nodeToWorldCoords(_anchor*getContentSize());
639  }
640 
641 
642 #pragma mark -
643 #pragma mark Size
644 
652  const Size& getContentSize() const { return _contentSize; }
653 
667  virtual void setContentSize(const Size& size);
668 
683  virtual void setContentSize(float width, float height) {
684  setContentSize(Size(width, height));
685  }
686 
695  float getContentWidth() const { return getContentSize().width; }
696 
710  void setContentWidth(float width) { setContentSize(width,getContentHeight()); }
711 
720  float getContentHeight() const { return getContentSize().height; }
721 
735  void setContentHeight(float height) { setContentSize(getContentWidth(),height); }
736 
747  Size getSize() const {
748  return getBoundingBox().size;
749  }
750 
761  float getWidth() const { return getSize().width; }
762 
773  float getHeight() const { return getSize().height; }
774 
786  }
787 
788 
789 #pragma mark -
790 #pragma mark Anchors
791 
810  virtual void setAnchor(const Vec2& anchor);
811 
832  void setAnchor(float x, float y) { setAnchor(Vec2(x,y)); }
833 
853  const Vec2& getAnchor() const { return _anchor; }
854 
869  Vec2 getAnchorInPixels() { return _anchor * _contentSize; }
870 
871 
872 #pragma mark -
873 #pragma mark Visibility
874 
885  Color4 getColor() const { return _tintColor; }
886 
898  void setColor(Color4 color) { _tintColor = color; }
899 
910 
920  bool isVisible() const { return _isVisible; }
921 
931  void setVisible(bool visible) { _isVisible = visible; }
932 
943 
953  void setRelativeColor(bool flag) { _hasParentColor = flag; }
954 
955 
956 #pragma mark -
957 #pragma mark Transforms
958 
968  const Vec2& getScale() const { return _scale; }
969 
980  float getScaleX() const { return _scale.x; }
981 
992  float getScaleY() const { return _scale.y; }
993 
1004  void setScale(float scale) {
1005  _scale.set(scale,scale);
1006  if (!_useTransform) updateTransform();
1007  }
1008 
1019  void setScale(const Vec2& vec) {
1020  _scale = vec;
1021  if (!_useTransform) updateTransform();
1022  }
1023 
1035  void setScale(float sx, float sy) {
1036  _scale.set(sx,sy);
1037  if (!_useTransform) updateTransform();
1038  }
1039 
1049  float getAngle() { return _angle; }
1050 
1060  void setAngle(float angle) {
1061  _angle = angle;
1062  if (!_useTransform) updateTransform();
1063  }
1064 
1080 
1095  void setAlternateTransform(const Mat4& transform) {
1096  _transform = transform;
1097  updateTransform();
1098  }
1099 
1115 
1130  void chooseAlternateTransform(bool active) {
1131  _useTransform = active; updateTransform();
1132  }
1133 
1143  const Mat4& getNodeToParentTransform() const { return _combined; }
1144 
1154  Mat4 getParentToNodeTransform() const { return _combined.getInverse(); }
1155 
1165  Mat4 getNodeToWorldTransform() const;
1166 
1179  }
1180 
1198  Vec2 screenToNodeCoords(const Vec2& screenPoint) const;
1199 
1200 
1212  Vec2 worldToNodeCoords(const Vec2& worldPoint) const {
1213  return getWorldToNodeTransform().transform(worldPoint);
1214  }
1215 
1233  Vec2 nodeToScreenCoords(const Vec2& nodePoint) const;
1234 
1246  Vec2 nodeToWorldCoords(const Vec2& nodePoint) const {
1247  return getNodeToWorldTransform().transform(nodePoint);
1248  }
1249 
1261  Vec2 parentToNodeCoords(const Vec2& parentPoint) const {
1262  return getParentToNodeTransform().transform(parentPoint);
1263  }
1264 
1276  Vec2 nodeToParentCoords(const Vec2& nodePoint) const {
1277  return getNodeToParentTransform().transform(nodePoint);
1278  }
1279 
1280 #pragma mark -
1281 #pragma mark Z-order
1282 
1299  void setZOrder(int z);
1300 
1318  int getZOrder() const { return _zOrder; }
1319 
1337  bool isZDirty() const { return _zDirty; }
1338 
1356  void sortZOrder();
1357 
1358 
1359 #pragma mark -
1360 #pragma mark Scene Graph
1361 
1366  size_t getChildCount() const { return _children.size(); }
1367 
1379  std::shared_ptr<Node> getChild(unsigned int pos);
1380 
1392  const std::shared_ptr<Node>& getChild(unsigned int pos) const;
1393 
1410  template <typename T>
1411  inline std::shared_ptr<T> getChild(unsigned int pos) const {
1412  return std::dynamic_pointer_cast<T>(getChild(pos));
1413  }
1414 
1428  std::shared_ptr<Node> getChildByTag(unsigned int tag) const;
1429 
1448  template <typename T>
1449  inline std::shared_ptr<T> getChildByTag(unsigned int tag) const {
1450  return std::dynamic_pointer_cast<T>(getChildByTag(tag));
1451  }
1452 
1466  std::shared_ptr<Node> getChildByName(const std::string& name) const;
1467 
1486  template <typename T>
1487  inline std::shared_ptr<T> getChildByName(const std::string& name) const {
1488  return std::dynamic_pointer_cast<T>(getChildByName(name));
1489  }
1490 
1496  std::vector<std::shared_ptr<Node>> getChildren() { return _children; }
1497 
1503  const std::vector<std::shared_ptr<Node>>& getChildren() const { return _children; }
1504 
1514  void addChild(std::shared_ptr<Node> child) {
1515  addChild(child,child->_zOrder);
1516  }
1517 
1530  virtual void addChild(const std::shared_ptr<Node>& child, int zval);
1531 
1542  void addChildWithTag(const std::shared_ptr<Node>& child, unsigned int tag) {
1543  addChild(child);
1544  child->setTag(tag);
1545  }
1546 
1560  void addChildWithTag(const std::shared_ptr<Node>& child, unsigned int tag, int zval) {
1561  addChild(child,zval);
1562  child->setTag(tag);
1563  }
1564 
1575  void addChildWithName(const std::shared_ptr<Node>& child, const std::string &name) {
1576  addChild(child);
1577  child->setName(name);
1578  }
1579 
1593  void addChildWithName(const std::shared_ptr<Node>& child, const std::string &name, int zval) {
1594  addChild(child,zval);
1595  child->setName(name);
1596  }
1597 
1611  void swapChild(const std::shared_ptr<Node>& child1, const std::shared_ptr<Node>& child2, bool inherit=false);
1612 
1621  Node* getParent() { return _parent; }
1622 
1631  const Node* getParent() const { return _parent; }
1632 
1641  Scene* getScene() { return _graph; }
1642 
1651  const Scene* getScene() const { return _graph; }
1652 
1658  void removeFromParent() { if (_parent) { _parent->removeChild(_childOffset); } }
1659 
1668  virtual void removeChild(unsigned int pos);
1669 
1680  void removeChild(const std::shared_ptr<Node>& child);
1681 
1693  void removeChildByTag(unsigned int tag);
1694 
1706  void removeChildByName(const std::string &name);
1707 
1711  virtual void removeAllChildren();
1712 
1713 
1714 #pragma mark -
1715 #pragma mark Rendering
1716 
1727  void render(const std::shared_ptr<SpriteBatch>& batch, const Mat4& transform, Color4 tint);
1728 
1738  void render(const std::shared_ptr<SpriteBatch>& batch) {
1740  }
1741 
1765  virtual void draw(const std::shared_ptr<SpriteBatch>& batch, const Mat4& transform, Color4 tint) {}
1766 
1767 private:
1768 #pragma mark -
1769 #pragma mark Internal Helpers
1770 
1787  void setZDirty(bool value);
1788 
1797  void setParent(Node* parent) { _parent = parent; }
1798 
1807  void setScene(Scene* scene) { _graph = scene; }
1808 
1817  void pushScene(Scene* scene);
1818 
1829  static bool compareNodeSibs(const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b);
1830 
1837  virtual void updateTransform();
1838 
1839  // Copying is only allowed via shared pointer.
1840  CU_DISALLOW_COPY_AND_ASSIGN(Node);
1841 
1842  friend class Scene;
1843 };
1844 
1845 
1846 }
1847 #endif /* __CU_NODE_H__ */
Definition: CUSize.h:57
Vec2 _position
Definition: CUNode.h:101
bool initWithPosition(float x, float y)
Definition: CUNode.h:265
std::vector< std::shared_ptr< Node > > _children
Definition: CUNode.h:162
void setRelativeColor(bool flag)
Definition: CUNode.h:953
Color4 _tintColor
Definition: CUNode.h:115
Vec2 nodeToScreenCoords(const Vec2 &nodePoint) const
unsigned int getTag() const
Definition: CUNode.h:488
const Mat4 & getNodeToParentTransform() const
Definition: CUNode.h:1143
float x
Definition: CUVec2.h:66
float getHeight() const
Definition: CUNode.h:773
Vec2 screenToNodeCoords(const Vec2 &screenPoint) const
static std::shared_ptr< Node > allocWithPosition(const Vec2 &pos)
Definition: CUNode.h:378
float y
Definition: CUVec2.h:68
static Vec2 * transform(const Mat4 &mat, const Vec2 &point, Vec2 *dst)
void render(const std::shared_ptr< SpriteBatch > &batch)
Definition: CUNode.h:1738
const Node * getParent() const
Definition: CUNode.h:1631
void addChildWithName(const std::shared_ptr< Node > &child, const std::string &name)
Definition: CUNode.h:1575
void setPosition(const Vec2 &position)
Definition: CUNode.h:566
Definition: CUVec2.h:61
Vec2 nodeToParentCoords(const Vec2 &nodePoint) const
Definition: CUNode.h:1276
size_t getChildCount() const
Definition: CUNode.h:1366
float _angle
Definition: CUNode.h:137
float getAngle()
Definition: CUNode.h:1049
float getPositionY(void) const
Definition: CUNode.h:615
bool _hasParentColor
Definition: CUNode.h:117
Node * _parent
Definition: CUNode.h:165
Vec2 _scale
Definition: CUNode.h:127
virtual bool initWithBounds(const Size &size)
Definition: CUNode.h:92
std::shared_ptr< Node > getChildByTag(unsigned int tag) const
virtual void setContentSize(const Size &size)
Size getSize() const
Definition: CUNode.h:747
virtual void draw(const std::shared_ptr< SpriteBatch > &batch, const Mat4 &transform, Color4 tint)
Definition: CUNode.h:1765
void removeChildByTag(unsigned int tag)
Mat4 getNodeToWorldTransform() const
static std::shared_ptr< Node > allocWithBounds(const Rect &rect)
Definition: CUNode.h:449
std::shared_ptr< Node > getChildByName(const std::string &name) const
void setPositionY(float y)
Definition: CUNode.h:627
int _zOrder
Definition: CUNode.h:197
Mat4 _combined
Definition: CUNode.h:159
void setColor(Color4 color)
Definition: CUNode.h:898
virtual void removeChild(unsigned int pos)
Vec2 getWorldPosition() const
Definition: CUNode.h:637
bool hasRelativeColor()
Definition: CUNode.h:942
void setZOrder(int z)
void setScale(const Vec2 &vec)
Definition: CUNode.h:1019
virtual std::string toString(bool verbose=false) const
void setPositionX(float x)
Definition: CUNode.h:603
void addChildWithTag(const std::shared_ptr< Node > &child, unsigned int tag, int zval)
Definition: CUNode.h:1560
float getScaleX() const
Definition: CUNode.h:980
bool _zDirty
Definition: CUNode.h:199
Vec2 worldToNodeCoords(const Vec2 &worldPoint) const
Definition: CUNode.h:1212
bool initWithBounds(float x, float y, float width, float height)
Definition: CUNode.h:335
Vec2 getAnchorInPixels()
Definition: CUNode.h:869
virtual void setAnchor(const Vec2 &anchor)
bool isVisible() const
Definition: CUNode.h:920
void sortZOrder()
static const Color4 WHITE
Definition: CUColor4.h:1126
unsigned int _tag
Definition: CUNode.h:179
const Vec2 & getPosition() const
Definition: CUNode.h:554
void setContentHeight(float height)
Definition: CUNode.h:735
void setAnchor(float x, float y)
Definition: CUNode.h:832
void setContentWidth(float width)
Definition: CUNode.h:710
float width
Definition: CUSize.h:61
bool isZDirty() const
Definition: CUNode.h:1337
Vec2 nodeToWorldCoords(const Vec2 &nodePoint) const
Definition: CUNode.h:1246
void setTag(unsigned int tag)
Definition: CUNode.h:499
static std::shared_ptr< Node > allocWithBounds(float x, float y, float width, float height)
Definition: CUNode.h:472
const Size & getContentSize() const
Definition: CUNode.h:652
Mat4 getInverse() const
Definition: CUMat4.h:1037
void addChild(std::shared_ptr< Node > child)
Definition: CUNode.h:1514
Mat4 getWorldToNodeTransform() const
Definition: CUNode.h:1177
Scene * _graph
Definition: CUNode.h:167
void setAngle(float angle)
Definition: CUNode.h:1060
float getWidth() const
Definition: CUNode.h:761
const std::string & getName() const
Definition: CUNode.h:510
Color4 getAbsoluteColor()
void setAlternateTransform(const Mat4 &transform)
Definition: CUNode.h:1095
void addChildWithName(const std::shared_ptr< Node > &child, const std::string &name, int zval)
Definition: CUNode.h:1593
void render(const std::shared_ptr< SpriteBatch > &batch, const Mat4 &transform, Color4 tint)
float height
Definition: CUSize.h:63
Vec2 _anchor
Definition: CUNode.h:109
void chooseAlternateTransform(bool active)
Definition: CUNode.h:1130
static std::shared_ptr< Node > allocWithPosition(float x, float y)
Definition: CUNode.h:394
void addChildWithTag(const std::shared_ptr< Node > &child, unsigned int tag)
Definition: CUNode.h:1542
std::vector< std::shared_ptr< Node > > getChildren()
Definition: CUNode.h:1496
const Vec2 & getAnchor() const
Definition: CUNode.h:853
int _childOffset
Definition: CUNode.h:170
float getScaleY() const
Definition: CUNode.h:992
std::shared_ptr< Node > getChild(unsigned int pos)
void setName(const std::string &name)
Definition: CUNode.h:521
Mat4 _transform
Definition: CUNode.h:147
Definition: CURect.h:45
static const Mat4 IDENTITY
Definition: CUMat4.h:114
Vec2 parentToNodeCoords(const Vec2 &parentPoint) const
Definition: CUNode.h:1261
static std::shared_ptr< Node > alloc()
Definition: CUNode.h:363
void removeFromParent()
Definition: CUNode.h:1658
const Vec2 & getScale() const
Definition: CUNode.h:968
Mat4 getParentToNodeTransform() const
Definition: CUNode.h:1154
const Mat4 & getAlternateTransform()
Definition: CUNode.h:1079
float getContentHeight() const
Definition: CUNode.h:720
void setScale(float scale)
Definition: CUNode.h:1004
void removeChildByName(const std::string &name)
virtual void dispose()
static std::shared_ptr< Node > allocWithBounds(const Size &size)
Definition: CUNode.h:411
Scene * getScene()
Definition: CUNode.h:1641
virtual Node * copy(Node *dst)
void swapChild(const std::shared_ptr< Node > &child1, const std::shared_ptr< Node > &child2, bool inherit=false)
Size size
Definition: CURect.h:51
std::shared_ptr< T > getChildByName(const std::string &name) const
Definition: CUNode.h:1487
float getContentWidth() const
Definition: CUNode.h:695
std::string _name
Definition: CUNode.h:187
float getPositionX(void) const
Definition: CUNode.h:591
virtual void removeAllChildren()
Node * getParent()
Definition: CUNode.h:1621
const Scene * getScene() const
Definition: CUNode.h:1651
bool _useTransform
Definition: CUNode.h:150
virtual void setContentSize(float width, float height)
Definition: CUNode.h:683
Definition: CUColor4.h:1104
Size _contentSize
Definition: CUNode.h:112
Rect getBoundingBox() const
Definition: CUNode.h:784
static std::shared_ptr< Node > allocWithBounds(float width, float height)
Definition: CUNode.h:429
Color4 getColor() const
Definition: CUNode.h:885
std::shared_ptr< T > getChild(unsigned int pos) const
Definition: CUNode.h:1411
bool initWithBounds(float width, float height)
Definition: CUNode.h:296
Vec2 & set(float x, float y)
Definition: CUVec2.h:176
Definition: CUAnimationNode.h:52
bool withAlternateTransform()
Definition: CUNode.h:1114
virtual ~Node()
Definition: CUNode.h:217
virtual bool initWithPosition(const Vec2 &pos)
static const Vec2 ZERO
Definition: CUVec2.h:71
Definition: CUScene.h:64
void setScale(float sx, float sy)
Definition: CUNode.h:1035
Definition: CUMat4.h:92
virtual bool init()
Definition: CUNode.h:237
void setVisible(bool visible)
Definition: CUNode.h:931
const std::vector< std::shared_ptr< Node > > & getChildren() const
Definition: CUNode.h:1503
std::shared_ptr< T > getChildByTag(unsigned int tag) const
Definition: CUNode.h:1449
int getZOrder() const
Definition: CUNode.h:1318
bool _isVisible
Definition: CUNode.h:119
size_t _hashOfName
Definition: CUNode.h:194