Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp7
-rw-r--r--projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj2
-rw-r--r--projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj8
-rw-r--r--projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj17
-rw-r--r--source/blender/blenkernel/intern/world.c1
-rw-r--r--source/blender/makesdna/DNA_world_types.h3
-rw-r--r--source/blender/src/buttons_shading.c4
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp67
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h12
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp58
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h25
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp48
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_MotionState.h1
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp17
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h3
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp31
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.h9
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp103
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h17
-rw-r--r--source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h1
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.cpp112
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.h74
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp16
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp107
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h15
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Physics/common/PHY_DynamicTypes.h35
-rw-r--r--source/gameengine/Physics/common/PHY_IController.cpp39
-rw-r--r--source/gameengine/Physics/common/PHY_IController.h53
-rw-r--r--source/gameengine/Physics/common/PHY_IGraphicController.cpp39
-rw-r--r--source/gameengine/Physics/common/PHY_IGraphicController.h56
-rw-r--r--source/gameengine/Physics/common/PHY_IMotionState.h2
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h8
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp8
-rw-r--r--source/gameengine/Rasterizer/RAS_FramingManager.h7
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.h1
-rw-r--r--source/gameengine/SceneGraph/SG_BBox.cpp7
-rw-r--r--source/gameengine/SceneGraph/SG_BBox.h2
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.cpp2
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.h30
-rw-r--r--source/gameengine/SceneGraph/SG_Node.cpp7
-rw-r--r--source/gameengine/SceneGraph/SG_Node.h3
-rw-r--r--source/gameengine/SceneGraph/SG_ParentRelation.h3
-rw-r--r--source/gameengine/SceneGraph/SG_Spatial.cpp19
-rw-r--r--source/gameengine/SceneGraph/SG_Spatial.h13
54 files changed, 990 insertions, 151 deletions
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index 457e26b1dc0..b6231a8fda6 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -350,12 +350,13 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
for (int i=0;i<clampedSimulationSteps;i++)
{
internalSingleStepSimulation(fixedTimeStep);
- synchronizeMotionStates();
+ //for Blender, no need to synchronize here, it is done in blender anyway
+ //synchronizeMotionStates();
}
}
-
- synchronizeMotionStates();
+ //else
+ // synchronizeMotionStates();
clearForces();
diff --git a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
index 9fa3751c436..336c40ef0e8 100644
--- a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
+++ b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
@@ -166,7 +166,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"
+ AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"
OutputFile="..\..\..\..\bin\blenderplayer.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
index 8c22733b4e9..c941704ce23 100644
--- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
+++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj
@@ -431,6 +431,10 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
+ RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdGraphicController.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdPhysicsController.cpp"
>
</File>
@@ -445,6 +449,10 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
+ RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdGraphicController.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdPhysicsController.h"
>
</File>
diff --git a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj
index 582aed500ac..5441c5bd4f1 100644
--- a/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj
+++ b/projectfiles_vc9/gameengine/physics/PHY_Physics/PHY_Physics.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="PHY_Physics"
ProjectGUID="{E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}"
+ RootNamespace="PHY_Physics"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -470,6 +471,14 @@
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
+ RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_IController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_IGraphicController.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_IMotionState.cpp"
>
</File>
@@ -495,6 +504,14 @@
>
</File>
<File
+ RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_IController.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_IGraphicController.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_IMotionState.h"
>
</File>
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 2e89ce3f805..594d18f1ca7 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -106,6 +106,7 @@ World *add_world(char *name)
wrld->ao_approx_error= 0.25f;
wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
+ wrld->mode = WO_DBVT_CAMERA_CULLING; // DBVT culling by default
wrld->preview = NULL;
return wrld;
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index ab7e25190ad..a51e9704be2 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -84,6 +84,8 @@ typedef struct World {
* bit 1: Do stars
* bit 2: (reserved) depth of field
* bit 3: (gameengine): Activity culling is enabled.
+ * bit 4: ambient occlusion
+ * bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling
*/
short mode;
int physicsEngine; /* here it's aligned */
@@ -133,6 +135,7 @@ typedef struct World {
#define WO_DOF 4
#define WO_ACTIVITY_CULLING 8
#define WO_AMB_OCC 16
+#define WO_DBVT_CAMERA_CULLING 32
/* aomix */
#define WO_AOADD 0
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index fe4649f31f4..e68c86349ce 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -2181,7 +2181,7 @@ static void world_panel_mistaph(World *wrld)
uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
#if GAMEBLENDER == 1
- uiDefButI(block, MENU, 1,
+ uiDefButI(block, MENU, B_REDR,
#ifdef USE_ODE
"Physics %t|None %x0|Sumo %x2|Ode %x4 |Bullet %x5",
#else
@@ -2198,6 +2198,8 @@ static void world_panel_mistaph(World *wrld)
/* Gravitation for the game worlds */
uiDefButF(block, NUMSLI,0, "Grav ", 150,180,150,19, &(wrld->gravity), 0.0, 25.0, 0, 0, "Sets the gravitation constant of the game world");
+ if (wrld->physicsEngine == WOPHY_BULLET)
+ uiDefButBitS(block, TOG, WO_DBVT_CAMERA_CULLING, 0, "DBVT culling", 10,160,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for camera culling");
#endif
uiBlockSetCol(block, TH_BUT_SETTING1);
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index d74243b0eb0..3c77f122758 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -164,7 +164,11 @@ extern "C" {
// defines USE_ODE to choose physics engine
#include "KX_ConvertPhysicsObject.h"
-
+#ifdef USE_BULLET
+#include "CcdPhysicsEnvironment.h"
+#include "CcdGraphicController.h"
+#endif
+#include "KX_MotionState.h"
// This file defines relationships between parents and children
// in the game engine.
@@ -1265,8 +1269,37 @@ static void my_get_local_bounds(Object *ob, float *center, float *size)
//////////////////////////////////////////////////////
-
-
+void BL_CreateGraphicObjectNew(KX_GameObject* gameobj,
+ const MT_Point3& localAabbMin,
+ const MT_Point3& localAabbMax,
+ KX_Scene* kxscene,
+ bool isActive,
+ e_PhysicsEngine physics_engine)
+{
+ if (gameobj->GetMeshCount() > 0)
+ {
+ switch (physics_engine)
+ {
+#ifdef USE_BULLET
+ case UseBullet:
+ {
+ CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
+ assert(env);
+ PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
+ CcdGraphicController* ctrl = new CcdGraphicController(env, motionstate);
+ gameobj->SetGraphicController(ctrl);
+ ctrl->setNewClientInfo(gameobj->getClientInfo());
+ ctrl->setLocalAabb(localAabbMin, localAabbMax);
+ if (isActive)
+ env->addCcdGraphicController(ctrl);
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+}
void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
struct Object* blenderobject,
@@ -1859,8 +1892,10 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (blenderscene->world) {
kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
+ kxscene->SetDbvtCameraCulling((blenderscene->world->mode & WO_DBVT_CAMERA_CULLING) != 0);
} else {
kxscene->SetActivityCulling(false);
+ kxscene->SetDbvtCameraCulling(false);
}
int activeLayerBitInfo = blenderscene->lay;
@@ -1954,7 +1989,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeSetLocalPosition(pos);
gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
gameobj->NodeSetLocalScale(scale);
- gameobj->NodeUpdateGS(0,true);
+ gameobj->NodeUpdateGS(0);
BL_ConvertIpos(blenderobject,gameobj,converter);
BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
@@ -2037,7 +2072,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
objectlist->Add(gameobj->AddRef());
//tf.Add(gameobj->GetSGNode());
- gameobj->NodeUpdateGS(0,true);
+ gameobj->NodeUpdateGS(0);
gameobj->AddMeshUser();
}
@@ -2148,7 +2183,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeSetLocalPosition(pos);
gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
gameobj->NodeSetLocalScale(scale);
- gameobj->NodeUpdateGS(0,true);
+ gameobj->NodeUpdateGS(0);
BL_ConvertIpos(blenderobject,gameobj,converter);
BL_ConvertMaterialIpos(blenderobject,gameobj, converter);
@@ -2226,7 +2261,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
objectlist->Add(gameobj->AddRef());
//tf.Add(gameobj->GetSGNode());
- gameobj->NodeUpdateGS(0,true);
+ gameobj->NodeUpdateGS(0);
gameobj->AddMeshUser();
}
else
@@ -2377,7 +2412,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (gameobj->GetSGNode()->GetSGParent() == 0)
{
parentlist->Add(gameobj->AddRef());
- gameobj->NodeUpdateGS(0,true);
+ gameobj->NodeUpdateGS(0);
}
}
@@ -2414,6 +2449,22 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
}
+ // create graphic controller for culling
+ if (kxscene->GetDbvtCameraCulling())
+ {
+ for (i=0; i<sumolist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+ if (gameobj->GetMeshCount() > 0)
+ {
+ MT_Point3 box[2];
+ gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity());
+ // box[0] is the min, box[1] is the max
+ bool isactive = objectlist->SearchValue(gameobj);
+ BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
+ }
+ }
+ }
//set ini linearVel and int angularVel //rcruiz
if (converter->addInitFromFrame)
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 97a0819147c..b0c676a410d 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -267,9 +267,11 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
Scene *blenderscene = GetBlenderSceneForName(scenename);
e_PhysicsEngine physics_engine = UseBullet;
+ bool useDbvtCulling = false;
// hook for registration function during conversion.
m_currentScene = destinationscene;
destinationscene->SetSceneConverter(this);
+ SG_SetActiveStage(SG_STAGE_CONVERTER);
if (blenderscene)
{
@@ -281,6 +283,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
case WOPHY_BULLET:
{
physics_engine = UseBullet;
+ useDbvtCulling = (blenderscene->world->mode & WO_DBVT_CAMERA_CULLING) != 0;
break;
}
@@ -313,7 +316,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
#ifdef USE_BULLET
case UseBullet:
{
- CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment();
+ CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python
@@ -806,7 +809,7 @@ void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){
gameobj->NodeSetLocalPosition(pos);
gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
gameobj->NodeSetLocalScale(scale);
- gameobj->NodeUpdateGS(0,true);
+ gameobj->NodeUpdateGS(0);
}
}
}
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 062e9f7df50..435b2b5db19 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -417,13 +417,14 @@ void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly)
{
if (!nondynaonly)
{
+ /*
btTransform worldTrans;
if (GetRigidBody())
{
GetRigidBody()->getMotionState()->getWorldTransform(worldTrans);
GetRigidBody()->setCenterOfMassTransform(worldTrans);
}
-
+ */
/*
scaling?
if (m_bDyna)
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index 6ed21506372..4accd4bc2f1 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -45,6 +45,7 @@ class KX_Camera : public KX_GameObject
{
Py_Header;
protected:
+ friend class KX_Scene;
/** Camera parameters (clips distances, focal lenght). These
* params are closely tied to Blender. In the gameengine, only the
* projection and modelview matrices are relevant. There's a
@@ -67,6 +68,7 @@ protected:
* Storage for the projection matrix that is passed to the
* rasterizer. */
MT_Matrix4x4 m_projection_matrix;
+ //MT_Matrix4x4 m_projection_matrix1;
/**
* Storage for the modelview matrix that is passed to the
@@ -119,6 +121,16 @@ protected:
* Extracts the bound sphere of the view frustum.
*/
void ExtractFrustumSphere();
+ /**
+ * return the clip plane
+ */
+ MT_Vector4 *GetNormalizedClipPlanes()
+ {
+ ExtractClipPlanes();
+ NormalizeClipPlanes();
+ return m_planes;
+ }
+
public:
enum { INSIDE, INTERSECT, OUTSIDE } ;
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 7f99a565769..339a955702a 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -55,6 +55,7 @@ typedef unsigned long uint_ptr;
#include <stdio.h> // printf
#include "SG_Controller.h"
#include "KX_IPhysicsController.h"
+#include "PHY_IGraphicController.h"
#include "SG_Node.h"
#include "SG_Controller.h"
#include "KX_ClientObjectInfo.h"
@@ -91,6 +92,7 @@ KX_GameObject::KX_GameObject(
m_bVisible(true),
m_bCulled(true),
m_pPhysicsController1(NULL),
+ m_pGraphicController(NULL),
m_pPhysicsEnvironment(NULL),
m_xray(false),
m_pHitObject(NULL),
@@ -132,6 +134,10 @@ KX_GameObject::~KX_GameObject()
}
m_pSGNode->SetSGClientObject(NULL);
}
+ if (m_pGraphicController)
+ {
+ delete m_pGraphicController;
+ }
}
@@ -249,7 +255,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
NodeSetLocalScale(scale1);
NodeSetLocalPosition(MT_Point3(newpos[0],newpos[1],newpos[2]));
NodeSetLocalOrientation(invori*NodeGetWorldOrientation());
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
// object will now be a child, it must be removed from the parent list
CListValue* rootlist = scene->GetRootParentList();
if (rootlist->RemoveValue(this))
@@ -269,6 +275,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
rootobj->m_pPhysicsController1->AddCompoundChild(m_pPhysicsController1);
}
}
+ // graphically, the object hasn't change place, no need to update m_pGraphicController
}
}
@@ -286,7 +293,7 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
// Remove us from our parent
GetSGNode()->DisconnectFromParent();
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
// the object is now a root object, add it to the parentlist
CListValue* rootlist = scene->GetRootParentList();
if (!rootlist->SearchValue(this))
@@ -303,12 +310,14 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
}
m_pPhysicsController1->RestoreDynamics();
}
+ // graphically, the object hasn't change place, no need to update m_pGraphicController
}
}
void KX_GameObject::ProcessReplica(KX_GameObject* replica)
{
replica->m_pPhysicsController1 = NULL;
+ replica->m_pGraphicController = NULL;
replica->m_pSGNode = NULL;
replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
replica->m_pClient_info->m_gameobject = replica;
@@ -437,22 +446,18 @@ void KX_GameObject::RemoveMeshes()
m_meshes.clear();
}
-
-
-void KX_GameObject::UpdateNonDynas()
+void KX_GameObject::UpdateTransform()
{
if (m_pPhysicsController1)
- {
+ // only update the transform of static object, dynamic object are handled differently
+ // note that for bullet, this does not even update the transform of static object
+ // but merely sets there collision flag to "kinematic" because the synchronization is
+ // done differently during physics simulation
m_pPhysicsController1->SetSumoTransform(true);
- }
-}
+ if (m_pGraphicController)
+ // update the culling tree
+ m_pGraphicController->SetGraphicTransform();
-
-
-void KX_GameObject::UpdateTransform()
-{
- if (m_pPhysicsController1)
- m_pPhysicsController1->SetSumoTransform(false);
}
void KX_GameObject::UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene)
@@ -832,6 +837,7 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
}
GetSGNode()->SetLocalPosition(trans);
+
}
@@ -911,7 +917,7 @@ void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans)
}
-void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
+void KX_GameObject::NodeUpdateGS(double time)
{
if (GetSGNode())
GetSGNode()->UpdateWorldData(time);
@@ -1295,7 +1301,7 @@ int KX_GameObject::pyattr_set_position(void *self_v, const KX_PYATTRIBUTE_DEF *a
return 1;
self->NodeSetLocalPosition(pos);
- self->NodeUpdateGS(0.f,true);
+ self->NodeUpdateGS(0.f);
return 0;
}
@@ -1319,10 +1325,10 @@ int KX_GameObject::pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF
if (PyMatTo(value, rot))
{
self->NodeSetLocalOrientation(rot);
- self->NodeUpdateGS(0.f,true);
+ self->NodeUpdateGS(0.f);
return 0;
}
- return 1;
+ PyErr_Clear();
if (PySequence_Size(value) == 4)
{
@@ -1331,7 +1337,7 @@ int KX_GameObject::pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF
{
rot.setRotation(qrot);
self->NodeSetLocalOrientation(rot);
- self->NodeUpdateGS(0.f,true);
+ self->NodeUpdateGS(0.f);
return 0;
}
return 1;
@@ -1344,7 +1350,7 @@ int KX_GameObject::pyattr_set_orientation(void *self_v, const KX_PYATTRIBUTE_DEF
{
rot.setEuler(erot);
self->NodeSetLocalOrientation(rot);
- self->NodeUpdateGS(0.f,true);
+ self->NodeUpdateGS(0.f);
return 0;
}
return 1;
@@ -1368,7 +1374,7 @@ int KX_GameObject::pyattr_set_scaling(void *self_v, const KX_PYATTRIBUTE_DEF *at
return 1;
self->NodeSetLocalScale(scale);
- self->NodeUpdateGS(0.f,true);
+ self->NodeUpdateGS(0.f);
return 0;
}
@@ -1929,7 +1935,7 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self, PyObject* value)
if (PyObject_IsMT_Matrix(value, 3) && PyMatTo(value, matrix))
{
NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
@@ -1938,7 +1944,7 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self, PyObject* value)
{
matrix.setRotation(quat);
NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
return NULL;
@@ -1959,7 +1965,7 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, PyObject* args)
if (fac> 1.0) fac= 1.0;
AlignAxisToVect(vect,axis,fac);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
}
@@ -1983,7 +1989,7 @@ PyObject* KX_GameObject::PySetPosition(PyObject* self, PyObject* value)
if (PyVecTo(value, pos))
{
NodeSetLocalPosition(pos);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
@@ -1996,7 +2002,7 @@ PyObject* KX_GameObject::PySetWorldPosition(PyObject* self, PyObject* value)
if (PyVecTo(value, pos))
{
NodeSetWorldPosition(pos);
- NodeUpdateGS(0.f,true);
+ NodeUpdateGS(0.f);
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index bc6b60102d6..9c7dda5e394 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -57,6 +57,7 @@ struct KX_ClientObjectInfo;
class KX_RayCast;
class RAS_MeshObject;
class KX_IPhysicsController;
+class PHY_IGraphicController;
class PHY_IPhysicsEnvironment;
struct Object;
@@ -88,6 +89,7 @@ protected:
bool m_bCulled;
KX_IPhysicsController* m_pPhysicsController1;
+ PHY_IGraphicController* m_pGraphicController;
// used for ray casting
PHY_IPhysicsEnvironment* m_pPhysicsEnvironment;
STR_String m_testPropName;
@@ -351,6 +353,19 @@ public:
}
/**
+ * @return a pointer to the graphic controller owner by this class
+ */
+ PHY_IGraphicController* GetGraphicController()
+ {
+ return m_pGraphicController;
+ }
+
+ void SetGraphicController(PHY_IGraphicController* graphiccontroller)
+ {
+ m_pGraphicController = graphiccontroller;
+ }
+
+ /**
* @section Coordinate system manipulation functions
*/
@@ -367,8 +382,7 @@ public:
void
NodeUpdateGS(
- double time,
- bool bInitiator
+ double time
);
const
@@ -525,13 +539,6 @@ public:
static void UpdateTransformFunc(SG_IObject* node, void* gameobj, void* scene);
/**
- * Only update the transform if it's a non-dynamic object
- */
- void
- UpdateNonDynas(
- );
-
- /**
* Function to set IPO option at start of IPO
*/
void
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 97b4213b8bd..70ae0e4b937 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -412,7 +412,7 @@ else
// Compute the number of logic frames to do each update (fixed tic bricks)
- int frames =int(deltatime*m_ticrate);
+ int frames =int(deltatime*m_ticrate+1e-6);
// if (frames>1)
// printf("****************************************");
// printf("dt = %f, deltatime = %f, frames = %d\n",dt, deltatime,frames);
@@ -465,12 +465,15 @@ else
m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_NETWORK);
scene->GetNetworkScene()->proceed(m_frameTime);
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- scene->UpdateParents(m_frameTime);
+ //m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ //SG_SetActiveStage(SG_STAGE_NETWORK_UPDATE);
+ //scene->UpdateParents(m_frameTime);
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS1);
// set Python hooks for each scene
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
KX_SetActiveScene(scene);
@@ -479,31 +482,37 @@ else
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- scene->UpdateParents(m_frameTime);
+ //m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ //SG_SetActiveStage(SG_STAGE_PHYSICS1_UPDATE);
+ //scene->UpdateParents(m_frameTime);
// Process sensors, and controllers
m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_CONTROLLER);
scene->LogicBeginFrame(m_frameTime);
// Scenegraph needs to be updated again, because Logic Controllers
// can affect the local matrices.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_CONTROLLER_UPDATE);
scene->UpdateParents(m_frameTime);
// Process actuators
// Do some cleanup work for this logic frame
m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ACTUATOR);
scene->LogicUpdateFrame(m_frameTime, true);
scene->LogicEndFrame();
// Actuators can affect the scenegraph
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
scene->UpdateParents(m_frameTime);
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS2);
scene->GetPhysicsEnvironment()->beginFrame();
// Perform physics calculations on the scene. This can involve
@@ -511,6 +520,7 @@ else
scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,1.0/m_ticrate);//m_deltatimerealDeltaTime);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS2_UPDATE);
scene->UpdateParents(m_frameTime);
@@ -574,6 +584,7 @@ else
KX_SetActiveScene(scene);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS1);
scene->UpdateParents(m_clockTime);
// Perform physics calculations on the scene. This can involve
@@ -583,6 +594,7 @@ else
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_PHYSICS2);
scene->UpdateParents(m_clockTime);
// Do some cleanup work for this logic frame
@@ -591,6 +603,7 @@ else
// Actuators can affect the scenegraph
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ACTUATOR);
scene->UpdateParents(m_clockTime);
scene->setSuspendedTime(0.0);
@@ -622,6 +635,7 @@ void KX_KetsjiEngine::Render()
const RAS_FrameSettings &framesettings = firstscene->GetFramingType();
m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_RENDER);
// hiding mouse cursor each frame
// (came back when going out of focus and then back in again)
@@ -1102,14 +1116,22 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
cam->GetCameraLocation(), cam->GetCameraOrientation());
cam->SetModelviewMatrix(viewmat);
- scene->UpdateMeshTransformations();
+ //redundant, already done in
+ //scene->UpdateMeshTransformations();
// The following actually reschedules all vertices to be
// redrawn. There is a cache between the actual rescheduling
// and this call though. Visibility is imparted when this call
// runs through the individual objects.
+
+ m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_CULLING);
+
scene->CalculateVisibleMeshes(m_rasterizer,cam);
+ m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_RENDER);
+
scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
if (scene->GetPhysicsEnvironment())
@@ -1166,15 +1188,17 @@ void KX_KetsjiEngine::AddScene(KX_Scene* scene)
void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
{
bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName));
-
- // if there is no activecamera, or the camera is being
- // overridden we need to construct a temporarily camera
+
+ SG_SetActiveStage(SG_STAGE_SCENE);
+
+ // if there is no activecamera, or the camera is being
+ // overridden we need to construct a temporarily camera
if (!scene->GetActiveCamera() || override_camera)
{
KX_Camera* activecam = NULL;
RAS_CameraData camdata = RAS_CameraData();
- activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata, false);
+ activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata);
activecam->SetName("__default__cam__");
// set transformation
@@ -1186,11 +1210,11 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
activecam->NodeSetLocalPosition(camtrans.getOrigin());
activecam->NodeSetLocalOrientation(camtrans.getBasis());
- activecam->NodeUpdateGS(0,true);
+ activecam->NodeUpdateGS(0);
} else {
activecam->NodeSetLocalPosition(MT_Point3(0.0, 0.0, 0.0));
activecam->NodeSetLocalOrientation(MT_Vector3(0.0, 0.0, 0.0));
- activecam->NodeUpdateGS(0,true);
+ activecam->NodeUpdateGS(0);
}
scene->AddCamera(activecam);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 7b5b77ccacf..f996f86d751 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -159,7 +159,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T
cam->NodeSetLocalPosition(camtrans.getOrigin());
cam->NodeSetLocalOrientation(camtrans.getBasis());
- cam->NodeUpdateGS(0,true);
+ cam->NodeUpdateGS(0);
/* setup rasterizer transformations */
ras->SetProjectionMatrix(projectionmat);
diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp
index 15f100af915..00d9a32eb38 100644
--- a/source/gameengine/Ketsji/KX_MotionState.cpp
+++ b/source/gameengine/Ketsji/KX_MotionState.cpp
@@ -44,7 +44,7 @@ KX_MotionState::~KX_MotionState()
void KX_MotionState::getWorldPosition(float& posX,float& posY,float& posZ)
{
- MT_Point3 pos = m_node->GetWorldPosition();
+ const MT_Point3& pos = m_node->GetWorldPosition();
posX = pos[0];
posY = pos[1];
posZ = pos[2];
@@ -52,7 +52,7 @@ void KX_MotionState::getWorldPosition(float& posX,float& posY,float& posZ)
void KX_MotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
{
- MT_Vector3 scale = m_node->GetWorldScaling();
+ const MT_Vector3& scale = m_node->GetWorldScaling();
scaleX = scale[0];
scaleY = scale[1];
scaleZ = scale[2];
@@ -60,17 +60,23 @@ void KX_MotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
void KX_MotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)
{
- MT_Quaternion orn = m_node->GetWorldOrientation().getRotation();
+ MT_Quaternion& orn = m_node->GetWorldOrientation().getRotation();
quatIma0 = orn[0];
quatIma1 = orn[1];
quatIma2 = orn[2];
quatReal = orn[3];
}
+void KX_MotionState::getWorldOrientation(float* ori)
+{
+ const MT_Matrix3x3& mat = m_node->GetWorldOrientation();
+ mat.getValue(ori);
+}
+
void KX_MotionState::setWorldPosition(float posX,float posY,float posZ)
{
m_node->SetLocalPosition(MT_Point3(posX,posY,posZ));
- m_node->SetWorldPosition(MT_Point3(posX,posY,posZ));
+ //m_node->SetWorldPosition(MT_Point3(posX,posY,posZ));
}
void KX_MotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
@@ -82,13 +88,15 @@ void KX_MotionState::setWorldOrientation(float quatIma0,float quatIma1,float qua
orn[3] = quatReal;
m_node->SetLocalOrientation(orn);
- m_node->SetWorldOrientation(orn);
+ //m_node->SetWorldOrientation(orn);
}
void KX_MotionState::calculateWorldTransformations()
{
- m_node->ComputeWorldTransforms(NULL);
+ //Not needed, will be done in KX_Scene::UpdateParents() after the physics simulation
+ //bool parentUpdated = false;
+ //m_node->ComputeWorldTransforms(NULL, parentUpdated);
}
diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h
index c83af664817..7ba3ca2f85c 100644
--- a/source/gameengine/Ketsji/KX_MotionState.h
+++ b/source/gameengine/Ketsji/KX_MotionState.h
@@ -44,6 +44,7 @@ public:
virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal);
virtual void setWorldPosition(float posX,float posY,float posZ);
virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal);
+ virtual void getWorldOrientation(float* ori);
virtual void calculateWorldTransformations();
};
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index cd753210184..b9d1939e5db 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -127,13 +127,10 @@ CValue* KX_NearSensor::GetReplica()
}
}
- //static_cast<KX_TouchEventManager*>(m_eventmgr)->RegisterSensor(this);
- //todo: make sure replication works fine
- //>m_sumoObj = new SM_Object(DT_NewSphere(0.0),NULL,NULL,NULL);
- //replica->m_sumoObj->setMargin(m_Margin);
- //replica->m_sumoObj->setClientObject(replica->m_client_info);
-
- ((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
+ //Wrong: the parent object could be a child, this code works only if it is a root parent.
+ //Anyway, at this stage, the parent object is already synchronized, nothing to do.
+ //bool parentUpdated = false;
+ //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL, parentUpdated);
replica->SynchronizeTransform();
return replica;
@@ -154,8 +151,10 @@ void KX_NearSensor::ReParent(SCA_IObject* parent)
client_info->m_sensors.push_back(this);
SCA_ISensor::ReParent(parent);
*/
- ((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
- SynchronizeTransform();
+ //Not needed, was done in GetReplica() already
+ //bool parentUpdated = false;
+ //((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
+ //SynchronizeTransform();
SCA_ISensor::ReParent(parent);
}
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 355ac89a926..b9abe69633e 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -100,8 +100,9 @@ CValue* KX_RadarSensor::GetReplica()
//>m_sumoObj = new SM_Object(DT_NewCone(m_coneradius, m_coneheight),NULL,NULL,NULL);
//replica->m_sumoObj->setMargin(m_Margin);
//replica->m_sumoObj->setClientObject(replica->m_client_info);
-
- ((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
+ //Wrong: see KX_TouchSensor
+ //bool parentUpdated = false;
+ //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
replica->SynchronizeTransform();
return replica;
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
index 151270cbd68..0e7571031e8 100644
--- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
+++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
@@ -57,7 +57,8 @@ New(Bone* bone
KX_BoneParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
@@ -67,6 +68,8 @@ UpdateChildCoordinates(
const MT_Vector3 & child_scale = child->GetLocalScale();
const MT_Point3 & child_pos = child->GetLocalPosition();
const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
+ // we don't know if the armature has been updated or not, assume yes
+ parentUpdated = true;
// the childs world locations which we will update.
@@ -122,7 +125,7 @@ UpdateChildCoordinates(
else {
child->SetWorldFromLocalTransform();
}
-
+ child->SetModified(false);
return valid_parent_transform;
}
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
index 2a19d8a1784..c9baf228855 100644
--- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
+++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h
@@ -82,7 +82,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
index 0729ec8a902..87ff3b53911 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
@@ -51,13 +51,20 @@ New(
KX_NormalParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
+ if (!parentUpdated && !child->IsModified())
+ return false;
+
+ parentUpdated = true;
+
if (parent==NULL) { /* Simple case */
child->SetWorldFromLocalTransform();
- return false;
+ child->SetModified(false);
+ return true; //false;
}
else {
// the childs world locations which we will update.
@@ -68,6 +75,7 @@ UpdateChildCoordinates(
child->SetWorldScale(p_world_scale * child->GetLocalScale());
child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
+ child->SetModified(false);
return true;
}
}
@@ -112,10 +120,15 @@ New(
KX_VertexParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
+
+ if (!parentUpdated && !child->IsModified())
+ return false;
+
child->SetWorldScale(child->GetLocalScale());
if (parent)
@@ -124,7 +137,8 @@ UpdateChildCoordinates(
child->SetWorldPosition(child->GetLocalPosition());
child->SetWorldOrientation(child->GetLocalOrientation());
- return parent != NULL;
+ child->SetModified(false);
+ return true; //parent != NULL;
}
/**
@@ -172,10 +186,14 @@ New(
KX_SlowParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
){
MT_assert(child != NULL);
+ // the child will move even if the parent is not
+ parentUpdated = true;
+
const MT_Vector3 & child_scale = child->GetLocalScale();
const MT_Point3 & child_pos = child->GetLocalPosition();
const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
@@ -252,8 +270,9 @@ UpdateChildCoordinates(
child->SetWorldScale(child_w_scale);
child->SetWorldPosition(child_w_pos);
child->SetWorldOrientation(child_w_rotation);
+ child->SetModified(false);
- return parent != NULL;
+ return true; //parent != NULL;
}
/**
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
index faa650106c8..d8fb9211f21 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h
@@ -71,7 +71,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
@@ -115,7 +116,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
@@ -166,7 +168,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
);
/**
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 04d6bd75f92..7eed1cc387b 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -76,7 +76,9 @@
#include "NG_NetworkScene.h"
#include "PHY_IPhysicsEnvironment.h"
#include "KX_IPhysicsController.h"
+#include "PHY_IGraphicController.h"
#include "KX_BlenderSceneConverter.h"
+#include "KX_MotionState.h"
#include "BL_ShapeDeformer.h"
#include "BL_DeformableGameObject.h"
@@ -133,6 +135,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_suspendedtime = 0.0;
m_suspendeddelta = 0.0;
+ m_dbvt_culling = false;
m_activity_culling = false;
m_suspend = false;
m_isclearingZbuffer = true;
@@ -407,6 +410,13 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam
// will in any case be deleted. This ensures that the object will not try to use the node
// when it is finally deleted (see KX_GameObject destructor)
orgobj->SetSGNode(NULL);
+ PHY_IGraphicController* ctrl = orgobj->GetGraphicController();
+ if (ctrl)
+ {
+ // a graphic controller is set, we must delete it as the node will be deleted
+ delete ctrl;
+ orgobj->SetGraphicController(NULL);
+ }
}
if (node)
delete node;
@@ -485,7 +495,14 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
replicanode->AddSGController(replicacontroller);
}
}
-
+ // replicate graphic controller
+ if (orgobj->GetGraphicController())
+ {
+ PHY_IMotionState* motionstate = new KX_MotionState(newobj->GetSGNode());
+ PHY_IGraphicController* newctrl = orgobj->GetGraphicController()->GetReplica(motionstate);
+ newctrl->setNewClientInfo(newobj->getClientInfo());
+ newobj->SetGraphicController(newctrl);
+ }
return newobj;
}
@@ -792,6 +809,24 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->AddChild(childreplicanode);
}
+ // At this stage all the objects in the hierarchy have been duplicated,
+ // we can update the scenegraph, we need it for the duplication of logic
+ MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
+ replica->NodeSetLocalPosition(newpos);
+
+ MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+
+ // get the rootnode's scale
+ MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
+
+ // set the replica's relative scale with the rootnode's scale
+ replica->NodeSetRelativeScale(newscale);
+
+ replica->GetSGNode()->UpdateWorldData(0);
+ replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
+ replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
+
// now replicate logic
vector<KX_GameObject*>::iterator git;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
@@ -814,21 +849,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
ReplicateLogic((*git));
}
- MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
- replica->NodeSetLocalPosition(newpos);
-
- MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
- replica->NodeSetLocalOrientation(newori);
-
- // get the rootnode's scale
- MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
-
- // set the replica's relative scale with the rootnode's scale
- replica->NodeSetRelativeScale(newscale);
-
- replica->GetSGNode()->UpdateWorldData(0);
- replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
- replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
// check if there are objects with dupligroup in the hierarchy
vector<KX_GameObject*> duplilist;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
@@ -1163,7 +1183,6 @@ void KX_Scene::UpdateMeshTransformations()
{
KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i);
gameobj->GetOpenGLMatrix();
-// gameobj->UpdateNonDynas();
}
}
@@ -1298,21 +1317,46 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
}
}
+void KX_Scene::PhysicsCullingCallback(KX_ClientObjectInfo* objectInfo, void* cullingInfo)
+{
+ KX_GameObject* gameobj = objectInfo->m_gameobject;
+ if (!gameobj->GetVisible())
+ // ideally, invisible objects should be removed from the culling tree temporarily
+ return;
+ if(((CullingInfo*)cullingInfo)->m_layer && !(gameobj->GetLayer() & ((CullingInfo*)cullingInfo)->m_layer))
+ // used for shadow: object is not in shadow layer
+ return;
+
+ // make object visible
+ gameobj->SetCulled(false);
+ gameobj->UpdateBuckets(false);
+}
+
void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer)
{
-// FIXME: When tree is operational
-#if 1
- // do this incrementally in the future
- for (int i = 0; i < m_objectlist->GetCount(); i++)
+ bool dbvt_culling = false;
+ if (m_dbvt_culling)
{
- MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
+ // test culling through Bullet
+ PHY__Vector4 planes[5];
+ // get the clip planes
+ MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
+ // and convert
+ planes[0].setValue(cplanes[0].getValue());
+ planes[1].setValue(cplanes[1].getValue());
+ planes[2].setValue(cplanes[2].getValue());
+ planes[3].setValue(cplanes[3].getValue());
+ planes[4].setValue(cplanes[5].getValue());
+ CullingInfo info(layer);
+ dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5);
+ }
+ if (!dbvt_culling) {
+ // the physics engine couldn't help us, do it the hard way
+ for (int i = 0; i < m_objectlist->GetCount(); i++)
+ {
+ MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
+ }
}
-#else
- if (cam->GetFrustumCulling())
- MarkVisible(m_objecttree, rasty, cam, layer);
- else
- MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer);
-#endif
}
// logic stuff
@@ -1393,7 +1437,7 @@ void KX_Scene::UpdateParents(double curtime)
for (int i=0; i<GetRootParentList()->GetCount(); i++)
{
KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i);
- parentobj->NodeUpdateGS(curtime,true);
+ parentobj->NodeUpdateGS(curtime);
}
}
@@ -1588,6 +1632,7 @@ PyAttributeDef KX_Scene::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend),
KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling),
KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius),
+ KX_PYATTRIBUTE_BOOL_RO("dbvt_culling", KX_Scene, m_dbvt_culling),
KX_PYATTRIBUTE_RO_FUNCTION("__dict__", KX_Scene, pyattr_get_dir_dict),
{ NULL } //Sentinel
};
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index df51fcec8f7..9f05ddf70c2 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -85,6 +85,8 @@ class RAS_IRenderTools;
class SCA_JoystickManager;
class btCollisionShape;
class KX_BlenderSceneConverter;
+struct KX_ClientObjectInfo;
+
/**
* The KX_Scene holds all data for an independent scene. It relates
* KX_Objects to the specific objects in the modules.
@@ -92,6 +94,12 @@ class KX_BlenderSceneConverter;
class KX_Scene : public PyObjectPlus, public SCA_IScene
{
Py_Header;
+
+ struct CullingInfo {
+ int m_layer;
+ CullingInfo(int layer) : m_layer(layer) {}
+ };
+
protected:
RAS_BucketManager* m_bucketmanager;
CListValue* m_tempObjectList;
@@ -252,6 +260,11 @@ protected:
bool m_activity_culling;
/**
+ * Toggle to enable or disable culling via DBVT broadphase of Bullet.
+ */
+ bool m_dbvt_culling;
+
+ /**
* The framing settings used by this scene
*/
@@ -269,6 +282,7 @@ protected:
void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam,int layer=0);
void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam,int layer=0);
void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam, int layer=0);
+ static void PhysicsCullingCallback(KX_ClientObjectInfo* objectInfo, void* cullingInfo);
double m_suspendedtime;
double m_suspendeddelta;
@@ -530,6 +544,9 @@ public:
bool IsSuspended();
bool IsClearingZBuffer();
void EnableZBufferClearing(bool isclearingZbuffer);
+ // use of DBVT tree for camera culling
+ void SetDbvtCameraCulling(bool b) { m_dbvt_culling = b; };
+ bool GetDbvtCameraCulling() { return m_dbvt_culling; };
void SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter);
diff --git a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
index dcc87d614c0..e4aaef1803d 100644
--- a/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
+++ b/source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
@@ -55,6 +55,7 @@ public:
virtual void removeConstraint(void * constraintid);
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
+ virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes) { return false; }
//gamelogic callbacks
diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
new file mode 100644
index 00000000000..caf18fd28ba
--- /dev/null
+++ b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
@@ -0,0 +1,112 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "CcdPhysicsEnvironment.h"
+#include "CcdGraphicController.h"
+#include "btBulletDynamicsCommon.h"
+#include "MT_Point3.h"
+
+
+CcdGraphicController::CcdGraphicController (CcdPhysicsEnvironment* phyEnv, PHY_IMotionState* motionState) :
+ m_localAabbMin(0.f, 0.f, 0.f),
+ m_localAabbMax(0.f, 0.f, 0.f),
+ m_motionState(motionState),
+ m_phyEnv(phyEnv),
+ m_handle(NULL),
+ m_newClientInfo(NULL)
+{
+}
+
+CcdGraphicController::~CcdGraphicController()
+{
+ if (m_phyEnv)
+ m_phyEnv->removeCcdGraphicController(this);
+
+ if (m_motionState)
+ delete m_motionState;
+}
+
+void CcdGraphicController::setLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ m_localAabbMin = aabbMin;
+ m_localAabbMax = aabbMax;
+ SetGraphicTransform();
+}
+
+void CcdGraphicController::setLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax)
+{
+ m_localAabbMin = btVector3(aabbMin[0],aabbMin[1],aabbMin[2]);
+ m_localAabbMax = btVector3(aabbMax[0],aabbMax[1],aabbMax[2]);
+ SetGraphicTransform();
+}
+
+
+void CcdGraphicController::getAabb(btVector3& aabbMin, btVector3& aabbMax)
+{
+ btVector3 pos;
+ btVector3 scale;
+ float ori[12];
+ m_motionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]);
+ m_motionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]);
+ m_motionState->getWorldOrientation(ori);
+ btMatrix3x3 rot(ori[0], ori[4], ori[8],
+ ori[1], ori[5], ori[9],
+ ori[2], ori[6], ori[10]);
+
+ btVector3 localAabbMin = m_localAabbMin;
+ btVector3 localAabbMax = m_localAabbMax;
+ btVector3 tmpAabbMin = m_localAabbMin * scale;
+ btVector3 tmpAabbMax = m_localAabbMax * scale;
+
+ localAabbMin[0] = (scale.getX() >= 0.) ? tmpAabbMin[0] : tmpAabbMax[0];
+ localAabbMin[1] = (scale.getY() >= 0.) ? tmpAabbMin[1] : tmpAabbMax[1];
+ localAabbMin[2] = (scale.getZ() >= 0.) ? tmpAabbMin[2] : tmpAabbMax[2];
+ localAabbMax[0] = (scale.getX() <= 0.) ? tmpAabbMin[0] : tmpAabbMax[0];
+ localAabbMax[1] = (scale.getY() <= 0.) ? tmpAabbMin[1] : tmpAabbMax[1];
+ localAabbMax[2] = (scale.getZ() <= 0.) ? tmpAabbMin[2] : tmpAabbMax[2];
+
+ btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
+ btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
+
+ btMatrix3x3 abs_b = rot.absolute();
+ btVector3 center = rot*localCenter + pos;
+ btVector3 extent = abs_b*localHalfExtents;
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+}
+
+bool CcdGraphicController::SetGraphicTransform()
+{
+ if (!m_handle)
+ return false;
+ btVector3 aabbMin;
+ btVector3 aabbMax;
+ getAabb(aabbMin, aabbMax);
+ // update Aabb in broadphase
+ m_phyEnv->getCullingTree()->setAabb(m_handle,aabbMin,aabbMax,NULL);
+ return true;
+}
+
+PHY_IGraphicController* CcdGraphicController::GetReplica(class PHY_IMotionState* motionState)
+{
+ CcdGraphicController* replica = new CcdGraphicController(*this);
+ replica->m_motionState = motionState;
+ replica->m_newClientInfo = NULL;
+ replica->m_handle = NULL;
+ m_phyEnv->addCcdGraphicController(replica);
+ return replica;
+}
+
+
diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h
new file mode 100644
index 00000000000..8faa0944313
--- /dev/null
+++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h
@@ -0,0 +1,74 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef BULLET2_GRAPHICCONTROLLER_H
+#define BULLET2_GRAPHICCONTROLLER_H
+
+#include "PHY_IGraphicController.h"
+
+#include "btBulletDynamicsCommon.h"
+#include "LinearMath/btTransform.h"
+
+#include "PHY_IMotionState.h"
+#include "MT_Point3.h"
+
+class CcdPhysicsEnvironment;
+class btCollisionObject;
+
+///CcdGraphicController is a graphic object that supports view frustrum culling and occlusion
+class CcdGraphicController : public PHY_IGraphicController
+{
+public:
+ CcdGraphicController(CcdPhysicsEnvironment* phyEnv, PHY_IMotionState* motionState);
+
+ virtual ~CcdGraphicController();
+
+ void setLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax);
+ void setLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax);
+
+ PHY_IMotionState* GetMotionState() { return m_motionState; }
+ void getAabb(btVector3& aabbMin, btVector3& aabbMax);
+
+ virtual void setBroadphaseHandle(btBroadphaseProxy* handle) { m_handle = handle; }
+ virtual btBroadphaseProxy* getBroadphaseHandle() { return m_handle; }
+
+ ////////////////////////////////////
+ // PHY_IGraphicController interface
+ ////////////////////////////////////
+
+ /**
+ * Updates the Aabb based on the motion state
+ */
+ virtual bool SetGraphicTransform();
+
+ // client info for culling
+ virtual void* getNewClientInfo() { return m_newClientInfo; }
+ virtual void setNewClientInfo(void* clientinfo) { m_newClientInfo = clientinfo; }
+ virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate);
+
+private:
+ // unscaled aabb corner
+ btVector3 m_localAabbMin;
+ btVector3 m_localAabbMax;
+
+ PHY_IMotionState* m_motionState;
+ CcdPhysicsEnvironment* m_phyEnv;
+ btBroadphaseProxy* m_handle;
+ void* m_newClientInfo;
+
+};
+
+#endif //BULLET2_PHYSICSCONTROLLER_H
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index bb2f53a1988..2283968801f 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -1245,6 +1245,22 @@ void DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,flo
quatReal = m_worldTransform.getRotation()[3];
}
+void DefaultMotionState::getWorldOrientation(float* ori)
+{
+ *ori++ = m_worldTransform.getBasis()[0].x();
+ *ori++ = m_worldTransform.getBasis()[1].x();
+ *ori++ = m_worldTransform.getBasis()[1].x();
+ *ori++ = 0.f;
+ *ori++ = m_worldTransform.getBasis()[0].y();
+ *ori++ = m_worldTransform.getBasis()[1].y();
+ *ori++ = m_worldTransform.getBasis()[1].y();
+ *ori++ = 0.f;
+ *ori++ = m_worldTransform.getBasis()[0].z();
+ *ori++ = m_worldTransform.getBasis()[1].z();
+ *ori++ = m_worldTransform.getBasis()[1].z();
+ *ori++ = 0.f;
+}
+
void DefaultMotionState::setWorldPosition(float posX,float posY,float posZ)
{
btVector3 pos(posX,posY,posZ);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 510454a7b63..245cde2baaa 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -544,6 +544,7 @@ class DefaultMotionState : public PHY_IMotionState
virtual void setWorldPosition(float posX,float posY,float posZ);
virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal);
+ virtual void getWorldOrientation(float* ori);
virtual void calculateWorldTransformations();
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index dd21e58bd68..cef2f2477b7 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -18,6 +18,7 @@ subject to the following restrictions:
#include "CcdPhysicsEnvironment.h"
#include "CcdPhysicsController.h"
+#include "CcdGraphicController.h"
#include <algorithm>
#include "btBulletDynamicsCommon.h"
@@ -316,8 +317,10 @@ static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVec
-CcdPhysicsEnvironment::CcdPhysicsEnvironment(btDispatcher* dispatcher,btOverlappingPairCache* pairCache)
-:m_numIterations(10),
+CcdPhysicsEnvironment::CcdPhysicsEnvironment(bool useDbvtCulling,btDispatcher* dispatcher,btOverlappingPairCache* pairCache)
+:m_cullingCache(NULL),
+m_cullingTree(NULL),
+m_numIterations(10),
m_scalingPropagated(false),
m_numTimeSubSteps(1),
m_ccdMode(0),
@@ -350,6 +353,11 @@ m_ownDispatcher(NULL)
//m_broadphase = new btAxisSweep3(btVector3(-1000,-1000,-1000),btVector3(1000,1000,1000));
//m_broadphase = new btSimpleBroadphase();
m_broadphase = new btDbvtBroadphase();
+ // avoid any collision in the culling tree
+ if (useDbvtCulling) {
+ m_cullingCache = new btNullPairCache();
+ m_cullingTree = new btDbvtBroadphase(m_cullingCache);
+ }
m_filterCallback = new CcdOverlapFilterCallBack(this);
m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback);
@@ -364,7 +372,6 @@ m_ownDispatcher(NULL)
m_gravity = btVector3(0.f,-10.f,0.f);
m_dynamicsWorld->setGravity(m_gravity);
-
}
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
@@ -558,6 +565,41 @@ void CcdPhysicsEnvironment::refreshCcdPhysicsController(CcdPhysicsController* ct
}
}
+void CcdPhysicsEnvironment::addCcdGraphicController(CcdGraphicController* ctrl)
+{
+ if (m_cullingTree)
+ {
+ btVector3 minAabb;
+ btVector3 maxAabb;
+ ctrl->getAabb(minAabb, maxAabb);
+
+ ctrl->setBroadphaseHandle(m_cullingTree->createProxy(
+ minAabb,
+ maxAabb,
+ INVALID_SHAPE_PROXYTYPE, // this parameter is not used
+ ctrl,
+ 0, // this object does not collision with anything
+ 0,
+ NULL, // dispatcher => this parameter is not used
+ 0));
+
+ assert(ctrl->getBroadphaseHandle());
+ }
+}
+
+void CcdPhysicsEnvironment::removeCcdGraphicController(CcdGraphicController* ctrl)
+{
+ if (m_cullingTree)
+ {
+ btBroadphaseProxy* bp = ctrl->getBroadphaseHandle();
+ if (bp)
+ {
+ m_cullingTree->destroyProxy(bp,NULL);
+ ctrl->setBroadphaseHandle(0);
+ }
+ }
+}
+
void CcdPhysicsEnvironment::beginFrame()
{
@@ -593,10 +635,10 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
(*it)->SynchronizeMotionStates(timeStep);
}
- for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
- {
- (*it)->SynchronizeMotionStates(timeStep);
- }
+ //for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
+ //{
+ // (*it)->SynchronizeMotionStates(timeStep);
+ //}
for (i=0;i<m_wrapperVehicles.size();i++)
{
@@ -1146,6 +1188,50 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
return result.m_controller;
}
+struct DbvtCullingCallback : btDbvt::ICollide
+{
+ PHY_CullingCallback m_clientCallback;
+ void* m_userData;
+
+ DbvtCullingCallback(PHY_CullingCallback clientCallback, void* userData)
+ {
+ m_clientCallback = clientCallback;
+ m_userData = userData;
+ }
+
+ void Process(const btDbvtNode* node,btScalar depth)
+ {
+ Process(node);
+ }
+ void Process(const btDbvtNode* leaf)
+ {
+ btBroadphaseProxy* proxy=(btBroadphaseProxy*)leaf->data;
+ // the client object is a graphic controller
+ CcdGraphicController* ctrl = static_cast<CcdGraphicController*>(proxy->m_clientObject);
+ KX_ClientObjectInfo* info = (KX_ClientObjectInfo*)ctrl->getNewClientInfo();
+ if (info)
+ (*m_clientCallback)(info, m_userData);
+ }
+};
+
+bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes)
+{
+ if (!m_cullingTree)
+ return false;
+ DbvtCullingCallback dispatcher(callback, userData);
+ btVector3 planes_n[5];
+ btScalar planes_o[5];
+ if (nplanes > 5)
+ nplanes = 5;
+ for (int i=0; i<nplanes; i++)
+ {
+ planes_n[i].setValue(planes[i][0], planes[i][1], planes[i][2]);
+ planes_o[i] = planes[i][3];
+ }
+ btDbvt::collideKDOP(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,nplanes,dispatcher);
+ btDbvt::collideKDOP(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,nplanes,dispatcher);
+ return true;
+}
int CcdPhysicsEnvironment::getNumContactPoints()
@@ -1211,6 +1297,13 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
if (NULL != m_broadphase)
delete m_broadphase;
+
+ if (NULL != m_cullingTree)
+ delete m_cullingTree;
+
+ if (NULL != m_cullingCache)
+ delete m_cullingCache;
+
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 2f1f0bb254b..ddbcbe6b4d6 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -20,6 +20,7 @@ subject to the following restrictions:
#include <vector>
#include <set>
class CcdPhysicsController;
+class CcdGraphicController;
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
@@ -40,6 +41,7 @@ class btDispatcher;
class WrapperVehicle;
class btPersistentManifold;
class btBroadphaseInterface;
+struct btDbvtBroadphase;
class btOverlappingPairCache;
class btIDebugDraw;
class PHY_IVehicle;
@@ -58,7 +60,10 @@ protected:
btIDebugDraw* m_debugDrawer;
class btDefaultCollisionConfiguration* m_collisionConfiguration;
- class btBroadphaseInterface* m_broadphase;
+ class btBroadphaseInterface* m_broadphase; // broadphase for dynamic world
+ // for culling only
+ btOverlappingPairCache* m_cullingCache;
+ struct btDbvtBroadphase* m_cullingTree; // broadphase for culling
//solver iterations
int m_numIterations;
@@ -77,7 +82,7 @@ protected:
void processFhSprings(double curTime,float timeStep);
public:
- CcdPhysicsEnvironment(btDispatcher* dispatcher=0, btOverlappingPairCache* pairCache=0);
+ CcdPhysicsEnvironment(bool useDbvtCulling, btDispatcher* dispatcher=0, btOverlappingPairCache* pairCache=0);
virtual ~CcdPhysicsEnvironment();
@@ -167,6 +172,7 @@ protected:
btTypedConstraint* getConstraintById(int constraintId);
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
+ virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes);
//Methods for gamelogic collision/physics callbacks
@@ -200,7 +206,12 @@ protected:
void refreshCcdPhysicsController(CcdPhysicsController* ctrl);
+ void addCcdGraphicController(CcdGraphicController* ctrl);
+
+ void removeCcdGraphicController(CcdGraphicController* ctrl);
+
btBroadphaseInterface* getBroadphase();
+ btDbvtBroadphase* getCullingTree() { return m_cullingTree; }
btDispatcher* getDispatcher();
diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
index a92b1e7f4a6..fae1844d505 100644
--- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
@@ -70,6 +70,7 @@ public:
}
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
+ virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes) { return false; }
//gamelogic callbacks
diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
index 65b07a7a0be..9942a367451 100644
--- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
@@ -76,6 +76,7 @@ public:
}
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
+ virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes) { return false; }
//gamelogic callbacks
diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h
index c5cf92b553a..7ce40001af7 100644
--- a/source/gameengine/Physics/common/PHY_DynamicTypes.h
+++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h
@@ -19,12 +19,42 @@ subject to the following restrictions:
-
+struct KX_ClientObjectInfo;
class PHY_Shape;
struct PHY__Vector3
{
float m_vec[4];
+
+ operator const float* () const
+ {
+ return &m_vec[0];
+ }
+ operator float* ()
+ {
+ return &m_vec[0];
+ }
+};
+
+struct PHY__Vector4
+{
+ float m_vec[4];
+ PHY__Vector4() {}
+ void setValue(const float *value)
+ {
+ m_vec[0] = *value++;
+ m_vec[1] = *value++;
+ m_vec[2] = *value++;
+ m_vec[3] = *value++;
+ }
+ void setValue(const double *value)
+ {
+ m_vec[0] = (float)(*value++);
+ m_vec[1] = (float)(*value++);
+ m_vec[2] = (float)(*value++);
+ m_vec[3] = (float)(*value++);
+ }
+
operator const float* () const
{
return &m_vec[0];
@@ -34,6 +64,7 @@ struct PHY__Vector3
return &m_vec[0];
}
};
+
//typedef float PHY__Vector3[4];
enum
@@ -59,7 +90,7 @@ enum
void *client_object1,
void *client_object2,
const PHY_CollData *coll_data);
-
+ typedef void (*PHY_CullingCallback)(KX_ClientObjectInfo* info, void* param);
/// PHY_PhysicsType enumerates all possible Physics Entities.
diff --git a/source/gameengine/Physics/common/PHY_IController.cpp b/source/gameengine/Physics/common/PHY_IController.cpp
new file mode 100644
index 00000000000..47fe9a9eea8
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IController.cpp
@@ -0,0 +1,39 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "PHY_IController.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+PHY_IController::~PHY_IController()
+{
+
+}
+
diff --git a/source/gameengine/Physics/common/PHY_IController.h b/source/gameengine/Physics/common/PHY_IController.h
new file mode 100644
index 00000000000..45e93f9d24e
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IController.h
@@ -0,0 +1,53 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef PHY_ICONTROLLER_H
+#define PHY_ICONTROLLER_H
+
+#include "PHY_DynamicTypes.h"
+
+
+
+/**
+ PHY_IController is the abstract simplified Interface to objects
+ controlled by the physics engine. This includes the physics objects
+ and the graphics object for view frustrum and occlusion culling.
+*/
+class PHY_IController
+{
+ public:
+
+ virtual ~PHY_IController();
+ // clientinfo for raycasts for example
+ virtual void* getNewClientInfo()=0;
+ virtual void setNewClientInfo(void* clientinfo)=0;
+
+};
+
+#endif //PHY_ICONTROLLER_H
+
diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.cpp b/source/gameengine/Physics/common/PHY_IGraphicController.cpp
new file mode 100644
index 00000000000..4dccecd3d29
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IGraphicController.cpp
@@ -0,0 +1,39 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "PHY_IGraphicController.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+PHY_IGraphicController::~PHY_IGraphicController()
+{
+
+}
+
diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h
new file mode 100644
index 00000000000..36b8a978e87
--- /dev/null
+++ b/source/gameengine/Physics/common/PHY_IGraphicController.h
@@ -0,0 +1,56 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef PHY_IGRAPHICCONTROLLER_H
+#define PHY_IGRAPHICCONTROLLER_H
+
+#include "PHY_IController.h"
+
+
+
+/**
+ PHY_IPhysicsController is the abstract simplified Interface to a physical object.
+ It contains the IMotionState and IDeformableMesh Interfaces.
+*/
+class PHY_IGraphicController : public PHY_IController
+{
+
+ public:
+
+ virtual ~PHY_IGraphicController();
+ /**
+ SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
+ */
+ virtual bool SetGraphicTransform()=0;
+
+ virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate) {return 0;}
+
+};
+
+#endif //PHY_IGRAPHICCONTROLLER_H
+
diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h
index d759b0aeff4..64bb810ee7c 100644
--- a/source/gameengine/Physics/common/PHY_IMotionState.h
+++ b/source/gameengine/Physics/common/PHY_IMotionState.h
@@ -43,6 +43,8 @@ class PHY_IMotionState
virtual void getWorldPosition(float& posX,float& posY,float& posZ)=0;
virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)=0;
virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)=0;
+ // ori = array 12 floats, [0..3] = first column + 0, [4..7] = second colum, [8..11] = third column
+ virtual void getWorldOrientation(float* ori)=0;
virtual void setWorldPosition(float posX,float posY,float posZ)=0;
virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)=0;
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index 884e14cfb5a..6cba6fa88af 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -29,7 +29,7 @@
#ifndef PHY_IPHYSICSCONTROLLER_H
#define PHY_IPHYSICSCONTROLLER_H
-#include "PHY_DynamicTypes.h"
+#include "PHY_IController.h"
@@ -37,7 +37,7 @@
PHY_IPhysicsController is the abstract simplified Interface to a physical object.
It contains the IMotionState and IDeformableMesh Interfaces.
*/
-class PHY_IPhysicsController
+class PHY_IPhysicsController : public PHY_IController
{
public:
@@ -82,9 +82,7 @@ class PHY_IPhysicsController
// dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted
virtual void setRigidBody(bool rigid)=0;
- // clientinfo for raycasts for example
- virtual void* getNewClientInfo()=0;
- virtual void setNewClientInfo(void* clientinfo)=0;
+
virtual PHY_IPhysicsController* GetReplica() {return 0;}
virtual void calcXform() =0;
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index 226ba3a7e74..5edafe6b51e 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -142,6 +142,8 @@ class PHY_IPhysicsEnvironment
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)=0;
+ //culling based on physical broad phase
+ virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber) = 0;
//Methods for gamelogic collision/physics callbacks
//todo:
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index f7938bb62e6..ec290f89d9e 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -148,6 +148,10 @@ void RAS_BucketManager::RenderAlphaBuckets(
while(sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools))
sit->m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(sit->m_ms));
+
+ // make this mesh slot culled automatically for next frame
+ // it will be culled out by frustrum culling
+ sit->m_ms->SetCulled(true);
}
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
@@ -170,6 +174,10 @@ void RAS_BucketManager::RenderSolidBuckets(
while ((*bit)->ActivateMaterial(cameratrans, rasty, rendertools))
(*bit)->RenderMeshSlot(cameratrans, rasty, rendertools, *mit);
+
+ // make this mesh slot culled automatically for next frame
+ // it will be culled out by frustrum culling
+ mit->SetCulled(true);
}
}
diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h
index 610bd13ff12..0a226ac30f9 100644
--- a/source/gameengine/Rasterizer/RAS_FramingManager.h
+++ b/source/gameengine/Rasterizer/RAS_FramingManager.h
@@ -163,6 +163,13 @@ struct RAS_FrameFrustum
float x2,y2;
};
+/* must match R_CULLING_... from DNA_scene_types.h */
+enum RAS_CullingMode
+{
+ RAS_CULLING_DBVT = 0,
+ RAS_CULLING_NORMAL,
+ RAS_CULLING_NONE
+};
/**
* @section RAS_FramingManager
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
index 475f01d549a..211770318ae 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
@@ -156,6 +156,7 @@ public:
bool Join(RAS_MeshSlot *target, MT_Scalar distance);
bool Equals(RAS_MeshSlot *target);
bool IsCulled();
+ void SetCulled(bool culled) { m_bCulled = culled; }
};
/* Used by RAS_MeshObject, to point to it's slots in a bucket */
diff --git a/source/gameengine/SceneGraph/SG_BBox.cpp b/source/gameengine/SceneGraph/SG_BBox.cpp
index a44262d04f7..66fcc5c7408 100644
--- a/source/gameengine/SceneGraph/SG_BBox.cpp
+++ b/source/gameengine/SceneGraph/SG_BBox.cpp
@@ -188,6 +188,13 @@ void SG_BBox::getaa(MT_Point3 *box, const MT_Transform &world) const
*box++ = max;
}
+void SG_BBox::getmm(MT_Point3 *box, const MT_Transform &world) const
+{
+ const MT_Point3 min(world(m_min)), max(world(m_max));
+ *box++ = min;
+ *box++ = max;
+}
+
void SG_BBox::split(SG_BBox &left, SG_BBox &right) const
{
MT_Scalar sizex = m_max[0] - m_min[0];
diff --git a/source/gameengine/SceneGraph/SG_BBox.h b/source/gameengine/SceneGraph/SG_BBox.h
index b7e8ff65865..c39ad268e25 100644
--- a/source/gameengine/SceneGraph/SG_BBox.h
+++ b/source/gameengine/SceneGraph/SG_BBox.h
@@ -122,6 +122,8 @@ public:
*/
void getaa(MT_Point3 *box, const MT_Transform &world) const;
+ void getmm(MT_Point3 *box, const MT_Transform &world) const;
+
void split(SG_BBox &left, SG_BBox &right) const;
friend class SG_Tree;
diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp
index d0bdac5c8f0..fbab4032a10 100644
--- a/source/gameengine/SceneGraph/SG_IObject.cpp
+++ b/source/gameengine/SceneGraph/SG_IObject.cpp
@@ -33,6 +33,8 @@
#include <config.h>
#endif
+SG_Stage gSG_Stage = SG_STAGE_UNKNOWN;
+
SG_IObject::
SG_IObject(
void* clientobj,
diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h
index 7f6bdfbbb1c..9012b532059 100644
--- a/source/gameengine/SceneGraph/SG_IObject.h
+++ b/source/gameengine/SceneGraph/SG_IObject.h
@@ -31,6 +31,36 @@
#include <vector>
+// used for debugging: stage of the game engine main loop at which a Scenegraph modification is done
+enum SG_Stage
+{
+ SG_STAGE_UNKNOWN = 0,
+ SG_STAGE_NETWORK,
+ SG_STAGE_NETWORK_UPDATE,
+ SG_STAGE_PHYSICS1,
+ SG_STAGE_PHYSICS1_UPDATE,
+ SG_STAGE_CONTROLLER,
+ SG_STAGE_CONTROLLER_UPDATE,
+ SG_STAGE_ACTUATOR,
+ SG_STAGE_ACTUATOR_UPDATE,
+ SG_STAGE_PHYSICS2,
+ SG_STAGE_PHYSICS2_UPDATE,
+ SG_STAGE_SCENE,
+ SG_STAGE_RENDER,
+ SG_STAGE_CONVERTER,
+ SG_STAGE_CULLING,
+ SG_STAGE_MAX
+};
+
+extern SG_Stage gSG_Stage;
+
+inline void SG_SetActiveStage(SG_Stage stage)
+{
+ gSG_Stage = stage;
+}
+
+
+
class SG_Controller;
class SG_IObject;
diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp
index 8de7ac83477..64d9019c86a 100644
--- a/source/gameengine/SceneGraph/SG_Node.cpp
+++ b/source/gameengine/SceneGraph/SG_Node.cpp
@@ -219,18 +219,19 @@ void SG_Node::RemoveChild(SG_Node* child)
-void SG_Node::UpdateWorldData(double time)
+void SG_Node::UpdateWorldData(double time, bool parentUpdated)
{
//if (!GetSGParent())
// return;
- if (UpdateSpatialData(GetSGParent(),time))
+ if (UpdateSpatialData(GetSGParent(),time,parentUpdated))
+ // to update the
ActivateUpdateTransformCallback();
// update children's worlddata
for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
{
- (*it)->UpdateWorldData(time);
+ (*it)->UpdateWorldData(time, parentUpdated);
}
}
diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h
index ffaaad861e2..29943653a81 100644
--- a/source/gameengine/SceneGraph/SG_Node.h
+++ b/source/gameengine/SceneGraph/SG_Node.h
@@ -175,7 +175,8 @@ public:
void
UpdateWorldData(
- double time
+ double time,
+ bool parentUpdated=false
);
/**
diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h
index 6507cb98519..8f45df09b27 100644
--- a/source/gameengine/SceneGraph/SG_ParentRelation.h
+++ b/source/gameengine/SceneGraph/SG_ParentRelation.h
@@ -69,7 +69,8 @@ public :
bool
UpdateChildCoordinates(
SG_Spatial * child,
- const SG_Spatial * parent
+ const SG_Spatial * parent,
+ bool& parentUpdated
) = 0;
virtual
diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp
index 99aeb3e72ee..2f3176816c6 100644
--- a/source/gameengine/SceneGraph/SG_Spatial.cpp
+++ b/source/gameengine/SceneGraph/SG_Spatial.cpp
@@ -55,7 +55,8 @@ SG_Spatial(
m_parent_relation (NULL),
m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)),
- m_radius(1.0)
+ m_radius(1.0),
+ m_modified(true)
{
}
@@ -101,6 +102,7 @@ SetParentRelation(
){
delete (m_parent_relation);
m_parent_relation = relation;
+ m_modified = true;
}
@@ -114,7 +116,8 @@ SetParentRelation(
SG_Spatial::
UpdateSpatialData(
const SG_Spatial *parent,
- double time
+ double time,
+ bool& parentUpdated
){
bool bComputesWorldTransform = false;
@@ -135,14 +138,14 @@ UpdateSpatialData(
// our world coordinates.
if (!bComputesWorldTransform)
- bComputesWorldTransform = ComputeWorldTransforms(parent);
+ bComputesWorldTransform = ComputeWorldTransforms(parent, parentUpdated);
return bComputesWorldTransform;
}
-bool SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent)
+bool SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated)
{
- return m_parent_relation->UpdateChildCoordinates(this,parent);
+ return m_parent_relation->UpdateChildCoordinates(this,parent,parentUpdated);
}
/**
@@ -166,6 +169,7 @@ RelativeTranslate(
m_localPosition += trans;
}
}
+ m_modified = true;
}
void
@@ -174,6 +178,7 @@ SetLocalPosition(
const MT_Point3& trans
){
m_localPosition = trans;
+ m_modified = true;
}
void
@@ -194,6 +199,7 @@ RelativeScale(
const MT_Vector3& scale
){
m_localScaling = m_localScaling * scale;
+ m_modified = true;
}
void
@@ -202,6 +208,7 @@ SetLocalScale(
const MT_Vector3& scale
){
m_localScaling = scale;
+ m_modified = true;
}
@@ -229,6 +236,7 @@ RelativeRotate(
rot
:
(GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
+ m_modified = true;
}
void
@@ -236,6 +244,7 @@ SG_Spatial::
SetLocalOrientation(const MT_Matrix3x3& rot)
{
m_localRotation = rot;
+ m_modified = true;
}
diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h
index 6ccec2aa9c1..c2ed80d21b2 100644
--- a/source/gameengine/SceneGraph/SG_Spatial.h
+++ b/source/gameengine/SceneGraph/SG_Spatial.h
@@ -61,7 +61,7 @@ protected:
SG_BBox m_bbox;
MT_Scalar m_radius;
-
+ bool m_modified;
public:
@@ -180,7 +180,7 @@ public:
MT_Transform GetWorldTransform() const;
- bool ComputeWorldTransforms( const SG_Spatial *parent);
+ bool ComputeWorldTransforms(const SG_Spatial *parent, bool& parentUpdated);
/**
* Bounding box functions.
@@ -193,9 +193,14 @@ public:
MT_Scalar Radius() const { return m_radius; }
void SetRadius(MT_Scalar radius) { m_radius = radius; }
+ bool IsModified() { return m_modified; }
protected:
friend class SG_Controller;
+ friend class KX_BoneParentRelation;
+ friend class KX_VertexParentRelation;
+ friend class KX_SlowParentRelation;
+ friend class KX_NormalParentRelation;
/**
* Protected constructor this class is not
@@ -223,8 +228,10 @@ protected:
bool
UpdateSpatialData(
const SG_Spatial *parent,
- double time
+ double time,
+ bool& parentUpdated
);
+ void SetModified(bool modified) { m_modified = modified; }
};