CCNode.cpp 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271
  1. /****************************************************************************
  2. Copyright (c) 2008-2010 Ricardo Quesada
  3. Copyright (c) 2009 Valentin Milea
  4. Copyright (c) 2010-2012 cocos2d-x.org
  5. Copyright (c) 2011 Zynga Inc.
  6. Copyright (c) 2013-2017 Chukong Technologies Inc.
  7. http://www.cocos2d-x.org
  8. Permission is hereby granted, free of charge, to any person obtaining a copy
  9. of this software and associated documentation files (the "Software"), to deal
  10. in the Software without restriction, including without limitation the rights
  11. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. copies of the Software, and to permit persons to whom the Software is
  13. furnished to do so, subject to the following conditions:
  14. The above copyright notice and this permission notice shall be included in
  15. all copies or substantial portions of the Software.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. THE SOFTWARE.
  23. ****************************************************************************/
  24. #include "2d/CCNode.h"
  25. #include <algorithm>
  26. #include <string>
  27. #include <regex>
  28. #include "base/CCDirector.h"
  29. #include "base/CCScheduler.h"
  30. #include "base/CCEventDispatcher.h"
  31. #include "base/ccUTF8.h"
  32. #include "2d/CCCamera.h"
  33. #include "2d/CCActionManager.h"
  34. #include "2d/CCScene.h"
  35. #include "2d/CCComponent.h"
  36. #include "renderer/CCGLProgram.h"
  37. #include "renderer/CCGLProgramState.h"
  38. #include "renderer/CCMaterial.h"
  39. #include "math/TransformUtils.h"
  40. #if CC_NODE_RENDER_SUBPIXEL
  41. #define RENDER_IN_SUBPIXEL
  42. #else
  43. #define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__))
  44. #endif
  45. NS_CC_BEGIN
  46. // FIXME:: Yes, nodes might have a sort problem once every 30 days if the game runs at 60 FPS and each frame sprites are reordered.
  47. unsigned int Node::s_globalOrderOfArrival = 0;
  48. int Node::__attachedNodeCount = 0;
  49. // MARK: Constructor, Destructor, Init
  50. Node::Node()
  51. : _rotationX(0.0f)
  52. , _rotationY(0.0f)
  53. , _rotationZ_X(0.0f)
  54. , _rotationZ_Y(0.0f)
  55. , _scaleX(1.0f)
  56. , _scaleY(1.0f)
  57. , _scaleZ(1.0f)
  58. , _positionZ(0.0f)
  59. , _usingNormalizedPosition(false)
  60. , _normalizedPositionDirty(false)
  61. , _skewX(0.0f)
  62. , _skewY(0.0f)
  63. , _contentSize(Size::ZERO)
  64. , _contentSizeDirty(true)
  65. , _transformDirty(true)
  66. , _inverseDirty(true)
  67. , _additionalTransform(nullptr)
  68. , _additionalTransformDirty(false)
  69. , _transformUpdated(true)
  70. // children (lazy allocs)
  71. // lazy alloc
  72. , _localZOrderAndArrival(0)
  73. , _localZOrder(0)
  74. , _globalZOrder(0)
  75. , _parent(nullptr)
  76. // "whole screen" objects. like Scenes and Layers, should set _ignoreAnchorPointForPosition to true
  77. , _tag(Node::INVALID_TAG)
  78. , _name("")
  79. , _hashOfName(0)
  80. // userData is always inited as nil
  81. , _userData(nullptr)
  82. , _userObject(nullptr)
  83. , _glProgramState(nullptr)
  84. , _running(false)
  85. , _visible(true)
  86. , _ignoreAnchorPointForPosition(false)
  87. , _reorderChildDirty(false)
  88. , _isTransitionFinished(false)
  89. #if CC_ENABLE_SCRIPT_BINDING
  90. , _updateScriptHandler(0)
  91. #endif
  92. , _componentContainer(nullptr)
  93. , _displayedOpacity(255)
  94. , _realOpacity(255)
  95. , _displayedColor(Color3B::WHITE)
  96. , _realColor(Color3B::WHITE)
  97. , _cascadeColorEnabled(false)
  98. , _cascadeOpacityEnabled(false)
  99. , _cameraMask(1)
  100. #if CC_USE_PHYSICS
  101. , _physicsBody(nullptr)
  102. #endif
  103. , _anchorPoint(0, 0)
  104. , _onEnterCallback(nullptr)
  105. , _onExitCallback(nullptr)
  106. , _onEnterTransitionDidFinishCallback(nullptr)
  107. , _onExitTransitionDidStartCallback(nullptr)
  108. {
  109. //by zml
  110. #if ZML_EXPEND_SPRITE_VERTEX
  111. _expandVec4 = Vec4::ZERO;
  112. _expandVec4_1 = Vec4::ZERO;
  113. _expandVec4_2 = Vec4::ZERO;
  114. #endif
  115. // set default scheduler and actionManager
  116. _director = Director::getInstance();
  117. _actionManager = _director->getActionManager();
  118. _actionManager->retain();
  119. _scheduler = _director->getScheduler();
  120. _scheduler->retain();
  121. _eventDispatcher = _director->getEventDispatcher();
  122. _eventDispatcher->retain();
  123. #if CC_ENABLE_SCRIPT_BINDING
  124. ScriptEngineProtocol* engine = ScriptEngineManager::getInstance()->getScriptEngine();
  125. _scriptType = engine != nullptr ? engine->getScriptType() : kScriptTypeNone;
  126. #endif
  127. _transform = _inverse = Mat4::IDENTITY;
  128. }
  129. Node * Node::create()
  130. {
  131. Node * ret = new (std::nothrow) Node();
  132. if (ret && ret->init())
  133. {
  134. ret->autorelease();
  135. }
  136. else
  137. {
  138. CC_SAFE_DELETE(ret);
  139. }
  140. return ret;
  141. }
  142. Node::~Node()
  143. {
  144. if (_batchNode) {
  145. _batchNode->release();
  146. _batchNode = nullptr;
  147. }
  148. CCLOGINFO( "deallocing Node: %p - tag: %i", this, _tag );
  149. #if CC_ENABLE_SCRIPT_BINDING
  150. if (_updateScriptHandler)
  151. {
  152. ScriptEngineManager::getInstance()->getScriptEngine()->removeScriptHandler(_updateScriptHandler);
  153. }
  154. #endif
  155. // User object has to be released before others, since userObject may have a weak reference of this node
  156. // It may invoke `node->stopAllActions();` while `_actionManager` is null if the next line is after `CC_SAFE_RELEASE_NULL(_actionManager)`.
  157. CC_SAFE_RELEASE_NULL(_userObject);
  158. // attributes
  159. CC_SAFE_RELEASE_NULL(_glProgramState);
  160. for (auto& child : _children)
  161. {
  162. child->_parent = nullptr;
  163. }
  164. removeAllComponents();
  165. CC_SAFE_DELETE(_componentContainer);
  166. stopAllActions();
  167. unscheduleAllCallbacks();
  168. CC_SAFE_RELEASE_NULL(_actionManager);
  169. CC_SAFE_RELEASE_NULL(_scheduler);
  170. _eventDispatcher->removeEventListenersForTarget(this);
  171. #if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS && COCOS2D_DEBUG > 0
  172. _eventDispatcher->debugCheckNodeHasNoEventListenersOnDestruction(this);
  173. #endif
  174. CCASSERT(!_running, "Node still marked as running on node destruction! Was base class onExit() called in derived class onExit() implementations?");
  175. CC_SAFE_RELEASE(_eventDispatcher);
  176. delete[] _additionalTransform;
  177. }
  178. void Node::setBatchNode(Ref* bnode){
  179. if (_batchNode) {
  180. CCASSERT(0, "不允许重复加");
  181. return;
  182. }
  183. _batchNode = bnode;
  184. if(_batchNode){
  185. _batchNode->retain();
  186. }
  187. }
  188. Ref* Node::getBatchNode(){
  189. return _batchNode;
  190. }
  191. bool Node::init()
  192. {
  193. return true;
  194. }
  195. void Node::cleanup()
  196. {
  197. #if CC_ENABLE_SCRIPT_BINDING
  198. if (_scriptType == kScriptTypeJavascript)
  199. {
  200. if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnCleanup))
  201. return;
  202. }
  203. else if (_scriptType == kScriptTypeLua)
  204. {
  205. ScriptEngineManager::sendNodeEventToLua(this, kNodeOnCleanup);
  206. }
  207. #endif // #if CC_ENABLE_SCRIPT_BINDING
  208. // actions
  209. this->stopAllActions();
  210. // timers
  211. this->unscheduleAllCallbacks();
  212. // _eventDispatcher->removeEventListenersForTarget(this);
  213. for( const auto &child: _children)
  214. child->cleanup();
  215. }
  216. std::string Node::getDescription() const
  217. {
  218. return StringUtils::format("<Node | Tag = %d", _tag);
  219. }
  220. // MARK: getters / setters
  221. float Node::getSkewX() const
  222. {
  223. return _skewX;
  224. }
  225. void Node::setSkewX(float skewX)
  226. {
  227. if (_skewX == skewX)
  228. return;
  229. _skewX = skewX;
  230. _transformUpdated = _transformDirty = _inverseDirty = true;
  231. }
  232. float Node::getSkewY() const
  233. {
  234. return _skewY;
  235. }
  236. void Node::setSkewY(float skewY)
  237. {
  238. if (_skewY == skewY)
  239. return;
  240. _skewY = skewY;
  241. _transformUpdated = _transformDirty = _inverseDirty = true;
  242. }
  243. void Node::setLocalZOrder(int z)
  244. {
  245. if (getLocalZOrder() == z)
  246. return;
  247. _setLocalZOrder(z);
  248. if (_parent)
  249. {
  250. _parent->reorderChild(this, z);
  251. }
  252. _eventDispatcher->setDirtyForNode(this);
  253. }
  254. /// zOrder setter : private method
  255. /// used internally to alter the zOrder variable. DON'T call this method manually
  256. void Node::_setLocalZOrder(int z)
  257. {
  258. _localZOrderAndArrival = (static_cast<std::int64_t>(z) << 32) | (_localZOrderAndArrival & 0xffffffff);
  259. _localZOrder = z;
  260. }
  261. void Node::updateOrderOfArrival()
  262. {
  263. _localZOrderAndArrival = (_localZOrderAndArrival & 0xffffffff00000000) | (++s_globalOrderOfArrival);
  264. }
  265. void Node::setGlobalZOrder(float globalZOrder)
  266. {
  267. if (_globalZOrder != globalZOrder)
  268. {
  269. _globalZOrder = globalZOrder;
  270. _eventDispatcher->setDirtyForNode(this);
  271. }
  272. }
  273. /// rotation getter
  274. float Node::getRotation() const
  275. {
  276. CCASSERT(_rotationZ_X == _rotationZ_Y, "CCNode#rotation. RotationX != RotationY. Don't know which one to return");
  277. return _rotationZ_X;
  278. }
  279. /// rotation setter
  280. void Node::setRotation(float rotation)
  281. {
  282. if (_rotationZ_X == rotation)
  283. return;
  284. _rotationZ_X = _rotationZ_Y = rotation;
  285. _transformUpdated = _transformDirty = _inverseDirty = true;
  286. updateRotationQuat();
  287. }
  288. float Node::getRotationSkewX() const
  289. {
  290. return _rotationZ_X;
  291. }
  292. void Node::setRotation3D(const Vec3& rotation)
  293. {
  294. if (_rotationX == rotation.x &&
  295. _rotationY == rotation.y &&
  296. _rotationZ_X == rotation.z)
  297. return;
  298. _transformUpdated = _transformDirty = _inverseDirty = true;
  299. _rotationX = rotation.x;
  300. _rotationY = rotation.y;
  301. // rotation Z is decomposed in 2 to simulate Skew for Flash animations
  302. _rotationZ_Y = _rotationZ_X = rotation.z;
  303. updateRotationQuat();
  304. }
  305. Vec3 Node::getRotation3D() const
  306. {
  307. // rotation Z is decomposed in 2 to simulate Skew for Flash animations
  308. CCASSERT(_rotationZ_X == _rotationZ_Y, "_rotationZ_X != _rotationZ_Y");
  309. return Vec3(_rotationX,_rotationY,_rotationZ_X);
  310. }
  311. void Node::updateRotationQuat()
  312. {
  313. // convert Euler angle to quaternion
  314. // when _rotationZ_X == _rotationZ_Y, _rotationQuat = RotationZ_X * RotationY * RotationX
  315. // when _rotationZ_X != _rotationZ_Y, _rotationQuat = RotationY * RotationX
  316. float halfRadx = CC_DEGREES_TO_RADIANS(_rotationX / 2.f), halfRady = CC_DEGREES_TO_RADIANS(_rotationY / 2.f), halfRadz = _rotationZ_X == _rotationZ_Y ? -CC_DEGREES_TO_RADIANS(_rotationZ_X / 2.f) : 0;
  317. float coshalfRadx = cosf(halfRadx), sinhalfRadx = sinf(halfRadx), coshalfRady = cosf(halfRady), sinhalfRady = sinf(halfRady), coshalfRadz = cosf(halfRadz), sinhalfRadz = sinf(halfRadz);
  318. _rotationQuat.x = sinhalfRadx * coshalfRady * coshalfRadz - coshalfRadx * sinhalfRady * sinhalfRadz;
  319. _rotationQuat.y = coshalfRadx * sinhalfRady * coshalfRadz + sinhalfRadx * coshalfRady * sinhalfRadz;
  320. _rotationQuat.z = coshalfRadx * coshalfRady * sinhalfRadz - sinhalfRadx * sinhalfRady * coshalfRadz;
  321. _rotationQuat.w = coshalfRadx * coshalfRady * coshalfRadz + sinhalfRadx * sinhalfRady * sinhalfRadz;
  322. }
  323. void Node::updateRotation3D()
  324. {
  325. //convert quaternion to Euler angle
  326. float x = _rotationQuat.x, y = _rotationQuat.y, z = _rotationQuat.z, w = _rotationQuat.w;
  327. _rotationX = atan2f(2.f * (w * x + y * z), 1.f - 2.f * (x * x + y * y));
  328. float sy = 2.f * (w * y - z * x);
  329. sy = clampf(sy, -1, 1);
  330. _rotationY = asinf(sy);
  331. _rotationZ_X = atan2f(2.f * (w * z + x * y), 1.f - 2.f * (y * y + z * z));
  332. _rotationX = CC_RADIANS_TO_DEGREES(_rotationX);
  333. _rotationY = CC_RADIANS_TO_DEGREES(_rotationY);
  334. _rotationZ_X = _rotationZ_Y = -CC_RADIANS_TO_DEGREES(_rotationZ_X);
  335. }
  336. void Node::setRotationQuat(const Quaternion& quat)
  337. {
  338. _rotationQuat = quat;
  339. updateRotation3D();
  340. _transformUpdated = _transformDirty = _inverseDirty = true;
  341. }
  342. Quaternion Node::getRotationQuat() const
  343. {
  344. return _rotationQuat;
  345. }
  346. void Node::setRotationSkewX(float rotationX)
  347. {
  348. if (_rotationZ_X == rotationX)
  349. return;
  350. _rotationZ_X = rotationX;
  351. _transformUpdated = _transformDirty = _inverseDirty = true;
  352. updateRotationQuat();
  353. }
  354. float Node::getRotationSkewY() const
  355. {
  356. return _rotationZ_Y;
  357. }
  358. void Node::setRotationSkewY(float rotationY)
  359. {
  360. if (_rotationZ_Y == rotationY)
  361. return;
  362. _rotationZ_Y = rotationY;
  363. _transformUpdated = _transformDirty = _inverseDirty = true;
  364. updateRotationQuat();
  365. }
  366. /// scale getter
  367. float Node::getScale(void) const
  368. {
  369. CCASSERT( _scaleX == _scaleY, "CCNode#scale. ScaleX != ScaleY. Don't know which one to return");
  370. return _scaleX;
  371. }
  372. /// scale setter
  373. void Node::setScale(float scale)
  374. {
  375. if (_scaleX == scale && _scaleY == scale && _scaleZ == scale)
  376. return;
  377. _scaleX = _scaleY = _scaleZ = scale;
  378. _transformUpdated = _transformDirty = _inverseDirty = true;
  379. }
  380. /// scaleX getter
  381. float Node::getScaleX() const
  382. {
  383. return _scaleX;
  384. }
  385. /// scale setter
  386. void Node::setScale(float scaleX,float scaleY)
  387. {
  388. if (_scaleX == scaleX && _scaleY == scaleY)
  389. return;
  390. _scaleX = scaleX;
  391. _scaleY = scaleY;
  392. _transformUpdated = _transformDirty = _inverseDirty = true;
  393. }
  394. /// scaleX setter
  395. void Node::setScaleX(float scaleX)
  396. {
  397. if (_scaleX == scaleX)
  398. return;
  399. _scaleX = scaleX;
  400. _transformUpdated = _transformDirty = _inverseDirty = true;
  401. }
  402. /// scaleY getter
  403. float Node::getScaleY() const
  404. {
  405. return _scaleY;
  406. }
  407. /// scaleY setter
  408. void Node::setScaleZ(float scaleZ)
  409. {
  410. if (_scaleZ == scaleZ)
  411. return;
  412. _scaleZ = scaleZ;
  413. _transformUpdated = _transformDirty = _inverseDirty = true;
  414. }
  415. /// scaleY getter
  416. float Node::getScaleZ() const
  417. {
  418. return _scaleZ;
  419. }
  420. /// scaleY setter
  421. void Node::setScaleY(float scaleY)
  422. {
  423. if (_scaleY == scaleY)
  424. return;
  425. _scaleY = scaleY;
  426. _transformUpdated = _transformDirty = _inverseDirty = true;
  427. }
  428. /// position getter
  429. const Vec2& Node::getPosition() const
  430. {
  431. return _position;
  432. }
  433. /// position setter
  434. void Node::setPosition(const Vec2& position)
  435. {
  436. setPosition(position.x, position.y);
  437. }
  438. void Node::getPosition(float* x, float* y) const
  439. {
  440. *x = _position.x;
  441. *y = _position.y;
  442. }
  443. void Node::setPosition(float x, float y)
  444. {
  445. if (_position.x == x && _position.y == y)
  446. return;
  447. _position.x = x;
  448. _position.y = y;
  449. _transformUpdated = _transformDirty = _inverseDirty = true;
  450. _usingNormalizedPosition = false;
  451. }
  452. void Node::setPosition3D(const Vec3& position)
  453. {
  454. setPositionZ(position.z);
  455. setPosition(position.x, position.y);
  456. }
  457. Vec3 Node::getPosition3D() const
  458. {
  459. return Vec3(_position.x, _position.y, _positionZ);
  460. }
  461. float Node::getPositionX() const
  462. {
  463. return _position.x;
  464. }
  465. void Node::setPositionX(float x)
  466. {
  467. setPosition(x, _position.y);
  468. }
  469. float Node::getPositionY() const
  470. {
  471. return _position.y;
  472. }
  473. void Node::setPositionY(float y)
  474. {
  475. setPosition(_position.x, y);
  476. }
  477. float Node::getPositionZ() const
  478. {
  479. return _positionZ;
  480. }
  481. void Node::setPositionZ(float positionZ)
  482. {
  483. if (_positionZ == positionZ)
  484. return;
  485. _transformUpdated = _transformDirty = _inverseDirty = true;
  486. _positionZ = positionZ;
  487. }
  488. /// position getter
  489. const Vec2& Node::getPositionNormalized() const
  490. {
  491. return _normalizedPosition;
  492. }
  493. /// position setter
  494. void Node::setPositionNormalized(const Vec2& position)
  495. {
  496. if (_normalizedPosition.equals(position))
  497. return;
  498. _normalizedPosition = position;
  499. _usingNormalizedPosition = true;
  500. _normalizedPositionDirty = true;
  501. _transformUpdated = _transformDirty = _inverseDirty = true;
  502. }
  503. ssize_t Node::getChildrenCount() const
  504. {
  505. return _children.size();
  506. }
  507. /// isVisible getter
  508. bool Node::isVisible() const
  509. {
  510. return _visible;
  511. }
  512. /// isVisible setter
  513. void Node::setVisible(bool visible)
  514. {
  515. if(visible != _visible)
  516. {
  517. _visible = visible;
  518. if(_visible)
  519. _transformUpdated = _transformDirty = _inverseDirty = true;
  520. }
  521. }
  522. const Vec2& Node::getAnchorPointInPoints() const
  523. {
  524. return _anchorPointInPoints;
  525. }
  526. /// anchorPoint getter
  527. const Vec2& Node::getAnchorPoint() const
  528. {
  529. return _anchorPoint;
  530. }
  531. void Node::setAnchorPoint(const Vec2& point)
  532. {
  533. if (! point.equals(_anchorPoint))
  534. {
  535. _anchorPoint = point;
  536. _anchorPointInPoints.set(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y);
  537. _transformUpdated = _transformDirty = _inverseDirty = true;
  538. }
  539. }
  540. /// contentSize getter
  541. const Size& Node::getContentSize() const
  542. {
  543. return _contentSize;
  544. }
  545. void Node::setContentSize(const Size & size)
  546. {
  547. if (! size.equals(_contentSize))
  548. {
  549. _contentSize = size;
  550. _anchorPointInPoints.set(_contentSize.width * _anchorPoint.x, _contentSize.height * _anchorPoint.y);
  551. _transformUpdated = _transformDirty = _inverseDirty = _contentSizeDirty = true;
  552. }
  553. }
  554. // isRunning getter
  555. bool Node::isRunning() const
  556. {
  557. return _running;
  558. }
  559. /// parent setter
  560. void Node::setParent(Node * parent)
  561. {
  562. _parent = parent;
  563. _transformUpdated = _transformDirty = _inverseDirty = true;
  564. }
  565. /// isRelativeAnchorPoint getter
  566. bool Node::isIgnoreAnchorPointForPosition() const
  567. {
  568. return _ignoreAnchorPointForPosition;
  569. }
  570. /// isRelativeAnchorPoint setter
  571. void Node::setIgnoreAnchorPointForPosition(bool newValue)
  572. {
  573. if (newValue != _ignoreAnchorPointForPosition)
  574. {
  575. _ignoreAnchorPointForPosition = newValue;
  576. _transformUpdated = _transformDirty = _inverseDirty = true;
  577. }
  578. }
  579. /// tag getter
  580. int Node::getTag() const
  581. {
  582. return _tag;
  583. }
  584. /// tag setter
  585. void Node::setTag(int tag)
  586. {
  587. _tag = tag ;
  588. }
  589. const std::string& Node::getName() const
  590. {
  591. return _name;
  592. }
  593. void Node::setName(const std::string& name)
  594. {
  595. _name = name;
  596. std::hash<std::string> h;
  597. _hashOfName = h(name);
  598. }
  599. /// userData setter
  600. void Node::setUserData(void *userData)
  601. {
  602. _userData = userData;
  603. }
  604. void Node::setUserObject(Ref* userObject)
  605. {
  606. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  607. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  608. if (sEngine)
  609. {
  610. if (userObject)
  611. sEngine->retainScriptObject(this, userObject);
  612. if (_userObject)
  613. sEngine->releaseScriptObject(this, _userObject);
  614. }
  615. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  616. CC_SAFE_RETAIN(userObject);
  617. CC_SAFE_RELEASE(_userObject);
  618. _userObject = userObject;
  619. }
  620. GLProgramState* Node::getGLProgramState() const
  621. {
  622. return _glProgramState;
  623. }
  624. void Node::setGLProgramState(cocos2d::GLProgramState* glProgramState)
  625. {
  626. if (glProgramState != _glProgramState)
  627. {
  628. CC_SAFE_RELEASE(_glProgramState);
  629. _glProgramState = glProgramState;
  630. CC_SAFE_RETAIN(_glProgramState);
  631. if (_glProgramState)
  632. _glProgramState->setNodeBinding(this);
  633. }
  634. }
  635. void Node::setGLProgram(GLProgram* glProgram)
  636. {
  637. if (_glProgramState == nullptr || (_glProgramState && _glProgramState->getGLProgram() != glProgram))
  638. {
  639. CC_SAFE_RELEASE(_glProgramState);
  640. _glProgramState = GLProgramState::getOrCreateWithGLProgram(glProgram);
  641. _glProgramState->retain();
  642. _glProgramState->setNodeBinding(this);
  643. }
  644. }
  645. GLProgram * Node::getGLProgram() const
  646. {
  647. return _glProgramState ? _glProgramState->getGLProgram() : nullptr;
  648. }
  649. Scene* Node::getScene() const
  650. {
  651. if (!_parent)
  652. return nullptr;
  653. auto sceneNode = _parent;
  654. while (sceneNode->_parent)
  655. {
  656. sceneNode = sceneNode->_parent;
  657. }
  658. return dynamic_cast<Scene*>(sceneNode);
  659. }
  660. Rect Node::getBoundingBox() const
  661. {
  662. Rect rect(0, 0, _contentSize.width, _contentSize.height);
  663. return RectApplyAffineTransform(rect, getNodeToParentAffineTransform());
  664. }
  665. // MARK: Children logic
  666. // lazy allocs
  667. void Node::childrenAlloc()
  668. {
  669. _children.reserve(4);
  670. }
  671. Node* Node::getChildByTag(int tag) const
  672. {
  673. CCASSERT(tag != Node::INVALID_TAG, "Invalid tag");
  674. for (const auto child : _children)
  675. {
  676. if(child && child->_tag == tag)
  677. return child;
  678. }
  679. return nullptr;
  680. }
  681. Node* Node::getChildByName(const std::string& name) const
  682. {
  683. CCASSERT(!name.empty(), "Invalid name");
  684. std::hash<std::string> h;
  685. size_t hash = h(name);
  686. for (const auto& child : _children)
  687. {
  688. // Different strings may have the same hash code, but can use it to compare first for speed
  689. if(child->_hashOfName == hash && child->_name.compare(name) == 0)
  690. return child;
  691. }
  692. return nullptr;
  693. }
  694. void Node::enumerateChildren(const std::string &name, std::function<bool (Node *)> callback) const
  695. {
  696. CCASSERT(!name.empty(), "Invalid name");
  697. CCASSERT(callback != nullptr, "Invalid callback function");
  698. size_t length = name.length();
  699. size_t subStrStartPos = 0; // sub string start index
  700. size_t subStrlength = length; // sub string length
  701. // Starts with '//'?
  702. bool searchRecursively = false;
  703. if (length > 2 && name[0] == '/' && name[1] == '/')
  704. {
  705. searchRecursively = true;
  706. subStrStartPos = 2;
  707. subStrlength -= 2;
  708. }
  709. // End with '/..'?
  710. bool searchFromParent = false;
  711. if (length > 3 &&
  712. name[length-3] == '/' &&
  713. name[length-2] == '.' &&
  714. name[length-1] == '.')
  715. {
  716. searchFromParent = true;
  717. subStrlength -= 3;
  718. }
  719. // Remove '//', '/..' if exist
  720. std::string newName = name.substr(subStrStartPos, subStrlength);
  721. if (searchFromParent)
  722. {
  723. newName.insert(0, "[[:alnum:]]+/");
  724. }
  725. if (searchRecursively)
  726. {
  727. // name is '//xxx'
  728. doEnumerateRecursive(this, newName, callback);
  729. }
  730. else
  731. {
  732. // name is xxx
  733. doEnumerate(newName, callback);
  734. }
  735. }
  736. bool Node::doEnumerateRecursive(const Node* node, const std::string &name, std::function<bool (Node *)> callback) const
  737. {
  738. bool ret =false;
  739. if (node->doEnumerate(name, callback))
  740. {
  741. // search itself
  742. ret = true;
  743. }
  744. else
  745. {
  746. // search its children
  747. for (const auto& child : node->getChildren())
  748. {
  749. if (doEnumerateRecursive(child, name, callback))
  750. {
  751. ret = true;
  752. break;
  753. }
  754. }
  755. }
  756. return ret;
  757. }
  758. bool Node::doEnumerate(std::string name, std::function<bool (Node *)> callback) const
  759. {
  760. // name may be xxx/yyy, should find its parent
  761. size_t pos = name.find('/');
  762. std::string searchName = name;
  763. bool needRecursive = false;
  764. if (pos != name.npos)
  765. {
  766. searchName = name.substr(0, pos);
  767. name.erase(0, pos+1);
  768. needRecursive = true;
  769. }
  770. bool ret = false;
  771. for (const auto& child : getChildren())
  772. {
  773. if (std::regex_match(child->_name, std::regex(searchName)))
  774. {
  775. if (!needRecursive)
  776. {
  777. // terminate enumeration if callback return true
  778. if (callback(child))
  779. {
  780. ret = true;
  781. break;
  782. }
  783. }
  784. else
  785. {
  786. ret = child->doEnumerate(name, callback);
  787. if (ret)
  788. break;
  789. }
  790. }
  791. }
  792. return ret;
  793. }
  794. /* "add" logic MUST only be on this method
  795. * If a class want's to extend the 'addChild' behavior it only needs
  796. * to override this method
  797. */
  798. void Node::addChild(Node *child, int localZOrder, int tag)
  799. {
  800. CCASSERT( child != nullptr, "Argument must be non-nil");
  801. CCASSERT( child->_parent == nullptr, "child already added. It can't be added again");
  802. addChildHelper(child, localZOrder, tag, "", true);
  803. }
  804. void Node::addChild(Node* child, int localZOrder, const std::string &name)
  805. {
  806. CCASSERT(child != nullptr, "Argument must be non-nil");
  807. CCASSERT(child->_parent == nullptr, "child already added. It can't be added again");
  808. addChildHelper(child, localZOrder, INVALID_TAG, name, false);
  809. }
  810. void Node::addChildHelper(Node* child, int localZOrder, int tag, const std::string &name, bool setTag)
  811. {
  812. auto assertNotSelfChild
  813. ( [ this, child ]() -> bool
  814. {
  815. for ( Node* parent( getParent() ); parent != nullptr;
  816. parent = parent->getParent() )
  817. if ( parent == child )
  818. return false;
  819. return true;
  820. } );
  821. (void)assertNotSelfChild;
  822. CCASSERT( assertNotSelfChild(),
  823. "A node cannot be the child of his own children" );
  824. if (_children.empty())
  825. {
  826. this->childrenAlloc();
  827. }
  828. this->insertChild(child, localZOrder);
  829. if (setTag)
  830. child->setTag(tag);
  831. else
  832. child->setName(name);
  833. child->setParent(this);
  834. child->updateOrderOfArrival();
  835. if( _running )
  836. {
  837. child->onEnter();
  838. // prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
  839. if (_isTransitionFinished)
  840. {
  841. child->onEnterTransitionDidFinish();
  842. }
  843. }
  844. if (_cascadeColorEnabled)
  845. {
  846. updateCascadeColor();
  847. }
  848. if (_cascadeOpacityEnabled)
  849. {
  850. updateCascadeOpacity();
  851. }
  852. }
  853. void Node::addChild(Node *child, int zOrder)
  854. {
  855. CCASSERT( child != nullptr, "Argument must be non-nil");
  856. this->addChild(child, zOrder, child->_name);
  857. }
  858. void Node::addChild(Node *child)
  859. {
  860. CCASSERT( child != nullptr, "Argument must be non-nil");
  861. this->addChild(child, child->getLocalZOrder(), child->_name);
  862. }
  863. void Node::removeFromParent()
  864. {
  865. this->removeFromParentAndCleanup(true);
  866. }
  867. void Node::removeFromParentAndCleanup(bool cleanup)
  868. {
  869. if (_parent != nullptr)
  870. {
  871. _parent->removeChild(this,cleanup);
  872. }
  873. }
  874. /* "remove" logic MUST only be on this method
  875. * If a class want's to extend the 'removeChild' behavior it only needs
  876. * to override this method
  877. */
  878. void Node::removeChild(Node* child, bool cleanup /* = true */)
  879. {
  880. // explicit nil handling
  881. if (_children.empty())
  882. {
  883. return;
  884. }
  885. ssize_t index = _children.getIndex(child);
  886. if( index != CC_INVALID_INDEX )
  887. this->detachChild( child, index, cleanup );
  888. }
  889. void Node::removeChildByTag(int tag, bool cleanup/* = true */)
  890. {
  891. CCASSERT( tag != Node::INVALID_TAG, "Invalid tag");
  892. Node *child = this->getChildByTag(tag);
  893. if (child == nullptr)
  894. {
  895. CCLOG("cocos2d: removeChildByTag(tag = %d): child not found!", tag);
  896. }
  897. else
  898. {
  899. this->removeChild(child, cleanup);
  900. }
  901. }
  902. void Node::removeChildByName(const std::string &name, bool cleanup)
  903. {
  904. CCASSERT(!name.empty(), "Invalid name");
  905. Node *child = this->getChildByName(name);
  906. if (child == nullptr)
  907. {
  908. CCLOG("cocos2d: removeChildByName(name = %s): child not found!", name.c_str());
  909. }
  910. else
  911. {
  912. this->removeChild(child, cleanup);
  913. }
  914. }
  915. void Node::removeAllChildren()
  916. {
  917. this->removeAllChildrenWithCleanup(true);
  918. }
  919. void Node::removeAllChildrenWithCleanup(bool cleanup)
  920. {
  921. // not using detachChild improves speed here
  922. for (const auto& child : _children)
  923. {
  924. // IMPORTANT:
  925. // -1st do onExit
  926. // -2nd cleanup
  927. if(_running)
  928. {
  929. child->onExitTransitionDidStart();
  930. child->onExit();
  931. }
  932. if (cleanup)
  933. {
  934. child->cleanup();
  935. }
  936. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  937. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  938. if (sEngine)
  939. {
  940. sEngine->releaseScriptObject(this, child);
  941. }
  942. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  943. // set parent nil at the end
  944. child->setParent(nullptr);
  945. }
  946. _children.clear();
  947. }
  948. void Node::detachChild(Node *child, ssize_t childIndex, bool doCleanup)
  949. {
  950. // IMPORTANT:
  951. // -1st do onExit
  952. // -2nd cleanup
  953. if (_running)
  954. {
  955. child->onExitTransitionDidStart();
  956. child->onExit();
  957. }
  958. // If you don't do cleanup, the child's actions will not get removed and the
  959. // its scheduledSelectors_ dict will not get released!
  960. if (doCleanup)
  961. {
  962. child->cleanup();
  963. }
  964. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  965. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  966. if (sEngine)
  967. {
  968. sEngine->releaseScriptObject(this, child);
  969. }
  970. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  971. // set parent nil at the end
  972. child->setParent(nullptr);
  973. _children.erase(childIndex);
  974. }
  975. // helper used by reorderChild & add
  976. void Node::insertChild(Node* child, int z)
  977. {
  978. #if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  979. auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
  980. if (sEngine)
  981. {
  982. sEngine->retainScriptObject(this, child);
  983. }
  984. #endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
  985. _transformUpdated = true;
  986. _reorderChildDirty = true;
  987. _children.pushBack(child);
  988. child->_setLocalZOrder(z);
  989. }
  990. void Node::reorderChild(Node *child, int zOrder)
  991. {
  992. CCASSERT( child != nullptr, "Child must be non-nil");
  993. _reorderChildDirty = true;
  994. child->updateOrderOfArrival();
  995. child->_setLocalZOrder(zOrder);
  996. }
  997. void Node::sortAllChildren()
  998. {
  999. if (_reorderChildDirty)
  1000. {
  1001. sortNodes(_children);
  1002. _reorderChildDirty = false;
  1003. _eventDispatcher->setDirtyForNode(this);
  1004. }
  1005. }
  1006. // MARK: draw / visit
  1007. void Node::draw()
  1008. {
  1009. auto renderer = _director->getRenderer();
  1010. draw(renderer, _modelViewTransform, true);
  1011. }
  1012. void Node::draw(Renderer* /*renderer*/, const Mat4 & /*transform*/, uint32_t /*flags*/)
  1013. {
  1014. }
  1015. void Node::visit()
  1016. {
  1017. auto renderer = _director->getRenderer();
  1018. auto& parentTransform = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
  1019. visit(renderer, parentTransform, true);
  1020. }
  1021. uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFlags)
  1022. {
  1023. if(_usingNormalizedPosition)
  1024. {
  1025. CCASSERT(_parent, "setPositionNormalized() doesn't work with orphan nodes");
  1026. if ((parentFlags & FLAGS_CONTENT_SIZE_DIRTY) || _normalizedPositionDirty)
  1027. {
  1028. auto& s = _parent->getContentSize();
  1029. _position.x = _normalizedPosition.x * s.width;
  1030. _position.y = _normalizedPosition.y * s.height;
  1031. _transformUpdated = _transformDirty = _inverseDirty = true;
  1032. _normalizedPositionDirty = false;
  1033. }
  1034. }
  1035. // Fixes Github issue #16100. Basically when having two cameras, one camera might set as dirty the
  1036. // node that is not visited by it, and might affect certain calculations. Besides, it is faster to do this.
  1037. if (!isVisitableByVisitingCamera())
  1038. return parentFlags;
  1039. uint32_t flags = parentFlags;
  1040. flags |= (_transformUpdated ? FLAGS_TRANSFORM_DIRTY : 0);
  1041. flags |= (_contentSizeDirty ? FLAGS_CONTENT_SIZE_DIRTY : 0);
  1042. if(flags & FLAGS_DIRTY_MASK)
  1043. _modelViewTransform = this->transform(parentTransform);
  1044. _transformUpdated = false;
  1045. _contentSizeDirty = false;
  1046. return flags;
  1047. }
  1048. bool Node::isVisitableByVisitingCamera() const
  1049. {
  1050. auto camera = Camera::getVisitingCamera();
  1051. bool visibleByCamera = camera ? ((unsigned short)camera->getCameraFlag() & _cameraMask) != 0 : true;
  1052. return visibleByCamera;
  1053. }
  1054. void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
  1055. {
  1056. // quick return if not visible. children won't be drawn.
  1057. if (!_visible)
  1058. {
  1059. return;
  1060. }
  1061. uint32_t flags = processParentFlags(parentTransform, parentFlags);
  1062. // IMPORTANT:
  1063. // To ease the migration to v3.0, we still support the Mat4 stack,
  1064. // but it is deprecated and your code should not rely on it
  1065. _director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
  1066. _director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
  1067. bool visibleByCamera = isVisitableByVisitingCamera();
  1068. int i = 0;
  1069. if(!_children.empty())
  1070. {
  1071. sortAllChildren();
  1072. // draw children zOrder < 0
  1073. for(auto size = _children.size(); i < size; ++i)
  1074. {
  1075. auto node = _children.at(i);
  1076. if (node && node->_localZOrder < 0)
  1077. node->visit(renderer, _modelViewTransform, flags);
  1078. else
  1079. break;
  1080. }
  1081. // self draw
  1082. if (visibleByCamera)
  1083. this->draw(renderer, _modelViewTransform, flags);
  1084. for(auto it=_children.cbegin()+i, itCend = _children.cend(); it != itCend; ++it)
  1085. (*it)->visit(renderer, _modelViewTransform, flags);
  1086. }
  1087. else if (visibleByCamera)
  1088. {
  1089. this->draw(renderer, _modelViewTransform, flags);
  1090. }
  1091. _director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
  1092. // FIX ME: Why need to set _orderOfArrival to 0??
  1093. // Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920
  1094. // reset for next frame
  1095. // _orderOfArrival = 0;
  1096. }
  1097. Mat4 Node::transform(const Mat4& parentTransform)
  1098. {
  1099. return parentTransform * this->getNodeToParentTransform();
  1100. }
  1101. // MARK: events
  1102. void Node::onEnter()
  1103. {
  1104. if (!_running)
  1105. {
  1106. ++__attachedNodeCount;
  1107. }
  1108. #if CC_ENABLE_SCRIPT_BINDING
  1109. if (_scriptType == kScriptTypeJavascript)
  1110. {
  1111. if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnEnter))
  1112. return;
  1113. }
  1114. #endif
  1115. if (_onEnterCallback)
  1116. _onEnterCallback();
  1117. if (_componentContainer && !_componentContainer->isEmpty())
  1118. {
  1119. _componentContainer->onEnter();
  1120. }
  1121. _isTransitionFinished = false;
  1122. for( const auto &child: _children)
  1123. child->onEnter();
  1124. this->resume();
  1125. _running = true;
  1126. #if CC_ENABLE_SCRIPT_BINDING
  1127. if (_scriptType == kScriptTypeLua)
  1128. {
  1129. ScriptEngineManager::sendNodeEventToLua(this, kNodeOnEnter);
  1130. }
  1131. #endif
  1132. }
  1133. void Node::onEnterTransitionDidFinish()
  1134. {
  1135. #if CC_ENABLE_SCRIPT_BINDING
  1136. if (_scriptType == kScriptTypeJavascript)
  1137. {
  1138. if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnEnterTransitionDidFinish))
  1139. return;
  1140. }
  1141. #endif
  1142. if (_onEnterTransitionDidFinishCallback)
  1143. _onEnterTransitionDidFinishCallback();
  1144. _isTransitionFinished = true;
  1145. for( const auto &child: _children)
  1146. child->onEnterTransitionDidFinish();
  1147. #if CC_ENABLE_SCRIPT_BINDING
  1148. if (_scriptType == kScriptTypeLua)
  1149. {
  1150. ScriptEngineManager::sendNodeEventToLua(this, kNodeOnEnterTransitionDidFinish);
  1151. }
  1152. #endif
  1153. }
  1154. void Node::onExitTransitionDidStart()
  1155. {
  1156. #if CC_ENABLE_SCRIPT_BINDING
  1157. if (_scriptType == kScriptTypeJavascript)
  1158. {
  1159. if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnExitTransitionDidStart))
  1160. return;
  1161. }
  1162. #endif
  1163. if (_onExitTransitionDidStartCallback)
  1164. _onExitTransitionDidStartCallback();
  1165. for( const auto &child: _children)
  1166. child->onExitTransitionDidStart();
  1167. #if CC_ENABLE_SCRIPT_BINDING
  1168. if (_scriptType == kScriptTypeLua)
  1169. {
  1170. ScriptEngineManager::sendNodeEventToLua(this, kNodeOnExitTransitionDidStart);
  1171. }
  1172. #endif
  1173. }
  1174. void Node::onExit()
  1175. {
  1176. if (_running)
  1177. {
  1178. --__attachedNodeCount;
  1179. }
  1180. #if CC_ENABLE_SCRIPT_BINDING
  1181. if (_scriptType == kScriptTypeJavascript)
  1182. {
  1183. if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnExit))
  1184. return;
  1185. }
  1186. #endif
  1187. if (_onExitCallback)
  1188. _onExitCallback();
  1189. if (_componentContainer && !_componentContainer->isEmpty())
  1190. {
  1191. _componentContainer->onExit();
  1192. }
  1193. this->pause();
  1194. _running = false;
  1195. for( const auto &child: _children)
  1196. child->onExit();
  1197. #if CC_ENABLE_SCRIPT_BINDING
  1198. if (_scriptType == kScriptTypeLua)
  1199. {
  1200. ScriptEngineManager::sendNodeEventToLua(this, kNodeOnExit);
  1201. }
  1202. #endif
  1203. }
  1204. void Node::setEventDispatcher(EventDispatcher* dispatcher)
  1205. {
  1206. if (dispatcher != _eventDispatcher)
  1207. {
  1208. _eventDispatcher->removeEventListenersForTarget(this);
  1209. CC_SAFE_RETAIN(dispatcher);
  1210. CC_SAFE_RELEASE(_eventDispatcher);
  1211. _eventDispatcher = dispatcher;
  1212. }
  1213. }
  1214. void Node::setActionManager(ActionManager* actionManager)
  1215. {
  1216. if( actionManager != _actionManager )
  1217. {
  1218. this->stopAllActions();
  1219. CC_SAFE_RETAIN(actionManager);
  1220. CC_SAFE_RELEASE(_actionManager);
  1221. _actionManager = actionManager;
  1222. }
  1223. }
  1224. // MARK: actions
  1225. Action * Node::runAction(Action* action)
  1226. {
  1227. CCASSERT( action != nullptr, "Argument must be non-nil");
  1228. CCASSERT( _actionManager != nullptr, "Action Mananger must be non-nil");
  1229. _actionManager->addAction(action, this, !_running);
  1230. return action;
  1231. }
  1232. void Node::stopAllActions()
  1233. {
  1234. if(_actionManager){
  1235. _actionManager->removeAllActionsFromTarget(this);
  1236. }
  1237. }
  1238. void Node::stopAction(Action* action)
  1239. {
  1240. if (_actionManager) {
  1241. _actionManager->removeAction(action);
  1242. }
  1243. }
  1244. void Node::stopActionByTag(int tag)
  1245. {
  1246. CCASSERT( tag != Action::INVALID_TAG, "Invalid tag");
  1247. _actionManager->removeActionByTag(tag, this);
  1248. }
  1249. void Node::stopAllActionsByTag(int tag)
  1250. {
  1251. CCASSERT( tag != Action::INVALID_TAG, "Invalid tag");
  1252. _actionManager->removeAllActionsByTag(tag, this);
  1253. }
  1254. void Node::stopActionsByFlags(unsigned int flags)
  1255. {
  1256. if (flags > 0)
  1257. {
  1258. _actionManager->removeActionsByFlags(flags, this);
  1259. }
  1260. }
  1261. Action * Node::getActionByTag(int tag)
  1262. {
  1263. CCASSERT( tag != Action::INVALID_TAG, "Invalid tag");
  1264. return _actionManager->getActionByTag(tag, this);
  1265. }
  1266. ssize_t Node::getNumberOfRunningActions() const
  1267. {
  1268. return _actionManager->getNumberOfRunningActionsInTarget(this);
  1269. }
  1270. ssize_t Node::getNumberOfRunningActionsByTag(int tag) const
  1271. {
  1272. return _actionManager->getNumberOfRunningActionsInTargetByTag(this, tag);
  1273. }
  1274. // MARK: Callbacks
  1275. void Node::setScheduler(Scheduler* scheduler)
  1276. {
  1277. if( scheduler != _scheduler )
  1278. {
  1279. this->unscheduleAllCallbacks();
  1280. CC_SAFE_RETAIN(scheduler);
  1281. CC_SAFE_RELEASE(_scheduler);
  1282. _scheduler = scheduler;
  1283. }
  1284. }
  1285. bool Node::isScheduled(SEL_SCHEDULE selector) const
  1286. {
  1287. return _scheduler->isScheduled(selector, this);
  1288. }
  1289. bool Node::isScheduled(const std::string &key) const
  1290. {
  1291. return _scheduler->isScheduled(key, this);
  1292. }
  1293. void Node::scheduleUpdate()
  1294. {
  1295. scheduleUpdateWithPriority(0);
  1296. }
  1297. void Node::scheduleUpdateWithPriority(int priority)
  1298. {
  1299. _scheduler->scheduleUpdate(this, priority, !_running);
  1300. }
  1301. void Node::scheduleUpdateWithPriorityLua(int nHandler, int priority)
  1302. {
  1303. unscheduleUpdate();
  1304. #if CC_ENABLE_SCRIPT_BINDING
  1305. _updateScriptHandler = nHandler;
  1306. #endif
  1307. _scheduler->scheduleUpdate(this, priority, !_running);
  1308. }
  1309. void Node::unscheduleUpdate()
  1310. {
  1311. _scheduler->unscheduleUpdate(this);
  1312. #if CC_ENABLE_SCRIPT_BINDING
  1313. if (_updateScriptHandler)
  1314. {
  1315. ScriptEngineManager::getInstance()->getScriptEngine()->removeScriptHandler(_updateScriptHandler);
  1316. _updateScriptHandler = 0;
  1317. }
  1318. #endif
  1319. }
  1320. void Node::schedule(SEL_SCHEDULE selector)
  1321. {
  1322. this->schedule(selector, 0.0f, CC_REPEAT_FOREVER, 0.0f);
  1323. }
  1324. void Node::schedule(SEL_SCHEDULE selector, float interval)
  1325. {
  1326. this->schedule(selector, interval, CC_REPEAT_FOREVER, 0.0f);
  1327. }
  1328. void Node::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
  1329. {
  1330. CCASSERT( selector, "Argument must be non-nil");
  1331. CCASSERT( interval >=0, "Argument must be positive");
  1332. _scheduler->schedule(selector, this, interval , repeat, delay, !_running);
  1333. }
  1334. void Node::schedule(const std::function<void(float)> &callback, const std::string &key)
  1335. {
  1336. _scheduler->schedule(callback, this, 0, !_running, key);
  1337. }
  1338. void Node::schedule(const std::function<void(float)> &callback, float interval, const std::string &key)
  1339. {
  1340. _scheduler->schedule(callback, this, interval, !_running, key);
  1341. }
  1342. void Node::schedule(const std::function<void(float)>& callback, float interval, unsigned int repeat, float delay, const std::string &key)
  1343. {
  1344. _scheduler->schedule(callback, this, interval, repeat, delay, !_running, key);
  1345. }
  1346. void Node::scheduleOnce(SEL_SCHEDULE selector, float delay)
  1347. {
  1348. this->schedule(selector, 0.0f, 0, delay);
  1349. }
  1350. void Node::scheduleOnce(const std::function<void(float)> &callback, float delay, const std::string &key)
  1351. {
  1352. _scheduler->schedule(callback, this, 0, 0, delay, !_running, key);
  1353. }
  1354. void Node::unschedule(SEL_SCHEDULE selector)
  1355. {
  1356. // explicit null handling
  1357. if (selector == nullptr)
  1358. return;
  1359. _scheduler->unschedule(selector, this);
  1360. }
  1361. void Node::unschedule(const std::string &key)
  1362. {
  1363. _scheduler->unschedule(key, this);
  1364. }
  1365. void Node::unscheduleAllCallbacks()
  1366. {
  1367. _scheduler->unscheduleAllForTarget(this);
  1368. }
  1369. void Node::resume()
  1370. {
  1371. _scheduler->resumeTarget(this);
  1372. _actionManager->resumeTarget(this);
  1373. _eventDispatcher->resumeEventListenersForTarget(this);
  1374. }
  1375. void Node::pause()
  1376. {
  1377. _scheduler->pauseTarget(this);
  1378. _actionManager->pauseTarget(this);
  1379. _eventDispatcher->pauseEventListenersForTarget(this);
  1380. }
  1381. void Node::resumeSchedulerAndActions()
  1382. {
  1383. resume();
  1384. }
  1385. void Node::pauseSchedulerAndActions()
  1386. {
  1387. pause();
  1388. }
  1389. // override me
  1390. void Node::update(float fDelta)
  1391. {
  1392. #if CC_ENABLE_SCRIPT_BINDING
  1393. if (0 != _updateScriptHandler)
  1394. {
  1395. //only lua use
  1396. SchedulerScriptData data(_updateScriptHandler,fDelta);
  1397. ScriptEvent event(kScheduleEvent,&data);
  1398. ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&event);
  1399. }
  1400. #endif
  1401. if (_componentContainer && !_componentContainer->isEmpty())
  1402. {
  1403. _componentContainer->visit(fDelta);
  1404. }
  1405. }
  1406. // MARK: coordinates
  1407. AffineTransform Node::getNodeToParentAffineTransform() const
  1408. {
  1409. AffineTransform ret;
  1410. GLToCGAffine(getNodeToParentTransform().m, &ret);
  1411. return ret;
  1412. }
  1413. Mat4 Node::getNodeToParentTransform(Node* ancestor) const
  1414. {
  1415. Mat4 t(this->getNodeToParentTransform());
  1416. for (Node *p = _parent; p != nullptr && p != ancestor ; p = p->getParent())
  1417. {
  1418. t = p->getNodeToParentTransform() * t;
  1419. }
  1420. return t;
  1421. }
  1422. float Node::getWordRoation(){
  1423. float roation = getRotation();
  1424. for (Node *p = _parent; p != nullptr ; p = p->getParent())
  1425. {
  1426. roation = roation + p->getRotation();
  1427. }
  1428. return roation/180 * M_PI;
  1429. }
  1430. AffineTransform Node::getNodeToParentAffineTransform(Node* ancestor) const
  1431. {
  1432. AffineTransform t(this->getNodeToParentAffineTransform());
  1433. for (Node *p = _parent; p != nullptr && p != ancestor; p = p->getParent())
  1434. t = AffineTransformConcat(t, p->getNodeToParentAffineTransform());
  1435. return t;
  1436. }
  1437. const Mat4& Node::getNodeToParentTransform() const
  1438. {
  1439. if (_transformDirty)
  1440. {
  1441. // Translate values
  1442. float x = _position.x;
  1443. float y = _position.y;
  1444. float z = _positionZ;
  1445. if (_ignoreAnchorPointForPosition)
  1446. {
  1447. x += _anchorPointInPoints.x;
  1448. y += _anchorPointInPoints.y;
  1449. }
  1450. bool needsSkewMatrix = ( _skewX || _skewY );
  1451. // Build Transform Matrix = translation * rotation * scale
  1452. Mat4 translation;
  1453. //move to anchor point first, then rotate
  1454. Mat4::createTranslation(x, y, z, &translation);
  1455. Mat4::createRotation(_rotationQuat, &_transform);
  1456. if (_rotationZ_X != _rotationZ_Y)
  1457. {
  1458. // Rotation values
  1459. // Change rotation code to handle X and Y
  1460. // If we skew with the exact same value for both x and y then we're simply just rotating
  1461. float radiansX = -CC_DEGREES_TO_RADIANS(_rotationZ_X);
  1462. float radiansY = -CC_DEGREES_TO_RADIANS(_rotationZ_Y);
  1463. float cx = cosf(radiansX);
  1464. float sx = sinf(radiansX);
  1465. float cy = cosf(radiansY);
  1466. float sy = sinf(radiansY);
  1467. float m0 = _transform.m[0], m1 = _transform.m[1], m4 = _transform.m[4], m5 = _transform.m[5], m8 = _transform.m[8], m9 = _transform.m[9];
  1468. _transform.m[0] = cy * m0 - sx * m1, _transform.m[4] = cy * m4 - sx * m5, _transform.m[8] = cy * m8 - sx * m9;
  1469. _transform.m[1] = sy * m0 + cx * m1, _transform.m[5] = sy * m4 + cx * m5, _transform.m[9] = sy * m8 + cx * m9;
  1470. }
  1471. _transform = translation * _transform;
  1472. if (_scaleX != 1.f)
  1473. {
  1474. _transform.m[0] *= _scaleX, _transform.m[1] *= _scaleX, _transform.m[2] *= _scaleX;
  1475. }
  1476. if (_scaleY != 1.f)
  1477. {
  1478. _transform.m[4] *= _scaleY, _transform.m[5] *= _scaleY, _transform.m[6] *= _scaleY;
  1479. }
  1480. if (_scaleZ != 1.f)
  1481. {
  1482. _transform.m[8] *= _scaleZ, _transform.m[9] *= _scaleZ, _transform.m[10] *= _scaleZ;
  1483. }
  1484. // FIXME:: Try to inline skew
  1485. // If skew is needed, apply skew and then anchor point
  1486. if (needsSkewMatrix)
  1487. {
  1488. float skewMatArray[16] =
  1489. {
  1490. 1, (float)tanf(CC_DEGREES_TO_RADIANS(_skewY)), 0, 0,
  1491. (float)tanf(CC_DEGREES_TO_RADIANS(_skewX)), 1, 0, 0,
  1492. 0, 0, 1, 0,
  1493. 0, 0, 0, 1
  1494. };
  1495. Mat4 skewMatrix(skewMatArray);
  1496. _transform = _transform * skewMatrix;
  1497. }
  1498. // adjust anchor point
  1499. if (!_anchorPointInPoints.isZero())
  1500. {
  1501. // FIXME:: Argh, Mat4 needs a "translate" method.
  1502. // FIXME:: Although this is faster than multiplying a vec4 * mat4
  1503. _transform.m[12] += _transform.m[0] * -_anchorPointInPoints.x + _transform.m[4] * -_anchorPointInPoints.y;
  1504. _transform.m[13] += _transform.m[1] * -_anchorPointInPoints.x + _transform.m[5] * -_anchorPointInPoints.y;
  1505. _transform.m[14] += _transform.m[2] * -_anchorPointInPoints.x + _transform.m[6] * -_anchorPointInPoints.y;
  1506. }
  1507. }
  1508. if (_additionalTransform)
  1509. {
  1510. // This is needed to support both Node::setNodeToParentTransform() and Node::setAdditionalTransform()
  1511. // at the same time. The scenario is this:
  1512. // at some point setNodeToParentTransform() is called.
  1513. // and later setAdditionalTransform() is called every time. And since _transform
  1514. // is being overwritten everyframe, _additionalTransform[1] is used to have a copy
  1515. // of the last "_transform without _additionalTransform"
  1516. if (_transformDirty)
  1517. _additionalTransform[1] = _transform;
  1518. if (_transformUpdated)
  1519. _transform = _additionalTransform[1] * _additionalTransform[0];
  1520. }
  1521. _transformDirty = _additionalTransformDirty = false;
  1522. return _transform;
  1523. }
  1524. void Node::setNodeToParentTransform(const Mat4& transform)
  1525. {
  1526. _transform = transform;
  1527. _transformDirty = false;
  1528. _transformUpdated = true;
  1529. if (_additionalTransform)
  1530. // _additionalTransform[1] has a copy of lastest transform
  1531. _additionalTransform[1] = transform;
  1532. }
  1533. void Node::setAdditionalTransform(const AffineTransform& additionalTransform)
  1534. {
  1535. Mat4 tmp;
  1536. CGAffineToGL(additionalTransform, tmp.m);
  1537. setAdditionalTransform(&tmp);
  1538. }
  1539. void Node::setAdditionalTransform(const Mat4* additionalTransform)
  1540. {
  1541. if (additionalTransform == nullptr)
  1542. {
  1543. if(_additionalTransform) _transform = _additionalTransform[1];
  1544. delete[] _additionalTransform;
  1545. _additionalTransform = nullptr;
  1546. }
  1547. else
  1548. {
  1549. if (!_additionalTransform) {
  1550. _additionalTransform = new Mat4[2];
  1551. // _additionalTransform[1] is used as a backup for _transform
  1552. _additionalTransform[1] = _transform;
  1553. }
  1554. _additionalTransform[0] = *additionalTransform;
  1555. }
  1556. _transformUpdated = _additionalTransformDirty = _inverseDirty = true;
  1557. }
  1558. void Node::setAdditionalTransform(const Mat4& additionalTransform)
  1559. {
  1560. setAdditionalTransform(&additionalTransform);
  1561. }
  1562. AffineTransform Node::getParentToNodeAffineTransform() const
  1563. {
  1564. AffineTransform ret;
  1565. GLToCGAffine(getParentToNodeTransform().m,&ret);
  1566. return ret;
  1567. }
  1568. const Mat4& Node::getParentToNodeTransform() const
  1569. {
  1570. if ( _inverseDirty )
  1571. {
  1572. _inverse = getNodeToParentTransform().getInversed();
  1573. _inverseDirty = false;
  1574. }
  1575. return _inverse;
  1576. }
  1577. AffineTransform Node::getNodeToWorldAffineTransform() const
  1578. {
  1579. return this->getNodeToParentAffineTransform(nullptr);
  1580. }
  1581. Mat4 Node::getNodeToWorldTransform() const
  1582. {
  1583. return this->getNodeToParentTransform(nullptr);
  1584. }
  1585. AffineTransform Node::getWorldToNodeAffineTransform() const
  1586. {
  1587. return AffineTransformInvert(this->getNodeToWorldAffineTransform());
  1588. }
  1589. Mat4 Node::getWorldToNodeTransform() const
  1590. {
  1591. return getNodeToWorldTransform().getInversed();
  1592. }
  1593. Vec2 Node::convertToNodeSpace(const Vec2& worldPoint) const
  1594. {
  1595. Mat4 tmp = getWorldToNodeTransform();
  1596. Vec3 vec3(worldPoint.x, worldPoint.y, 0);
  1597. Vec3 ret;
  1598. tmp.transformPoint(vec3,&ret);
  1599. return Vec2(ret.x, ret.y);
  1600. }
  1601. Vec2 Node::convertToWorldSpace(const Vec2& nodePoint) const
  1602. {
  1603. Mat4 tmp = getNodeToWorldTransform();
  1604. Vec3 vec3(nodePoint.x, nodePoint.y, 0);
  1605. Vec3 ret;
  1606. tmp.transformPoint(vec3,&ret);
  1607. return Vec2(ret.x, ret.y);
  1608. }
  1609. Vec2 Node::convertToNodeSpaceAR(const Vec2& worldPoint) const
  1610. {
  1611. Vec2 nodePoint(convertToNodeSpace(worldPoint));
  1612. return nodePoint - _anchorPointInPoints;
  1613. }
  1614. Vec2 Node::convertToWorldSpaceAR(const Vec2& nodePoint) const
  1615. {
  1616. return convertToWorldSpace(nodePoint + _anchorPointInPoints);
  1617. }
  1618. Vec2 Node::convertToWindowSpace(const Vec2& nodePoint) const
  1619. {
  1620. Vec2 worldPoint(this->convertToWorldSpace(nodePoint));
  1621. return _director->convertToUI(worldPoint);
  1622. }
  1623. // convenience methods which take a Touch instead of Vec2
  1624. Vec2 Node::convertTouchToNodeSpace(Touch *touch) const
  1625. {
  1626. return this->convertToNodeSpace(touch->getLocation());
  1627. }
  1628. Vec2 Node::convertTouchToNodeSpaceAR(Touch *touch) const
  1629. {
  1630. Vec2 point = touch->getLocation();
  1631. return this->convertToNodeSpaceAR(point);
  1632. }
  1633. void Node::updateTransform()
  1634. {
  1635. // Recursively iterate over children
  1636. for( const auto &child: _children)
  1637. child->updateTransform();
  1638. }
  1639. // MARK: components
  1640. Component* Node::getComponent(const std::string& name)
  1641. {
  1642. if (_componentContainer)
  1643. return _componentContainer->get(name);
  1644. return nullptr;
  1645. }
  1646. bool Node::addComponent(Component *component)
  1647. {
  1648. // lazy alloc
  1649. if (!_componentContainer)
  1650. _componentContainer = new (std::nothrow) ComponentContainer(this);
  1651. // should enable schedule update, then all components can receive this call back
  1652. scheduleUpdate();
  1653. return _componentContainer->add(component);
  1654. }
  1655. bool Node::removeComponent(const std::string& name)
  1656. {
  1657. if (_componentContainer)
  1658. return _componentContainer->remove(name);
  1659. return false;
  1660. }
  1661. bool Node::removeComponent(Component *component)
  1662. {
  1663. if (_componentContainer)
  1664. {
  1665. return _componentContainer->remove(component);
  1666. }
  1667. return false;
  1668. }
  1669. void Node::removeAllComponents()
  1670. {
  1671. if (_componentContainer)
  1672. _componentContainer->removeAll();
  1673. }
  1674. // MARK: Opacity and Color
  1675. GLubyte Node::getOpacity(void) const
  1676. {
  1677. return _realOpacity;
  1678. }
  1679. GLubyte Node::getDisplayedOpacity() const
  1680. {
  1681. return _displayedOpacity;
  1682. }
  1683. void Node::setOpacity(GLubyte opacity)
  1684. {
  1685. _displayedOpacity = _realOpacity = opacity;
  1686. updateCascadeOpacity();
  1687. }
  1688. void Node::updateDisplayedOpacity(GLubyte parentOpacity)
  1689. {
  1690. _displayedOpacity = _realOpacity * parentOpacity/255.0;
  1691. updateColor();
  1692. if (_cascadeOpacityEnabled)
  1693. {
  1694. for(const auto& child : _children)
  1695. {
  1696. child->updateDisplayedOpacity(_displayedOpacity);
  1697. }
  1698. }
  1699. }
  1700. bool Node::isCascadeOpacityEnabled(void) const
  1701. {
  1702. return _cascadeOpacityEnabled;
  1703. }
  1704. void Node::setCascadeOpacityEnabled(bool cascadeOpacityEnabled)
  1705. {
  1706. if (_cascadeOpacityEnabled == cascadeOpacityEnabled)
  1707. {
  1708. return;
  1709. }
  1710. _cascadeOpacityEnabled = cascadeOpacityEnabled;
  1711. if (cascadeOpacityEnabled)
  1712. {
  1713. updateCascadeOpacity();
  1714. }
  1715. else
  1716. {
  1717. disableCascadeOpacity();
  1718. }
  1719. }
  1720. void Node::updateCascadeOpacity()
  1721. {
  1722. GLubyte parentOpacity = 255;
  1723. if (_parent != nullptr && _parent->isCascadeOpacityEnabled())
  1724. {
  1725. parentOpacity = _parent->getDisplayedOpacity();
  1726. }
  1727. updateDisplayedOpacity(parentOpacity);
  1728. }
  1729. void Node::disableCascadeOpacity()
  1730. {
  1731. _displayedOpacity = _realOpacity;
  1732. for(const auto& child : _children)
  1733. {
  1734. child->updateDisplayedOpacity(255);
  1735. }
  1736. }
  1737. void Node::setOpacityModifyRGB(bool /*value*/)
  1738. {}
  1739. bool Node::isOpacityModifyRGB() const
  1740. {
  1741. return false;
  1742. }
  1743. const Color3B& Node::getColor(void) const
  1744. {
  1745. return _realColor;
  1746. }
  1747. const Color3B& Node::getDisplayedColor() const
  1748. {
  1749. return _displayedColor;
  1750. }
  1751. void Node::setColor(const Color3B& color)
  1752. {
  1753. _displayedColor = _realColor = color;
  1754. updateCascadeColor();
  1755. }
  1756. void Node::updateDisplayedColor(const Color3B& parentColor)
  1757. {
  1758. _displayedColor.r = _realColor.r * parentColor.r/255.0;
  1759. _displayedColor.g = _realColor.g * parentColor.g/255.0;
  1760. _displayedColor.b = _realColor.b * parentColor.b/255.0;
  1761. updateColor();
  1762. if (_cascadeColorEnabled)
  1763. {
  1764. for(const auto &child : _children)
  1765. {
  1766. child->updateDisplayedColor(_displayedColor);
  1767. }
  1768. }
  1769. }
  1770. bool Node::isCascadeColorEnabled(void) const
  1771. {
  1772. return _cascadeColorEnabled;
  1773. }
  1774. void Node::setCascadeColorEnabled(bool cascadeColorEnabled)
  1775. {
  1776. if (_cascadeColorEnabled == cascadeColorEnabled)
  1777. {
  1778. return;
  1779. }
  1780. _cascadeColorEnabled = cascadeColorEnabled;
  1781. if (_cascadeColorEnabled)
  1782. {
  1783. updateCascadeColor();
  1784. }
  1785. else
  1786. {
  1787. disableCascadeColor();
  1788. }
  1789. }
  1790. void Node::updateCascadeColor()
  1791. {
  1792. Color3B parentColor = Color3B::WHITE;
  1793. if (_parent && _parent->isCascadeColorEnabled())
  1794. {
  1795. parentColor = _parent->getDisplayedColor();
  1796. }
  1797. updateDisplayedColor(parentColor);
  1798. }
  1799. void Node::disableCascadeColor()
  1800. {
  1801. for(const auto& child : _children)
  1802. {
  1803. child->updateDisplayedColor(Color3B::WHITE);
  1804. }
  1805. }
  1806. bool isScreenPointInRect(const Vec2 &pt, const Camera* camera, const Mat4& w2l, const Rect& rect, Vec3 *p)
  1807. {
  1808. if (nullptr == camera || rect.size.width <= 0 || rect.size.height <= 0)
  1809. {
  1810. return false;
  1811. }
  1812. // first, convert pt to near/far plane, get Pn and Pf
  1813. Vec3 Pn(pt.x, pt.y, -1), Pf(pt.x, pt.y, 1);
  1814. Pn = camera->unprojectGL(Pn);
  1815. Pf = camera->unprojectGL(Pf);
  1816. // then convert Pn and Pf to node space
  1817. w2l.transformPoint(&Pn);
  1818. w2l.transformPoint(&Pf);
  1819. // Pn and Pf define a line Q(t) = D + t * E which D = Pn
  1820. auto E = Pf - Pn;
  1821. // second, get three points which define content plane
  1822. // these points define a plane P(u, w) = A + uB + wC
  1823. Vec3 A = Vec3(rect.origin.x, rect.origin.y, 0);
  1824. Vec3 B(rect.origin.x + rect.size.width, rect.origin.y, 0);
  1825. Vec3 C(rect.origin.x, rect.origin.y + rect.size.height, 0);
  1826. B = B - A;
  1827. C = C - A;
  1828. // the line Q(t) intercept with plane P(u, w)
  1829. // calculate the intercept point P = Q(t)
  1830. // (BxC).A - (BxC).D
  1831. // t = -----------------
  1832. // (BxC).E
  1833. Vec3 BxC;
  1834. Vec3::cross(B, C, &BxC);
  1835. auto BxCdotE = BxC.dot(E);
  1836. if (BxCdotE == 0) {
  1837. return false;
  1838. }
  1839. auto t = (BxC.dot(A) - BxC.dot(Pn)) / BxCdotE;
  1840. Vec3 P = Pn + t * E;
  1841. if (p) {
  1842. *p = P;
  1843. }
  1844. return rect.containsPoint(Vec2(P.x, P.y));
  1845. }
  1846. // MARK: Camera
  1847. void Node::setCameraMask(unsigned short mask, bool applyChildren)
  1848. {
  1849. _cameraMask = mask;
  1850. if (applyChildren)
  1851. {
  1852. for (const auto& child : _children)
  1853. {
  1854. child->setCameraMask(mask, applyChildren);
  1855. }
  1856. }
  1857. }
  1858. int Node::getAttachedNodeCount()
  1859. {
  1860. return __attachedNodeCount;
  1861. }
  1862. //
  1863. DelayDrawProtocol::~DelayDrawProtocol() {
  1864. }
  1865. void DelayDrawProtocol::enableDelayDraw(bool bEnabled) {
  1866. _bDelayDraw = bEnabled;
  1867. }
  1868. bool DelayDrawProtocol::delayDrawEnabled() {
  1869. return _bDelayDraw;
  1870. }
  1871. // MARK: Deprecated
  1872. __NodeRGBA::__NodeRGBA()
  1873. {
  1874. CCLOG("NodeRGBA deprecated.");
  1875. }
  1876. NS_CC_END