Skip to content

Commit

Permalink
UPBGE: Simplify bullet occlusion.
Browse files Browse the repository at this point in the history
The bullet occlusion and culling call was simplified by avoiding passing extra
arguments. The number of planes is statically set to 6, the modelview and projection
are replaced by the matrix from the camera frustum as this matrix is the result
of the same operation made in CullingTest.

In the same time the plane reordering is removed in favor of a reorder in SG_Frustum.
  • Loading branch information
panzergame committed Jul 20, 2017
1 parent 3341047 commit a65557c
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 35 deletions.
20 changes: 7 additions & 13 deletions source/gameengine/Ketsji/KX_Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,8 @@ void KX_Scene::CalculateVisibleMeshes(KX_CullingNodeList& nodes, KX_Camera *cam,
return;
}

const SG_Frustum& frustum = cam->GetFrustum();

bool dbvt_culling = false;
if (m_dbvt_culling) {
/* Reset KX_GameObject m_bCulled to true before doing culling
Expand All @@ -1333,23 +1335,15 @@ void KX_Scene::CalculateVisibleMeshes(KX_CullingNodeList& nodes, KX_Camera *cam,

// test culling through Bullet
// get the clip planes
const std::array<MT_Vector4, 6>& cplanes = cam->GetFrustum().GetPlanes();
// and convert
MT_Vector4 planes[6] = {cplanes[4], cplanes[5], cplanes[0], cplanes[1], cplanes[2], cplanes[3]};

const std::array<MT_Vector4, 6>& planes = frustum.GetPlanes();
const MT_Matrix4x4& matrix = frustum.GetMatrix();
const int *viewport = KX_GetActiveEngine()->GetCanvas()->GetViewPort();
CullingInfo info(layer, nodes);

float mvmat[16] = {0.0f};
cam->GetModelviewMatrix().getValue(mvmat);
float pmat[16] = {0.0f};
cam->GetProjectionMatrix().getValue(pmat);

dbvt_culling = m_physicsEnvironment->CullingTest(PhysicsCullingCallback,&info,planes,6,m_dbvt_occlusion_res,
KX_GetActiveEngine()->GetCanvas()->GetViewPort(),
mvmat, pmat);
dbvt_culling = m_physicsEnvironment->CullingTest(PhysicsCullingCallback, &info, planes, m_dbvt_occlusion_res, viewport, matrix);
}
if (!dbvt_culling) {
KX_CullingHandler handler(nodes, cam->GetFrustum());
KX_CullingHandler handler(nodes, frustum);
for (KX_GameObject *gameobj : m_objectlist) {
if (gameobj->UseCulling() && gameobj->GetVisible() && (layer == 0 || gameobj->GetLayer() & layer)) {
handler.Process(gameobj->GetCullingNode());
Expand Down
25 changes: 14 additions & 11 deletions source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ struct OcclusionBuffer {
m[15] = btScalar(m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]);
}

void setup(int size, const int *view, float modelview[16], float projection[16])
void setup(int size, const int *view, float mat[16])
{
m_initialized = false;
m_occlusion = false;
Expand All @@ -1381,7 +1381,9 @@ struct OcclusionBuffer {
// at this time of the rendering, the modelview matrix is the
// world to camera transformation and the projection matrix is
// camera to clip transformation. combine both so that
CMmat4mul(m_wtc, projection, modelview);
for (unsigned short i = 0; i < 16; i++) {
m_wtc[i] = btScalar(mat[i]);
}
}

void initialize()
Expand Down Expand Up @@ -1897,30 +1899,31 @@ struct DbvtCullingCallback : btDbvt::ICollide {
};

static OcclusionBuffer gOcb;
bool CcdPhysicsEnvironment::CullingTest(PHY_CullingCallback callback, void *userData, MT_Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, float modelview[16], float projection[16])
bool CcdPhysicsEnvironment::CullingTest(PHY_CullingCallback callback, void *userData, const std::array<MT_Vector4, 6>& planes,
int occlusionRes, const int *viewport, const MT_Matrix4x4& matrix)
{
if (!m_cullingTree)
return false;
DbvtCullingCallback dispatcher(callback, userData);
btVector3 planes_n[6];
btScalar planes_o[6];
if (nplanes > 6)
nplanes = 6;
for (int i = 0; i < nplanes; i++) {
for (int i = 0; i < 6; i++) {
planes_n[i] = ToBullet(planes[i]);
planes_o[i] = planes[i][3];
}
// if occlusionRes != 0 => occlusion culling
if (occlusionRes) {
gOcb.setup(occlusionRes, viewport, modelview, projection);
float mat[16];
matrix.getValue(mat);
gOcb.setup(occlusionRes, viewport, mat);
dispatcher.m_ocb = &gOcb;
// occlusion culling, the direction of the view is taken from the first plan which MUST be the near plane
btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root, planes_n, planes_o, planes_n[0], nplanes, dispatcher);
btDbvt::collideOCL(m_cullingTree->m_sets[0].m_root, planes_n, planes_o, planes_n[0], nplanes, dispatcher);
btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root, planes_n, planes_o, planes_n[0], 6, dispatcher);
btDbvt::collideOCL(m_cullingTree->m_sets[0].m_root, planes_n, planes_o, planes_n[0], 6, dispatcher);
}
else {
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);
btDbvt::collideKDOP(m_cullingTree->m_sets[1].m_root, planes_n, planes_o, 6, dispatcher);
btDbvt::collideKDOP(m_cullingTree->m_sets[0].m_root, planes_n, planes_o, 6, dispatcher);
}
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
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, MT_Vector4 * planes, int nplanes, int occlusionRes, const int *viewport, float modelview[16], float projection[16]);
virtual bool CullingTest(PHY_CullingCallback callback, void *userData, const std::array<MT_Vector4, 6>& planes,
int occlusionRes, const int *viewport, const MT_Matrix4x4& matrix);


//Methods for gamelogic collision/physics callbacks
Expand Down
6 changes: 5 additions & 1 deletion source/gameengine/Physics/Common/PHY_IPhysicsEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@
#define __PHY_IPHYSICSENVIRONMENT_H__

#include "PHY_DynamicTypes.h"
#include "MT_Matrix4x4.h"
#include "MT_Vector2.h"
#include "MT_Vector3.h"
#include "MT_Vector4.h"

#include <array>

class PHY_IConstraint;
class PHY_IVehicle;
class PHY_ICharacter;
Expand Down Expand Up @@ -209,7 +212,8 @@ class PHY_IPhysicsEnvironment
// culling based on physical broad phase
// the plane number must be set as follow: near, far, left, right, top, botton
// the near plane must be the first one and must always be present, it is used to get the direction of the view
virtual bool CullingTest(PHY_CullingCallback callback, void *userData, MT_Vector4 * planeNormals, int planeNumber, int occlusionRes, const int *viewport, float modelview[16], float projection[16]) = 0;
virtual bool CullingTest(PHY_CullingCallback callback, void *userData, const std::array<MT_Vector4, 6>& planes,
int occlusionRes, const int *viewport, const MT_Matrix4x4& matrix) = 0;

// Methods for gamelogic collision/physics callbacks
virtual void AddSensor(PHY_IPhysicsController *ctrl) = 0;
Expand Down
3 changes: 2 additions & 1 deletion source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ class DummyPhysicsEnvironment : public PHY_IPhysicsEnvironment
}

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, class MT_Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, float modelview[16], float projection[16])
virtual bool CullingTest(PHY_CullingCallback callback, void *userData, const std::array<MT_Vector4, 6>& planes,
int occlusionRes, const int *viewport, const MT_Matrix4x4& matrix)
{
return false;
}
Expand Down
21 changes: 13 additions & 8 deletions source/gameengine/SceneGraph/SG_Frustum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
SG_Frustum::SG_Frustum(const MT_Matrix4x4& matrix)
:m_matrix(matrix)
{
// Near clip plane
m_planes[0] = m_matrix[3] + m_matrix[2];
// Far clip plane
m_planes[1] = m_matrix[3] - m_matrix[2];
// Left clip plane
m_planes[0] = m_matrix[3] + m_matrix[0];
m_planes[2] = m_matrix[3] + m_matrix[0];
// Right clip plane
m_planes[1] = m_matrix[3] - m_matrix[0];
m_planes[3] = m_matrix[3] - m_matrix[0];
// Top clip plane
m_planes[2] = m_matrix[3] - m_matrix[1];
m_planes[4] = m_matrix[3] - m_matrix[1];
// Bottom clip plane
m_planes[3] = m_matrix[3] + m_matrix[1];
// Near clip plane
m_planes[4] = m_matrix[3] + m_matrix[2];
// Far clip plane
m_planes[5] = m_matrix[3] - m_matrix[2];
m_planes[5] = m_matrix[3] + m_matrix[1];

// Normalize clip planes.
for (MT_Vector4& plane : m_planes) {
Expand All @@ -32,6 +32,11 @@ const std::array<MT_Vector4, 6>& SG_Frustum::GetPlanes() const
return m_planes;
}

const MT_Matrix4x4& SG_Frustum::GetMatrix() const
{
return m_matrix;
}

SG_Frustum::TestType SG_Frustum::PointInsideFrustum(const MT_Vector3& point) const
{
for (const MT_Vector4& plane : m_planes) {
Expand Down
1 change: 1 addition & 0 deletions source/gameengine/SceneGraph/SG_Frustum.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SG_Frustum
~SG_Frustum() = default;

const std::array<MT_Vector4, 6>& GetPlanes() const;
const MT_Matrix4x4& GetMatrix() const;

TestType PointInsideFrustum(const MT_Vector3& point) const;
TestType SphereInsideFrustum(const MT_Vector3& center, float radius) const;
Expand Down

0 comments on commit a65557c

Please sign in to comment.