BGE: work around a problem with DBVT culling when graphic objects are rescaled. This happens when objects with very diverse scale are instantiated with dupligroup. The problem remains when the objects are rescaled during the game. The effect of the problem is an inefficient culling: objects can have a bounding box larger than needed. Patch to fix the problem is filed at Bullet forum.

This commit is contained in:
Benoit Bolsee
2009-05-01 19:02:23 +00:00
parent 672492f563
commit e13a089d91
7 changed files with 55 additions and 3 deletions

View File

@@ -331,6 +331,35 @@ void KX_GameObject::ProcessReplica()
}
static void setGraphicController_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->ActivateGraphicController(v, false);
// if the childobj is NULL then this may be an inverse parent link
// so a non recursive search should still look down this node.
setGraphicController_recursive(childnode, v);
}
}
void KX_GameObject::ActivateGraphicController(bool active, bool recurse)
{
if (m_pGraphicController)
{
m_pGraphicController->Activate(active);
}
if (recurse)
{
setGraphicController_recursive(GetSGNode(), active);
}
}
CValue* KX_GameObject::GetReplica()

View File

@@ -385,6 +385,10 @@ public:
{
m_pGraphicController = graphiccontroller;
}
/*
* @add/remove the graphic controller to the physic system
*/
void ActivateGraphicController(bool active, bool recurse);
/**
* @section Coordinate system manipulation functions

View File

@@ -717,10 +717,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
// set the orientation after position for softbody!
MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
replica->NodeSetLocalOrientation(newori);
// update scenegraph for entire tree of children
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox());
replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius());
// we can now add the graphic controller to the physic engine
replica->ActivateGraphicController(true,true);
// done with replica
replica->Release();
}
@@ -831,6 +834,8 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
// the size is correct, we can add the graphic controller to the physic engine
replica->ActivateGraphicController(true,true);
// now replicate logic
vector<KX_GameObject*>::iterator git;

View File

@@ -118,8 +118,17 @@ PHY_IGraphicController* CcdGraphicController::GetReplica(class PHY_IMotionState*
replica->m_motionState = motionState;
replica->m_newClientInfo = NULL;
replica->m_handle = NULL;
m_phyEnv->addCcdGraphicController(replica);
// don't add the graphic controller now: work around a bug in Bullet with rescaling,
// (the scale of the controller is not yet defined).
//m_phyEnv->addCcdGraphicController(replica);
return replica;
}
void CcdGraphicController::Activate(bool active)
{
if (active)
m_phyEnv->addCcdGraphicController(this);
else
m_phyEnv->removeCcdGraphicController(this);
}

View File

@@ -55,6 +55,10 @@ public:
* Updates the Aabb based on the motion state
*/
virtual bool SetGraphicTransform();
/**
* Add/remove to environment
*/
virtual void Activate(bool active);
// client info for culling
virtual void* getNewClientInfo() { return m_newClientInfo; }

View File

@@ -579,7 +579,7 @@ void CcdPhysicsEnvironment::refreshCcdPhysicsController(CcdPhysicsController* ct
void CcdPhysicsEnvironment::addCcdGraphicController(CcdGraphicController* ctrl)
{
if (m_cullingTree)
if (m_cullingTree && !ctrl->getBroadphaseHandle())
{
btVector3 minAabb;
btVector3 maxAabb;

View File

@@ -47,6 +47,7 @@ class PHY_IGraphicController : public PHY_IController
SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
*/
virtual bool SetGraphicTransform()=0;
virtual void Activate(bool active=true)=0;
virtual void setLocalAabb(const PHY__Vector3& aabbMin,const PHY__Vector3& aabbMax)=0;
virtual void setLocalAabb(const float* aabbMin,const float* aabbMax)=0;