Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-12-14 15:01:33 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-12-14 15:01:33 +0300
commit91bbffd37942f3c71b065b3c1365c771e1939f45 (patch)
treea6d783805ea05170552a646c925cab63361fe8a4 /intern
parent696721648558aef94e8488dbef13eff758abdf08 (diff)
Cycles: Move object culling helper to own files
This is a stand-alone logic, which becomes quite comprehensive now.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/blender_object.cpp138
-rw-r--r--intern/cycles/blender/blender_object_cull.cpp149
-rw-r--r--intern/cycles/blender/blender_object_cull.h49
4 files changed, 201 insertions, 137 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index a79deca53e1..b57502b3b14 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -25,6 +25,7 @@ set(SRC
blender_camera.cpp
blender_mesh.cpp
blender_object.cpp
+ blender_object_cull.cpp
blender_particles.cpp
blender_curves.cpp
blender_logging.cpp
@@ -35,6 +36,7 @@ set(SRC
blender_texture.cpp
CCL_api.h
+ blender_object_cull.h
blender_sync.h
blender_session.h
blender_texture.h
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 22cc4e6f030..637cf7abda8 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -25,6 +25,7 @@
#include "particles.h"
#include "shader.h"
+#include "blender_object_cull.h"
#include "blender_sync.h"
#include "blender_util.h"
@@ -88,143 +89,6 @@ 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,
diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp
new file mode 100644
index 00000000000..b8582df0f93
--- /dev/null
+++ b/intern/cycles/blender/blender_object_cull.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2011-2016 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+
+#include "camera.h"
+
+#include "blender_object_cull.h"
+
+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)
+{
+ 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)
+{
+ 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 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.
+ */
+bool BlenderObjectCulling::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 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_);
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/blender/blender_object_cull.h b/intern/cycles/blender/blender_object_cull.h
new file mode 100644
index 00000000000..b6f0ca5cd31
--- /dev/null
+++ b/intern/cycles/blender/blender_object_cull.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011-2016 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLENDER_OBJECT_CULL_H__
+#define __BLENDER_OBJECT_CULL_H__
+
+#include "blender_sync.h"
+#include "util_types.h"
+
+CCL_NAMESPACE_BEGIN
+
+class Scene;
+
+class BlenderObjectCulling
+{
+public:
+ BlenderObjectCulling(Scene *scene, BL::Scene& b_scene);
+
+ void init_object(Scene *scene, BL::Object& b_ob);
+ bool test(Scene *scene, BL::Object& b_ob, Transform& tfm);
+
+private:
+ bool test_camera(Scene *scene, float3 bb[8]);
+ bool test_distance(Scene *scene, float3 bb[8]);
+
+ 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_;
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __BLENDER_OBJECT_CULL_H__ */