From 5eab0da6335b57cc3508d85277592e0f789c7ebd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 5 Sep 2008 16:22:14 +0000 Subject: BGE set visible actuator, option to set visibility recursively to make managing visibility for collections of objects a lot easier. BGE Python api's ob.setVisible() also takes an optional recursive arg thats off by default --- .../gameengine/Converter/KX_ConvertActuators.cpp | 5 +- source/gameengine/Ketsji/KX_GameObject.cpp | 67 +++++++++++++++++----- source/gameengine/Ketsji/KX_GameObject.h | 6 +- source/gameengine/Ketsji/KX_Scene.cpp | 8 +-- source/gameengine/Ketsji/KX_VisibilityActuator.cpp | 8 ++- source/gameengine/Ketsji/KX_VisibilityActuator.h | 2 + 6 files changed, 70 insertions(+), 26 deletions(-) (limited to 'source/gameengine') diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 321fc325bb8..3142f7652de 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -962,10 +962,9 @@ void BL_ConvertActuators(char* maggiename, bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data; KX_VisibilityActuator * tmp_vis_act = NULL; bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0); + bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0); - tmp_vis_act = - new KX_VisibilityActuator(gameobj, - !v); + tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, recursive); baseact = tmp_vis_act; } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index bec5d188f06..204eed9fa92 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -364,15 +364,36 @@ void KX_GameObject::AddMeshUser() for (size_t i=0;iAddMeshUser(this); - UpdateBuckets(); + UpdateBuckets(false); } -void KX_GameObject::UpdateBuckets() +static void UpdateBuckets_recursive(SG_Node* node) +{ + NodeList& children = node->GetSGChildren(); + + for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) + { + SG_Node* childnode = (*childit); + KX_GameObject *clientgameobj = static_cast( (*childit)->GetSGClientObject()); + if (clientgameobj != NULL) // This is a GameObject + clientgameobj->UpdateBuckets(0); + + // if the childobj is NULL then this may be an inverse parent link + // so a non recursive search should still look down this node. + UpdateBuckets_recursive(childnode); + } +} + +void KX_GameObject::UpdateBuckets( bool recursive ) { double* fl = GetOpenGLMatrix(); for (size_t i=0;iUpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled); + + if (recursive) { + UpdateBuckets_recursive(m_pSGNode); + } } void KX_GameObject::RemoveMeshes() @@ -502,12 +523,33 @@ KX_GameObject::GetVisible( return m_bVisible; } +static void setVisible_recursive(SG_Node* node, bool v) +{ + NodeList& children = node->GetSGChildren(); + + for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) + { + SG_Node* childnode = (*childit); + KX_GameObject *clientgameobj = static_cast( (*childit)->GetSGClientObject()); + if (clientgameobj != NULL) // This is a GameObject + clientgameobj->SetVisible(v, 0); + + // if the childobj is NULL then this may be an inverse parent link + // so a non recursive search should still look down this node. + setVisible_recursive(childnode, v); + } +} + + void KX_GameObject::SetVisible( - bool v + bool v, + bool recursive ) { m_bVisible = v; + if (recursive) + setVisible_recursive(m_pSGNode, v); } bool @@ -880,7 +922,7 @@ PyMethodDef KX_GameObject::Methods[] = { {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS}, {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O}, {"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_NOARGS}, - {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_O}, + {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS}, {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS}, {"setState",(PyCFunction) KX_GameObject::sPySetState, METH_O}, {"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS}, @@ -1036,8 +1078,8 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr int val = PyInt_AsLong(value); if (attr == "visible") { - SetVisible(val != 0); - UpdateBuckets(); + SetVisible(val != 0, false); + UpdateBuckets(false); return 0; } } @@ -1198,17 +1240,14 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args) return NULL; } -PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* value) +PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args) { - int visible = PyInt_AsLong(value); - - if (visible==-1 && PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, "expected 0 or 1"); + int visible, recursive = 0; + if (!PyArg_ParseTuple(args,"i|i",&visible, &recursive)) return NULL; - } - SetVisible(visible != 0); - UpdateBuckets(); + SetVisible(visible ? true:false, recursive ? true:false); + UpdateBuckets(recursive ? true:false); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 9dcf6526448..98b3f3b4c3f 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -566,6 +566,7 @@ public: */ void UpdateBuckets( + bool recursive ); /** @@ -640,7 +641,8 @@ public: */ void SetVisible( - bool b + bool b, + bool recursive ); /** @@ -762,7 +764,7 @@ public: KX_PYMETHOD_NOARGS(KX_GameObject,GetOrientation); KX_PYMETHOD_O(KX_GameObject,SetOrientation); KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible); - KX_PYMETHOD_O(KX_GameObject,SetVisible); + KX_PYMETHOD_VARARGS(KX_GameObject,SetVisible); KX_PYMETHOD_NOARGS(KX_GameObject,GetState); KX_PYMETHOD_O(KX_GameObject,SetState); KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 2ad0412f1bf..72875bbc039 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1235,7 +1235,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi } gameobj->SetCulled(!visible); - gameobj->UpdateBuckets(); + gameobj->UpdateBuckets(false); } } if (node->Left()) @@ -1253,7 +1253,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam // Shadow lamp layers if(layer && !(gameobj->GetLayer() & layer)) { gameobj->SetCulled(true); - gameobj->UpdateBuckets(); + gameobj->UpdateBuckets(false); return; } @@ -1300,10 +1300,10 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam // Visibility/ non-visibility are marked // elsewhere now. gameobj->SetCulled(false); - gameobj->UpdateBuckets(); + gameobj->UpdateBuckets(false); } else { gameobj->SetCulled(true); - gameobj->UpdateBuckets(); + gameobj->UpdateBuckets(false); } } diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp index 5a0cadcbcfe..60ea6ace53b 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -38,10 +38,12 @@ KX_VisibilityActuator::KX_VisibilityActuator( SCA_IObject* gameobj, bool visible, + bool recursive, PyTypeObject* T ) : SCA_IActuator(gameobj,T), - m_visible(visible) + m_visible(visible), + m_recursive(recursive) { // intentionally empty } @@ -75,8 +77,8 @@ KX_VisibilityActuator::Update() KX_GameObject *obj = (KX_GameObject*) GetParent(); - obj->SetVisible(m_visible); - obj->UpdateBuckets(); + obj->SetVisible(m_visible, m_recursive); + obj->UpdateBuckets(m_recursive); return true; } diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h index 9b4753033fb..d1b85ab998c 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.h +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -39,12 +39,14 @@ class KX_VisibilityActuator : public SCA_IActuator /** Make visible? */ bool m_visible; + bool m_recursive; public: KX_VisibilityActuator( SCA_IObject* gameobj, bool visible, + bool recursive, PyTypeObject* T=&Type ); -- cgit v1.2.3