1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #include "../Precompiled.h"
24 
25 #include "../Core/Context.h"
26 #include "../Core/Profiler.h"
27 #include "../IO/Log.h"
28 #include "../IO/MemoryBuffer.h"
29 #include "../Resource/XMLFile.h"
30 #include "../Resource/JSONFile.h"
31 #include "../Scene/Component.h"
32 #include "../Scene/ObjectAnimation.h"
33 #include "../Scene/ReplicationState.h"
34 #include "../Scene/Scene.h"
35 #include "../Scene/SceneEvents.h"
36 #include "../Scene/SmoothedTransform.h"
37 #include "../Scene/UnknownComponent.h"
38 
39 #include "../DebugNew.h"
40 
41 #ifdef _MSC_VER
42 #pragma warning(disable:6293)
43 #endif
44 
45 namespace Urho3D
46 {
47 
Node(Context * context)48 Node::Node(Context* context) :
49     Animatable(context),
50     worldTransform_(Matrix3x4::IDENTITY),
51     dirty_(false),
52     enabled_(true),
53     enabledPrev_(true),
54     networkUpdate_(false),
55     parent_(0),
56     scene_(0),
57     id_(0),
58     position_(Vector3::ZERO),
59     rotation_(Quaternion::IDENTITY),
60     scale_(Vector3::ONE),
61     worldRotation_(Quaternion::IDENTITY)
62 {
63     impl_ = new NodeImpl();
64     impl_->owner_ = 0;
65 }
66 
~Node()67 Node::~Node()
68 {
69     RemoveAllChildren();
70     RemoveAllComponents();
71 
72     // Remove from the scene
73     if (scene_)
74         scene_->NodeRemoved(this);
75 }
76 
RegisterObject(Context * context)77 void Node::RegisterObject(Context* context)
78 {
79     context->RegisterFactory<Node>();
80 
81     URHO3D_ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
82     URHO3D_ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_DEFAULT);
83     URHO3D_ACCESSOR_ATTRIBUTE("Tags", GetTags, SetTags, StringVector, Variant::emptyStringVector, AM_DEFAULT);
84     URHO3D_ACCESSOR_ATTRIBUTE("Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_FILE);
85     URHO3D_ACCESSOR_ATTRIBUTE("Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_FILE);
86     URHO3D_ACCESSOR_ATTRIBUTE("Scale", GetScale, SetScale, Vector3, Vector3::ONE, AM_DEFAULT);
87     URHO3D_ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE); // Network replication of vars uses custom data
88     URHO3D_ACCESSOR_ATTRIBUTE("Network Position", GetNetPositionAttr, SetNetPositionAttr, Vector3, Vector3::ZERO,
89         AM_NET | AM_LATESTDATA | AM_NOEDIT);
90     URHO3D_ACCESSOR_ATTRIBUTE("Network Rotation", GetNetRotationAttr, SetNetRotationAttr, PODVector<unsigned char>, Variant::emptyBuffer,
91         AM_NET | AM_LATESTDATA | AM_NOEDIT);
92     URHO3D_ACCESSOR_ATTRIBUTE("Network Parent Node", GetNetParentAttr, SetNetParentAttr, PODVector<unsigned char>, Variant::emptyBuffer,
93         AM_NET | AM_NOEDIT);
94 }
95 
Load(Deserializer & source,bool setInstanceDefault)96 bool Node::Load(Deserializer& source, bool setInstanceDefault)
97 {
98     SceneResolver resolver;
99 
100     // Read own ID. Will not be applied, only stored for resolving possible references
101     unsigned nodeID = source.ReadUInt();
102     resolver.AddNode(nodeID, this);
103 
104     // Read attributes, components and child nodes
105     bool success = Load(source, resolver);
106     if (success)
107     {
108         resolver.Resolve();
109         ApplyAttributes();
110     }
111 
112     return success;
113 }
114 
Save(Serializer & dest) const115 bool Node::Save(Serializer& dest) const
116 {
117     // Write node ID
118     if (!dest.WriteUInt(id_))
119         return false;
120 
121     // Write attributes
122     if (!Animatable::Save(dest))
123         return false;
124 
125     // Write components
126     dest.WriteVLE(GetNumPersistentComponents());
127     for (unsigned i = 0; i < components_.Size(); ++i)
128     {
129         Component* component = components_[i];
130         if (component->IsTemporary())
131             continue;
132 
133         // Create a separate buffer to be able to skip failing components during deserialization
134         VectorBuffer compBuffer;
135         if (!component->Save(compBuffer))
136             return false;
137         dest.WriteVLE(compBuffer.GetSize());
138         dest.Write(compBuffer.GetData(), compBuffer.GetSize());
139     }
140 
141     // Write child nodes
142     dest.WriteVLE(GetNumPersistentChildren());
143     for (unsigned i = 0; i < children_.Size(); ++i)
144     {
145         Node* node = children_[i];
146         if (node->IsTemporary())
147             continue;
148 
149         if (!node->Save(dest))
150             return false;
151     }
152 
153     return true;
154 }
155 
LoadXML(const XMLElement & source,bool setInstanceDefault)156 bool Node::LoadXML(const XMLElement& source, bool setInstanceDefault)
157 {
158     SceneResolver resolver;
159 
160     // Read own ID. Will not be applied, only stored for resolving possible references
161     unsigned nodeID = source.GetUInt("id");
162     resolver.AddNode(nodeID, this);
163 
164     // Read attributes, components and child nodes
165     bool success = LoadXML(source, resolver);
166     if (success)
167     {
168         resolver.Resolve();
169         ApplyAttributes();
170     }
171 
172     return success;
173 }
174 
LoadJSON(const JSONValue & source,bool setInstanceDefault)175 bool Node::LoadJSON(const JSONValue& source, bool setInstanceDefault)
176 {
177     SceneResolver resolver;
178 
179     // Read own ID. Will not be applied, only stored for resolving possible references
180     unsigned nodeID = source.Get("id").GetUInt();
181     resolver.AddNode(nodeID, this);
182 
183     // Read attributes, components and child nodes
184     bool success = LoadJSON(source, resolver);
185     if (success)
186     {
187         resolver.Resolve();
188         ApplyAttributes();
189     }
190 
191     return success;
192 }
193 
SaveXML(XMLElement & dest) const194 bool Node::SaveXML(XMLElement& dest) const
195 {
196     // Write node ID
197     if (!dest.SetUInt("id", id_))
198         return false;
199 
200     // Write attributes
201     if (!Animatable::SaveXML(dest))
202         return false;
203 
204     // Write components
205     for (unsigned i = 0; i < components_.Size(); ++i)
206     {
207         Component* component = components_[i];
208         if (component->IsTemporary())
209             continue;
210 
211         XMLElement compElem = dest.CreateChild("component");
212         if (!component->SaveXML(compElem))
213             return false;
214     }
215 
216     // Write child nodes
217     for (unsigned i = 0; i < children_.Size(); ++i)
218     {
219         Node* node = children_[i];
220         if (node->IsTemporary())
221             continue;
222 
223         XMLElement childElem = dest.CreateChild("node");
224         if (!node->SaveXML(childElem))
225             return false;
226     }
227 
228     return true;
229 }
230 
SaveJSON(JSONValue & dest) const231 bool Node::SaveJSON(JSONValue& dest) const
232 {
233     // Write node ID
234     dest.Set("id", id_);
235 
236     // Write attributes
237     if (!Animatable::SaveJSON(dest))
238         return false;
239 
240     // Write components
241     JSONArray componentsArray;
242     componentsArray.Reserve(components_.Size());
243     for (unsigned i = 0; i < components_.Size(); ++i)
244     {
245         Component* component = components_[i];
246         if (component->IsTemporary())
247             continue;
248 
249         JSONValue compVal;
250         if (!component->SaveJSON(compVal))
251             return false;
252         componentsArray.Push(compVal);
253     }
254     dest.Set("components", componentsArray);
255 
256     // Write child nodes
257     JSONArray childrenArray;
258     childrenArray.Reserve(children_.Size());
259     for (unsigned i = 0; i < children_.Size(); ++i)
260     {
261         Node* node = children_[i];
262         if (node->IsTemporary())
263             continue;
264 
265         JSONValue childVal;
266         if (!node->SaveJSON(childVal))
267             return false;
268         childrenArray.Push(childVal);
269     }
270     dest.Set("children", childrenArray);
271 
272     return true;
273 }
274 
ApplyAttributes()275 void Node::ApplyAttributes()
276 {
277     for (unsigned i = 0; i < components_.Size(); ++i)
278         components_[i]->ApplyAttributes();
279 
280     for (unsigned i = 0; i < children_.Size(); ++i)
281         children_[i]->ApplyAttributes();
282 }
283 
MarkNetworkUpdate()284 void Node::MarkNetworkUpdate()
285 {
286     if (!networkUpdate_ && scene_ && id_ < FIRST_LOCAL_ID)
287     {
288         scene_->MarkNetworkUpdate(this);
289         networkUpdate_ = true;
290     }
291 }
292 
AddReplicationState(NodeReplicationState * state)293 void Node::AddReplicationState(NodeReplicationState* state)
294 {
295     if (!networkState_)
296         AllocateNetworkState();
297 
298     networkState_->replicationStates_.Push(state);
299 }
300 
SaveXML(Serializer & dest,const String & indentation) const301 bool Node::SaveXML(Serializer& dest, const String& indentation) const
302 {
303     SharedPtr<XMLFile> xml(new XMLFile(context_));
304     XMLElement rootElem = xml->CreateRoot("node");
305     if (!SaveXML(rootElem))
306         return false;
307 
308     return xml->Save(dest, indentation);
309 }
310 
SaveJSON(Serializer & dest,const String & indentation) const311 bool Node::SaveJSON(Serializer& dest, const String& indentation) const
312 {
313     SharedPtr<JSONFile> json(new JSONFile(context_));
314     JSONValue& rootElem = json->GetRoot();
315 
316     if (!SaveJSON(rootElem))
317         return false;
318 
319     return json->Save(dest, indentation);
320 }
321 
SetName(const String & name)322 void Node::SetName(const String& name)
323 {
324     if (name != impl_->name_)
325     {
326         impl_->name_ = name;
327         impl_->nameHash_ = name;
328 
329         MarkNetworkUpdate();
330 
331         // Send change event
332         if (scene_)
333         {
334             using namespace NodeNameChanged;
335 
336             VariantMap& eventData = GetEventDataMap();
337             eventData[P_SCENE] = scene_;
338             eventData[P_NODE] = this;
339 
340             scene_->SendEvent(E_NODENAMECHANGED, eventData);
341         }
342     }
343 }
344 
SetTags(const StringVector & tags)345 void Node::SetTags(const StringVector& tags)
346 {
347     RemoveAllTags();
348     AddTags(tags);
349     // MarkNetworkUpdate() already called in RemoveAllTags() / AddTags()
350 }
351 
AddTag(const String & tag)352 void Node::AddTag(const String& tag)
353 {
354     // Check if tag empty or already added
355     if (tag.Empty() || HasTag(tag))
356         return;
357 
358     // Add tag
359     impl_->tags_.Push(tag);
360 
361     // Cache
362     scene_->NodeTagAdded(this, tag);
363 
364     // Send event
365     using namespace NodeTagAdded;
366     VariantMap& eventData = GetEventDataMap();
367     eventData[P_SCENE] = scene_;
368     eventData[P_NODE] = this;
369     eventData[P_TAG] = tag;
370     scene_->SendEvent(E_NODETAGADDED, eventData);
371 
372     // Sync
373     MarkNetworkUpdate();
374 }
375 
AddTags(const String & tags,char separator)376 void Node::AddTags(const String& tags, char separator)
377 {
378     StringVector tagVector = tags.Split(separator);
379     AddTags(tagVector);
380 }
381 
AddTags(const StringVector & tags)382 void Node::AddTags(const StringVector& tags)
383 {
384     // This is OK, as MarkNetworkUpdate() early-outs when called multiple times
385     for (unsigned i = 0; i < tags.Size(); ++i)
386         AddTag(tags[i]);
387 }
388 
RemoveTag(const String & tag)389 bool Node::RemoveTag(const String& tag)
390 {
391     bool removed = impl_->tags_.Remove(tag);
392 
393     // Nothing to do
394     if (!removed)
395         return false;
396 
397     // Scene cache update
398     if (scene_)
399     {
400         scene_->NodeTagRemoved(this, tag);
401         // Send event
402         using namespace NodeTagRemoved;
403         VariantMap& eventData = GetEventDataMap();
404         eventData[P_SCENE] = scene_;
405         eventData[P_NODE] = this;
406         eventData[P_TAG] = tag;
407         scene_->SendEvent(E_NODETAGREMOVED, eventData);
408     }
409 
410     // Sync
411     MarkNetworkUpdate();
412     return true;
413 }
414 
RemoveAllTags()415 void Node::RemoveAllTags()
416 {
417     // Clear old scene cache
418     if (scene_)
419     {
420         for (unsigned i = 0; i < impl_->tags_.Size(); ++i)
421         {
422             scene_->NodeTagRemoved(this, impl_->tags_[i]);
423 
424             // Send event
425             using namespace NodeTagRemoved;
426             VariantMap& eventData = GetEventDataMap();
427             eventData[P_SCENE] = scene_;
428             eventData[P_NODE] = this;
429             eventData[P_TAG] = impl_->tags_[i];
430             scene_->SendEvent(E_NODETAGREMOVED, eventData);
431         }
432     }
433 
434     impl_->tags_.Clear();
435 
436     // Sync
437     MarkNetworkUpdate();
438 }
439 
SetPosition(const Vector3 & position)440 void Node::SetPosition(const Vector3& position)
441 {
442     position_ = position;
443     MarkDirty();
444 
445     MarkNetworkUpdate();
446 }
447 
SetRotation(const Quaternion & rotation)448 void Node::SetRotation(const Quaternion& rotation)
449 {
450     rotation_ = rotation;
451     MarkDirty();
452 
453     MarkNetworkUpdate();
454 }
455 
SetDirection(const Vector3 & direction)456 void Node::SetDirection(const Vector3& direction)
457 {
458     SetRotation(Quaternion(Vector3::FORWARD, direction));
459 }
460 
SetScale(float scale)461 void Node::SetScale(float scale)
462 {
463     SetScale(Vector3(scale, scale, scale));
464 }
465 
SetScale(const Vector3 & scale)466 void Node::SetScale(const Vector3& scale)
467 {
468     scale_ = scale;
469     // Prevent exact zero scale e.g. from momentary edits as this may cause division by zero
470     // when decomposing the world transform matrix
471     if (scale_.x_ == 0.0f)
472         scale_.x_ = M_EPSILON;
473     if (scale_.y_ == 0.0f)
474         scale_.y_ = M_EPSILON;
475     if (scale_.z_ == 0.0f)
476         scale_.z_ = M_EPSILON;
477 
478     MarkDirty();
479     MarkNetworkUpdate();
480 }
481 
SetTransform(const Vector3 & position,const Quaternion & rotation)482 void Node::SetTransform(const Vector3& position, const Quaternion& rotation)
483 {
484     position_ = position;
485     rotation_ = rotation;
486     MarkDirty();
487 
488     MarkNetworkUpdate();
489 }
490 
SetTransform(const Vector3 & position,const Quaternion & rotation,float scale)491 void Node::SetTransform(const Vector3& position, const Quaternion& rotation, float scale)
492 {
493     SetTransform(position, rotation, Vector3(scale, scale, scale));
494 }
495 
SetTransform(const Vector3 & position,const Quaternion & rotation,const Vector3 & scale)496 void Node::SetTransform(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
497 {
498     position_ = position;
499     rotation_ = rotation;
500     scale_ = scale;
501     MarkDirty();
502 
503     MarkNetworkUpdate();
504 }
505 
SetTransform(const Matrix3x4 & matrix)506 void Node::SetTransform(const Matrix3x4& matrix)
507 {
508     SetTransform(matrix.Translation(), matrix.Rotation(), matrix.Scale());
509 }
510 
SetWorldPosition(const Vector3 & position)511 void Node::SetWorldPosition(const Vector3& position)
512 {
513     SetPosition((parent_ == scene_ || !parent_) ? position : parent_->GetWorldTransform().Inverse() * position);
514 }
515 
SetWorldRotation(const Quaternion & rotation)516 void Node::SetWorldRotation(const Quaternion& rotation)
517 {
518     SetRotation((parent_ == scene_ || !parent_) ? rotation : parent_->GetWorldRotation().Inverse() * rotation);
519 }
520 
SetWorldDirection(const Vector3 & direction)521 void Node::SetWorldDirection(const Vector3& direction)
522 {
523     Vector3 localDirection = (parent_ == scene_ || !parent_) ? direction : parent_->GetWorldRotation().Inverse() * direction;
524     SetRotation(Quaternion(Vector3::FORWARD, localDirection));
525 }
526 
SetWorldScale(float scale)527 void Node::SetWorldScale(float scale)
528 {
529     SetWorldScale(Vector3(scale, scale, scale));
530 }
531 
SetWorldScale(const Vector3 & scale)532 void Node::SetWorldScale(const Vector3& scale)
533 {
534     SetScale((parent_ == scene_ || !parent_) ? scale : scale / parent_->GetWorldScale());
535 }
536 
SetWorldTransform(const Vector3 & position,const Quaternion & rotation)537 void Node::SetWorldTransform(const Vector3& position, const Quaternion& rotation)
538 {
539     SetWorldPosition(position);
540     SetWorldRotation(rotation);
541 }
542 
SetWorldTransform(const Vector3 & position,const Quaternion & rotation,float scale)543 void Node::SetWorldTransform(const Vector3& position, const Quaternion& rotation, float scale)
544 {
545     SetWorldPosition(position);
546     SetWorldRotation(rotation);
547     SetWorldScale(scale);
548 }
549 
SetWorldTransform(const Vector3 & position,const Quaternion & rotation,const Vector3 & scale)550 void Node::SetWorldTransform(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
551 {
552     SetWorldPosition(position);
553     SetWorldRotation(rotation);
554     SetWorldScale(scale);
555 }
556 
Translate(const Vector3 & delta,TransformSpace space)557 void Node::Translate(const Vector3& delta, TransformSpace space)
558 {
559     switch (space)
560     {
561     case TS_LOCAL:
562         // Note: local space translation disregards local scale for scale-independent movement speed
563         position_ += rotation_ * delta;
564         break;
565 
566     case TS_PARENT:
567         position_ += delta;
568         break;
569 
570     case TS_WORLD:
571         position_ += (parent_ == scene_ || !parent_) ? delta : parent_->GetWorldTransform().Inverse() * Vector4(delta, 0.0f);
572         break;
573     }
574 
575     MarkDirty();
576 
577     MarkNetworkUpdate();
578 }
579 
Rotate(const Quaternion & delta,TransformSpace space)580 void Node::Rotate(const Quaternion& delta, TransformSpace space)
581 {
582     switch (space)
583     {
584     case TS_LOCAL:
585         rotation_ = (rotation_ * delta).Normalized();
586         break;
587 
588     case TS_PARENT:
589         rotation_ = (delta * rotation_).Normalized();
590         break;
591 
592     case TS_WORLD:
593         if (parent_ == scene_ || !parent_)
594             rotation_ = (delta * rotation_).Normalized();
595         else
596         {
597             Quaternion worldRotation = GetWorldRotation();
598             rotation_ = rotation_ * worldRotation.Inverse() * delta * worldRotation;
599         }
600         break;
601     }
602 
603     MarkDirty();
604 
605     MarkNetworkUpdate();
606 }
607 
RotateAround(const Vector3 & point,const Quaternion & delta,TransformSpace space)608 void Node::RotateAround(const Vector3& point, const Quaternion& delta, TransformSpace space)
609 {
610     Vector3 parentSpacePoint;
611     Quaternion oldRotation = rotation_;
612 
613     switch (space)
614     {
615     case TS_LOCAL:
616         parentSpacePoint = GetTransform() * point;
617         rotation_ = (rotation_ * delta).Normalized();
618         break;
619 
620     case TS_PARENT:
621         parentSpacePoint = point;
622         rotation_ = (delta * rotation_).Normalized();
623         break;
624 
625     case TS_WORLD:
626         if (parent_ == scene_ || !parent_)
627         {
628             parentSpacePoint = point;
629             rotation_ = (delta * rotation_).Normalized();
630         }
631         else
632         {
633             parentSpacePoint = parent_->GetWorldTransform().Inverse() * point;
634             Quaternion worldRotation = GetWorldRotation();
635             rotation_ = rotation_ * worldRotation.Inverse() * delta * worldRotation;
636         }
637         break;
638     }
639 
640     Vector3 oldRelativePos = oldRotation.Inverse() * (position_ - parentSpacePoint);
641     position_ = rotation_ * oldRelativePos + parentSpacePoint;
642 
643     MarkDirty();
644 
645     MarkNetworkUpdate();
646 }
647 
Yaw(float angle,TransformSpace space)648 void Node::Yaw(float angle, TransformSpace space)
649 {
650     Rotate(Quaternion(angle, Vector3::UP), space);
651 }
652 
Pitch(float angle,TransformSpace space)653 void Node::Pitch(float angle, TransformSpace space)
654 {
655     Rotate(Quaternion(angle, Vector3::RIGHT), space);
656 }
657 
Roll(float angle,TransformSpace space)658 void Node::Roll(float angle, TransformSpace space)
659 {
660     Rotate(Quaternion(angle, Vector3::FORWARD), space);
661 }
662 
LookAt(const Vector3 & target,const Vector3 & up,TransformSpace space)663 bool Node::LookAt(const Vector3& target, const Vector3& up, TransformSpace space)
664 {
665     Vector3 worldSpaceTarget;
666 
667     switch (space)
668     {
669     case TS_LOCAL:
670         worldSpaceTarget = GetWorldTransform() * target;
671         break;
672 
673     case TS_PARENT:
674         worldSpaceTarget = (parent_ == scene_ || !parent_) ? target : parent_->GetWorldTransform() * target;
675         break;
676 
677     case TS_WORLD:
678         worldSpaceTarget = target;
679         break;
680     }
681 
682     Vector3 lookDir = worldSpaceTarget - GetWorldPosition();
683     // Check if target is very close, in that case can not reliably calculate lookat direction
684     if (lookDir.Equals(Vector3::ZERO))
685         return false;
686     Quaternion newRotation;
687     // Do nothing if setting look rotation failed
688     if (!newRotation.FromLookRotation(lookDir, up))
689         return false;
690 
691     SetWorldRotation(newRotation);
692     return true;
693 }
694 
Scale(float scale)695 void Node::Scale(float scale)
696 {
697     Scale(Vector3(scale, scale, scale));
698 }
699 
Scale(const Vector3 & scale)700 void Node::Scale(const Vector3& scale)
701 {
702     scale_ *= scale;
703     MarkDirty();
704 
705     MarkNetworkUpdate();
706 }
707 
SetEnabled(bool enable)708 void Node::SetEnabled(bool enable)
709 {
710     SetEnabled(enable, false, true);
711 }
712 
SetDeepEnabled(bool enable)713 void Node::SetDeepEnabled(bool enable)
714 {
715     SetEnabled(enable, true, false);
716 }
717 
ResetDeepEnabled()718 void Node::ResetDeepEnabled()
719 {
720     SetEnabled(enabledPrev_, false, false);
721 
722     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
723         (*i)->ResetDeepEnabled();
724 }
725 
SetEnabledRecursive(bool enable)726 void Node::SetEnabledRecursive(bool enable)
727 {
728     SetEnabled(enable, true, true);
729 }
730 
SetOwner(Connection * owner)731 void Node::SetOwner(Connection* owner)
732 {
733     impl_->owner_ = owner;
734 }
735 
MarkDirty()736 void Node::MarkDirty()
737 {
738     Node *cur = this;
739     for (;;)
740     {
741         // Precondition:
742         // a) whenever a node is marked dirty, all its children are marked dirty as well.
743         // b) whenever a node is cleared from being dirty, all its parents must have been
744         //    cleared as well.
745         // Therefore if we are recursing here to mark this node dirty, and it already was,
746         // then all children of this node must also be already dirty, and we don't need to
747         // reflag them again.
748         if (cur->dirty_)
749             return;
750         cur->dirty_ = true;
751 
752         // Notify listener components first, then mark child nodes
753         for (Vector<WeakPtr<Component> >::Iterator i = cur->listeners_.Begin(); i != cur->listeners_.End();)
754         {
755             Component *c = *i;
756             if (c)
757             {
758                 c->OnMarkedDirty(cur);
759                 ++i;
760             }
761             // If listener has expired, erase from list (swap with the last element to avoid O(n^2) behavior)
762             else
763             {
764                 *i = cur->listeners_.Back();
765                 cur->listeners_.Pop();
766             }
767         }
768 
769         // Tail call optimization: Don't recurse to mark the first child dirty, but
770         // instead process it in the context of the current function. If there are more
771         // than one child, then recurse to the excess children.
772         Vector<SharedPtr<Node> >::Iterator i = cur->children_.Begin();
773         if (i != cur->children_.End())
774         {
775             Node *next = *i;
776             for (++i; i != cur->children_.End(); ++i)
777                 (*i)->MarkDirty();
778             cur = next;
779         }
780         else
781             return;
782     }
783 }
784 
CreateChild(const String & name,CreateMode mode,unsigned id,bool temporary)785 Node* Node::CreateChild(const String& name, CreateMode mode, unsigned id, bool temporary)
786 {
787     Node* newNode = CreateChild(id, mode, temporary);
788     newNode->SetName(name);
789     return newNode;
790 }
791 
CreateTemporaryChild(const String & name,CreateMode mode,unsigned id)792 Node* Node::CreateTemporaryChild(const String& name, CreateMode mode, unsigned id)
793 {
794     return CreateChild(name, mode, id, true);
795 }
796 
AddChild(Node * node,unsigned index)797 void Node::AddChild(Node* node, unsigned index)
798 {
799     // Check for illegal or redundant parent assignment
800     if (!node || node == this || node->parent_ == this)
801         return;
802     // Check for possible cyclic parent assignment
803     if (IsChildOf(node))
804         return;
805 
806     // Keep a shared ptr to the node while transferring
807     SharedPtr<Node> nodeShared(node);
808     Node* oldParent = node->parent_;
809     if (oldParent)
810     {
811         // If old parent is in different scene, perform the full removal
812         if (oldParent->GetScene() != scene_)
813             oldParent->RemoveChild(node);
814         else
815         {
816             if (scene_)
817             {
818                 // Otherwise do not remove from the scene during reparenting, just send the necessary change event
819                 using namespace NodeRemoved;
820 
821                 VariantMap& eventData = GetEventDataMap();
822                 eventData[P_SCENE] = scene_;
823                 eventData[P_PARENT] = oldParent;
824                 eventData[P_NODE] = node;
825 
826                 scene_->SendEvent(E_NODEREMOVED, eventData);
827             }
828 
829             oldParent->children_.Remove(nodeShared);
830         }
831     }
832 
833     // Add to the child vector, then add to the scene if not added yet
834     children_.Insert(index, nodeShared);
835     if (scene_ && node->GetScene() != scene_)
836         scene_->NodeAdded(node);
837 
838     node->parent_ = this;
839     node->MarkDirty();
840     node->MarkNetworkUpdate();
841     // If the child node has components, also mark network update on them to ensure they have a valid NetworkState
842     for (Vector<SharedPtr<Component> >::Iterator i = node->components_.Begin(); i != node->components_.End(); ++i)
843         (*i)->MarkNetworkUpdate();
844 
845     // Send change event
846     if (scene_)
847     {
848         using namespace NodeAdded;
849 
850         VariantMap& eventData = GetEventDataMap();
851         eventData[P_SCENE] = scene_;
852         eventData[P_PARENT] = this;
853         eventData[P_NODE] = node;
854 
855         scene_->SendEvent(E_NODEADDED, eventData);
856     }
857 }
858 
RemoveChild(Node * node)859 void Node::RemoveChild(Node* node)
860 {
861     if (!node)
862         return;
863 
864     for (Vector<SharedPtr<Node> >::Iterator i = children_.Begin(); i != children_.End(); ++i)
865     {
866         if (*i == node)
867         {
868             RemoveChild(i);
869             return;
870         }
871     }
872 }
873 
RemoveAllChildren()874 void Node::RemoveAllChildren()
875 {
876     RemoveChildren(true, true, true);
877 }
878 
RemoveChildren(bool removeReplicated,bool removeLocal,bool recursive)879 void Node::RemoveChildren(bool removeReplicated, bool removeLocal, bool recursive)
880 {
881     unsigned numRemoved = 0;
882 
883     for (unsigned i = children_.Size() - 1; i < children_.Size(); --i)
884     {
885         bool remove = false;
886         Node* childNode = children_[i];
887 
888         if (recursive)
889             childNode->RemoveChildren(removeReplicated, removeLocal, true);
890         if (childNode->GetID() < FIRST_LOCAL_ID && removeReplicated)
891             remove = true;
892         else if (childNode->GetID() >= FIRST_LOCAL_ID && removeLocal)
893             remove = true;
894 
895         if (remove)
896         {
897             RemoveChild(children_.Begin() + i);
898             ++numRemoved;
899         }
900     }
901 
902     // Mark node dirty in all replication states
903     if (numRemoved)
904         MarkReplicationDirty();
905 }
906 
CreateComponent(StringHash type,CreateMode mode,unsigned id)907 Component* Node::CreateComponent(StringHash type, CreateMode mode, unsigned id)
908 {
909     // Do not attempt to create replicated components to local nodes, as that may lead to component ID overwrite
910     // as replicated components are synced over
911     if (id_ >= FIRST_LOCAL_ID && mode == REPLICATED)
912         mode = LOCAL;
913 
914     // Check that creation succeeds and that the object in fact is a component
915     SharedPtr<Component> newComponent = DynamicCast<Component>(context_->CreateObject(type));
916     if (!newComponent)
917     {
918         URHO3D_LOGERROR("Could not create unknown component type " + type.ToString());
919         return 0;
920     }
921 
922     AddComponent(newComponent, id, mode);
923     return newComponent;
924 }
925 
GetOrCreateComponent(StringHash type,CreateMode mode,unsigned id)926 Component* Node::GetOrCreateComponent(StringHash type, CreateMode mode, unsigned id)
927 {
928     Component* oldComponent = GetComponent(type);
929     if (oldComponent)
930         return oldComponent;
931     else
932         return CreateComponent(type, mode, id);
933 }
934 
CloneComponent(Component * component,unsigned id)935 Component* Node::CloneComponent(Component* component, unsigned id)
936 {
937     if (!component)
938     {
939         URHO3D_LOGERROR("Null source component given for CloneComponent");
940         return 0;
941     }
942 
943     return CloneComponent(component, component->GetID() < FIRST_LOCAL_ID ? REPLICATED : LOCAL, id);
944 }
945 
CloneComponent(Component * component,CreateMode mode,unsigned id)946 Component* Node::CloneComponent(Component* component, CreateMode mode, unsigned id)
947 {
948     if (!component)
949     {
950         URHO3D_LOGERROR("Null source component given for CloneComponent");
951         return 0;
952     }
953 
954     Component* cloneComponent = SafeCreateComponent(component->GetTypeName(), component->GetType(), mode, 0);
955     if (!cloneComponent)
956     {
957         URHO3D_LOGERROR("Could not clone component " + component->GetTypeName());
958         return 0;
959     }
960 
961     const Vector<AttributeInfo>* compAttributes = component->GetAttributes();
962     const Vector<AttributeInfo>* cloneAttributes = cloneComponent->GetAttributes();
963 
964     if (compAttributes)
965     {
966         for (unsigned i = 0; i < compAttributes->Size() && i < cloneAttributes->Size(); ++i)
967         {
968             const AttributeInfo& attr = compAttributes->At(i);
969             const AttributeInfo& cloneAttr = cloneAttributes->At(i);
970             if (attr.mode_ & AM_FILE)
971             {
972                 Variant value;
973                 component->OnGetAttribute(attr, value);
974                 // Note: when eg. a ScriptInstance component is cloned, its script object attributes are unique and therefore we
975                 // can not simply refer to the source component's AttributeInfo
976                 cloneComponent->OnSetAttribute(cloneAttr, value);
977             }
978         }
979         cloneComponent->ApplyAttributes();
980     }
981 
982     {
983         using namespace ComponentCloned;
984 
985         VariantMap& eventData = GetEventDataMap();
986         eventData[P_SCENE] = scene_;
987         eventData[P_COMPONENT] = component;
988         eventData[P_CLONECOMPONENT] = cloneComponent;
989 
990         scene_->SendEvent(E_COMPONENTCLONED, eventData);
991     }
992 
993     return cloneComponent;
994 }
995 
RemoveComponent(Component * component)996 void Node::RemoveComponent(Component* component)
997 {
998     for (Vector<SharedPtr<Component> >::Iterator i = components_.Begin(); i != components_.End(); ++i)
999     {
1000         if (*i == component)
1001         {
1002             RemoveComponent(i);
1003 
1004             // Mark node dirty in all replication states
1005             MarkReplicationDirty();
1006             return;
1007         }
1008     }
1009 }
1010 
RemoveComponent(StringHash type)1011 void Node::RemoveComponent(StringHash type)
1012 {
1013     for (Vector<SharedPtr<Component> >::Iterator i = components_.Begin(); i != components_.End(); ++i)
1014     {
1015         if ((*i)->GetType() == type)
1016         {
1017             RemoveComponent(i);
1018 
1019             // Mark node dirty in all replication states
1020             MarkReplicationDirty();
1021             return;
1022         }
1023     }
1024 }
1025 
RemoveComponents(bool removeReplicated,bool removeLocal)1026 void Node::RemoveComponents(bool removeReplicated, bool removeLocal)
1027 {
1028     unsigned numRemoved = 0;
1029 
1030     for (unsigned i = components_.Size() - 1; i < components_.Size(); --i)
1031     {
1032         bool remove = false;
1033         Component* component = components_[i];
1034 
1035         if (component->GetID() < FIRST_LOCAL_ID && removeReplicated)
1036             remove = true;
1037         else if (component->GetID() >= FIRST_LOCAL_ID && removeLocal)
1038             remove = true;
1039 
1040         if (remove)
1041         {
1042             RemoveComponent(components_.Begin() + i);
1043             ++numRemoved;
1044         }
1045     }
1046 
1047     // Mark node dirty in all replication states
1048     if (numRemoved)
1049         MarkReplicationDirty();
1050 }
1051 
RemoveComponents(StringHash type)1052 void Node::RemoveComponents(StringHash type)
1053 {
1054     unsigned numRemoved = 0;
1055 
1056     for (unsigned i = components_.Size() - 1; i < components_.Size(); --i)
1057     {
1058         if (components_[i]->GetType() == type)
1059         {
1060             RemoveComponent(components_.Begin() + i);
1061             ++numRemoved;
1062         }
1063     }
1064 
1065     // Mark node dirty in all replication states
1066     if (numRemoved)
1067         MarkReplicationDirty();
1068 }
1069 
RemoveAllComponents()1070 void Node::RemoveAllComponents()
1071 {
1072     RemoveComponents(true, true);
1073 }
1074 
ReorderComponent(Component * component,unsigned index)1075 void Node::ReorderComponent(Component* component, unsigned index)
1076 {
1077     if (!component || component->GetNode() != this)
1078         return;
1079 
1080     for (Vector<SharedPtr<Component> >::Iterator i = components_.Begin(); i != components_.End(); ++i)
1081     {
1082         if (*i == component)
1083         {
1084             // Need shared ptr to insert. Also, prevent destruction when removing first
1085             SharedPtr<Component> componentShared(component);
1086             components_.Erase(i);
1087             components_.Insert(index, componentShared);
1088             return;
1089         }
1090     }
1091 }
1092 
Clone(CreateMode mode)1093 Node* Node::Clone(CreateMode mode)
1094 {
1095     // The scene itself can not be cloned
1096     if (this == scene_ || !parent_)
1097     {
1098         URHO3D_LOGERROR("Can not clone node without a parent");
1099         return 0;
1100     }
1101 
1102     URHO3D_PROFILE(CloneNode);
1103 
1104     SceneResolver resolver;
1105     Node* clone = CloneRecursive(parent_, resolver, mode);
1106     resolver.Resolve();
1107     clone->ApplyAttributes();
1108     return clone;
1109 }
1110 
Remove()1111 void Node::Remove()
1112 {
1113     if (parent_)
1114         parent_->RemoveChild(this);
1115 }
1116 
SetParent(Node * parent)1117 void Node::SetParent(Node* parent)
1118 {
1119     if (parent)
1120     {
1121         Matrix3x4 oldWorldTransform = GetWorldTransform();
1122 
1123         parent->AddChild(this);
1124 
1125         if (parent != scene_)
1126         {
1127             Matrix3x4 newTransform = parent->GetWorldTransform().Inverse() * oldWorldTransform;
1128             SetTransform(newTransform.Translation(), newTransform.Rotation(), newTransform.Scale());
1129         }
1130         else
1131         {
1132             // The root node is assumed to have identity transform, so can disregard it
1133             SetTransform(oldWorldTransform.Translation(), oldWorldTransform.Rotation(), oldWorldTransform.Scale());
1134         }
1135     }
1136 }
1137 
SetVar(StringHash key,const Variant & value)1138 void Node::SetVar(StringHash key, const Variant& value)
1139 {
1140     vars_[key] = value;
1141     MarkNetworkUpdate();
1142 }
1143 
AddListener(Component * component)1144 void Node::AddListener(Component* component)
1145 {
1146     if (!component)
1147         return;
1148 
1149     // Check for not adding twice
1150     for (Vector<WeakPtr<Component> >::Iterator i = listeners_.Begin(); i != listeners_.End(); ++i)
1151     {
1152         if (*i == component)
1153             return;
1154     }
1155 
1156     listeners_.Push(WeakPtr<Component>(component));
1157     // If the node is currently dirty, notify immediately
1158     if (dirty_)
1159         component->OnMarkedDirty(this);
1160 }
1161 
RemoveListener(Component * component)1162 void Node::RemoveListener(Component* component)
1163 {
1164     for (Vector<WeakPtr<Component> >::Iterator i = listeners_.Begin(); i != listeners_.End(); ++i)
1165     {
1166         if (*i == component)
1167         {
1168             listeners_.Erase(i);
1169             return;
1170         }
1171     }
1172 }
1173 
GetSignedWorldScale() const1174 Vector3 Node::GetSignedWorldScale() const
1175 {
1176     if (dirty_)
1177         UpdateWorldTransform();
1178 
1179     return worldTransform_.SignedScale(worldRotation_.RotationMatrix());
1180 }
1181 
LocalToWorld(const Vector3 & position) const1182 Vector3 Node::LocalToWorld(const Vector3& position) const
1183 {
1184     return GetWorldTransform() * position;
1185 }
1186 
LocalToWorld(const Vector4 & vector) const1187 Vector3 Node::LocalToWorld(const Vector4& vector) const
1188 {
1189     return GetWorldTransform() * vector;
1190 }
1191 
LocalToWorld2D(const Vector2 & vector) const1192 Vector2 Node::LocalToWorld2D(const Vector2& vector) const
1193 {
1194     Vector3 result = LocalToWorld(Vector3(vector));
1195     return Vector2(result.x_, result.y_);
1196 }
1197 
WorldToLocal(const Vector3 & position) const1198 Vector3 Node::WorldToLocal(const Vector3& position) const
1199 {
1200     return GetWorldTransform().Inverse() * position;
1201 }
1202 
WorldToLocal(const Vector4 & vector) const1203 Vector3 Node::WorldToLocal(const Vector4& vector) const
1204 {
1205     return GetWorldTransform().Inverse() * vector;
1206 }
1207 
WorldToLocal2D(const Vector2 & vector) const1208 Vector2 Node::WorldToLocal2D(const Vector2& vector) const
1209 {
1210     Vector3 result = WorldToLocal(Vector3(vector));
1211     return Vector2(result.x_, result.y_);
1212 }
1213 
GetNumChildren(bool recursive) const1214 unsigned Node::GetNumChildren(bool recursive) const
1215 {
1216     if (!recursive)
1217         return children_.Size();
1218     else
1219     {
1220         unsigned allChildren = children_.Size();
1221         for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1222             allChildren += (*i)->GetNumChildren(true);
1223 
1224         return allChildren;
1225     }
1226 }
1227 
GetChildren(PODVector<Node * > & dest,bool recursive) const1228 void Node::GetChildren(PODVector<Node*>& dest, bool recursive) const
1229 {
1230     dest.Clear();
1231 
1232     if (!recursive)
1233     {
1234         for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1235             dest.Push(*i);
1236     }
1237     else
1238         GetChildrenRecursive(dest);
1239 }
1240 
GetChildren(bool recursive) const1241 PODVector<Node*> Node::GetChildren(bool recursive) const
1242 {
1243     PODVector<Node*> dest;
1244     GetChildren(dest, recursive);
1245     return dest;
1246 }
1247 
GetChildrenWithComponent(PODVector<Node * > & dest,StringHash type,bool recursive) const1248 void Node::GetChildrenWithComponent(PODVector<Node*>& dest, StringHash type, bool recursive) const
1249 {
1250     dest.Clear();
1251 
1252     if (!recursive)
1253     {
1254         for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1255         {
1256             if ((*i)->HasComponent(type))
1257                 dest.Push(*i);
1258         }
1259     }
1260     else
1261         GetChildrenWithComponentRecursive(dest, type);
1262 }
1263 
GetChildrenWithComponent(StringHash type,bool recursive) const1264 PODVector<Node*> Node::GetChildrenWithComponent(StringHash type, bool recursive) const
1265 {
1266     PODVector<Node*> dest;
1267     GetChildrenWithComponent(dest, type, recursive);
1268     return dest;
1269 }
1270 
GetChildrenWithTag(PODVector<Node * > & dest,const String & tag,bool recursive) const1271 void Node::GetChildrenWithTag(PODVector<Node*>& dest, const String& tag, bool recursive /*= true*/) const
1272 {
1273     dest.Clear();
1274 
1275     if (!recursive)
1276     {
1277         for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1278         {
1279             if ((*i)->HasTag(tag))
1280                 dest.Push(*i);
1281         }
1282     }
1283     else
1284         GetChildrenWithTagRecursive(dest, tag);
1285 }
1286 
GetChildrenWithTag(const String & tag,bool recursive) const1287 PODVector<Node*> Node::GetChildrenWithTag(const String& tag, bool recursive) const
1288 {
1289     PODVector<Node*> dest;
1290     GetChildrenWithTag(dest, tag, recursive);
1291     return dest;
1292 }
1293 
GetChild(unsigned index) const1294 Node* Node::GetChild(unsigned index) const
1295 {
1296     return index < children_.Size() ? children_[index].Get() : 0;
1297 }
1298 
GetChild(const String & name,bool recursive) const1299 Node* Node::GetChild(const String& name, bool recursive) const
1300 {
1301     return GetChild(StringHash(name), recursive);
1302 }
1303 
GetChild(const char * name,bool recursive) const1304 Node* Node::GetChild(const char* name, bool recursive) const
1305 {
1306     return GetChild(StringHash(name), recursive);
1307 }
1308 
GetChild(StringHash nameHash,bool recursive) const1309 Node* Node::GetChild(StringHash nameHash, bool recursive) const
1310 {
1311     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1312     {
1313         if ((*i)->GetNameHash() == nameHash)
1314             return *i;
1315 
1316         if (recursive)
1317         {
1318             Node* node = (*i)->GetChild(nameHash, true);
1319             if (node)
1320                 return node;
1321         }
1322     }
1323 
1324     return 0;
1325 }
1326 
GetNumNetworkComponents() const1327 unsigned Node::GetNumNetworkComponents() const
1328 {
1329     unsigned num = 0;
1330     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
1331     {
1332         if ((*i)->GetID() < FIRST_LOCAL_ID)
1333             ++num;
1334     }
1335 
1336     return num;
1337 }
1338 
GetComponents(PODVector<Component * > & dest,StringHash type,bool recursive) const1339 void Node::GetComponents(PODVector<Component*>& dest, StringHash type, bool recursive) const
1340 {
1341     dest.Clear();
1342 
1343     if (!recursive)
1344     {
1345         for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
1346         {
1347             if ((*i)->GetType() == type)
1348                 dest.Push(*i);
1349         }
1350     }
1351     else
1352         GetComponentsRecursive(dest, type);
1353 }
1354 
HasComponent(StringHash type) const1355 bool Node::HasComponent(StringHash type) const
1356 {
1357     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
1358     {
1359         if ((*i)->GetType() == type)
1360             return true;
1361     }
1362     return false;
1363 }
1364 
HasTag(const String & tag) const1365 bool Node::HasTag(const String& tag) const
1366 {
1367     return impl_->tags_.Contains(tag);
1368 }
1369 
IsChildOf(Node * node) const1370 bool Node::IsChildOf(Node* node) const
1371 {
1372     Node* parent = parent_;
1373     while (parent)
1374     {
1375         if (parent == node)
1376             return true;
1377         parent = parent->parent_;
1378     }
1379     return false;
1380 }
1381 
GetVar(StringHash key) const1382 const Variant& Node::GetVar(StringHash key) const
1383 {
1384     VariantMap::ConstIterator i = vars_.Find(key);
1385     return i != vars_.End() ? i->second_ : Variant::EMPTY;
1386 }
1387 
GetComponent(StringHash type,bool recursive) const1388 Component* Node::GetComponent(StringHash type, bool recursive) const
1389 {
1390     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
1391     {
1392         if ((*i)->GetType() == type)
1393             return *i;
1394     }
1395 
1396     if (recursive)
1397     {
1398         for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1399         {
1400             Component* component = (*i)->GetComponent(type, true);
1401             if (component)
1402                 return component;
1403         }
1404     }
1405 
1406     return 0;
1407 }
1408 
GetParentComponent(StringHash type,bool fullTraversal) const1409 Component* Node::GetParentComponent(StringHash type, bool fullTraversal) const
1410 {
1411     Node* current = GetParent();
1412     while (current)
1413     {
1414         Component* soughtComponent = current->GetComponent(type);
1415         if (soughtComponent)
1416             return soughtComponent;
1417 
1418         if (fullTraversal)
1419             current = current->GetParent();
1420         else
1421             break;
1422     }
1423     return 0;
1424 }
1425 
SetID(unsigned id)1426 void Node::SetID(unsigned id)
1427 {
1428     id_ = id;
1429 }
1430 
SetScene(Scene * scene)1431 void Node::SetScene(Scene* scene)
1432 {
1433     scene_ = scene;
1434 }
1435 
ResetScene()1436 void Node::ResetScene()
1437 {
1438     SetID(0);
1439     SetScene(0);
1440     SetOwner(0);
1441 }
1442 
SetNetPositionAttr(const Vector3 & value)1443 void Node::SetNetPositionAttr(const Vector3& value)
1444 {
1445     SmoothedTransform* transform = GetComponent<SmoothedTransform>();
1446     if (transform)
1447         transform->SetTargetPosition(value);
1448     else
1449         SetPosition(value);
1450 }
1451 
SetNetRotationAttr(const PODVector<unsigned char> & value)1452 void Node::SetNetRotationAttr(const PODVector<unsigned char>& value)
1453 {
1454     MemoryBuffer buf(value);
1455     SmoothedTransform* transform = GetComponent<SmoothedTransform>();
1456     if (transform)
1457         transform->SetTargetRotation(buf.ReadPackedQuaternion());
1458     else
1459         SetRotation(buf.ReadPackedQuaternion());
1460 }
1461 
SetNetParentAttr(const PODVector<unsigned char> & value)1462 void Node::SetNetParentAttr(const PODVector<unsigned char>& value)
1463 {
1464     Scene* scene = GetScene();
1465     if (!scene)
1466         return;
1467 
1468     MemoryBuffer buf(value);
1469     // If nothing in the buffer, parent is the root node
1470     if (buf.IsEof())
1471     {
1472         scene->AddChild(this);
1473         return;
1474     }
1475 
1476     unsigned baseNodeID = buf.ReadNetID();
1477     Node* baseNode = scene->GetNode(baseNodeID);
1478     if (!baseNode)
1479     {
1480         URHO3D_LOGWARNING("Failed to find parent node " + String(baseNodeID));
1481         return;
1482     }
1483 
1484     // If buffer contains just an ID, the parent is replicated and we are done
1485     if (buf.IsEof())
1486         baseNode->AddChild(this);
1487     else
1488     {
1489         // Else the parent is local and we must find it recursively by name hash
1490         StringHash nameHash = buf.ReadStringHash();
1491         Node* parentNode = baseNode->GetChild(nameHash, true);
1492         if (!parentNode)
1493             URHO3D_LOGWARNING("Failed to find parent node with name hash " + nameHash.ToString());
1494         else
1495             parentNode->AddChild(this);
1496     }
1497 }
1498 
GetNetPositionAttr() const1499 const Vector3& Node::GetNetPositionAttr() const
1500 {
1501     return position_;
1502 }
1503 
GetNetRotationAttr() const1504 const PODVector<unsigned char>& Node::GetNetRotationAttr() const
1505 {
1506     impl_->attrBuffer_.Clear();
1507     impl_->attrBuffer_.WritePackedQuaternion(rotation_);
1508     return impl_->attrBuffer_.GetBuffer();
1509 }
1510 
GetNetParentAttr() const1511 const PODVector<unsigned char>& Node::GetNetParentAttr() const
1512 {
1513     impl_->attrBuffer_.Clear();
1514     Scene* scene = GetScene();
1515     if (scene && parent_ && parent_ != scene)
1516     {
1517         // If parent is replicated, can write the ID directly
1518         unsigned parentID = parent_->GetID();
1519         if (parentID < FIRST_LOCAL_ID)
1520             impl_->attrBuffer_.WriteNetID(parentID);
1521         else
1522         {
1523             // Parent is local: traverse hierarchy to find a non-local base node
1524             // This iteration always stops due to the scene (root) being non-local
1525             Node* current = parent_;
1526             while (current->GetID() >= FIRST_LOCAL_ID)
1527                 current = current->GetParent();
1528 
1529             // Then write the base node ID and the parent's name hash
1530             impl_->attrBuffer_.WriteNetID(current->GetID());
1531             impl_->attrBuffer_.WriteStringHash(parent_->GetNameHash());
1532         }
1533     }
1534 
1535     return impl_->attrBuffer_.GetBuffer();
1536 }
1537 
Load(Deserializer & source,SceneResolver & resolver,bool readChildren,bool rewriteIDs,CreateMode mode)1538 bool Node::Load(Deserializer& source, SceneResolver& resolver, bool readChildren, bool rewriteIDs, CreateMode mode)
1539 {
1540     // Remove all children and components first in case this is not a fresh load
1541     RemoveAllChildren();
1542     RemoveAllComponents();
1543 
1544     // ID has been read at the parent level
1545     if (!Animatable::Load(source))
1546         return false;
1547 
1548     unsigned numComponents = source.ReadVLE();
1549     for (unsigned i = 0; i < numComponents; ++i)
1550     {
1551         VectorBuffer compBuffer(source, source.ReadVLE());
1552         StringHash compType = compBuffer.ReadStringHash();
1553         unsigned compID = compBuffer.ReadUInt();
1554 
1555         Component* newComponent = SafeCreateComponent(String::EMPTY, compType,
1556             (mode == REPLICATED && compID < FIRST_LOCAL_ID) ? REPLICATED : LOCAL, rewriteIDs ? 0 : compID);
1557         if (newComponent)
1558         {
1559             resolver.AddComponent(compID, newComponent);
1560             // Do not abort if component fails to load, as the component buffer is nested and we can skip to the next
1561             newComponent->Load(compBuffer);
1562         }
1563     }
1564 
1565     if (!readChildren)
1566         return true;
1567 
1568     unsigned numChildren = source.ReadVLE();
1569     for (unsigned i = 0; i < numChildren; ++i)
1570     {
1571         unsigned nodeID = source.ReadUInt();
1572         Node* newNode = CreateChild(rewriteIDs ? 0 : nodeID, (mode == REPLICATED && nodeID < FIRST_LOCAL_ID) ? REPLICATED :
1573             LOCAL);
1574         resolver.AddNode(nodeID, newNode);
1575         if (!newNode->Load(source, resolver, readChildren, rewriteIDs, mode))
1576             return false;
1577     }
1578 
1579     return true;
1580 }
1581 
LoadXML(const XMLElement & source,SceneResolver & resolver,bool readChildren,bool rewriteIDs,CreateMode mode)1582 bool Node::LoadXML(const XMLElement& source, SceneResolver& resolver, bool readChildren, bool rewriteIDs, CreateMode mode)
1583 {
1584     // Remove all children and components first in case this is not a fresh load
1585     RemoveAllChildren();
1586     RemoveAllComponents();
1587 
1588     if (!Animatable::LoadXML(source))
1589         return false;
1590 
1591     XMLElement compElem = source.GetChild("component");
1592     while (compElem)
1593     {
1594         String typeName = compElem.GetAttribute("type");
1595         unsigned compID = compElem.GetUInt("id");
1596         Component* newComponent = SafeCreateComponent(typeName, StringHash(typeName),
1597             (mode == REPLICATED && compID < FIRST_LOCAL_ID) ? REPLICATED : LOCAL, rewriteIDs ? 0 : compID);
1598         if (newComponent)
1599         {
1600             resolver.AddComponent(compID, newComponent);
1601             if (!newComponent->LoadXML(compElem))
1602                 return false;
1603         }
1604 
1605         compElem = compElem.GetNext("component");
1606     }
1607 
1608     if (!readChildren)
1609         return true;
1610 
1611     XMLElement childElem = source.GetChild("node");
1612     while (childElem)
1613     {
1614         unsigned nodeID = childElem.GetUInt("id");
1615         Node* newNode = CreateChild(rewriteIDs ? 0 : nodeID, (mode == REPLICATED && nodeID < FIRST_LOCAL_ID) ? REPLICATED :
1616             LOCAL);
1617         resolver.AddNode(nodeID, newNode);
1618         if (!newNode->LoadXML(childElem, resolver, readChildren, rewriteIDs, mode))
1619             return false;
1620 
1621         childElem = childElem.GetNext("node");
1622     }
1623 
1624     return true;
1625 }
1626 
LoadJSON(const JSONValue & source,SceneResolver & resolver,bool readChildren,bool rewriteIDs,CreateMode mode)1627 bool Node::LoadJSON(const JSONValue& source, SceneResolver& resolver, bool readChildren, bool rewriteIDs, CreateMode mode)
1628 {
1629     // Remove all children and components first in case this is not a fresh load
1630     RemoveAllChildren();
1631     RemoveAllComponents();
1632 
1633     if (!Animatable::LoadJSON(source))
1634         return false;
1635 
1636     const JSONArray& componentsArray = source.Get("components").GetArray();
1637 
1638     for (unsigned i = 0; i < componentsArray.Size(); i++)
1639     {
1640         const JSONValue& compVal = componentsArray.At(i);
1641         String typeName = compVal.Get("type").GetString();
1642         unsigned compID = compVal.Get("id").GetUInt();
1643         Component* newComponent = SafeCreateComponent(typeName, StringHash(typeName),
1644             (mode == REPLICATED && compID < FIRST_LOCAL_ID) ? REPLICATED : LOCAL, rewriteIDs ? 0 : compID);
1645         if (newComponent)
1646         {
1647             resolver.AddComponent(compID, newComponent);
1648             if (!newComponent->LoadJSON(compVal))
1649                 return false;
1650         }
1651     }
1652 
1653     if (!readChildren)
1654         return true;
1655 
1656     const JSONArray& childrenArray = source.Get("children").GetArray();
1657     for (unsigned i = 0; i < childrenArray.Size(); i++)
1658     {
1659         const JSONValue& childVal = childrenArray.At(i);
1660 
1661         unsigned nodeID = childVal.Get("id").GetUInt();
1662         Node* newNode = CreateChild(rewriteIDs ? 0 : nodeID, (mode == REPLICATED && nodeID < FIRST_LOCAL_ID) ? REPLICATED :
1663             LOCAL);
1664         resolver.AddNode(nodeID, newNode);
1665         if (!newNode->LoadJSON(childVal, resolver, readChildren, rewriteIDs, mode))
1666             return false;
1667     }
1668 
1669     return true;
1670 }
1671 
PrepareNetworkUpdate()1672 void Node::PrepareNetworkUpdate()
1673 {
1674     // Update dependency nodes list first
1675     impl_->dependencyNodes_.Clear();
1676 
1677     // Add the parent node, but if it is local, traverse to the first non-local node
1678     if (parent_ && parent_ != scene_)
1679     {
1680         Node* current = parent_;
1681         while (current->id_ >= FIRST_LOCAL_ID)
1682             current = current->parent_;
1683         if (current && current != scene_)
1684             impl_->dependencyNodes_.Push(current);
1685     }
1686 
1687     // Let the components add their dependencies
1688     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
1689     {
1690         Component* component = *i;
1691         if (component->GetID() < FIRST_LOCAL_ID)
1692             component->GetDependencyNodes(impl_->dependencyNodes_);
1693     }
1694 
1695     // Then check for node attribute changes
1696     if (!networkState_)
1697         AllocateNetworkState();
1698 
1699     const Vector<AttributeInfo>* attributes = networkState_->attributes_;
1700     unsigned numAttributes = attributes->Size();
1701 
1702     // Check for attribute changes
1703     for (unsigned i = 0; i < numAttributes; ++i)
1704     {
1705         const AttributeInfo& attr = attributes->At(i);
1706 
1707         if (animationEnabled_ && IsAnimatedNetworkAttribute(attr))
1708             continue;
1709 
1710         OnGetAttribute(attr, networkState_->currentValues_[i]);
1711 
1712         if (networkState_->currentValues_[i] != networkState_->previousValues_[i])
1713         {
1714             networkState_->previousValues_[i] = networkState_->currentValues_[i];
1715 
1716             // Mark the attribute dirty in all replication states that are tracking this node
1717             for (PODVector<ReplicationState*>::Iterator j = networkState_->replicationStates_.Begin();
1718                  j != networkState_->replicationStates_.End(); ++j)
1719             {
1720                 NodeReplicationState* nodeState = static_cast<NodeReplicationState*>(*j);
1721                 nodeState->dirtyAttributes_.Set(i);
1722 
1723                 // Add node to the dirty set if not added yet
1724                 if (!nodeState->markedDirty_)
1725                 {
1726                     nodeState->markedDirty_ = true;
1727                     nodeState->sceneState_->dirtyNodes_.Insert(id_);
1728                 }
1729             }
1730         }
1731     }
1732 
1733     // Finally check for user var changes
1734     for (VariantMap::ConstIterator i = vars_.Begin(); i != vars_.End(); ++i)
1735     {
1736         VariantMap::ConstIterator j = networkState_->previousVars_.Find(i->first_);
1737         if (j == networkState_->previousVars_.End() || j->second_ != i->second_)
1738         {
1739             networkState_->previousVars_[i->first_] = i->second_;
1740 
1741             // Mark the var dirty in all replication states that are tracking this node
1742             for (PODVector<ReplicationState*>::Iterator j = networkState_->replicationStates_.Begin();
1743                  j != networkState_->replicationStates_.End(); ++j)
1744             {
1745                 NodeReplicationState* nodeState = static_cast<NodeReplicationState*>(*j);
1746                 nodeState->dirtyVars_.Insert(i->first_);
1747 
1748                 if (!nodeState->markedDirty_)
1749                 {
1750                     nodeState->markedDirty_ = true;
1751                     nodeState->sceneState_->dirtyNodes_.Insert(id_);
1752                 }
1753             }
1754         }
1755     }
1756 
1757     networkUpdate_ = false;
1758 }
1759 
CleanupConnection(Connection * connection)1760 void Node::CleanupConnection(Connection* connection)
1761 {
1762     if (impl_->owner_ == connection)
1763         impl_->owner_ = 0;
1764 
1765     if (networkState_)
1766     {
1767         for (unsigned i = networkState_->replicationStates_.Size() - 1; i < networkState_->replicationStates_.Size(); --i)
1768         {
1769             if (networkState_->replicationStates_[i]->connection_ == connection)
1770                 networkState_->replicationStates_.Erase(i);
1771         }
1772     }
1773 }
1774 
MarkReplicationDirty()1775 void Node::MarkReplicationDirty()
1776 {
1777     if (networkState_)
1778     {
1779         for (PODVector<ReplicationState*>::Iterator j = networkState_->replicationStates_.Begin();
1780              j != networkState_->replicationStates_.End(); ++j)
1781         {
1782             NodeReplicationState* nodeState = static_cast<NodeReplicationState*>(*j);
1783             if (!nodeState->markedDirty_)
1784             {
1785                 nodeState->markedDirty_ = true;
1786                 nodeState->sceneState_->dirtyNodes_.Insert(id_);
1787             }
1788         }
1789     }
1790 }
1791 
CreateChild(unsigned id,CreateMode mode,bool temporary)1792 Node* Node::CreateChild(unsigned id, CreateMode mode, bool temporary)
1793 {
1794     SharedPtr<Node> newNode(new Node(context_));
1795     newNode->SetTemporary(temporary);
1796 
1797     // If zero ID specified, or the ID is already taken, let the scene assign
1798     if (scene_)
1799     {
1800         if (!id || scene_->GetNode(id))
1801             id = scene_->GetFreeNodeID(mode);
1802         newNode->SetID(id);
1803     }
1804     else
1805         newNode->SetID(id);
1806 
1807     AddChild(newNode);
1808     return newNode;
1809 }
1810 
AddComponent(Component * component,unsigned id,CreateMode mode)1811 void Node::AddComponent(Component* component, unsigned id, CreateMode mode)
1812 {
1813     if (!component)
1814         return;
1815 
1816     components_.Push(SharedPtr<Component>(component));
1817 
1818     if (component->GetNode())
1819         URHO3D_LOGWARNING("Component " + component->GetTypeName() + " already belongs to a node!");
1820 
1821     component->SetNode(this);
1822 
1823     // If zero ID specified, or the ID is already taken, let the scene assign
1824     if (scene_)
1825     {
1826         if (!id || scene_->GetComponent(id))
1827             id = scene_->GetFreeComponentID(mode);
1828         component->SetID(id);
1829         scene_->ComponentAdded(component);
1830     }
1831     else
1832         component->SetID(id);
1833 
1834     component->OnMarkedDirty(this);
1835 
1836     // Check attributes of the new component on next network update, and mark node dirty in all replication states
1837     component->MarkNetworkUpdate();
1838     MarkNetworkUpdate();
1839     MarkReplicationDirty();
1840 
1841     // Send change event
1842     if (scene_)
1843     {
1844         using namespace ComponentAdded;
1845 
1846         VariantMap& eventData = GetEventDataMap();
1847         eventData[P_SCENE] = scene_;
1848         eventData[P_NODE] = this;
1849         eventData[P_COMPONENT] = component;
1850 
1851         scene_->SendEvent(E_COMPONENTADDED, eventData);
1852     }
1853 }
1854 
GetNumPersistentChildren() const1855 unsigned Node::GetNumPersistentChildren() const
1856 {
1857     unsigned ret = 0;
1858 
1859     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
1860     {
1861         if (!(*i)->IsTemporary())
1862             ++ret;
1863     }
1864 
1865     return ret;
1866 }
1867 
GetNumPersistentComponents() const1868 unsigned Node::GetNumPersistentComponents() const
1869 {
1870     unsigned ret = 0;
1871 
1872     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
1873     {
1874         if (!(*i)->IsTemporary())
1875             ++ret;
1876     }
1877 
1878     return ret;
1879 }
1880 
SetTransformSilent(const Vector3 & position,const Quaternion & rotation,const Vector3 & scale)1881 void Node::SetTransformSilent(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
1882 {
1883     position_ = position;
1884     rotation_ = rotation;
1885     scale_ = scale;
1886 }
1887 
OnAttributeAnimationAdded()1888 void Node::OnAttributeAnimationAdded()
1889 {
1890     if (attributeAnimationInfos_.Size() == 1)
1891         SubscribeToEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE, URHO3D_HANDLER(Node, HandleAttributeAnimationUpdate));
1892 }
1893 
OnAttributeAnimationRemoved()1894 void Node::OnAttributeAnimationRemoved()
1895 {
1896     if (attributeAnimationInfos_.Empty())
1897         UnsubscribeFromEvent(GetScene(), E_ATTRIBUTEANIMATIONUPDATE);
1898 }
1899 
FindAttributeAnimationTarget(const String & name,String & outName)1900 Animatable* Node::FindAttributeAnimationTarget(const String& name, String& outName)
1901 {
1902     Vector<String> names = name.Split('/');
1903     // Only attribute name
1904     if (names.Size() == 1)
1905     {
1906         outName = name;
1907         return this;
1908     }
1909     else
1910     {
1911         // Name must in following format: "#0/#1/@component#0/attribute"
1912         Node* node = this;
1913         unsigned i = 0;
1914         for (; i < names.Size() - 1; ++i)
1915         {
1916             if (names[i].Front() != '#')
1917                 break;
1918 
1919             String name = names[i].Substring(1, names[i].Length() - 1);
1920             char s = name.Front();
1921             if (s >= '0' && s <= '9')
1922             {
1923                 unsigned index = ToUInt(name);
1924                 node = node->GetChild(index);
1925             }
1926             else
1927             {
1928                 node = node->GetChild(name, true);
1929             }
1930 
1931             if (!node)
1932             {
1933                 URHO3D_LOGERROR("Could not find node by name " + name);
1934                 return 0;
1935             }
1936         }
1937 
1938         if (i == names.Size() - 1)
1939         {
1940             outName = names.Back();
1941             return node;
1942         }
1943 
1944         if (i != names.Size() - 2 || names[i].Front() != '@')
1945         {
1946             URHO3D_LOGERROR("Invalid name " + name);
1947             return 0;
1948         }
1949 
1950         String componentName = names[i].Substring(1, names[i].Length() - 1);
1951         Vector<String> componentNames = componentName.Split('#');
1952         if (componentNames.Size() == 1)
1953         {
1954             Component* component = node->GetComponent(StringHash(componentNames.Front()));
1955             if (!component)
1956             {
1957                 URHO3D_LOGERROR("Could not find component by name " + name);
1958                 return 0;
1959             }
1960 
1961             outName = names.Back();
1962             return component;
1963         }
1964         else
1965         {
1966             unsigned index = ToUInt(componentNames[1]);
1967             PODVector<Component*> components;
1968             node->GetComponents(components, StringHash(componentNames.Front()));
1969             if (index >= components.Size())
1970             {
1971                 URHO3D_LOGERROR("Could not find component by name " + name);
1972                 return 0;
1973             }
1974 
1975             outName = names.Back();
1976             return components[index];
1977         }
1978     }
1979 }
1980 
SetEnabled(bool enable,bool recursive,bool storeSelf)1981 void Node::SetEnabled(bool enable, bool recursive, bool storeSelf)
1982 {
1983     // The enabled state of the whole scene can not be changed. SetUpdateEnabled() is used instead to start/stop updates.
1984     if (GetType() == Scene::GetTypeStatic())
1985     {
1986         URHO3D_LOGERROR("Can not change enabled state of the Scene");
1987         return;
1988     }
1989 
1990     if (storeSelf)
1991         enabledPrev_ = enable;
1992 
1993     if (enable != enabled_)
1994     {
1995         enabled_ = enable;
1996         MarkNetworkUpdate();
1997 
1998         // Notify listener components of the state change
1999         for (Vector<WeakPtr<Component> >::Iterator i = listeners_.Begin(); i != listeners_.End();)
2000         {
2001             if (*i)
2002             {
2003                 (*i)->OnNodeSetEnabled(this);
2004                 ++i;
2005             }
2006             // If listener has expired, erase from list
2007             else
2008                 i = listeners_.Erase(i);
2009         }
2010 
2011         // Send change event
2012         if (scene_)
2013         {
2014             using namespace NodeEnabledChanged;
2015 
2016             VariantMap& eventData = GetEventDataMap();
2017             eventData[P_SCENE] = scene_;
2018             eventData[P_NODE] = this;
2019 
2020             scene_->SendEvent(E_NODEENABLEDCHANGED, eventData);
2021         }
2022 
2023         for (Vector<SharedPtr<Component> >::Iterator i = components_.Begin(); i != components_.End(); ++i)
2024         {
2025             (*i)->OnSetEnabled();
2026 
2027             // Send change event for the component
2028             if (scene_)
2029             {
2030                 using namespace ComponentEnabledChanged;
2031 
2032                 VariantMap& eventData = GetEventDataMap();
2033                 eventData[P_SCENE] = scene_;
2034                 eventData[P_NODE] = this;
2035                 eventData[P_COMPONENT] = (*i);
2036 
2037                 scene_->SendEvent(E_COMPONENTENABLEDCHANGED, eventData);
2038             }
2039         }
2040     }
2041 
2042     if (recursive)
2043     {
2044         for (Vector<SharedPtr<Node> >::Iterator i = children_.Begin(); i != children_.End(); ++i)
2045             (*i)->SetEnabled(enable, recursive, storeSelf);
2046     }
2047 }
2048 
SafeCreateComponent(const String & typeName,StringHash type,CreateMode mode,unsigned id)2049 Component* Node::SafeCreateComponent(const String& typeName, StringHash type, CreateMode mode, unsigned id)
2050 {
2051     // Do not attempt to create replicated components to local nodes, as that may lead to component ID overwrite
2052     // as replicated components are synced over
2053     if (id_ >= FIRST_LOCAL_ID && mode == REPLICATED)
2054         mode = LOCAL;
2055 
2056     // First check if factory for type exists
2057     if (!context_->GetTypeName(type).Empty())
2058         return CreateComponent(type, mode, id);
2059     else
2060     {
2061         URHO3D_LOGWARNING("Component type " + type.ToString() + " not known, creating UnknownComponent as placeholder");
2062         // Else create as UnknownComponent
2063         SharedPtr<UnknownComponent> newComponent(new UnknownComponent(context_));
2064         if (typeName.Empty() || typeName.StartsWith("Unknown", false))
2065             newComponent->SetType(type);
2066         else
2067             newComponent->SetTypeName(typeName);
2068 
2069         AddComponent(newComponent, id, mode);
2070         return newComponent;
2071     }
2072 }
2073 
UpdateWorldTransform() const2074 void Node::UpdateWorldTransform() const
2075 {
2076     Matrix3x4 transform = GetTransform();
2077 
2078     // Assume the root node (scene) has identity transform
2079     if (parent_ == scene_ || !parent_)
2080     {
2081         worldTransform_ = transform;
2082         worldRotation_ = rotation_;
2083     }
2084     else
2085     {
2086         worldTransform_ = parent_->GetWorldTransform() * transform;
2087         worldRotation_ = parent_->GetWorldRotation() * rotation_;
2088     }
2089 
2090     dirty_ = false;
2091 }
2092 
RemoveChild(Vector<SharedPtr<Node>>::Iterator i)2093 void Node::RemoveChild(Vector<SharedPtr<Node> >::Iterator i)
2094 {
2095     // Keep a shared pointer to the child about to be removed, to make sure the erase from container completes first. Otherwise
2096     // it would be possible that other child nodes get removed as part of the node's components' cleanup, causing a re-entrant
2097     // erase and a crash
2098     SharedPtr<Node> child(*i);
2099 
2100     // Send change event. Do not send when this node is already being destroyed
2101     if (Refs() > 0 && scene_)
2102     {
2103         using namespace NodeRemoved;
2104 
2105         VariantMap& eventData = GetEventDataMap();
2106         eventData[P_SCENE] = scene_;
2107         eventData[P_PARENT] = this;
2108         eventData[P_NODE] = child;
2109 
2110         scene_->SendEvent(E_NODEREMOVED, eventData);
2111     }
2112 
2113     child->parent_ = 0;
2114     child->MarkDirty();
2115     child->MarkNetworkUpdate();
2116     if (scene_)
2117         scene_->NodeRemoved(child);
2118 
2119     children_.Erase(i);
2120 }
2121 
GetChildrenRecursive(PODVector<Node * > & dest) const2122 void Node::GetChildrenRecursive(PODVector<Node*>& dest) const
2123 {
2124     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
2125     {
2126         Node* node = *i;
2127         dest.Push(node);
2128         if (!node->children_.Empty())
2129             node->GetChildrenRecursive(dest);
2130     }
2131 }
2132 
GetChildrenWithComponentRecursive(PODVector<Node * > & dest,StringHash type) const2133 void Node::GetChildrenWithComponentRecursive(PODVector<Node*>& dest, StringHash type) const
2134 {
2135     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
2136     {
2137         Node* node = *i;
2138         if (node->HasComponent(type))
2139             dest.Push(node);
2140         if (!node->children_.Empty())
2141             node->GetChildrenWithComponentRecursive(dest, type);
2142     }
2143 }
2144 
GetComponentsRecursive(PODVector<Component * > & dest,StringHash type) const2145 void Node::GetComponentsRecursive(PODVector<Component*>& dest, StringHash type) const
2146 {
2147     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
2148     {
2149         if ((*i)->GetType() == type)
2150             dest.Push(*i);
2151     }
2152     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
2153         (*i)->GetComponentsRecursive(dest, type);
2154 }
2155 
GetChildrenWithTagRecursive(PODVector<Node * > & dest,const String & tag) const2156 void Node::GetChildrenWithTagRecursive(PODVector<Node*>& dest, const String& tag) const
2157 {
2158     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
2159     {
2160         Node* node = *i;
2161         if (node->HasTag(tag))
2162             dest.Push(node);
2163         if (!node->children_.Empty())
2164             node->GetChildrenWithTagRecursive(dest, tag);
2165     }
2166 }
2167 
CloneRecursive(Node * parent,SceneResolver & resolver,CreateMode mode)2168 Node* Node::CloneRecursive(Node* parent, SceneResolver& resolver, CreateMode mode)
2169 {
2170     // Create clone node
2171     Node* cloneNode = parent->CreateChild(0, (mode == REPLICATED && id_ < FIRST_LOCAL_ID) ? REPLICATED : LOCAL);
2172     resolver.AddNode(id_, cloneNode);
2173 
2174     // Copy attributes
2175     const Vector<AttributeInfo>* attributes = GetAttributes();
2176     for (unsigned j = 0; j < attributes->Size(); ++j)
2177     {
2178         const AttributeInfo& attr = attributes->At(j);
2179         // Do not copy network-only attributes, as they may have unintended side effects
2180         if (attr.mode_ & AM_FILE)
2181         {
2182             Variant value;
2183             OnGetAttribute(attr, value);
2184             cloneNode->OnSetAttribute(attr, value);
2185         }
2186     }
2187 
2188     // Clone components
2189     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
2190     {
2191         Component* component = *i;
2192         if (component->IsTemporary())
2193             continue;
2194 
2195         Component* cloneComponent = cloneNode->CloneComponent(component,
2196             (mode == REPLICATED && component->GetID() < FIRST_LOCAL_ID) ? REPLICATED : LOCAL, 0);
2197         if (cloneComponent)
2198             resolver.AddComponent(component->GetID(), cloneComponent);
2199     }
2200 
2201     // Clone child nodes recursively
2202     for (Vector<SharedPtr<Node> >::ConstIterator i = children_.Begin(); i != children_.End(); ++i)
2203     {
2204         Node* node = *i;
2205         if (node->IsTemporary())
2206             continue;
2207 
2208         node->CloneRecursive(cloneNode, resolver, mode);
2209     }
2210 
2211     {
2212         using namespace NodeCloned;
2213 
2214         VariantMap& eventData = GetEventDataMap();
2215         eventData[P_SCENE] = scene_;
2216         eventData[P_NODE] = this;
2217         eventData[P_CLONENODE] = cloneNode;
2218 
2219         scene_->SendEvent(E_NODECLONED, eventData);
2220     }
2221 
2222     return cloneNode;
2223 }
2224 
RemoveComponent(Vector<SharedPtr<Component>>::Iterator i)2225 void Node::RemoveComponent(Vector<SharedPtr<Component> >::Iterator i)
2226 {
2227     // Send node change event. Do not send when already being destroyed
2228     if (Refs() > 0 && scene_)
2229     {
2230         using namespace ComponentRemoved;
2231 
2232         VariantMap& eventData = GetEventDataMap();
2233         eventData[P_SCENE] = scene_;
2234         eventData[P_NODE] = this;
2235         eventData[P_COMPONENT] = (*i).Get();
2236 
2237         scene_->SendEvent(E_COMPONENTREMOVED, eventData);
2238     }
2239 
2240     RemoveListener(*i);
2241     if (scene_)
2242         scene_->ComponentRemoved(*i);
2243     (*i)->SetNode(0);
2244     components_.Erase(i);
2245 }
2246 
HandleAttributeAnimationUpdate(StringHash eventType,VariantMap & eventData)2247 void Node::HandleAttributeAnimationUpdate(StringHash eventType, VariantMap& eventData)
2248 {
2249     using namespace AttributeAnimationUpdate;
2250 
2251     UpdateAttributeAnimations(eventData[P_TIMESTEP].GetFloat());
2252 }
2253 
2254 }
2255