Cycles: Remove unneeded include statements
[blender-staging.git] / intern / cycles / bvh / bvh_unaligned.cpp
1 /*
2  * Copyright 2011-2016 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "bvh/bvh_unaligned.h"
18
19 #include "render/mesh.h"
20 #include "render/object.h"
21
22 #include "bvh/bvh_binning.h"
23 #include "bvh_params.h"
24
25 #include "util/util_boundbox.h"
26 #include "util/util_transform.h"
27
28 CCL_NAMESPACE_BEGIN
29
30
31 BVHUnaligned::BVHUnaligned(const vector<Object*>& objects)
32         : objects_(objects)
33 {
34 }
35
36 Transform BVHUnaligned::compute_aligned_space(
37         const BVHObjectBinning& range,
38         const BVHReference *references) const
39 {
40         for(int i = range.start(); i < range.end(); ++i) {
41                 const BVHReference& ref = references[i];
42                 Transform aligned_space;
43                 /* Use first primitive which defines correct direction to define
44                  * the orientation space.
45                  */
46                 if(compute_aligned_space(ref, &aligned_space)) {
47                         return aligned_space;
48                 }
49         }
50         return transform_identity();
51 }
52
53 Transform BVHUnaligned::compute_aligned_space(
54         const BVHRange& range,
55         const BVHReference *references) const
56 {
57         for(int i = range.start(); i < range.end(); ++i) {
58                 const BVHReference& ref = references[i];
59                 Transform aligned_space;
60                 /* Use first primitive which defines correct direction to define
61                  * the orientation space.
62                  */
63                 if(compute_aligned_space(ref, &aligned_space)) {
64                         return aligned_space;
65                 }
66         }
67         return transform_identity();
68 }
69
70 bool BVHUnaligned::compute_aligned_space(const BVHReference& ref,
71                                          Transform *aligned_space) const
72 {
73         const Object *object = objects_[ref.prim_object()];
74         const int packed_type = ref.prim_type();
75         const int type = (packed_type & PRIMITIVE_ALL);
76         if(type & PRIMITIVE_CURVE) {
77                 const int curve_index = ref.prim_index();
78                 const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
79                 const Mesh *mesh = object->mesh;
80                 const Mesh::Curve& curve = mesh->get_curve(curve_index);
81                 const int key = curve.first_key + segment;
82                 const float3 v1 = mesh->curve_keys[key],
83                              v2 = mesh->curve_keys[key + 1];
84                 float length;
85                 const float3 axis = normalize_len(v2 - v1, &length);
86                 if(length > 1e-6f) {
87                         *aligned_space = make_transform_frame(axis);
88                         return true;
89                 }
90         }
91         *aligned_space = transform_identity();
92         return false;
93 }
94
95 BoundBox BVHUnaligned::compute_aligned_prim_boundbox(
96         const BVHReference& prim,
97         const Transform& aligned_space) const
98 {
99         BoundBox bounds = BoundBox::empty;
100         const Object *object = objects_[prim.prim_object()];
101         const int packed_type = prim.prim_type();
102         const int type = (packed_type & PRIMITIVE_ALL);
103         if(type & PRIMITIVE_CURVE) {
104                 const int curve_index = prim.prim_index();
105                 const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type);
106                 const Mesh *mesh = object->mesh;
107                 const Mesh::Curve& curve = mesh->get_curve(curve_index);
108                 curve.bounds_grow(segment,
109                                   &mesh->curve_keys[0],
110                                   &mesh->curve_radius[0],
111                                   aligned_space,
112                                   bounds);
113         }
114         else {
115                 bounds = prim.bounds().transformed(&aligned_space);
116         }
117         return bounds;
118 }
119
120 BoundBox BVHUnaligned::compute_aligned_boundbox(
121         const BVHObjectBinning& range,
122         const BVHReference *references,
123         const Transform& aligned_space,
124         BoundBox *cent_bounds) const
125 {
126         BoundBox bounds = BoundBox::empty;
127         if(cent_bounds != NULL) {
128                 *cent_bounds = BoundBox::empty;
129         }
130         for(int i = range.start(); i < range.end(); ++i) {
131                 const BVHReference& ref = references[i];
132                 BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
133                 bounds.grow(ref_bounds);
134                 if(cent_bounds != NULL) {
135                         cent_bounds->grow(ref_bounds.center2());
136                 }
137         }
138         return bounds;
139 }
140
141 BoundBox BVHUnaligned::compute_aligned_boundbox(
142         const BVHRange& range,
143         const BVHReference *references,
144         const Transform& aligned_space,
145         BoundBox *cent_bounds) const
146 {
147         BoundBox bounds = BoundBox::empty;
148         if(cent_bounds != NULL) {
149                 *cent_bounds = BoundBox::empty;
150         }
151         for(int i = range.start(); i < range.end(); ++i) {
152                 const BVHReference& ref = references[i];
153                 BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
154                 bounds.grow(ref_bounds);
155                 if(cent_bounds != NULL) {
156                         cent_bounds->grow(ref_bounds.center2());
157                 }
158         }
159         return bounds;
160 }
161
162 Transform BVHUnaligned::compute_node_transform(
163         const BoundBox& bounds,
164         const Transform& aligned_space)
165 {
166         Transform space = aligned_space;
167         space.x.w -= bounds.min.x;
168         space.y.w -= bounds.min.y;
169         space.z.w -= bounds.min.z;
170         float3 dim = bounds.max - bounds.min;
171         return transform_scale(1.0f / max(1e-18f, dim.x),
172                                1.0f / max(1e-18f, dim.y),
173                                1.0f / max(1e-18f, dim.z)) * space;
174 }
175
176 CCL_NAMESPACE_END