forked from bartvdbraak/blender
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
This commit is contained in:
parent
2e653838c0
commit
5eab0da633
@ -193,7 +193,8 @@ typedef struct bGameActuator {
|
|||||||
} bGameActuator;
|
} bGameActuator;
|
||||||
|
|
||||||
typedef struct bVisibilityActuator {
|
typedef struct bVisibilityActuator {
|
||||||
/** bit 0: Is this object visible? */
|
/** bit 0: Is this object visible?
|
||||||
|
** bit 1: Apply recursively */
|
||||||
int flag;
|
int flag;
|
||||||
} bVisibilityActuator;
|
} bVisibilityActuator;
|
||||||
|
|
||||||
@ -448,6 +449,7 @@ typedef struct FreeCamera {
|
|||||||
/* visibilityact->flag */
|
/* visibilityact->flag */
|
||||||
/* Set means the object will become invisible */
|
/* Set means the object will become invisible */
|
||||||
#define ACT_VISIBILITY_INVISIBLE (1 << 0)
|
#define ACT_VISIBILITY_INVISIBLE (1 << 0)
|
||||||
|
#define ACT_VISIBILITY_RECURSIVE (1 << 1)
|
||||||
|
|
||||||
/* twodfilter->type */
|
/* twodfilter->type */
|
||||||
#define ACT_2DFILTER_ENABLED -2
|
#define ACT_2DFILTER_ENABLED -2
|
||||||
|
@ -2350,7 +2350,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
|
|||||||
|
|
||||||
visAct = act->data;
|
visAct = act->data;
|
||||||
|
|
||||||
str= "Visibility %t|Visible %x0|Invisible %x1";
|
str= "Visibility %t|Visible %x0|Invisible %x1|Visible Recursive %x2|Invisible Recursive %x3";
|
||||||
|
|
||||||
uiDefButI(block, MENU, B_REDR, str,
|
uiDefButI(block, MENU, B_REDR, str,
|
||||||
xco + 10, yco - 24, width - 20, 19, &visAct->flag,
|
xco + 10, yco - 24, width - 20, 19, &visAct->flag,
|
||||||
|
@ -962,10 +962,9 @@ void BL_ConvertActuators(char* maggiename,
|
|||||||
bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
|
bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
|
||||||
KX_VisibilityActuator * tmp_vis_act = NULL;
|
KX_VisibilityActuator * tmp_vis_act = NULL;
|
||||||
bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
|
bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
|
||||||
|
bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0);
|
||||||
|
|
||||||
tmp_vis_act =
|
tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, recursive);
|
||||||
new KX_VisibilityActuator(gameobj,
|
|
||||||
!v);
|
|
||||||
|
|
||||||
baseact = tmp_vis_act;
|
baseact = tmp_vis_act;
|
||||||
}
|
}
|
||||||
|
@ -364,15 +364,36 @@ void KX_GameObject::AddMeshUser()
|
|||||||
for (size_t i=0;i<m_meshes.size();i++)
|
for (size_t i=0;i<m_meshes.size();i++)
|
||||||
m_meshes[i]->AddMeshUser(this);
|
m_meshes[i]->AddMeshUser(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<KX_GameObject*>( (*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();
|
double* fl = GetOpenGLMatrix();
|
||||||
|
|
||||||
for (size_t i=0;i<m_meshes.size();i++)
|
for (size_t i=0;i<m_meshes.size();i++)
|
||||||
m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
|
m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
UpdateBuckets_recursive(m_pSGNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KX_GameObject::RemoveMeshes()
|
void KX_GameObject::RemoveMeshes()
|
||||||
@ -502,12 +523,33 @@ KX_GameObject::GetVisible(
|
|||||||
return m_bVisible;
|
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<KX_GameObject*>( (*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
|
void
|
||||||
KX_GameObject::SetVisible(
|
KX_GameObject::SetVisible(
|
||||||
bool v
|
bool v,
|
||||||
|
bool recursive
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_bVisible = v;
|
m_bVisible = v;
|
||||||
|
if (recursive)
|
||||||
|
setVisible_recursive(m_pSGNode, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -880,7 +922,7 @@ PyMethodDef KX_GameObject::Methods[] = {
|
|||||||
{"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS},
|
{"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS},
|
||||||
{"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O},
|
{"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O},
|
||||||
{"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_NOARGS},
|
{"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},
|
{"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS},
|
||||||
{"setState",(PyCFunction) KX_GameObject::sPySetState, METH_O},
|
{"setState",(PyCFunction) KX_GameObject::sPySetState, METH_O},
|
||||||
{"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
|
{"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);
|
int val = PyInt_AsLong(value);
|
||||||
if (attr == "visible")
|
if (attr == "visible")
|
||||||
{
|
{
|
||||||
SetVisible(val != 0);
|
SetVisible(val != 0, false);
|
||||||
UpdateBuckets();
|
UpdateBuckets(false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1198,17 +1240,14 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* value)
|
PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
int visible = PyInt_AsLong(value);
|
int visible, recursive = 0;
|
||||||
|
if (!PyArg_ParseTuple(args,"i|i",&visible, &recursive))
|
||||||
if (visible==-1 && PyErr_Occurred()) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "expected 0 or 1");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
SetVisible(visible != 0);
|
SetVisible(visible ? true:false, recursive ? true:false);
|
||||||
UpdateBuckets();
|
UpdateBuckets(recursive ? true:false);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -566,6 +566,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
UpdateBuckets(
|
UpdateBuckets(
|
||||||
|
bool recursive
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -640,7 +641,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
SetVisible(
|
SetVisible(
|
||||||
bool b
|
bool b,
|
||||||
|
bool recursive
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -762,7 +764,7 @@ public:
|
|||||||
KX_PYMETHOD_NOARGS(KX_GameObject,GetOrientation);
|
KX_PYMETHOD_NOARGS(KX_GameObject,GetOrientation);
|
||||||
KX_PYMETHOD_O(KX_GameObject,SetOrientation);
|
KX_PYMETHOD_O(KX_GameObject,SetOrientation);
|
||||||
KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible);
|
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_NOARGS(KX_GameObject,GetState);
|
||||||
KX_PYMETHOD_O(KX_GameObject,SetState);
|
KX_PYMETHOD_O(KX_GameObject,SetState);
|
||||||
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
|
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
|
||||||
|
@ -1235,7 +1235,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
|
|||||||
}
|
}
|
||||||
|
|
||||||
gameobj->SetCulled(!visible);
|
gameobj->SetCulled(!visible);
|
||||||
gameobj->UpdateBuckets();
|
gameobj->UpdateBuckets(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node->Left())
|
if (node->Left())
|
||||||
@ -1253,7 +1253,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
|
|||||||
// Shadow lamp layers
|
// Shadow lamp layers
|
||||||
if(layer && !(gameobj->GetLayer() & layer)) {
|
if(layer && !(gameobj->GetLayer() & layer)) {
|
||||||
gameobj->SetCulled(true);
|
gameobj->SetCulled(true);
|
||||||
gameobj->UpdateBuckets();
|
gameobj->UpdateBuckets(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1300,10 +1300,10 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
|
|||||||
// Visibility/ non-visibility are marked
|
// Visibility/ non-visibility are marked
|
||||||
// elsewhere now.
|
// elsewhere now.
|
||||||
gameobj->SetCulled(false);
|
gameobj->SetCulled(false);
|
||||||
gameobj->UpdateBuckets();
|
gameobj->UpdateBuckets(false);
|
||||||
} else {
|
} else {
|
||||||
gameobj->SetCulled(true);
|
gameobj->SetCulled(true);
|
||||||
gameobj->UpdateBuckets();
|
gameobj->UpdateBuckets(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +38,12 @@
|
|||||||
KX_VisibilityActuator::KX_VisibilityActuator(
|
KX_VisibilityActuator::KX_VisibilityActuator(
|
||||||
SCA_IObject* gameobj,
|
SCA_IObject* gameobj,
|
||||||
bool visible,
|
bool visible,
|
||||||
|
bool recursive,
|
||||||
PyTypeObject* T
|
PyTypeObject* T
|
||||||
)
|
)
|
||||||
: SCA_IActuator(gameobj,T),
|
: SCA_IActuator(gameobj,T),
|
||||||
m_visible(visible)
|
m_visible(visible),
|
||||||
|
m_recursive(recursive)
|
||||||
{
|
{
|
||||||
// intentionally empty
|
// intentionally empty
|
||||||
}
|
}
|
||||||
@ -75,8 +77,8 @@ KX_VisibilityActuator::Update()
|
|||||||
|
|
||||||
KX_GameObject *obj = (KX_GameObject*) GetParent();
|
KX_GameObject *obj = (KX_GameObject*) GetParent();
|
||||||
|
|
||||||
obj->SetVisible(m_visible);
|
obj->SetVisible(m_visible, m_recursive);
|
||||||
obj->UpdateBuckets();
|
obj->UpdateBuckets(m_recursive);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -39,12 +39,14 @@ class KX_VisibilityActuator : public SCA_IActuator
|
|||||||
|
|
||||||
/** Make visible? */
|
/** Make visible? */
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
|
bool m_recursive;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
KX_VisibilityActuator(
|
KX_VisibilityActuator(
|
||||||
SCA_IObject* gameobj,
|
SCA_IObject* gameobj,
|
||||||
bool visible,
|
bool visible,
|
||||||
|
bool recursive,
|
||||||
PyTypeObject* T=&Type
|
PyTypeObject* T=&Type
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user