forked from bartvdbraak/blender
BGE Scenegraph and View frustrum culling improvement.
This commit contains a number of performance improvements for the BGE in the Scenegraph (parent relation between objects in the scene) and view frustrum culling. The scenegraph improvement consists in avoiding position update if the object has not moved since last update and the removal of redundant updates and synchronization with the physics engine. The view frustrum culling improvement consists in using the DBVT broadphase facility of Bullet to build a tree of graphical objects in the scene. The elements of the tree are Aabb boxes (Aligned Axis Bounding Boxes) enclosing the objects. This provides good precision in closed and opened scenes. This new culling system is enabled by default but just in case, it can be disabled with a button in the World settings. There is no do_version in this commit but it will be added before the 2.49 release. For now you must manually enable the DBVT culling option in World settings when you open an old file. The above improvements speed up scenegraph and culling up to 5x. However, this performance improvement is only visible when you have hundreds or thousands of objects. The main interest of the DBVT tree is to allow easy occlusion culling and automatic LOD system. This will be the object of further improvements.
This commit is contained in:
parent
486985762a
commit
51b4145841
@ -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();
|
||||
|
||||
|
@ -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"
|
||||
|
@ -430,6 +430,10 @@
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdGraphicController.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdPhysicsController.cpp"
|
||||
>
|
||||
@ -444,6 +448,10 @@
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdGraphicController.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\..\source\gameengine\Physics\Bullet\CcdPhysicsController.h"
|
||||
>
|
||||
|
@ -4,6 +4,7 @@
|
||||
Version="9,00"
|
||||
Name="PHY_Physics"
|
||||
ProjectGUID="{E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}"
|
||||
RootNamespace="PHY_Physics"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
@ -469,6 +470,14 @@
|
||||
Name="Source Files"
|
||||
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"
|
||||
>
|
||||
@ -494,6 +503,14 @@
|
||||
RelativePath="..\..\..\..\source\gameengine\Physics\common\PHY_DynamicTypes.h"
|
||||
>
|
||||
</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"
|
||||
>
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 } ;
|
||||
|
@ -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()
|
||||
{
|
||||
if (m_pPhysicsController1)
|
||||
{
|
||||
m_pPhysicsController1->SetSumoTransform(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void KX_GameObject::UpdateTransform()
|
||||
{
|
||||
if (m_pPhysicsController1)
|
||||
m_pPhysicsController1->SetSumoTransform(false);
|
||||
// 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::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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -350,6 +352,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
|
||||
@ -524,13 +538,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
|
||||
*/
|
||||
|
@ -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())
|
||||
@ -1167,6 +1189,8 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
|
||||
{
|
||||
bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName));
|
||||
|
||||
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)
|
||||
@ -1174,7 +1198,7 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene)
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,8 @@ public :
|
||||
bool
|
||||
UpdateChildCoordinates(
|
||||
SG_Spatial * child,
|
||||
const SG_Spatial * parent
|
||||
const SG_Spatial * parent,
|
||||
bool& parentUpdated
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
bool dbvt_culling = false;
|
||||
if (m_dbvt_culling)
|
||||
{
|
||||
// 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
|
||||
};
|
||||
|
@ -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;
|
||||
@ -251,6 +259,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);
|
||||
|
||||
|
@ -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
|
||||
|
112
source/gameengine/Physics/Bullet/CcdGraphicController.cpp
Normal file
112
source/gameengine/Physics/Bullet/CcdGraphicController.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
74
source/gameengine/Physics/Bullet/CcdGraphicController.h
Normal file
74
source/gameengine/Physics/Bullet/CcdGraphicController.h
Normal file
@ -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
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -19,12 +19,13 @@ 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];
|
||||
@ -34,6 +35,36 @@ struct PHY__Vector3
|
||||
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];
|
||||
}
|
||||
operator float* ()
|
||||
{
|
||||
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.
|
||||
|
39
source/gameengine/Physics/common/PHY_IController.cpp
Normal file
39
source/gameengine/Physics/common/PHY_IController.cpp
Normal file
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
53
source/gameengine/Physics/common/PHY_IController.h
Normal file
53
source/gameengine/Physics/common/PHY_IController.h
Normal file
@ -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
|
||||
|
39
source/gameengine/Physics/common/PHY_IGraphicController.cpp
Normal file
39
source/gameengine/Physics/common/PHY_IGraphicController.cpp
Normal file
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
56
source/gameengine/Physics/common/PHY_IGraphicController.h
Normal file
56
source/gameengine/Physics/common/PHY_IGraphicController.h
Normal file
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
SG_Stage gSG_Stage = SG_STAGE_UNKNOWN;
|
||||
|
||||
SG_IObject::
|
||||
SG_IObject(
|
||||
void* clientobj,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,8 @@ public:
|
||||
|
||||
void
|
||||
UpdateWorldData(
|
||||
double time
|
||||
double time,
|
||||
bool parentUpdated=false
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -69,7 +69,8 @@ public :
|
||||
bool
|
||||
UpdateChildCoordinates(
|
||||
SG_Spatial * child,
|
||||
const SG_Spatial * parent
|
||||
const SG_Spatial * parent,
|
||||
bool& parentUpdated
|
||||
) = 0;
|
||||
|
||||
virtual
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user