Skip to content

Commit

Permalink
UPBGE: Implement physics and logic object activity culling.
Browse files Browse the repository at this point in the history
The activity culling helps to disable the physics or logic
of an object depending of its distance to the nearest camera.

From user side options were added in both UI and python API
to control this feature. In UI the activity culling is put
in three level, scene, camera, object. The two first level
are enabled as default and the last disabled. Also the object
panel expose option to enabled physics or logic culling with
a different radius.
In python the attribute activityCulling is added to these
three levels and KX_GameObject receive four attributes to
enabled physics and logic culling and controlling their
radius.

In internal sources the activity culling info are stored into
KX_GameObject::ActivityCullingInfo which is owned by in
KX_GameObject::m_activityCullingInfo.

To suspend logic we suspend from SCA_IObject calling Suspend
and Resume but in the same time we need to suspend animation
as they are independant of logic and that it will be hard
to control them when the object doesn't run its logic.
To do so BL_ActionManager implement a suspend flag which disallow
any task creation in KX_Scene::UpdateAnimations.

Thanks for youle's work on this.
  • Loading branch information
youle31 authored and panzergame committed Nov 11, 2017
1 parent f874e52 commit f9d7e24
Show file tree
Hide file tree
Showing 27 changed files with 496 additions and 126 deletions.
6 changes: 6 additions & 0 deletions doc/python_api/rst/bge_types/bge.types.KX_Camera.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ base class --- :class:`KX_GameObject`

:type: boolean

.. attribute:: activityCulling

True if this camera is used to compute object distance for object activity culling.

:type: boolean

.. attribute:: projection_matrix

This camera's 4x4 projection matrix.
Expand Down
26 changes: 26 additions & 0 deletions doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,32 @@ base class --- :class:`SCA_IObject`

:type: boolean

.. attribute:: physicsCulling

True if the object suspends its physics depending on its nearest distance to any camera.

:type: boolean

.. attribute:: logicCulling

True if the object suspends its logic and animation depending on its nearest distance to any camera.

:type: boolean

.. attribute:: physicsCullingRadius

Suspend object's physics if this radius is smaller than its nearest distance to any camera
and :data:`physicsCulling` set to `True`.

:type: float

.. attribute:: logicCullingRadius

Suspend object's logic and animation if this radius is smaller than its nearest distance to any camera
and :data:`logicCulling` set to `True`.

:type: float

.. attribute:: position

The object's position. [x, y, z] On write: local position, on read: world position
Expand Down
10 changes: 2 additions & 8 deletions doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,12 @@ base class --- :class:`EXP_PyObjectPlus`

:type: boolean

.. attribute:: activity_culling
.. attribute:: activityCulling

True if the scene is activity culling.
True if the scene allow object activity culling.

:type: boolean

.. attribute:: activity_culling_radius

The distance outside which to do activity culling. Measured in manhattan distance.

:type: float

.. attribute:: dbvt_culling

True when Dynamic Bounding box Volume Tree is set (read-only).
Expand Down
2 changes: 1 addition & 1 deletion release/datafiles/locale
Submodule locale updated from 507eac to 68c9db
2 changes: 1 addition & 1 deletion release/scripts/addons
Submodule addons updated from ff8ef5 to 29f2b2
19 changes: 13 additions & 6 deletions release/scripts/startup/bl_ui/properties_data_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ def draw(self, context):
col.prop(cam, "lod_factor", text="Distance Factor")


class DATA_PT_frustum_culling(CameraButtonsPanel, Panel):
bl_label = "Frustum Culling"
class DATA_PT_culling(CameraButtonsPanel, Panel):
bl_label = "Culling"
COMPAT_ENGINES = {'BLENDER_GAME'}

@classmethod
Expand All @@ -163,9 +163,16 @@ def draw(self, context):
layout = self.layout
cam = context.camera

row = layout.row()
row.prop(cam, "show_frustum")
row.prop(cam, "override_culling")
split = layout.split()

col = split.column()
col.label(text="Frustum Culling:")
col.prop(cam, "show_frustum")
col.prop(cam, "override_culling")

col = split.column()
col.label(text="Object Activity:")
col.prop(cam, "use_object_activity_culling")


class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
Expand Down Expand Up @@ -365,7 +372,7 @@ def draw_display_safe_settings(layout, safe_data, settings):
DATA_PT_lens,
DATA_PT_camera,
DATA_PT_levels_of_detail,
DATA_PT_frustum_culling,
DATA_PT_culling,
DATA_PT_camera_stereoscopy,
DATA_PT_camera_dof,
DATA_PT_camera_display,
Expand Down
37 changes: 36 additions & 1 deletion release/scripts/startup/bl_ui/properties_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,12 +526,19 @@ def draw(self, context):
sub = col.row()
sub.prop(gs, "deactivation_time", text="Time")

col = layout.column()
split = layout.split()

col = split.column()
col.label(text="Culling:")
col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
sub = col.column()
sub.active = gs.use_occlusion_culling
sub.prop(gs, "occlusion_culling_resolution", text="Resolution")

col = split.column()
col.label(text="Object Activity:")
col.prop(gs, "use_activity_culling")

else:
split = layout.split()

Expand Down Expand Up @@ -901,6 +908,33 @@ def draw(self, context):
layout.label(text="Predefined Bound:")
layout.prop(game, "predefined_bound", "")

class OBJECT_PT_activity_culling(ObjectButtonsPanel, Panel):
bl_label = "Activity Culling"
COMPAT_ENGINES = {'BLENDER_GAME'}

@classmethod
def poll(cls, context):
ob = context.object
return context.scene.render.engine in cls.COMPAT_ENGINES and ob.type not in {'CAMERA'}

def draw(self, context):
layout = self.layout
activity = context.object.game.activity_culling

split = layout.split()

col = split.column()
col.prop(activity, "use_physics", text="Physics")
sub = col.column()
sub.active = activity.use_physics
sub.prop(activity, "physics_radius")

col = split.column()
col.prop(activity, "use_logic", text="Logic")
sub = col.column()
sub.active = activity.use_logic
sub.prop(activity, "logic_radius")

class OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel):
bl_label = "Levels of Detail"
COMPAT_ENGINES = {'BLENDER_GAME'}
Expand Down Expand Up @@ -968,6 +1002,7 @@ def draw(self, context):
DATA_PT_shadow_game,
OBJECT_MT_lod_tools,
OBJECT_MT_culling,
OBJECT_PT_activity_culling,
OBJECT_PT_levels_of_detail,
)

Expand Down
1 change: 1 addition & 0 deletions source/blender/blenkernel/intern/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ void BKE_camera_init(Camera *cam)
cam->drawsize = 0.5f;
cam->ortho_scale = 6.0;
cam->flag |= CAM_SHOWPASSEPARTOUT;
cam->gameflag = GAME_CAM_OBJECT_ACTIVITY_CULLING;
cam->passepartalpha = 0.5f;
cam->lodfactor = 1.0f;

Expand Down
2 changes: 1 addition & 1 deletion source/blender/blenkernel/intern/scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ void BKE_scene_init(Scene *sce)

sce->gm.gravity = 9.8f;
sce->gm.physicsEngine = WOPHY_BULLET;
sce->gm.mode = 32; //XXX ugly harcoding, still not sure we should drop mode. 32 == 1 << 5 == use_occlusion_culling
sce->gm.mode = WO_ACTIVITY_CULLING | WO_DBVT_CULLING;
sce->gm.occlusionRes = 128;
sce->gm.ticrate = 60;
sce->gm.maxlogicstep = 5;
Expand Down
11 changes: 11 additions & 0 deletions source/blender/blenloader/intern/versioning_upbge.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "DNA_screen_types.h"
#include "DNA_mesh_types.h"
#include "DNA_material_types.h"
#include "DNA_world_types.h"

#include "BKE_main.h"

Expand Down Expand Up @@ -253,4 +254,14 @@ void blo_do_versions_upbge(FileData *fd, Library *lib, Main *main)
}
}
}

if (!MAIN_VERSION_UPBGE_ATLEAST(main, 2, 2)) {
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
scene->gm.mode |= WO_ACTIVITY_CULLING;
}

for (Camera *camera = main->camera.first; camera; camera = camera->id.next) {
camera->gameflag |= GAME_CAM_OBJECT_ACTIVITY_CULLING;
}
}
}
5 changes: 3 additions & 2 deletions source/blender/makesdna/DNA_camera_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ enum {

/* gameflag */
enum {
GAME_CAM_SHOW_FRUSTUM = (1 << 0),
GAME_CAM_OVERRIDE_CULLING = (1 << 1),
GAME_CAM_SHOW_FRUSTUM = (1 << 0),
GAME_CAM_OVERRIDE_CULLING = (1 << 1),
GAME_CAM_OBJECT_ACTIVITY_CULLING = (1 << 2),
};

/* yafray: dof sampling switch */
Expand Down
18 changes: 17 additions & 1 deletion source/blender/makesdna/DNA_object_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ typedef struct LodLevel {
int obhysteresis;
} LodLevel;

typedef struct ObjectActivityCulling {
/* For game engine, values around active camera where physics or logic are suspended */
float physicsRadius;
float logicRadius;

int flags;
int pad;
} ObjectActivityCulling;

/* object activity flags */
enum {
OB_ACTIVITY_PHYSICS = (1 << 0),
OB_ACTIVITY_LOGIC = (1 << 1),
};

typedef struct Object {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
Expand Down Expand Up @@ -245,6 +260,8 @@ typedef struct Object {
ListBase actuators; /* game logic actuators */
ListBase components; /* python components */

struct ObjectActivityCulling activityCulling;

float sf; /* sf is time-offset */

short index; /* custom index, for renderpasses */
Expand Down Expand Up @@ -580,7 +597,6 @@ enum {

/* ob->gameflag2 */
enum {
OB_NEVER_DO_ACTIVITY_CULLING = 1 << 0,
OB_LOCK_RIGID_BODY_X_AXIS = 1 << 2,
OB_LOCK_RIGID_BODY_Y_AXIS = 1 << 3,
OB_LOCK_RIGID_BODY_Z_AXIS = 1 << 4,
Expand Down
13 changes: 3 additions & 10 deletions source/blender/makesdna/DNA_scene_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -822,20 +822,13 @@ typedef struct GameData {
short depth, attrib, rt1, rt2;
short aasamples;
short hdr;
short pad4[2];

short stereoflag, stereomode;
float eyeseparation;
RecastData recastData;


/* physics (it was in world)*/
float gravity; /*Gravitation constant for the game world*/

/*
* Radius of the activity bubble, in Manhattan length. Objects
* outside the box are activity-culled. */
float activityBoxRadius;
short stereoflag, stereomode;
float eyeseparation;
RecastData recastData;

/*
* bit 3: (gameengine): Activity culling is enabled.
Expand Down
4 changes: 4 additions & 0 deletions source/blender/makesrna/intern/rna_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Frustum", "Show a visualization of frustum in Game Engine");
RNA_def_property_update(prop, NC_CAMERA, NULL);

prop = RNA_def_property(srna, "use_object_activity_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gameflag", GAME_CAM_OBJECT_ACTIVITY_CULLING);
RNA_def_property_ui_text(prop, "Activity Culling", "Enable object activity culling with this camera");

prop = RNA_def_property(srna, "show_limits", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWLIMITS);
RNA_def_property_ui_text(prop, "Show Limits", "Draw the clipping range and focus point on the camera");
Expand Down
44 changes: 38 additions & 6 deletions source/blender/makesrna/intern/rna_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,35 @@ static void rna_def_material_slot(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_MaterialSlot_path");
}

static void rna_def_game_object_activity_culling(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;

srna = RNA_def_struct(brna, "ObjectActivityCulling", NULL);
RNA_def_struct_sdna(srna, "ObjectActivityCulling");
RNA_def_struct_nested(brna, srna, "Object");
RNA_def_struct_ui_text(srna, "Object Activity Culling", "Object activity culling info");

prop = RNA_def_property(srna, "physics_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "physicsRadius");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_text(prop, "Physics Radius", "Distance to begin suspend physics of this object");

prop = RNA_def_property(srna, "logic_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "logicRadius");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_text(prop, "Logic Radius", "Distance to begin suspend logic and animation of this object");

prop = RNA_def_property(srna, "use_physics", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", OB_ACTIVITY_PHYSICS);
RNA_def_property_ui_text(prop, "Cull Physics", "Suspend physics of this object by its distance to nearest camera");

prop = RNA_def_property(srna, "use_logic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", OB_ACTIVITY_LOGIC);
RNA_def_property_ui_text(prop, "Cull Logic", "Suspend logic and animation of this object by its distance to nearest camera");
}

static void rna_def_object_game_settings(BlenderRNA *brna)
{
StructRNA *srna;
Expand Down Expand Up @@ -1827,11 +1856,6 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "lock_rotation_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_Z_ROT_AXIS);
RNA_def_property_ui_text(prop, "Lock Z Rotation Axis", "Disable simulation of angular motion along the Z axis");

/* is this used anywhere ? */
prop = RNA_def_property(srna, "use_activity_culling", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflag2", OB_NEVER_DO_ACTIVITY_CULLING);
RNA_def_property_ui_text(prop, "Lock Z Rotation Axis", "Disable simulation of angular motion along the Z axis");

prop = RNA_def_property(srna, "predefined_bound", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Mesh");
Expand Down Expand Up @@ -1975,6 +1999,15 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", OB_SHOWSTATE);
RNA_def_property_ui_text(prop, "States", "Show state panel");
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);

/* activity culling */
prop = RNA_def_property(srna, "activity_culling", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "activityCulling");
RNA_def_property_struct_type(prop, "ObjectActivityCulling");
RNA_def_property_ui_text(prop, "Object Activity Culling", "");

rna_def_game_object_activity_culling(brna);
}

static void rna_def_object_constraints(BlenderRNA *brna, PropertyRNA *cprop)
Expand Down Expand Up @@ -2204,7 +2237,6 @@ static void rna_def_object_lodlevel(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_LOD, NULL);
}


static void rna_def_object(BlenderRNA *brna)
{
StructRNA *srna;
Expand Down
Loading

1 comment on commit f9d7e24

@youle31
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool :)

Please sign in to comment.