Node.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  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 "Component.h"
  25. #include "Context.h"
  26. #include "Log.h"
  27. #include "Scene.h"
  28. #include "StringUtils.h"
  29. #include "VectorBuffer.h"
  30. #include "XMLElement.h"
  31. #include "DebugNew.h"
  32. // Normalize rotation quaternion after this many incremental updates to prevent distortion
  33. static const int NORMALIZE_ROTATION_EVERY = 32;
  34. OBJECTTYPESTATIC(Node);
  35. Node::Node(Context* context) :
  36. Serializable(context),
  37. id_(0),
  38. parent_(0),
  39. scene_(0),
  40. position_(Vector3::ZERO),
  41. rotation_(Quaternion::IDENTITY),
  42. scale_(Vector3::UNITY),
  43. worldTransform_(Matrix4x3::IDENTITY),
  44. rotateCount_(0),
  45. dirty_(false)
  46. {
  47. }
  48. Node::~Node()
  49. {
  50. RemoveAllChildren();
  51. RemoveAllComponents();
  52. // Remove from the scene
  53. if (scene_)
  54. scene_->NodeRemoved(this);
  55. }
  56. void Node::RegisterObject(Context* context)
  57. {
  58. context->RegisterFactory<Node>();
  59. ATTRIBUTE(Node, VAR_STRING, "Name", name_, std::string());
  60. ATTRIBUTE(Node, VAR_VECTOR3, "Position", position_, Vector3::ZERO);
  61. ATTRIBUTE(Node, VAR_QUATERNION, "Rotation", rotation_, Quaternion::IDENTITY);
  62. ATTRIBUTE(Node, VAR_VECTOR3, "Scale", scale_, Vector3::UNITY);
  63. ATTRIBUTE_MODE(Node, VAR_VARIANTMAP, "Variables", vars_, VariantMap(), AM_SERIALIZATION);
  64. }
  65. void Node::OnEvent(Object* sender, bool broadcast, StringHash eventType, VariantMap& eventData)
  66. {
  67. // Make a weak pointer to self to check for destruction during event handling
  68. WeakPtr<Node> self(this);
  69. // If this is a targeted event, forward it to all components
  70. if (!broadcast)
  71. {
  72. for (unsigned i = components_.size() - 1; i < components_.size(); --i)
  73. {
  74. components_[i]->OnEvent(sender, broadcast, eventType, eventData);
  75. if (self.IsExpired())
  76. return;
  77. }
  78. }
  79. else
  80. Object::OnEvent(sender, broadcast, eventType, eventData);
  81. }
  82. void Node::OnSetAttribute(const AttributeInfo& attr, const Variant& value)
  83. {
  84. switch (attr.offset_)
  85. {
  86. case offsetof(Node, name_):
  87. SetName(value.GetString());
  88. break;
  89. case offsetof(Node, position_):
  90. case offsetof(Node, rotation_):
  91. case offsetof(Node, scale_):
  92. Serializable::OnSetAttribute(attr, value);
  93. // If transform changes, dirty the node as applicable
  94. if (!dirty_)
  95. MarkDirty();
  96. break;
  97. default:
  98. Serializable::OnSetAttribute(attr, value);
  99. break;
  100. }
  101. }
  102. bool Node::Load(Deserializer& source)
  103. {
  104. // Remove all children and components first in case this is not a fresh load
  105. RemoveAllChildren();
  106. RemoveAllComponents();
  107. // ID has been read at the parent level
  108. if (!Serializable::Load(source))
  109. return false;
  110. unsigned numComponents = source.ReadVLE();
  111. for (unsigned i = 0; i < numComponents; ++i)
  112. {
  113. VectorBuffer compBuffer(source, source.ReadVLE());
  114. ShortStringHash newType = compBuffer.ReadShortStringHash();
  115. Component* newComponent = CreateComponent(newType, compBuffer.ReadUInt());
  116. if (newComponent)
  117. {
  118. if (!newComponent->Load(compBuffer))
  119. return false;
  120. }
  121. }
  122. unsigned numChildren = source.ReadVLE();
  123. for (unsigned i = 0; i < numChildren; ++i)
  124. {
  125. Node* newNode = CreateChild(source.ReadUInt());
  126. if (!newNode->Load(source))
  127. return false;
  128. }
  129. return true;
  130. }
  131. bool Node::Save(Serializer& dest)
  132. {
  133. if (!Serializable::Save(dest))
  134. return false;
  135. dest.WriteVLE(components_.size());
  136. for (unsigned i = 0; i < components_.size(); ++i)
  137. {
  138. Component* component = components_[i];
  139. // Create a separate buffer to be able to skip unknown components during deserialization
  140. VectorBuffer compBuffer;
  141. compBuffer.WriteShortStringHash(component->GetType());
  142. compBuffer.WriteUInt(component->GetID());
  143. if (!component->Save(compBuffer))
  144. return false;
  145. dest.WriteVLE(compBuffer.GetSize());
  146. dest.Write(compBuffer.GetData(), compBuffer.GetSize());
  147. }
  148. dest.WriteVLE(children_.size());
  149. for (unsigned i = 0; i < children_.size(); ++i)
  150. {
  151. Node* node = children_[i];
  152. dest.WriteUInt(node->GetID());
  153. if (!node->Save(dest))
  154. return false;
  155. }
  156. return true;
  157. }
  158. bool Node::LoadXML(const XMLElement& source)
  159. {
  160. // Remove all children and components first in case this is not a fresh load
  161. RemoveAllChildren();
  162. RemoveAllComponents();
  163. if (!Serializable::LoadXML(source))
  164. return false;
  165. XMLElement compElem = source.GetChildElement("component");
  166. while (compElem)
  167. {
  168. std::string typeName = compElem.GetString("type");
  169. Component* newComponent = CreateComponent(ShortStringHash(compElem.GetString("type")), compElem.GetInt("id"));
  170. if (newComponent)
  171. {
  172. if (!newComponent->LoadXML(compElem))
  173. return false;
  174. }
  175. compElem = compElem.GetNextElement("component");
  176. }
  177. XMLElement childElem = source.GetChildElement("node");
  178. while (childElem)
  179. {
  180. Node* newNode = CreateChild(compElem.GetInt("id"));
  181. if (!newNode->LoadXML(childElem))
  182. return false;
  183. childElem = childElem.GetNextElement("node");
  184. }
  185. return true;
  186. }
  187. bool Node::SaveXML(XMLElement& dest)
  188. {
  189. if (!Serializable::SaveXML(dest))
  190. return false;
  191. for (unsigned i = 0; i < components_.size(); ++i)
  192. {
  193. Component* component = components_[i];
  194. XMLElement compElem = dest.CreateChildElement("component");
  195. compElem.SetString("type", component->GetTypeNameStr());
  196. compElem.SetInt("id", component->GetID());
  197. if (!component->SaveXML(compElem))
  198. return false;
  199. }
  200. for (unsigned i = 0; i < children_.size(); ++i)
  201. {
  202. Node* node = children_[i];
  203. XMLElement childElem = dest.CreateChildElement("node");
  204. childElem.SetInt("id", node->GetID());
  205. if (!node->SaveXML(childElem))
  206. return false;
  207. }
  208. return true;
  209. }
  210. void Node::PostLoad()
  211. {
  212. for (unsigned i = 0; i < components_.size(); ++i)
  213. components_[i]->PostLoad();
  214. for (unsigned i = 0; i < children_.size(); ++i)
  215. children_[i]->PostLoad();
  216. }
  217. void Node::SetName(const std::string& name)
  218. {
  219. name_ = name;
  220. nameHash_ = StringHash(name);
  221. }
  222. void Node::SetPosition(const Vector3& position)
  223. {
  224. position_ = position;
  225. if (!dirty_)
  226. MarkDirty();
  227. }
  228. void Node::SetRotation(const Quaternion& rotation)
  229. {
  230. rotation_ = rotation;
  231. rotateCount_ = 0;
  232. if (!dirty_)
  233. MarkDirty();
  234. }
  235. void Node::SetDirection(const Vector3& direction)
  236. {
  237. SetRotation(Quaternion(Vector3::FORWARD, direction));
  238. }
  239. void Node::SetScale(float scale)
  240. {
  241. scale_ = Vector3(scale, scale, scale);
  242. if (!dirty_)
  243. MarkDirty();
  244. }
  245. void Node::SetScale(const Vector3& scale)
  246. {
  247. scale_ = scale;
  248. if (!dirty_)
  249. MarkDirty();
  250. }
  251. void Node::SetTransform(const Vector3& position, const Quaternion& rotation)
  252. {
  253. position_ = position;
  254. rotation_ = rotation;
  255. rotateCount_ = 0;
  256. if (!dirty_)
  257. MarkDirty();
  258. }
  259. void Node::SetTransform(const Vector3& position, const Quaternion& rotation, float scale)
  260. {
  261. position_ = position;
  262. rotation_ = rotation;
  263. scale_ = Vector3(scale, scale, scale);
  264. rotateCount_ = 0;
  265. if (!dirty_)
  266. MarkDirty();
  267. }
  268. void Node::SetTransform(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
  269. {
  270. position_ = position;
  271. rotation_ = rotation;
  272. scale_ = scale;
  273. rotateCount_ = 0;
  274. if (!dirty_)
  275. MarkDirty();
  276. }
  277. void Node::Translate(const Vector3& delta)
  278. {
  279. position_ += delta;
  280. if (!dirty_)
  281. MarkDirty();
  282. }
  283. void Node::TranslateRelative(const Vector3& delta)
  284. {
  285. position_ += rotation_ * delta;
  286. if (!dirty_)
  287. MarkDirty();
  288. }
  289. void Node::Rotate(const Quaternion& delta, bool fixedAxis)
  290. {
  291. if (!fixedAxis)
  292. rotation_ = rotation_ * delta;
  293. else
  294. rotation_ = delta * rotation_;
  295. ++rotateCount_;
  296. if (rotateCount_ >= NORMALIZE_ROTATION_EVERY)
  297. {
  298. rotation_.Normalize();
  299. rotateCount_ = 0;
  300. }
  301. if (!dirty_)
  302. MarkDirty();
  303. }
  304. void Node::Yaw(float angle, bool fixedAxis)
  305. {
  306. Rotate(Quaternion(angle, Vector3::UP), fixedAxis);
  307. }
  308. void Node::Pitch(float angle, bool fixedAxis)
  309. {
  310. Rotate(Quaternion(angle, Vector3::RIGHT), fixedAxis);
  311. }
  312. void Node::Roll(float angle, bool fixedAxis)
  313. {
  314. Rotate(Quaternion(angle, Vector3::FORWARD), fixedAxis);
  315. }
  316. void Node::Scale(float scale)
  317. {
  318. scale_ *= scale;
  319. if (!dirty_)
  320. MarkDirty();
  321. }
  322. void Node::Scale(const Vector3& scale)
  323. {
  324. scale_ *= scale;
  325. if (!dirty_)
  326. MarkDirty();
  327. }
  328. void Node::MarkDirty()
  329. {
  330. dirty_ = true;
  331. // Notify listener components first, then mark child nodes
  332. for (std::vector<WeakPtr<Component> >::iterator i = listeners_.begin(); i != listeners_.end();)
  333. {
  334. if (*i)
  335. {
  336. (*i)->OnMarkedDirty(this);
  337. ++i;
  338. }
  339. // If listener has expired, erase from list
  340. else
  341. i = listeners_.erase(i);
  342. }
  343. for (std::vector<SharedPtr<Node> >::iterator i = children_.begin(); i != children_.end(); ++i)
  344. (*i)->MarkDirty();
  345. }
  346. Node* Node::CreateChild(const std::string& name)
  347. {
  348. SharedPtr<Node> newNode(new Node(context_));
  349. newNode->SetName(name);
  350. AddChild(newNode);
  351. return newNode;
  352. }
  353. void Node::AddChild(Node* node)
  354. {
  355. // Check for illegal parent assignments, including attempt to reparent the scene
  356. if ((!node) || (node == this) || (node->parent_ == this) || (parent_ == node) || (scene_ == node))
  357. return;
  358. // Add first, then remove from old parent, to ensure the node does not get deleted
  359. children_.push_back(SharedPtr<Node>(node));
  360. if (node->parent_)
  361. node->parent_->RemoveChild(node);
  362. // Add to the scene if not added yet
  363. if ((scene_) && (!node->GetScene()))
  364. scene_->NodeAdded(node);
  365. node->parent_ = this;
  366. node->MarkDirty();
  367. }
  368. void Node::RemoveChild(Node* node)
  369. {
  370. if (!node)
  371. return;
  372. for (std::vector<SharedPtr<Node> >::iterator i = children_.begin(); i != children_.end(); ++i)
  373. {
  374. if (i->GetPtr() == node)
  375. {
  376. RemoveChild(i);
  377. return;
  378. }
  379. }
  380. }
  381. void Node::RemoveAllChildren()
  382. {
  383. while (children_.size())
  384. RemoveChild(children_.end() - 1);
  385. }
  386. void Node::SetParent(Node* parent)
  387. {
  388. if (parent)
  389. parent->AddChild(this);
  390. }
  391. Component* Node::CreateComponent(ShortStringHash type)
  392. {
  393. return CreateComponent(type, 0);
  394. }
  395. Component* Node::GetOrCreateComponent(ShortStringHash type)
  396. {
  397. Component* oldComponent = GetComponent(type);
  398. if (oldComponent)
  399. return oldComponent;
  400. else
  401. return CreateComponent(type, 0);
  402. }
  403. void Node::RemoveComponent(Component* component)
  404. {
  405. for (std::vector<SharedPtr<Component> >::iterator i = components_.begin(); i != components_.end(); ++i)
  406. {
  407. if (*i == component)
  408. {
  409. WeakPtr<Component> componentWeak(*i);
  410. RemoveListener(*i);
  411. if (scene_)
  412. scene_->ComponentRemoved(*i);
  413. components_.erase(i);
  414. // If the component is still referenced elsewhere, reset its node pointer now
  415. if (componentWeak)
  416. componentWeak->SetNode(0);
  417. return;
  418. }
  419. }
  420. }
  421. void Node::RemoveAllComponents()
  422. {
  423. while (components_.size())
  424. {
  425. std::vector<SharedPtr<Component> >::iterator i = components_.end() - 1;
  426. WeakPtr<Component> componentWeak(*i);
  427. RemoveListener(*i);
  428. if (scene_)
  429. scene_->ComponentRemoved(*i);
  430. components_.erase(i);
  431. // If the component is still referenced elsewhere, reset its node pointer now
  432. if (componentWeak)
  433. componentWeak->SetNode(0);
  434. }
  435. }
  436. void Node::AddListener(Component* component)
  437. {
  438. if (!component)
  439. return;
  440. // Check for not adding twice
  441. for (std::vector<WeakPtr<Component> >::iterator i = listeners_.begin(); i != listeners_.end(); ++i)
  442. {
  443. if ((*i) == component)
  444. return;
  445. }
  446. listeners_.push_back(WeakPtr<Component>(component));
  447. // If the node is currently dirty, notify immediately
  448. if (dirty_)
  449. component->OnMarkedDirty(this);
  450. }
  451. void Node::RemoveListener(Component* component)
  452. {
  453. for (std::vector<WeakPtr<Component> >::iterator i = listeners_.begin(); i != listeners_.end(); ++i)
  454. {
  455. if ((*i) == component)
  456. {
  457. listeners_.erase(i);
  458. return;
  459. }
  460. }
  461. }
  462. void Node::Remove()
  463. {
  464. if (parent_)
  465. parent_->RemoveChild(this);
  466. }
  467. unsigned Node::GetNumChildren(bool recursive) const
  468. {
  469. if (!recursive)
  470. return children_.size();
  471. else
  472. {
  473. unsigned allChildren = children_.size();
  474. for (std::vector<SharedPtr<Node> >::const_iterator i = children_.begin(); i != children_.end(); ++i)
  475. allChildren += (*i)->GetNumChildren(true);
  476. return allChildren;
  477. }
  478. }
  479. void Node::GetChildren(std::vector<Node*>& dest, bool recursive) const
  480. {
  481. dest.clear();
  482. if (!recursive)
  483. {
  484. for (std::vector<SharedPtr<Node> >::const_iterator i = children_.begin(); i != children_.end(); ++i)
  485. dest.push_back(*i);
  486. }
  487. else
  488. GetChildrenRecursive(dest);
  489. }
  490. void Node::GetChildrenWithComponent(std::vector<Node*>& dest, ShortStringHash type, bool recursive) const
  491. {
  492. dest.clear();
  493. if (!recursive)
  494. {
  495. for (std::vector<SharedPtr<Node> >::const_iterator i = children_.begin(); i != children_.end(); ++i)
  496. {
  497. if ((*i)->HasComponent(type))
  498. dest.push_back(*i);
  499. }
  500. }
  501. else
  502. GetChildrenWithComponentRecursive(dest, type);
  503. }
  504. Node* Node::GetChild(unsigned index) const
  505. {
  506. return index < children_.size() ? children_[index].GetPtr() : 0;
  507. }
  508. Node* Node::GetChild(const std::string& name, bool recursive) const
  509. {
  510. return GetChild(StringHash(name), recursive);
  511. }
  512. Node* Node::GetChild(StringHash nameHash, bool recursive) const
  513. {
  514. for (std::vector<SharedPtr<Node> >::const_iterator i = children_.begin(); i != children_.end(); ++i)
  515. {
  516. if ((*i)->GetNameHash() == nameHash)
  517. return *i;
  518. if (recursive)
  519. {
  520. Node* node = (*i)->GetChild(nameHash, true);
  521. if (node)
  522. return node;
  523. }
  524. }
  525. return 0;
  526. }
  527. void Node::GetComponents(std::vector<Component*>& dest, ShortStringHash type) const
  528. {
  529. dest.clear();
  530. for (std::vector<SharedPtr<Component> >::const_iterator i = components_.begin(); i != components_.end(); ++i)
  531. {
  532. if ((*i)->GetType() == type)
  533. dest.push_back(*i);
  534. }
  535. }
  536. bool Node::HasComponent(ShortStringHash type) const
  537. {
  538. for (std::vector<SharedPtr<Component> >::const_iterator i = components_.begin(); i != components_.end(); ++i)
  539. {
  540. if ((*i)->GetType() == type)
  541. return true;
  542. }
  543. return false;
  544. }
  545. Component* Node::GetComponent(unsigned index) const
  546. {
  547. return index < components_.size() ? components_[index].GetPtr() : 0;
  548. }
  549. Component* Node::GetComponent(ShortStringHash type, unsigned index) const
  550. {
  551. unsigned cmpIndex = 0;
  552. for (std::vector<SharedPtr<Component> >::const_iterator i = components_.begin(); i != components_.end(); ++i)
  553. {
  554. if ((*i)->GetType() == type)
  555. {
  556. if (cmpIndex == index)
  557. return *i;
  558. ++cmpIndex;
  559. }
  560. }
  561. return 0;
  562. }
  563. Component* Node::CreateComponent(ShortStringHash type, unsigned id)
  564. {
  565. // Make sure the object in question is a component
  566. SharedPtr<Component> newComponent = DynamicCast<Component>(CreateObject(type));
  567. if (!newComponent)
  568. {
  569. LOGERROR("Could not create unknown component type " + ToString(type));
  570. return 0;
  571. }
  572. // If zero ID specified, the scene will auto-assign
  573. newComponent->SetID(id);
  574. components_.push_back(newComponent);
  575. if (scene_)
  576. scene_->ComponentAdded(newComponent);
  577. newComponent->SetNode(this);
  578. newComponent->OnMarkedDirty(this);
  579. return newComponent;
  580. }
  581. Node* Node::CreateChild(unsigned id)
  582. {
  583. SharedPtr<Node> newNode(new Node(context_));
  584. newNode->SetID(id);
  585. AddChild(newNode);
  586. return newNode;
  587. }
  588. void Node::UpdateWorldTransform()
  589. {
  590. // For now, assume that the Scene has identity transform so that we skip one matrix multiply. However in the future
  591. // we may want dynamic root nodes for large worlds
  592. if ((parent_) && (parent_ != scene_))
  593. {
  594. if (parent_->dirty_)
  595. parent_->UpdateWorldTransform();
  596. worldTransform_ = parent_->worldTransform_ * Matrix4x3(position_, rotation_, scale_);
  597. }
  598. else
  599. worldTransform_ = Matrix4x3(position_, rotation_, scale_);
  600. dirty_ = false;
  601. }
  602. void Node::RemoveChild(std::vector<SharedPtr<Node> >::iterator i)
  603. {
  604. (*i)->parent_ = 0;
  605. (*i)->MarkDirty();
  606. children_.erase(i);
  607. }
  608. void Node::GetChildrenRecursive(std::vector<Node*>& dest) const
  609. {
  610. for (std::vector<SharedPtr<Node> >::const_iterator i = children_.begin(); i != children_.end(); ++i)
  611. {
  612. Node* node = *i;
  613. dest.push_back(node);
  614. if (!node->children_.empty())
  615. node->GetChildrenRecursive(dest);
  616. }
  617. }
  618. void Node::GetChildrenWithComponentRecursive(std::vector<Node*>& dest, ShortStringHash type) const
  619. {
  620. for (std::vector<SharedPtr<Node> >::const_iterator i = children_.begin(); i != children_.end(); ++i)
  621. {
  622. Node* node = *i;
  623. if (node->HasComponent(type))
  624. dest.push_back(node);
  625. if (!node->children_.empty())
  626. node->GetChildrenRecursive(dest);
  627. }
  628. }
  629. void Node::SetID(unsigned id)
  630. {
  631. id_ = id;
  632. }
  633. void Node::setScene(Scene* scene)
  634. {
  635. scene_ = scene;
  636. }