diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2012-10-07 04:09:02 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2012-10-07 04:09:02 +0400 |
commit | 7beff06950a9811a9689ab2d04f8ca4d573d1436 (patch) | |
tree | 28c1d83d556c4af2fa1adece16c15f544bcccaa4 | |
parent | e7db06ad9db5a1a05b00fc835038d4366d637851 (diff) |
BGE: Committing patch [#31442] "API improvements: Group references python api, for better control over groups and instances" by Martin Sell (moerdn). This patch adds a member and a group property to KX_GameObject:
* KX_GameObject.member returns the list of group members if the object is a group object, otherwise None is returned
* KX_GameObject.group returns the group object that the object belongs to or None if the object is not part of a group
-rw-r--r-- | doc/python_api/rst/bge.types.rst | 12 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.cpp | 76 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_GameObject.h | 32 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.cpp | 21 |
4 files changed, 140 insertions, 1 deletions
diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst index f4374f7f355..6599cfeb2b2 100644 --- a/doc/python_api/rst/bge.types.rst +++ b/doc/python_api/rst/bge.types.rst @@ -986,6 +986,18 @@ Types The object's parent object. (read-only). :type: :class:`KX_GameObject` or None + + .. attribute:: members + + Returns the list of group members if the object is a group object, otherwise None is returned. + + :type: :class:`CListValue` of :class:`KX_GameObject` or None + + .. attribute:: group + + Returns the group object that the object belongs to or None if the object is not part of a group. + + :type: :class:`KX_GameObject` or None .. attribute:: visible diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index fe8419d5343..80634c3d8fc 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -110,7 +110,9 @@ KX_GameObject::KX_GameObject( m_pHitObject(NULL), m_pObstacleSimulation(NULL), m_actionManager(NULL), - m_isDeformable(false) + m_isDeformable(false), + m_pDupliGroupObject(NULL), + m_pInstanceObjects(NULL) #ifdef WITH_PYTHON , m_attr_dict(NULL) #endif @@ -168,6 +170,16 @@ KX_GameObject::~KX_GameObject() KX_GetActiveScene()->RemoveAnimatedObject(this); delete m_actionManager; } + + if (m_pDupliGroupObject) + { + m_pDupliGroupObject->Release(); + } + + if (m_pInstanceObjects) + { + m_pInstanceObjects->Release(); + } #ifdef WITH_PYTHON if (m_attr_dict) { PyDict_Clear(m_attr_dict); /* in case of circular refs or other weird cases */ @@ -229,6 +241,46 @@ KX_IPhysicsController* KX_GameObject::GetPhysicsController() return m_pPhysicsController1; } +KX_GameObject* KX_GameObject::GetDupliGroupObject() +{ + return m_pDupliGroupObject; +} + +CListValue* KX_GameObject::GetInstanceObjects() +{ + return m_pInstanceObjects; +} + +void KX_GameObject::AddInstanceObjects(KX_GameObject* obj) +{ + if(!m_pInstanceObjects) + m_pInstanceObjects = new CListValue(); + + obj->AddRef(); + m_pInstanceObjects->Add(obj); +} + +void KX_GameObject::RemoveInstanceObject(KX_GameObject* obj) +{ + assert(m_pInstanceObjects); + m_pInstanceObjects->RemoveValue(obj); + obj->Release(); +} + +void KX_GameObject::RemoveDupliGroupObject() +{ + if(m_pDupliGroupObject) { + m_pDupliGroupObject->Release(); + m_pDupliGroupObject = NULL; + } +} + +void KX_GameObject::SetDupliGroupObject(KX_GameObject* obj) +{ + obj->AddRef(); + m_pDupliGroupObject = obj; +} + KX_GameObject* KX_GameObject::GetParent() { KX_GameObject* result = NULL; @@ -1629,6 +1681,8 @@ PyMethodDef KX_GameObject::Methods[] = { PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name), KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent), + KX_PYATTRIBUTE_RO_FUNCTION("members", KX_GameObject, pyattr_get_instance_objects), + KX_PYATTRIBUTE_RO_FUNCTION("group", KX_GameObject, pyattr_get_dupli_group_object), KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life), KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass), KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min), @@ -1924,6 +1978,26 @@ PyObject *KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE Py_RETURN_NONE; } +PyObject *KX_GameObject::pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + CListValue* instances = self->GetInstanceObjects(); + if (instances) { + return instances->GetProxy(); + } + Py_RETURN_NONE; +} + +PyObject *KX_GameObject::pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + KX_GameObject* pivot = self->GetDupliGroupObject(); + if (pivot) { + return pivot->GetProxy(); + } + Py_RETURN_NONE; +} + PyObject *KX_GameObject::pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast<KX_GameObject*>(self_v); diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index ea75ca4a917..4fde0752a13 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -116,6 +116,8 @@ protected: KX_ObstacleSimulation* m_pObstacleSimulation; + CListValue* m_pInstanceObjects; + KX_GameObject* m_pDupliGroupObject; // The action manager is used to play/stop/update actions BL_ActionManager* m_actionManager; @@ -208,6 +210,33 @@ public: void RemoveParent(KX_Scene *scene); /********************************* + * group reference API + *********************************/ + + KX_GameObject* + GetDupliGroupObject( + ); + + CListValue* + GetInstanceObjects( + ); + + void + SetDupliGroupObject(KX_GameObject* + ); + + void + AddInstanceObjects(KX_GameObject* + ); + + void + RemoveDupliGroupObject( + ); + + void + RemoveInstanceObject(KX_GameObject* + ); + /********************************* * Animation API *********************************/ @@ -949,6 +978,9 @@ public: static PyObject* pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_dupli_group_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_instance_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 652ed2ab2dd..a4237f9fabe 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -769,6 +769,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) // we can now add the graphic controller to the physic engine replica->ActivateGraphicController(true); + // set references for dupli-group + // groupobj holds a list of all objects, that belongs to this group + groupobj->AddInstanceObjects(replica); + + // every object gets the reference to its dupli-group object + replica->SetDupliGroupObject(groupobj); + // done with replica replica->Release(); } @@ -1017,6 +1024,20 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) m_timemgr->RemoveTimeProperty(propval); } } + + // if the object is the dupligroup proxy, you have to cleanup all m_pDupliGroupObject's in all + // instances refering to this group + if(newobj->GetInstanceObjects()) { + for (int i = 0; i < newobj->GetInstanceObjects()->GetCount(); i++) { + KX_GameObject* instance = (KX_GameObject*)newobj->GetInstanceObjects()->GetValue(i); + instance->RemoveDupliGroupObject(); + } + } + + // if this object was part of a group, make sure to remove it from that group's instance list + KX_GameObject* group = newobj->GetDupliGroupObject(); + if (group) + group->RemoveInstanceObject(newobj); newobj->RemoveMeshes(); ret = 1; |