Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBenoit Bolsee <benoit.bolsee@online.be>2010-03-26 00:43:36 +0300
committerBenoit Bolsee <benoit.bolsee@online.be>2010-03-26 00:43:36 +0300
commit3ed81eeccf19daef6ca3b8f7e5035ceef621bd19 (patch)
treecd0d72fc54e9aed1dd1708f24a16d1a00485c304 /source
parentaa3428e6abbf3ef453757b4909ad10bb52b9a418 (diff)
BGE: [#19836] Recursive Parenting in game crashes Blender. Added parenting loop detection.
Diffstat (limited to 'source')
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp6
-rw-r--r--source/gameengine/SceneGraph/SG_Node.cpp6
-rw-r--r--source/gameengine/SceneGraph/SG_Node.h7
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