Fix build error on Windows 32 bit.
[blender-staging.git] / intern / cycles / bvh / bvh_node.cpp
1 /*
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "bvh/bvh_node.h"
19
20 #include "bvh/bvh.h"
21 #include "bvh/bvh_build.h"
22
23 #include "util/util_vector.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 /* BVH Node */
28
29 int BVHNode::getSubtreeSize(BVH_STAT stat) const
30 {
31         int cnt = 0;
32
33         switch(stat)
34         {
35                 case BVH_STAT_NODE_COUNT:
36                         cnt = 1;
37                         break;
38                 case BVH_STAT_LEAF_COUNT:
39                         cnt = is_leaf() ? 1 : 0;
40                         break;
41                 case BVH_STAT_INNER_COUNT:
42                         cnt = is_leaf() ? 0 : 1;
43                         break;
44                 case BVH_STAT_TRIANGLE_COUNT:
45                         cnt = is_leaf() ? reinterpret_cast<const LeafNode*>(this)->num_triangles() : 0;
46                         break;
47                 case BVH_STAT_CHILDNODE_COUNT:
48                         cnt = num_children();
49                         break;
50                 case BVH_STAT_QNODE_COUNT:
51                         cnt = 1;
52                         for(int i = 0; i < num_children(); i++) {
53                                 BVHNode *node = get_child(i);
54                                 if(node->is_leaf()) {
55                                         cnt += 1;
56                                 }
57                                 else {
58                                         for(int j = 0; j < node->num_children(); j++) {
59                                                 cnt += node->get_child(j)->getSubtreeSize(stat);
60                                         }
61                                 }
62                         }
63                         return cnt;
64                 case BVH_STAT_ALIGNED_COUNT:
65                         if(!is_unaligned) {
66                                 cnt = 1;
67                         }
68                         break;
69                 case BVH_STAT_UNALIGNED_COUNT:
70                         if(is_unaligned) {
71                                 cnt = 1;
72                         }
73                         break;
74                 case BVH_STAT_ALIGNED_INNER_COUNT:
75                         if(!is_leaf()) {
76                                 bool has_unaligned = false;
77                                 for(int j = 0; j < num_children(); j++) {
78                                         has_unaligned |= get_child(j)->is_unaligned;
79                                 }
80                                 cnt += has_unaligned? 0: 1;
81                         }
82                         break;
83                 case BVH_STAT_UNALIGNED_INNER_COUNT:
84                         if(!is_leaf()) {
85                                 bool has_unaligned = false;
86                                 for(int j = 0; j < num_children(); j++) {
87                                         has_unaligned |= get_child(j)->is_unaligned;
88                                 }
89                                 cnt += has_unaligned? 1: 0;
90                         }
91                         break;
92                 case BVH_STAT_ALIGNED_INNER_QNODE_COUNT:
93                         {
94                                 bool has_unaligned = false;
95                                 for(int i = 0; i < num_children(); i++) {
96                                         BVHNode *node = get_child(i);
97                                         if(node->is_leaf()) {
98                                                 has_unaligned |= node->is_unaligned;
99                                         }
100                                         else {
101                                                 for(int j = 0; j < node->num_children(); j++) {
102                                                         cnt += node->get_child(j)->getSubtreeSize(stat);
103                                                         has_unaligned |= node->get_child(j)->is_unaligned;
104                                                 }
105                                         }
106                                 }
107                                 cnt += has_unaligned? 0: 1;
108                         }
109                         return cnt;
110                 case BVH_STAT_UNALIGNED_INNER_QNODE_COUNT:
111                         {
112                                 bool has_unaligned = false;
113                                 for(int i = 0; i < num_children(); i++) {
114                                         BVHNode *node = get_child(i);
115                                         if(node->is_leaf()) {
116                                                 has_unaligned |= node->is_unaligned;
117                                         }
118                                         else {
119                                                 for(int j = 0; j < node->num_children(); j++) {
120                                                         cnt += node->get_child(j)->getSubtreeSize(stat);
121                                                         has_unaligned |= node->get_child(j)->is_unaligned;
122                                                 }
123                                         }
124                                 }
125                                 cnt += has_unaligned? 1: 0;
126                         }
127                         return cnt;
128                 case BVH_STAT_ALIGNED_LEAF_COUNT:
129                         cnt = (is_leaf() && !is_unaligned) ? 1 : 0;
130                         break;
131                 case BVH_STAT_UNALIGNED_LEAF_COUNT:
132                         cnt = (is_leaf() && is_unaligned) ? 1 : 0;
133                         break;
134                 case BVH_STAT_DEPTH:
135                         if(is_leaf()) {
136                                 cnt = 1;
137                         }
138                         else {
139                                 for(int i = 0; i < num_children(); i++) {
140                                         cnt = max(cnt, get_child(i)->getSubtreeSize(stat));
141                                 }
142                                 cnt += 1;
143                         }
144                         return cnt;
145                 default:
146                         assert(0); /* unknown mode */
147         }
148
149         if(!is_leaf())
150                 for(int i = 0; i < num_children(); i++)
151                         cnt += get_child(i)->getSubtreeSize(stat);
152
153         return cnt;
154 }
155
156 void BVHNode::deleteSubtree()
157 {
158         for(int i = 0; i < num_children(); i++)
159                 if(get_child(i))
160                         get_child(i)->deleteSubtree();
161
162         delete this;
163 }
164
165 float BVHNode::computeSubtreeSAHCost(const BVHParams& p, float probability) const
166 {
167         float SAH = probability * p.cost(num_children(), num_triangles());
168
169         for(int i = 0; i < num_children(); i++) {
170                 BVHNode *child = get_child(i);
171                 SAH += child->computeSubtreeSAHCost(p, probability * child->bounds.safe_area()/bounds.safe_area());
172         }
173
174         return SAH;
175 }
176
177 uint BVHNode::update_visibility()
178 {
179         if(!is_leaf() && visibility == 0) {
180                 InnerNode *inner = (InnerNode*)this;
181                 BVHNode *child0 = inner->children[0];
182                 BVHNode *child1 = inner->children[1];
183
184                 visibility = child0->update_visibility()|child1->update_visibility();
185         }
186
187         return visibility;
188 }
189
190 void BVHNode::update_time()
191 {
192         if(!is_leaf()) {
193                 InnerNode *inner = (InnerNode*)this;
194                 BVHNode *child0 = inner->children[0];
195                 BVHNode *child1 = inner->children[1];
196                 child0->update_time();
197                 child1->update_time();
198                 time_from = min(child0->time_from, child1->time_from);
199                 time_to =  max(child0->time_to, child1->time_to);
200         }
201 }
202
203 /* Inner Node */
204
205 void InnerNode::print(int depth) const
206 {
207         for(int i = 0; i < depth; i++)
208                 printf("  ");
209         
210         printf("inner node %p\n", (void*)this);
211
212         if(children[0])
213                 children[0]->print(depth+1);
214         if(children[1])
215                 children[1]->print(depth+1);
216 }
217
218 void LeafNode::print(int depth) const
219 {
220         for(int i = 0; i < depth; i++)
221                 printf("  ");
222         
223         printf("leaf node %d to %d\n", lo, hi);
224 }
225
226 CCL_NAMESPACE_END
227