diff options
Diffstat (limited to 'intern/cycles/blender/blender_object_cull.cpp')
-rw-r--r-- | intern/cycles/blender/blender_object_cull.cpp | 193 |
1 files changed, 93 insertions, 100 deletions
diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp index 680d9d7b1ff..74f8fb1dc53 100644 --- a/intern/cycles/blender/blender_object_cull.cpp +++ b/intern/cycles/blender/blender_object_cull.cpp @@ -22,72 +22,69 @@ CCL_NAMESPACE_BEGIN -BlenderObjectCulling::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) +BlenderObjectCulling::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; - } - } + 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 BlenderObjectCulling::init_object(Scene *scene, BL::Object& b_ob) +void BlenderObjectCulling::init_object(Scene *scene, BL::Object &b_ob) { - if(!use_scene_camera_cull_ && !use_scene_distance_cull_) { - return; - } + if (!use_scene_camera_cull_ && !use_scene_distance_cull_) { + return; + } - PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); + 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"); + 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(scene); - } + if (use_camera_cull_ || use_distance_cull_) { + /* Need to have proper projection matrix. */ + scene->camera->update(scene); + } } -bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm) +bool BlenderObjectCulling::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_)); + 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_)); } /* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order @@ -95,54 +92,50 @@ bool BlenderObjectCulling::test(Scene *scene, BL::Object& b_ob, Transform& tfm) */ bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8]) { - Camera *cam = scene->camera; - const ProjectionTransform& 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_); + Camera *cam = scene->camera; + const ProjectionTransform &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 BlenderObjectCulling::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_); + 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_); } CCL_NAMESPACE_END |