diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2010-03-26 00:43:36 +0300 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2010-03-26 00:43:36 +0300 |
commit | 3ed81eeccf19daef6ca3b8f7e5035ceef621bd19 (patch) | |
tree | cd0d72fc54e9aed1dd1708f24a16d1a00485c304 /source/gameengine | |
parent | aa3428e6abbf3ef453757b4909ad10bb52b9a418 (diff) |
BGE: [#19836] Recursive Parenting in game crashes Blender. Added parenting loop detection.
Diffstat (limited to 'source/gameengine')
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Node.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/SceneGraph/SG_Node.h | 7 |
3 files changed, 18 insertions, 1 deletions
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 744dc85b9cc..9cb7e802235 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -234,7 +234,11 @@ KX_GameObject* KX_GameObject::GetParent() void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj, bool addToCompound, bool ghost) { // check on valid node in case a python controller holds a reference to a deleted object - if (obj && GetSGNode() && obj->GetSGNode() && GetSGNode()->GetSGParent() != obj->GetSGNode()) + if (obj && + GetSGNode() && // object is not zombi + obj->GetSGNode() && // object is not zombi + GetSGNode()->GetSGParent() != obj->GetSGNode() && // not already parented to same object + !GetSGNode()->IsAncessor(obj->GetSGNode())) // no parenting loop { // Make sure the objects have some scale MT_Vector3 scale1 = NodeGetWorldScaling(); diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp index 2436f6ecb55..706568fc3fe 100644 --- a/source/gameengine/SceneGraph/SG_Node.cpp +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -150,6 +150,12 @@ GetRootSGParent( return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this); } +bool SG_Node::IsAncessor(const SG_Node* child) const +{ + return (!child->m_SGparent) ? false : + (child->m_SGparent == this) ? true : IsAncessor(child->m_SGparent); +} + void SG_Node:: DisconnectFromParent( diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index 78fa61c019e..5d2bac2b955 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -77,6 +77,13 @@ public: SG_Node* child ); + /** + * Return true if the node is the ancessor of child + */ + bool + IsAncessor( + const SG_Node* child + ) const; /** * Get the current list of children. Do not use this interface for * adding or removing children please use the methods of this class for |