[Bf-blender-cvs] [aea4ed0] master: Cycles: refactor culling code into utility class.
Brecht Van Lommel
noreply at git.blender.org
Sun Nov 20 15:47:31 CET 2016
Commit: aea4ed00d5a7fe661f12fbe1a16ad6574d9be8ea
Author: Brecht Van Lommel
Date: Sun Nov 13 00:45:16 2016 +0100
Branches: master
https://developer.blender.org/rBaea4ed00d5a7fe661f12fbe1a16ad6574d9be8ea
Cycles: refactor culling code into utility class.
===================================================================
M intern/cycles/blender/blender_object.cpp
M intern/cycles/blender/blender_sync.h
===================================================================
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 84701a2..681a22e 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -88,6 +88,143 @@ static uint object_ray_visibility(BL::Object& b_ob)
return flag;
}
+/* Culling */
+
+class BlenderObjectCulling
+{
+public:
+ BlenderObjectCulling(Scene *scene, BL::Scene& b_scene)
+ : use_scene_camera_cull(false),
+ use_camera_cull(false),
+ camera_cull_margin(0.0f),
+ use_scene_distance_cull(false),
+ use_distance_cull(false),
+ distance_cull_margin(0.0f)
+ {
+ if(b_scene.render().use_simplify()) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ use_scene_camera_cull = scene->camera->type != CAMERA_PANORAMA &&
+ !b_scene.render().use_multiview() &&
+ get_boolean(cscene, "use_camera_cull");
+ use_scene_distance_cull = scene->camera->type != CAMERA_PANORAMA &&
+ !b_scene.render().use_multiview() &&
+ get_boolean(cscene, "use_distance_cull");
+
+ camera_cull_margin = get_float(cscene, "camera_cull_margin");
+ distance_cull_margin = get_float(cscene, "distance_cull_margin");
+
+ if (distance_cull_margin == 0.0f) {
+ use_scene_distance_cull = false;
+ }
+ }
+ }
+
+ void init_object(Scene *scene, BL::Object& b_ob)
+ {
+ if(!use_scene_camera_cull && !use_scene_distance_cull) {
+ return;
+ }
+
+ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+
+ use_camera_cull = use_scene_camera_cull && get_boolean(cobject, "use_camera_cull");
+ use_distance_cull = use_scene_distance_cull && get_boolean(cobject, "use_distance_cull");
+
+ if(use_camera_cull || use_distance_cull) {
+ /* Need to have proper projection matrix. */
+ scene->camera->update();
+ }
+ }
+
+ bool test(Scene *scene, BL::Object& b_ob, Transform& tfm)
+ {
+ if(!use_camera_cull && !use_distance_cull) {
+ return false;
+ }
+
+ /* Compute world space bounding box corners. */
+ float3 bb[8];
+ BL::Array<float, 24> boundbox = b_ob.bound_box();
+ for(int i = 0; i < 8; ++i) {
+ float3 p = make_float3(boundbox[3 * i + 0],
+ boundbox[3 * i + 1],
+ boundbox[3 * i + 2]);
+ bb[i] = transform_point(&tfm, p);
+ }
+
+ bool camera_culled = use_camera_cull && test_camera(scene, bb);
+ bool distance_culled = use_distance_cull && test_distance(scene, bb);
+
+ return ((camera_culled && distance_culled) ||
+ (camera_culled && !use_distance_cull) ||
+ (distance_culled && !use_camera_cull));
+ }
+
+private:
+ /* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
+ * to reduce number of objects which are wrongly considered visible.
+ */
+ bool test_camera(Scene *scene, float3 bb[8])
+ {
+ Camera *cam = scene->camera;
+ Transform& worldtondc = cam->worldtondc;
+ float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
+ bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+ bool all_behind = true;
+ for(int i = 0; i < 8; ++i) {
+ float3 p = bb[i];
+ float4 b = make_float4(p.x, p.y, p.z, 1.0f);
+ float4 c = make_float4(dot(worldtondc.x, b),
+ dot(worldtondc.y, b),
+ dot(worldtondc.z, b),
+ dot(worldtondc.w, b));
+ p = float4_to_float3(c / c.w);
+ if(c.z < 0.0f) {
+ p.x = 1.0f - p.x;
+ p.y = 1.0f - p.y;
+ }
+ if(c.z >= -camera_cull_margin) {
+ all_behind = false;
+ }
+ bb_min = min(bb_min, p);
+ bb_max = max(bb_max, p);
+ }
+ if(all_behind) {
+ return true;
+ }
+ return (bb_min.x >= 1.0f + camera_cull_margin ||
+ bb_min.y >= 1.0f + camera_cull_margin ||
+ bb_max.x <= -camera_cull_margin ||
+ bb_max.y <= -camera_cull_margin);
+ }
+
+ bool test_distance(Scene *scene, float3 bb[8])
+ {
+ float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
+ float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
+ bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+
+ /* Find min & max points for x & y & z on bounding box */
+ for(int i = 0; i < 8; ++i) {
+ float3 p = bb[i];
+ bb_min = min(bb_min, p);
+ bb_max = max(bb_max, p);
+ }
+
+ float3 closest_point = max(min(bb_max,camera_position),bb_min);
+ return (len_squared(camera_position - closest_point) >
+ distance_cull_margin * distance_cull_margin);
+ }
+
+ bool use_scene_camera_cull;
+ bool use_camera_cull;
+ float camera_cull_margin;
+ bool use_scene_distance_cull;
+ bool use_distance_cull;
+ float distance_cull_margin;
+};
+
/* Light */
void BlenderSync::sync_light(BL::Object& b_parent,
@@ -235,80 +372,6 @@ void BlenderSync::sync_background_light(bool use_portal)
/* Object */
-/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
- * to reduce number of objects which are wrongly considered visible.
- */
-static bool object_boundbox_clip(Scene *scene,
- BL::Object& b_ob,
- Transform& tfm,
- float margin)
-{
- Camera *cam = scene->camera;
- Transform& worldtondc = cam->worldtondc;
- BL::Array<float, 24> boundbox = b_ob.bound_box();
- float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
- bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
- bool all_behind = true;
- for(int i = 0; i < 8; ++i) {
- float3 p = make_float3(boundbox[3 * i + 0],
- boundbox[3 * i + 1],
- boundbox[3 * i + 2]);
- p = transform_point(&tfm, p);
-
- float4 b = make_float4(p.x, p.y, p.z, 1.0f);
- float4 c = make_float4(dot(worldtondc.x, b),
- dot(worldtondc.y, b),
- dot(worldtondc.z, b),
- dot(worldtondc.w, b));
- p = float4_to_float3(c / c.w);
- if(c.z < 0.0f) {
- p.x = 1.0f - p.x;
- p.y = 1.0f - p.y;
- }
- if(c.z >= -margin) {
- all_behind = false;
- }
- bb_min = min(bb_min, p);
- bb_max = max(bb_max, p);
- }
- if(!all_behind) {
- if(bb_min.x >= 1.0f + margin ||
- bb_min.y >= 1.0f + margin ||
- bb_max.x <= -margin ||
- bb_max.y <= -margin)
- {
- return true;
- }
- return false;
- }
- return true;
-}
-
-static bool object_distance_clip(Scene *scene,
- BL::Object& b_ob,
- Transform& tfm,
- float margin)
-{
- BL::Array<float, 24> boundbox = b_ob.bound_box();
- float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
-
- float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
- bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
-
- /* Find min & max points for x & y & z on bounding box */
- for(int i = 0; i < 8; ++i) {
- float3 p = make_float3(boundbox[3 * i + 0],
- boundbox[3 * i + 1],
- boundbox[3 * i + 2]);
- p = transform_point(&tfm, p);
- bb_min = min(bb_min, p);
- bb_max = max(bb_max, p);
- }
-
- float3 closest_point = max(min(bb_max,camera_position),bb_min);
- return (len_squared(camera_position - closest_point) > margin * margin);
-}
-
Object *BlenderSync::sync_object(BL::Object& b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
BL::DupliObject& b_dupli_ob,
@@ -316,10 +379,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
uint layer_flag,
float motion_time,
bool hide_tris,
- bool use_camera_cull,
- bool use_distance_cull,
- float camera_cull_margin,
- float distance_cull_margin,
+ BlenderObjectCulling& culling,
bool *use_portal)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
@@ -335,17 +395,12 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
}
/* only interested in object that we can create meshes from */
- if(!object_is_mesh(b_ob))
+ if(!object_is_mesh(b_ob)) {
return NULL;
+ }
/* Perform object culling. */
- bool camera_culled = use_camera_cull && object_boundbox_clip(scene, b_ob, tfm, camera_cull_margin);
- bool distance_culled = use_distance_cull && object_distance_clip(scene, b_ob, tfm, distance_cull_margin);
-
- if ((camera_culled && distance_culled) ||
- (camera_culled && !use_distance_cull) ||
- (distance_culled && !use_camera_cull))
- {
+ if(culling.test(scene, b_ob, tfm)) {
return NULL;
}
@@ -581,28 +636,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
mesh_motion_synced.clear();
}
- bool allow_camera_cull = false;
- bool allow_distance_cull = false;
- float camera_cull_margin = 0.0f;
- float distance_cull_margin = 0.0f;
- if(b_scene.render().use_simplify()) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- allow_camera_cull = scene->camera->type != CAMERA_PANORAMA &&
- !b_scene.render().use_multiview() &&
- get_boolean(cscene, "use_camera_cull");
- allow_distance_cull = scene->camera->type != CAMERA_PANORAMA &&
- !b_scene.render().use_multiview() &&
- get_boolean(cscene, "use_distance_cull");
- if(allow_camera_cull) {
- camera_cull_margin = get_float(cscene, "camera_cull_margin");
- }
- if(allow_distance_cull) {
- distance_cull_margin = get_float(cscene, "distance_cull_margin");
- if (distance_cull_margin == 0.0f) {
- allow_distance_cull = false;
- }
- }
- }
+ /* initialize culling */
+ BlenderObjectCulling culling(scene, b_scene);
/* object loop */
BL::Scene::object_bases_iterator b_base;
@@ -634,13 +669,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
if(!hide) {
progress.set_sync_status("Synchronizing object", b_ob.name());
- PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_camera_cull = allow_camera_cull && get_boolean(cobject, "use_camera_cull");
- bool u
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list