BGE: work around a problem with DBVT culling when graphic objects are rescaled. This...
authorBenoit Bolsee <benoit.bolsee@online.be>
Fri, 1 May 2009 19:02:23 +0000 (19:02 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Fri, 1 May 2009 19:02:23 +0000 (19:02 +0000)
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Physics/Bullet/CcdGraphicController.cpp
source/gameengine/Physics/Bullet/CcdGraphicController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/common/PHY_IGraphicController.h

index 20113afaae29e9399a6107679a93d6dafbe40f20..fa95a89135b835e26914e6b984cd625584bf527a 100644 (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()
index fe9f39a6ed35ca7b72ebf4cbd3bd1cdc8a168403..14ed713ecfa4f36ee6eaa04c8a9f289075b17d6a 100644 (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
index fd24403772287d6df71e2ac5e473927d4eb3cb3b..36486440c001044ed327cdd8352e8a021d99b8d0 100644 (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;
index 2d1f841af0c97d988c2fa993b1901a1c778dc2f8..2dbbb7fa4a02e3f9aa518315d93410f4b02ef755 100644 (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);
 
+}
index 8f44a623371fbdef128267360e4c60c4c7a4c92c..b0626f902c2c56815008928dfb3d98c532cc87c1 100644 (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; }
index bcf83e25d847e34a12e41d7c5315fbb41167c7cf..03c9d13a7dde6425795e2d00863647aaa6fe2d63 100644 (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;
index 8acc5c2f9d39c65dda3526d9538d1e0c089ec8d7..470d42cb84a31f94d88e30924a36c7771b8e3bb1 100644 (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;