Node.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  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);
  69. else
  70. removeChild(i, false);
  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 = ComponentRef();
  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::setNodeFlags(unsigned flags)
  403. {
  404. mNodeFlags = (mNodeFlags & NODE_PREDEFINEDFLAGS) | (flags & NODE_CUSTOMFLAGS);
  405. }
  406. void Node::addChild(Node* node)
  407. {
  408. if ((!node) || (node->mParent == this) || (mParent == node))
  409. return;
  410. // Add first, then remove from old parent, to ensure the node does not get deleted
  411. mChildren.push_back(SharedPtr<Node>(node));
  412. if (node->mParent)
  413. node->mParent->removeChild(node);
  414. node->mParent = this;
  415. node->markDirty();
  416. }
  417. void Node::removeChild(Node* node, bool setWorldTransform)
  418. {
  419. for (std::vector<SharedPtr<Node> >::iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  420. {
  421. if ((*i) == node)
  422. {
  423. removeChild(i, setWorldTransform);
  424. return;
  425. }
  426. }
  427. }
  428. void Node::removeAllChildren(bool setWorldPosition)
  429. {
  430. while (mChildren.size())
  431. removeChild(mChildren.end() - 1, setWorldPosition);
  432. }
  433. std::vector<Node*> Node::getChildren(unsigned nodeFlags, bool recursive) const
  434. {
  435. if (!recursive)
  436. {
  437. std::vector<Node*> children;
  438. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  439. {
  440. if ((*i)->mNodeFlags & nodeFlags)
  441. children.push_back(*i);
  442. }
  443. return children;
  444. }
  445. else
  446. {
  447. std::vector<Node*> allChildren;
  448. getChildrenRecursive(nodeFlags, allChildren);
  449. return allChildren;
  450. }
  451. }
  452. unsigned Node::getNumChildren(bool recursive) const
  453. {
  454. if (!recursive)
  455. return mChildren.size();
  456. else
  457. {
  458. unsigned allChildren = mChildren.size();
  459. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  460. allChildren += (*i)->getNumChildren(true);
  461. return allChildren;
  462. }
  463. }
  464. Node* Node::getChild(unsigned index) const
  465. {
  466. return index < mChildren.size() ? mChildren[index] : (Node*)0;
  467. }
  468. Node* Node::getChild(const std::string& name, bool recursive) const
  469. {
  470. return getChild(StringHash(name), recursive);
  471. }
  472. Node* Node::getChild(StringHash nameHash, bool recursive) const
  473. {
  474. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  475. {
  476. if ((*i)->getNameHash() == nameHash)
  477. return *i;
  478. if (recursive)
  479. {
  480. Node* node = (*i)->getChild(nameHash, true);
  481. if (node)
  482. return node;
  483. }
  484. }
  485. return 0;
  486. }
  487. void Node::markDirty()
  488. {
  489. mDirty = true;
  490. onMarkedDirty();
  491. for (std::vector<SharedPtr<Node> >::iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  492. (*i)->markDirty();
  493. }
  494. void Node::getNetTransform(Vector3& position, Quaternion& rotation, Vector3& scale, ComponentRef& parentRef, const NetUpdateInfo& info)
  495. {
  496. // Use the parent node only if it will be synced
  497. bool useParent = (!mParent) || (mParent->checkSync(info.mConnection));
  498. if (useParent)
  499. {
  500. position = mPosition;
  501. rotation = mRotation;
  502. scale = mScale;
  503. parentRef = ComponentRef(mParent);
  504. }
  505. else
  506. {
  507. position = getWorldPosition();
  508. rotation = getWorldRotation();
  509. scale = getWorldScale();
  510. parentRef = ComponentRef();
  511. }
  512. }
  513. void Node::updateWorldPosition()
  514. {
  515. if (mParent)
  516. {
  517. const Quaternion& parentRotation = mParent->getWorldRotation();
  518. const Vector3& parentScale = mParent->getWorldScale();
  519. mWorldPosition = mParent->getWorldPosition() + (parentRotation * (parentScale * mPosition));
  520. mWorldRotation = parentRotation * mRotation;
  521. mWorldScale = parentScale * mScale;
  522. }
  523. else
  524. {
  525. mWorldPosition = mPosition;
  526. mWorldRotation = mRotation;
  527. mWorldScale = mScale;
  528. }
  529. mDirty = false;
  530. mWorldTransformDirty = true;
  531. }
  532. void Node::removeChild(std::vector<SharedPtr<Node> >::iterator i, bool setWorldTransform)
  533. {
  534. Node* node = (*i);
  535. if (setWorldTransform)
  536. node->setTransform(node->getWorldPosition(), node->getWorldRotation(), node->getWorldScale());
  537. node->mParent = 0;
  538. node->markDirty();
  539. mChildren.erase(i);
  540. }
  541. void Node::getChildrenRecursive(unsigned nodeFlags, std::vector<Node*>& dest) const
  542. {
  543. for (std::vector<SharedPtr<Node> >::const_iterator i = mChildren.begin(); i != mChildren.end(); ++i)
  544. {
  545. if ((*i)->mNodeFlags & nodeFlags)
  546. dest.push_back(*i);
  547. (*i)->getChildrenRecursive(nodeFlags, dest);
  548. }
  549. }