Node.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "Node.h"
  25. #include "ReplicationUtils.h"
  26. #include "Scene.h"
  27. #include "StringUtils.h"
  28. #include "DebugNew.h"
  29. // Normalize rotation quaternion after this many incremental updates to prevent distortion
  30. static const unsigned NORMALIZE_ROTATION_EVERY = 32;
  31. Node::Node(const std::string& name) :
  32. Component(name),
  33. mParent(0),
  34. mInterpolationFlags(INTERP_NONE),
  35. mNodeFlags(NODE_NODE),
  36. mDirty(false),
  37. mWorldTransformDirty(false),
  38. mPosition(Vector3::sZero),
  39. mRotation(Quaternion::sIdentity),
  40. mScale(Vector3::sUnity),
  41. mWorldPosition(Vector3::sZero),
  42. mWorldRotation(Quaternion::sIdentity),
  43. mWorldScale(Vector3::sUnity),
  44. mWorldTransform(Matrix4x3::sIdentity),
  45. mRotateCount(0)
  46. {
  47. }
  48. Node::Node(unsigned flags, const std::string& name) :
  49. Component(name),
  50. mParent(0),
  51. mNodeFlags(flags),
  52. mDirty(true),
  53. mWorldTransformDirty(true),
  54. mPosition(Vector3::sZero),
  55. mRotation(Quaternion::sIdentity),
  56. mScale(Vector3::sUnity),
  57. mRotateCount(0),
  58. mInterpolationFlags(0)
  59. {
  60. }
  61. Node::~Node()
  62. {
  63. // Remove all children, and set world transform if they are refcounted elsewhere
  64. while (mChildren.size())
  65. {
  66. std::vector<SharedPtr<Node> >::iterator i = mChildren.end() - 1;
  67. if (i->getRefCount() > 1)
  68. removeChild(i, true, true);
  69. else
  70. removeChild(i, false, true);
  71. }
  72. }
  73. void Node::save(Serializer& dest)
  74. {
  75. // Write Component properties
  76. Component::save(dest);
  77. // Write transform (interpolation transform & flags for network proxies)
  78. if (!isProxy())
  79. {
  80. dest.writeVector3(mPosition);
  81. dest.writeQuaternion(mRotation);
  82. dest.writeVector3(mScale);
  83. }
  84. else
  85. {
  86. dest.writeVector3(mInterpolationPosition);
  87. dest.writeQuaternion(mInterpolationRotation);
  88. dest.writeVector3(mInterpolationScale);
  89. dest.writeUByte(mInterpolationFlags);
  90. }
  91. // Write parent node reference
  92. ComponentRef parentRef(mParent);
  93. parentRef.write(dest);
  94. }
  95. void Node::load(Deserializer& source, ResourceCache* cache)
  96. {
  97. // Read Component properties
  98. Component::load(source, cache);
  99. // Read transform (interpolation transform & flags for network proxies)
  100. if (!isProxy())
  101. {
  102. mPosition = source.readVector3();
  103. mRotation = source.readQuaternion();
  104. mScale = source.readVector3();
  105. }
  106. else
  107. {
  108. mInterpolationPosition = source.readVector3();
  109. mInterpolationRotation = source.readQuaternion();
  110. mInterpolationScale = source.readVector3();
  111. mInterpolationFlags = source.readUByte();
  112. }
  113. // Read parent node reference
  114. mParentRef.read(source);
  115. markDirty();
  116. }
  117. void Node::saveXML(XMLElement& dest)
  118. {
  119. // Write Component properties
  120. Component::saveXML(dest);
  121. // Write transform
  122. XMLElement transformElem = dest.createChildElement("transform");
  123. transformElem.setVector3("pos", mPosition);
  124. transformElem.setQuaternion("rot", mRotation);
  125. transformElem.setVector3("scale", mScale);
  126. // Write parent node reference
  127. ComponentRef parentRef(mParent, true);
  128. if (parentRef.mEntityID)
  129. {
  130. XMLElement parentElem = dest.createChildElement("parent");
  131. parentRef.writeXML(parentElem);
  132. }
  133. }
  134. void Node::loadXML(const XMLElement& source, ResourceCache* cache)
  135. {
  136. // Read Component properties
  137. Component::loadXML(source, cache);
  138. // Read transform
  139. XMLElement transformElem = source.getChildElement("transform");
  140. mPosition = transformElem.getVector3("pos");
  141. mRotation = transformElem.getQuaternion("rot");
  142. mScale = transformElem.getVector3("scale");
  143. // Read parent node reference
  144. if (source.hasChildElement("parent"))
  145. {
  146. XMLElement parentElem = source.getChildElement("parent");
  147. mParentRef.readXML(parentElem);
  148. }
  149. else
  150. mParentRef.mEntityID = 0;
  151. markDirty();
  152. }
  153. void Node::postLoad(ResourceCache* cache)
  154. {
  155. if (mParentRef.mDirty)
  156. {
  157. Node* parent = static_cast<Node*>(mEntity->getScene()->getComponent(mParentRef));
  158. if (parent)
  159. parent->addChild(this);
  160. mParentRef.mDirty = false;
  161. }
  162. }
  163. bool Node::writeNetUpdate(Serializer& dest, Serializer& destRevision, Deserializer& baseRevision, const NetUpdateInfo& info)
  164. {
  165. // Use possibly modified transform in case the parent component is not to be replicated
  166. Vector3 position;
  167. Quaternion rotation;
  168. Vector3 scale;
  169. ComponentRef parentRef;
  170. getNetTransform(position, rotation, scale, parentRef, info);
  171. // Build bitmask of changed properties
  172. unsigned char bits = 0;
  173. checkVector3(position, Vector3::sZero, baseRevision, bits, 1);
  174. checkQuaternion(rotation, Quaternion::sIdentity, baseRevision, bits, 2);
  175. checkVector3(scale, Vector3::sUnity, baseRevision, bits, 4);
  176. checkComponentRef(parentRef, ComponentRef(), baseRevision, bits, 8);
  177. // Update replication state fully, and network stream by delta
  178. dest.writeUByte(bits);
  179. writeVector3Delta(position, dest, destRevision, bits & 1);
  180. writePackedQuaternionDelta(rotation, dest, destRevision, bits & 2);
  181. writeVector3Delta(scale, dest, destRevision, bits & 4);
  182. writeComponentRefDelta(parentRef, dest, destRevision, bits & 8);
  183. return bits != 0;
  184. }
  185. void Node::readNetUpdate(Deserializer& source, ResourceCache* cache, const NetUpdateInfo& info)
  186. {
  187. unsigned char bits = source.readUByte();
  188. // Interpolate if just position/rotation/scale changes, snap if parent changes
  189. bool interpolate = (bits & 7) && (!(bits & 8));
  190. if (!interpolate)
  191. {
  192. if (bits & 1)
  193. setPosition(source.readVector3());
  194. if (bits & 2)
  195. setRotation(source.readPackedQuaternion());
  196. if (bits & 4)
  197. setScale(source.readVector3());
  198. }
  199. else
  200. {
  201. if (bits & 1)
  202. {
  203. mInterpolationPosition = source.readVector3();
  204. mInterpolationFlags |= INTERP_POS;
  205. }
  206. if (bits & 2)
  207. {
  208. mInterpolationRotation = source.readPackedQuaternion();
  209. mInterpolationFlags |= INTERP_ROT;
  210. }
  211. if (bits & 4)
  212. {
  213. mInterpolationScale = source.readVector3();
  214. mInterpolationFlags |= INTERP_SCALE;
  215. }
  216. }
  217. readComponentRefDelta(mParentRef, source, bits & 8);
  218. if (bits & 7)
  219. markDirty();
  220. }
  221. void Node::postNetUpdate(ResourceCache* cache)
  222. {
  223. // This is the same as in file deserialization: update parent if the ref is dirty
  224. postLoad(cache);
  225. }
  226. void Node::interpolate(bool snapToEnd)
  227. {
  228. if (!mInterpolationFlags)
  229. return;
  230. if (!snapToEnd)
  231. {
  232. Scene* scene = mEntity->getScene();
  233. float t = scene->getInterpolationLerpFactor();
  234. if (mInterpolationFlags & INTERP_POS)
  235. {
  236. // If position snaps, snap everything to the end
  237. float delta = (mPosition - mInterpolationPosition).getLengthSquared();
  238. if (delta > scene->getInterpolationSnapThresholdSquared())
  239. t = 1.0f;
  240. if (delta < M_EPSILON)
  241. {
  242. mPosition = mInterpolationPosition;
  243. mInterpolationFlags &= ~INTERP_POS;
  244. }
  245. else
  246. mPosition = mPosition.lerp(mInterpolationPosition, t);
  247. }
  248. if (mInterpolationFlags & INTERP_ROT)
  249. {
  250. float delta = (mRotation - mInterpolationRotation).getLengthSquared();
  251. if (delta < M_EPSILON)
  252. {
  253. mRotation = mInterpolationRotation;
  254. mInterpolationFlags &= ~INTERP_ROT;
  255. }
  256. else
  257. mRotation = mRotation.slerp(mInterpolationRotation, t);
  258. }
  259. if (mInterpolationFlags & INTERP_SCALE)
  260. {
  261. float delta = (mScale - mInterpolationScale).getLengthSquared();
  262. if (delta < M_EPSILON)
  263. {
  264. mScale = mInterpolationScale;
  265. mInterpolationFlags &= ~INTERP_SCALE;
  266. }
  267. else
  268. mScale = mScale.lerp(mInterpolationScale, t);
  269. }
  270. }
  271. else
  272. {
  273. if (mInterpolationFlags & INTERP_POS)
  274. mPosition = mInterpolationPosition;
  275. if (mInterpolationFlags & INTERP_ROT)
  276. mRotation = mInterpolationRotation;
  277. if (mInterpolationFlags & INTERP_SCALE)
  278. mScale = mInterpolationScale;
  279. mInterpolationFlags = INTERP_NONE;
  280. }
  281. markDirty();
  282. }
  283. void Node::getComponentRefs(std::vector<ComponentRef>& dest)
  284. {
  285. if (mParent)
  286. dest.push_back(ComponentRef(mParent));
  287. }
  288. void Node::setPosition(const Vector3& position)
  289. {
  290. mPosition = position;
  291. mInterpolationFlags &= ~INTERP_POS;
  292. if (!mDirty)
  293. markDirty();
  294. }
  295. void Node::setRotation(const Quaternion& rotation)
  296. {
  297. mRotation = rotation;
  298. mRotateCount = 0;
  299. mInterpolationFlags &= ~INTERP_ROT;
  300. if (!mDirty)
  301. markDirty();
  302. }
  303. void Node::setScale(float scale)
  304. {
  305. mScale = Vector3(scale, scale, scale);
  306. mInterpolationFlags &= ~INTERP_SCALE;
  307. if (!mDirty)
  308. markDirty();
  309. }
  310. void Node::setScale(const Vector3& scale)
  311. {
  312. mScale = scale;
  313. mInterpolationFlags &= ~INTERP_SCALE;
  314. if (!mDirty)
  315. markDirty();
  316. }
  317. void Node::setTransform(const Vector3& position, const Quaternion& rotation)
  318. {
  319. mPosition = position;
  320. mRotation = rotation;
  321. mRotateCount = 0;
  322. mInterpolationFlags &= ~(INTERP_POS | INTERP_ROT);
  323. if (!mDirty)
  324. markDirty();
  325. }
  326. void Node::setTransform(const Vector3& position, const Quaternion& rotation, float scale)
  327. {
  328. mPosition = position;
  329. mRotation = rotation;
  330. mScale = Vector3(scale, scale, scale);
  331. mRotateCount = 0;
  332. mInterpolationFlags &= ~(INTERP_POS | INTERP_ROT | INTERP_SCALE);
  333. if (!mDirty)
  334. markDirty();
  335. }
  336. void Node::setTransform(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
  337. {
  338. mPosition = position;
  339. mRotation = rotation;
  340. mScale = scale;
  341. mRotateCount = 0;
  342. mInterpolationFlags &= ~(INTERP_POS | INTERP_ROT | INTERP_SCALE);
  343. if (!mDirty)
  344. markDirty();
  345. }
  346. void Node::translate(const Vector3& delta)
  347. {
  348. mPosition += delta;
  349. mInterpolationFlags &= ~INTERP_POS;
  350. if (!mDirty)
  351. markDirty();
  352. }
  353. void Node::translateRelative(const Vector3& delta)
  354. {
  355. mPosition += mRotation * delta;
  356. mInterpolationFlags &= ~INTERP_POS;
  357. if (!mDirty)
  358. markDirty();
  359. }
  360. void Node::rotate(const Quaternion& delta, bool fixedAxis)
  361. {
  362. if (!fixedAxis)
  363. mRotation = mRotation * delta;
  364. else
  365. mRotation = delta * mRotation;
  366. mRotateCount++;
  367. if (mRotateCount >= NORMALIZE_ROTATION_EVERY)
  368. {
  369. mRotation.normalize();
  370. mRotateCount = 0;
  371. }
  372. mInterpolationFlags &= ~INTERP_ROT;
  373. if (!mDirty)
  374. markDirty();
  375. }
  376. void Node::yaw(float angle, bool fixedAxis)
  377. {
  378. rotate(Quaternion(angle, Vector3::sUp), fixedAxis);
  379. }
  380. void Node::pitch(float angle, bool fixedAxis)
  381. {
  382. rotate(Quaternion(angle, Vector3::sRight), fixedAxis);
  383. }
  384. void Node::roll(float angle, bool fixedAxis)
  385. {
  386. rotate(Quaternion(angle, Vector3::sForward), fixedAxis);
  387. }
  388. void Node::scale(float scale)
  389. {
  390. mScale *= scale;
  391. mInterpolationFlags &= ~INTERP_SCALE;
  392. if (!mDirty)
  393. markDirty();
  394. }
  395. void Node::scale(const Vector3& scale)
  396. {
  397. mScale *= scale;
  398. mInterpolationFlags &= ~INTERP_SCALE;
  399. if (!mDirty)
  400. markDirty();
  401. }
  402. void Node::addChild(Node* node)
  403. {
  404. if ((!node) || (node->mParent == this) || (mParent == node))
  405. return;
  406. if (node->mParent)
  407. node->mParent->removeChild(node);
  408. mChildren.push_back(SharedPtr<Node>(node));
  409. node->mParent = this;
  410. node->markDirty();
  411. node->onParentChanged();
  412. onChildAdded(node);
  413. }
  414. void Node::removeChild(Node* node, bool setWorldTransform)
  415. {
  416. for (std::vector<SharedPtr<Node> >::iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  417. {
  418. if ((*i) == node)
  419. {
  420. removeChild(i, setWorldTransform);
  421. return;
  422. }
  423. }
  424. }
  425. void Node::removeAllChildren(bool setWorldPosition)
  426. {
  427. while (mChildren.size())
  428. removeChild(mChildren.end() - 1, setWorldPosition);
  429. }
  430. std::vector<Node*> Node::getChildren(unsigned nodeFlags, bool recursive) const
  431. {
  432. if (!recursive)
  433. {
  434. std::vector<Node*> children;
  435. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  436. {
  437. if ((*i)->mNodeFlags & nodeFlags)
  438. children.push_back(*i);
  439. }
  440. return children;
  441. }
  442. else
  443. {
  444. std::vector<Node*> allChildren;
  445. getChildrenRecursive(nodeFlags, allChildren);
  446. return allChildren;
  447. }
  448. }
  449. unsigned Node::getNumChildren(bool recursive) const
  450. {
  451. if (!recursive)
  452. return mChildren.size();
  453. else
  454. {
  455. unsigned allChildren = mChildren.size();
  456. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  457. allChildren += (*i)->getNumChildren(true);
  458. return allChildren;
  459. }
  460. }
  461. Node* Node::getChild(unsigned index) const
  462. {
  463. if (index >= mChildren.size())
  464. return 0;
  465. return mChildren[index];
  466. }
  467. Node* Node::getChild(const std::string& name, bool recursive) const
  468. {
  469. return getChild(StringHash(name), recursive);
  470. }
  471. Node* Node::getChild(StringHash nameHash, bool recursive) const
  472. {
  473. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  474. {
  475. if ((*i)->getNameHash() == nameHash)
  476. return *i;
  477. if (recursive)
  478. {
  479. Node* node = (*i)->getChild(nameHash, true);
  480. if (node)
  481. return node;
  482. }
  483. }
  484. return 0;
  485. }
  486. void Node::markDirty()
  487. {
  488. mDirty = true;
  489. onMarkedDirty();
  490. for (std::vector<SharedPtr<Node> >::iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  491. (*i)->markDirty();
  492. }
  493. void Node::getNetTransform(Vector3& position, Quaternion& rotation, Vector3& scale, ComponentRef& parentRef, const NetUpdateInfo& info)
  494. {
  495. // Use the parent node only if it will be synced
  496. bool useParent = (!mParent) || (mParent->checkSync(info.mConnection));
  497. if (useParent)
  498. {
  499. position = mPosition;
  500. rotation = mRotation;
  501. scale = mScale;
  502. parentRef = ComponentRef(mParent);
  503. }
  504. else
  505. {
  506. position = getWorldPosition();
  507. rotation = getWorldRotation();
  508. scale = getWorldScale();
  509. parentRef = ComponentRef();
  510. }
  511. }
  512. void Node::updateWorldPosition()
  513. {
  514. if (mParent)
  515. {
  516. const Quaternion& parentRotation = mParent->getWorldRotation();
  517. const Vector3& parentScale = mParent->getWorldScale();
  518. mWorldPosition = mParent->getWorldPosition() + (parentRotation * (parentScale * mPosition));
  519. mWorldRotation = parentRotation * mRotation;
  520. mWorldScale = parentScale * mScale;
  521. }
  522. else
  523. {
  524. mWorldPosition = mPosition;
  525. mWorldRotation = mRotation;
  526. mWorldScale = mScale;
  527. }
  528. mDirty = false;
  529. mWorldTransformDirty = true;
  530. }
  531. void Node::removeChild(std::vector<SharedPtr<Node> >::iterator i, bool setWorldTransform, bool calledFromDestructor)
  532. {
  533. Node* node = (*i);
  534. if (setWorldTransform)
  535. node->setTransform(node->getWorldPosition(), node->getWorldRotation(), node->getWorldScale());
  536. node->mParent = 0;
  537. node->markDirty();
  538. node->onParentChanged();
  539. // Calling a virtual function will crash on destruction, so avoid it if necessary
  540. if (!calledFromDestructor)
  541. onChildRemoved(node);
  542. mChildren.erase(i);
  543. }
  544. void Node::getChildrenRecursive(unsigned nodeFlags, std::vector<Node*>& dest) const
  545. {
  546. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  547. {
  548. if ((*i)->mNodeFlags & nodeFlags)
  549. dest.push_back(*i);
  550. (*i)->getChildrenRecursive(nodeFlags, dest);
  551. }
  552. }