[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