/* 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; }
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_)); }
/* 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); p = transform_point(&worldtondc, p); if(p.z >= -margin) { all_behind = false; } p /= p.z; 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; }