CUGL 1.2
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 MIT 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 <cugl/math/cu_math.h>
46 #include <cugl/renderer/CUSpriteBatch.h>
47 #include <cugl/util/CUDebug.h>
48 #include <cugl/assets/CUJsonValue.h>
49 #include <vector>
50 #include <string>
51 
52 namespace cugl {
53 
55 class Scene;
56 class SceneLoader;
57 class Layout;
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 
169  std::shared_ptr<Layout> _layout;
170 
173 
181  unsigned int _tag;
182 
189  std::string _name;
190 
196  size_t _hashOfName;
197 
199  int _zOrder;
201  bool _zDirty;
202 
203 #pragma mark -
204 #pragma mark Constructors
205 public:
214  Node();
215 
219  ~Node() { dispose(); }
220 
230  virtual void dispose();
231 
239  virtual bool init() {
240  return initWithPosition(0, 0);
241  }
242 
243 
254  virtual bool initWithPosition(const Vec2& pos);
255 
267  bool initWithPosition(float x, float y) {
268  return initWithPosition(Vec2(x,y));
269  }
270 
283  virtual bool initWithBounds(const Size& size);
284 
298  bool initWithBounds(float width, float height) {
299  return initWithBounds(Size(width,height));
300  }
301 
317  virtual bool initWithBounds(const Rect& rect);
318 
337  bool initWithBounds(float x, float y, float width, float height) {
338  return initWithBounds(Rect(x,y,width,height));
339  }
340 
363  virtual bool initWithData(const SceneLoader* loader, const std::shared_ptr<JsonValue>& data);
364 
376  virtual Node* copy(Node* dst);
377 
378 
379 #pragma mark -
380 #pragma mark Static Constructors
381 
389  static std::shared_ptr<Node> alloc() {
390  std::shared_ptr<Node> result = std::make_shared<Node>();
391  return (result->init() ? result : nullptr);
392  }
393 
404  static std::shared_ptr<Node> allocWithPosition(const Vec2& pos) {
405  std::shared_ptr<Node> result = std::make_shared<Node>();
406  return (result->initWithPosition(pos) ? result : nullptr);
407  }
408 
420  static std::shared_ptr<Node> allocWithPosition(float x, float y) {
421  std::shared_ptr<Node> result = std::make_shared<Node>();
422  return (result->initWithPosition(x,y) ? result : nullptr);
423  }
424 
437  static std::shared_ptr<Node> allocWithBounds(const Size& size) {
438  std::shared_ptr<Node> result = std::make_shared<Node>();
439  return (result->initWithBounds(size) ? result : nullptr);
440  }
441 
455  static std::shared_ptr<Node> allocWithBounds(float width, float height) {
456  std::shared_ptr<Node> result = std::make_shared<Node>();
457  return (result->initWithBounds(width,height) ? result : nullptr);
458  }
459 
475  static std::shared_ptr<Node> allocWithBounds(const Rect& rect) {
476  std::shared_ptr<Node> result = std::make_shared<Node>();
477  return (result->initWithBounds(rect) ? result : nullptr);
478  }
479 
498  static std::shared_ptr<Node> allocWithBounds(float x, float y, float width, float height) {
499  std::shared_ptr<Node> result = std::make_shared<Node>();
500  return (result->initWithBounds(x,y,width,height) ? result : nullptr);
501  }
502 
525  static std::shared_ptr<Node> allocWithData(const SceneLoader* loader,
526  const std::shared_ptr<JsonValue>& data) {
527  std::shared_ptr<Node> result = std::make_shared<Node>();
528  return (result->initWithData(loader,data) ? result : nullptr);
529  }
530 
531 #pragma mark -
532 #pragma mark Identifiers
533 
542  unsigned int getTag() const { return _tag; }
543 
553  void setTag(unsigned int tag) { _tag = tag; }
554 
564  const std::string& getName() const { return _name; }
565 
575  void setName(const std::string& name) {
576  _name = name;
577  _hashOfName = std::hash<std::string>()(_name);
578  }
579 
590  virtual std::string toString(bool verbose = false) const;
591 
593  operator std::string() const { return toString(); }
594 
595 
596 #pragma mark -
597 #pragma mark Position
598 
608  const Vec2& getPosition() const { return _position; }
609 
620  void setPosition(const Vec2 &position) { setPosition(position.x,position.y); }
621 
633  void setPosition(float x, float y);
634 
645  float getPositionX(void) const { return getPosition().x; }
646 
657  void setPositionX(float x) { setPosition(x,getPositionY()); }
658 
669  float getPositionY(void) const { return getPosition().y; }
670 
681  void setPositionY(float y) { setPosition(getPositionX(),y); }
682 
692  return nodeToWorldCoords(_anchor*getContentSize());
693  }
694 
695 
696 #pragma mark -
697 #pragma mark Size
698 
706  const Size& getContentSize() const { return _contentSize; }
707 
721  virtual void setContentSize(const Size& size);
722 
737  virtual void setContentSize(float width, float height) {
738  setContentSize(Size(width, height));
739  }
740 
749  float getContentWidth() const { return getContentSize().width; }
750 
764  void setContentWidth(float width) { setContentSize(width,getContentHeight()); }
765 
774  float getContentHeight() const { return getContentSize().height; }
775 
789  void setContentHeight(float height) { setContentSize(getContentWidth(),height); }
790 
801  Size getSize() const;
802 
813  float getWidth() const { return getSize().width; }
814 
825  float getHeight() const { return getSize().height; }
826 
838  }
839 
840 #pragma mark -
841 #pragma mark Anchors
842 
861  virtual void setAnchor(const Vec2& anchor);
862 
883  void setAnchor(float x, float y) { setAnchor(Vec2(x,y)); }
884 
904  const Vec2& getAnchor() const { return _anchor; }
905 
920  Vec2 getAnchorInPixels() { return _anchor * _contentSize; }
921 
922 
923 #pragma mark -
924 #pragma mark Visibility
925 
936  Color4 getColor() const { return _tintColor; }
937 
949  virtual void setColor(Color4 color) { _tintColor = color; }
950 
961 
971  bool isVisible() const { return _isVisible; }
972 
982  void setVisible(bool visible) { _isVisible = visible; }
983 
994 
1004  void setRelativeColor(bool flag) { _hasParentColor = flag; }
1005 
1006 
1007 #pragma mark -
1008 #pragma mark Transforms
1009 
1019  const Vec2& getScale() const { return _scale; }
1020 
1031  float getScaleX() const { return _scale.x; }
1032 
1043  float getScaleY() const { return _scale.y; }
1044 
1055  void setScale(float scale) {
1056  _scale.set(scale,scale);
1057  if (!_useTransform) updateTransform();
1058  }
1059 
1070  void setScale(const Vec2& vec) {
1071  _scale = vec;
1072  if (!_useTransform) updateTransform();
1073  }
1074 
1086  void setScale(float sx, float sy) {
1087  _scale.set(sx,sy);
1088  if (!_useTransform) updateTransform();
1089  }
1090 
1100  float getAngle() { return _angle; }
1101 
1111  void setAngle(float angle) {
1112  _angle = angle;
1113  if (!_useTransform) updateTransform();
1114  }
1115 
1131 
1146  void setAlternateTransform(const Mat4& transform) {
1147  _transform = transform;
1148  updateTransform();
1149  }
1150 
1166 
1181  void chooseAlternateTransform(bool active) {
1182  _useTransform = active; updateTransform();
1183  }
1184 
1194  const Mat4& getNodeToParentTransform() const { return _combined; }
1195 
1205  Mat4 getParentToNodeTransform() const { return _combined.getInverse(); }
1206 
1216  Mat4 getNodeToWorldTransform() const;
1217 
1230  }
1231 
1249  Vec2 screenToNodeCoords(const Vec2& screenPoint) const;
1250 
1251 
1263  Vec2 worldToNodeCoords(const Vec2& worldPoint) const {
1264  return getWorldToNodeTransform().transform(worldPoint);
1265  }
1266 
1284  Vec2 nodeToScreenCoords(const Vec2& nodePoint) const;
1285 
1297  Vec2 nodeToWorldCoords(const Vec2& nodePoint) const {
1298  return getNodeToWorldTransform().transform(nodePoint);
1299  }
1300 
1312  Vec2 parentToNodeCoords(const Vec2& parentPoint) const {
1313  return getParentToNodeTransform().transform(parentPoint);
1314  }
1315 
1327  Vec2 nodeToParentCoords(const Vec2& nodePoint) const {
1328  return getNodeToParentTransform().transform(nodePoint);
1329  }
1330 
1331 #pragma mark -
1332 #pragma mark Z-order
1333 
1350  void setZOrder(int z);
1351 
1369  int getZOrder() const { return _zOrder; }
1370 
1388  bool isZDirty() const { return _zDirty; }
1389 
1407  void sortZOrder();
1408 
1409 
1410 #pragma mark -
1411 #pragma mark Scene Graph
1412 
1417  size_t getChildCount() const { return _children.size(); }
1418 
1430  std::shared_ptr<Node> getChild(unsigned int pos);
1431 
1443  const std::shared_ptr<Node>& getChild(unsigned int pos) const;
1444 
1461  template <typename T>
1462  inline std::shared_ptr<T> getChild(unsigned int pos) const {
1463  return std::dynamic_pointer_cast<T>(getChild(pos));
1464  }
1465 
1479  std::shared_ptr<Node> getChildByTag(unsigned int tag) const;
1480 
1499  template <typename T>
1500  inline std::shared_ptr<T> getChildByTag(unsigned int tag) const {
1501  return std::dynamic_pointer_cast<T>(getChildByTag(tag));
1502  }
1503 
1517  std::shared_ptr<Node> getChildByName(const std::string& name) const;
1518 
1537  template <typename T>
1538  inline std::shared_ptr<T> getChildByName(const std::string& name) const {
1539  return std::dynamic_pointer_cast<T>(getChildByName(name));
1540  }
1541 
1547  std::vector<std::shared_ptr<Node>> getChildren() { return _children; }
1548 
1554  const std::vector<std::shared_ptr<Node>>& getChildren() const { return _children; }
1555 
1565  void addChild(std::shared_ptr<Node> child) {
1566  addChild(child,child->_zOrder);
1567  }
1568 
1581  virtual void addChild(const std::shared_ptr<Node>& child, int zval);
1582 
1593  void addChildWithTag(const std::shared_ptr<Node>& child, unsigned int tag) {
1594  addChild(child);
1595  child->setTag(tag);
1596  }
1597 
1611  void addChildWithTag(const std::shared_ptr<Node>& child, unsigned int tag, int zval) {
1612  addChild(child,zval);
1613  child->setTag(tag);
1614  }
1615 
1626  void addChildWithName(const std::shared_ptr<Node>& child, const std::string &name) {
1627  addChild(child);
1628  child->setName(name);
1629  }
1630 
1644  void addChildWithName(const std::shared_ptr<Node>& child, const std::string &name, int zval) {
1645  addChild(child,zval);
1646  child->setName(name);
1647  }
1648 
1662  void swapChild(const std::shared_ptr<Node>& child1, const std::shared_ptr<Node>& child2, bool inherit=false);
1663 
1672  Node* getParent() { return _parent; }
1673 
1682  const Node* getParent() const { return _parent; }
1683 
1692  Scene* getScene() { return _graph; }
1693 
1702  const Scene* getScene() const { return _graph; }
1703 
1709  void removeFromParent() { if (_parent) { _parent->removeChild(_childOffset); } }
1710 
1719  virtual void removeChild(unsigned int pos);
1720 
1731  void removeChild(const std::shared_ptr<Node>& child);
1732 
1744  void removeChildByTag(unsigned int tag);
1745 
1757  void removeChildByName(const std::string &name);
1758 
1762  virtual void removeAllChildren();
1763 
1764 
1765 #pragma mark -
1766 #pragma mark Rendering
1767 
1778  virtual void render(const std::shared_ptr<SpriteBatch>& batch, const Mat4& transform, Color4 tint);
1779 
1789  virtual void render(const std::shared_ptr<SpriteBatch>& batch) {
1791  }
1792 
1816  virtual void draw(const std::shared_ptr<SpriteBatch>& batch, const Mat4& transform, Color4 tint) {}
1817 
1818 
1819 #pragma mark -
1820 #pragma mark Layout Automation
1821 
1832  const std::shared_ptr<Layout>& getLayout() const { return _layout; }
1833 
1848  void setLayout(const std::shared_ptr<Layout>& layout) { _layout = layout; }
1849 
1857  virtual void doLayout();
1858 
1859 private:
1860 #pragma mark -
1861 #pragma mark Internal Helpers
1862 
1879  void setZDirty(bool value);
1880 
1889  void setParent(Node* parent) { _parent = parent; }
1890 
1899  void setScene(Scene* scene) { _graph = scene; }
1900 
1909  void pushScene(Scene* scene);
1910 
1921  static bool compareNodeSibs(const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b);
1922 
1929  virtual void updateTransform();
1930 
1931  // Copying is only allowed via shared pointer.
1932  CU_DISALLOW_COPY_AND_ASSIGN(Node);
1933 
1934  friend class Scene;
1935 };
1936 
1937 
1938 }
1939 #endif /* __CU_NODE_H__ */
Definition: CUSize.h:57
Vec2 _position
Definition: CUNode.h:101
bool initWithPosition(float x, float y)
Definition: CUNode.h:267
std::vector< std::shared_ptr< Node > > _children
Definition: CUNode.h:162
void setRelativeColor(bool flag)
Definition: CUNode.h:1004
Color4 _tintColor
Definition: CUNode.h:115
Vec2 nodeToScreenCoords(const Vec2 &nodePoint) const
unsigned int getTag() const
Definition: CUNode.h:542
const Mat4 & getNodeToParentTransform() const
Definition: CUNode.h:1194
float x
Definition: CUVec2.h:66
float getHeight() const
Definition: CUNode.h:825
Vec2 screenToNodeCoords(const Vec2 &screenPoint) const
static std::shared_ptr< Node > allocWithPosition(const Vec2 &pos)
Definition: CUNode.h:404
float y
Definition: CUVec2.h:68
static Vec2 * transform(const Mat4 &mat, const Vec2 &point, Vec2 *dst)
const Node * getParent() const
Definition: CUNode.h:1682
void addChildWithName(const std::shared_ptr< Node > &child, const std::string &name)
Definition: CUNode.h:1626
void setPosition(const Vec2 &position)
Definition: CUNode.h:620
static std::shared_ptr< Node > allocWithData(const SceneLoader *loader, const std::shared_ptr< JsonValue > &data)
Definition: CUNode.h:525
Definition: CUVec2.h:61
Vec2 nodeToParentCoords(const Vec2 &nodePoint) const
Definition: CUNode.h:1327
size_t getChildCount() const
Definition: CUNode.h:1417
float _angle
Definition: CUNode.h:137
float getAngle()
Definition: CUNode.h:1100
float getPositionY(void) const
Definition: CUNode.h:669
virtual bool initWithData(const SceneLoader *loader, const std::shared_ptr< JsonValue > &data)
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
virtual void render(const std::shared_ptr< SpriteBatch > &batch, const Mat4 &transform, Color4 tint)
std::shared_ptr< Node > getChildByTag(unsigned int tag) const
virtual void setContentSize(const Size &size)
Size getSize() const
virtual void draw(const std::shared_ptr< SpriteBatch > &batch, const Mat4 &transform, Color4 tint)
Definition: CUNode.h:1816
void removeChildByTag(unsigned int tag)
Mat4 getNodeToWorldTransform() const
static std::shared_ptr< Node > allocWithBounds(const Rect &rect)
Definition: CUNode.h:475
std::shared_ptr< Node > getChildByName(const std::string &name) const
void setPositionY(float y)
Definition: CUNode.h:681
int _zOrder
Definition: CUNode.h:199
Mat4 _combined
Definition: CUNode.h:159
virtual void removeChild(unsigned int pos)
Vec2 getWorldPosition() const
Definition: CUNode.h:691
bool hasRelativeColor()
Definition: CUNode.h:993
void setZOrder(int z)
void setScale(const Vec2 &vec)
Definition: CUNode.h:1070
virtual std::string toString(bool verbose=false) const
void setPositionX(float x)
Definition: CUNode.h:657
void addChildWithTag(const std::shared_ptr< Node > &child, unsigned int tag, int zval)
Definition: CUNode.h:1611
float getScaleX() const
Definition: CUNode.h:1031
bool _zDirty
Definition: CUNode.h:201
Vec2 worldToNodeCoords(const Vec2 &worldPoint) const
Definition: CUNode.h:1263
bool initWithBounds(float x, float y, float width, float height)
Definition: CUNode.h:337
Vec2 getAnchorInPixels()
Definition: CUNode.h:920
virtual void setAnchor(const Vec2 &anchor)
bool isVisible() const
Definition: CUNode.h:971
void sortZOrder()
static const Color4 WHITE
Definition: CUColor4.h:1106
unsigned int _tag
Definition: CUNode.h:181
const Vec2 & getPosition() const
Definition: CUNode.h:608
void setContentHeight(float height)
Definition: CUNode.h:789
void setAnchor(float x, float y)
Definition: CUNode.h:883
void setContentWidth(float width)
Definition: CUNode.h:764
float width
Definition: CUSize.h:61
bool isZDirty() const
Definition: CUNode.h:1388
Vec2 nodeToWorldCoords(const Vec2 &nodePoint) const
Definition: CUNode.h:1297
void setTag(unsigned int tag)
Definition: CUNode.h:553
~Node()
Definition: CUNode.h:219
static std::shared_ptr< Node > allocWithBounds(float x, float y, float width, float height)
Definition: CUNode.h:498
const Size & getContentSize() const
Definition: CUNode.h:706
Mat4 getInverse() const
Definition: CUMat4.h:1047
void addChild(std::shared_ptr< Node > child)
Definition: CUNode.h:1565
void setLayout(const std::shared_ptr< Layout > &layout)
Definition: CUNode.h:1848
Mat4 getWorldToNodeTransform() const
Definition: CUNode.h:1228
Scene * _graph
Definition: CUNode.h:167
void setAngle(float angle)
Definition: CUNode.h:1111
float getWidth() const
Definition: CUNode.h:813
const std::string & getName() const
Definition: CUNode.h:564
Color4 getAbsoluteColor()
void setAlternateTransform(const Mat4 &transform)
Definition: CUNode.h:1146
void addChildWithName(const std::shared_ptr< Node > &child, const std::string &name, int zval)
Definition: CUNode.h:1644
float height
Definition: CUSize.h:63
const std::shared_ptr< Layout > & getLayout() const
Definition: CUNode.h:1832
Vec2 _anchor
Definition: CUNode.h:109
void chooseAlternateTransform(bool active)
Definition: CUNode.h:1181
static std::shared_ptr< Node > allocWithPosition(float x, float y)
Definition: CUNode.h:420
void addChildWithTag(const std::shared_ptr< Node > &child, unsigned int tag)
Definition: CUNode.h:1593
std::vector< std::shared_ptr< Node > > getChildren()
Definition: CUNode.h:1547
const Vec2 & getAnchor() const
Definition: CUNode.h:904
int _childOffset
Definition: CUNode.h:172
virtual void setColor(Color4 color)
Definition: CUNode.h:949
float getScaleY() const
Definition: CUNode.h:1043
std::shared_ptr< Node > getChild(unsigned int pos)
void setName(const std::string &name)
Definition: CUNode.h:575
Mat4 _transform
Definition: CUNode.h:147
Definition: CURect.h:45
static const Mat4 IDENTITY
Definition: CUMat4.h:105
Vec2 parentToNodeCoords(const Vec2 &parentPoint) const
Definition: CUNode.h:1312
static std::shared_ptr< Node > alloc()
Definition: CUNode.h:389
void removeFromParent()
Definition: CUNode.h:1709
const Vec2 & getScale() const
Definition: CUNode.h:1019
Definition: CUSceneLoader.h:77
Mat4 getParentToNodeTransform() const
Definition: CUNode.h:1205
const Mat4 & getAlternateTransform()
Definition: CUNode.h:1130
float getContentHeight() const
Definition: CUNode.h:774
void setScale(float scale)
Definition: CUNode.h:1055
void removeChildByName(const std::string &name)
virtual void dispose()
static std::shared_ptr< Node > allocWithBounds(const Size &size)
Definition: CUNode.h:437
Scene * getScene()
Definition: CUNode.h:1692
virtual Node * copy(Node *dst)
void swapChild(const std::shared_ptr< Node > &child1, const std::shared_ptr< Node > &child2, bool inherit=false)
std::shared_ptr< T > getChildByName(const std::string &name) const
Definition: CUNode.h:1538
float getContentWidth() const
Definition: CUNode.h:749
std::string _name
Definition: CUNode.h:189
float getPositionX(void) const
Definition: CUNode.h:645
virtual void removeAllChildren()
Node * getParent()
Definition: CUNode.h:1672
const Scene * getScene() const
Definition: CUNode.h:1702
virtual void doLayout()
bool _useTransform
Definition: CUNode.h:150
virtual void setContentSize(float width, float height)
Definition: CUNode.h:737
Definition: CUColor4.h:1084
Size _contentSize
Definition: CUNode.h:112
Rect getBoundingBox() const
Definition: CUNode.h:836
static std::shared_ptr< Node > allocWithBounds(float width, float height)
Definition: CUNode.h:455
Color4 getColor() const
Definition: CUNode.h:936
std::shared_ptr< T > getChild(unsigned int pos) const
Definition: CUNode.h:1462
bool initWithBounds(float width, float height)
Definition: CUNode.h:298
Vec2 & set(float x, float y)
Definition: CUVec2.h:153
Definition: CUAction.h:51
bool withAlternateTransform()
Definition: CUNode.h:1165
virtual bool initWithPosition(const Vec2 &pos)
virtual void render(const std::shared_ptr< SpriteBatch > &batch)
Definition: CUNode.h:1789
static const Vec2 ZERO
Definition: CUVec2.h:71
Definition: CUScene.h:65
void setScale(float sx, float sy)
Definition: CUNode.h:1086
Definition: CUMat4.h:83
virtual bool init()
Definition: CUNode.h:239
void setVisible(bool visible)
Definition: CUNode.h:982
const std::vector< std::shared_ptr< Node > > & getChildren() const
Definition: CUNode.h:1554
std::shared_ptr< T > getChildByTag(unsigned int tag) const
Definition: CUNode.h:1500
int getZOrder() const
Definition: CUNode.h:1369
bool _isVisible
Definition: CUNode.h:119
size_t _hashOfName
Definition: CUNode.h:196
std::shared_ptr< Layout > _layout
Definition: CUNode.h:169