Blender V2.61 - r43446

bvh.h

Go to the documentation of this file.
00001 /*
00002  * Adapted from code copyright 2009-2010 NVIDIA Corporation
00003  * Modifications Copyright 2011, Blender Foundation.
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #ifndef __BVH_H__
00019 #define __BVH_H__
00020 
00021 #include "bvh_params.h"
00022 
00023 #include "util_string.h"
00024 #include "util_types.h"
00025 #include "util_vector.h"
00026 
00027 CCL_NAMESPACE_BEGIN
00028 
00029 class BVHNode;
00030 struct BVHStackEntry;
00031 class BVHParams;
00032 class BoundBox;
00033 class CacheData;
00034 class LeafNode;
00035 class Object;
00036 class Progress;
00037 
00038 #define BVH_NODE_SIZE   4
00039 #define BVH_QNODE_SIZE  8
00040 #define BVH_ALIGN       4096
00041 #define TRI_NODE_SIZE   3
00042 
00043 /* Packed BVH
00044  *
00045  * BVH stored as it will be used for traversal on the rendering device. */
00046 
00047 struct PackedBVH {
00048     /* BVH nodes storage, one node is 4x int4, and contains two bounding boxes,
00049        and child, triangle or object indexes dependening on the node type */
00050     array<int4> nodes; 
00051     /* object index to BVH node index mapping for instances */
00052     array<int> object_node; 
00053     /* precomputed triangle intersection data, one triangle is 4x float4 */
00054     array<float4> tri_woop; 
00055     /* visibility visibilitys for primitives */
00056     array<uint> prim_visibility;
00057     /* mapping from BVH primitive index to true primitive index, as primitives
00058        may be duplicated due to spatial splits. -1 for instances. */
00059     array<int> prim_index;
00060     /* mapping from BVH primitive index, to the object id of that primitive. */
00061     array<int> prim_object;
00062     /* quick array to lookup if a node is a leaf, not used for traversal, only
00063        for instance BVH merging  */
00064     array<int> is_leaf;
00065 
00066     /* index of the root node. */
00067     int root_index;
00068 
00069     /* surface area heuristic, for building top level BVH */
00070     float SAH;
00071 
00072     PackedBVH()
00073     {
00074         root_index = 0;
00075         SAH = 0.0f;
00076     }
00077 };
00078 
00079 /* BVH */
00080 
00081 class BVH
00082 {
00083 public:
00084     PackedBVH pack;
00085     BVHParams params;
00086     vector<Object*> objects;
00087     string cache_filename;
00088 
00089     static BVH *create(const BVHParams& params, const vector<Object*>& objects);
00090     virtual ~BVH() {}
00091 
00092     void build(Progress& progress);
00093     void refit(Progress& progress);
00094 
00095     void clear_cache_except();
00096 
00097 protected:
00098     BVH(const BVHParams& params, const vector<Object*>& objects);
00099 
00100     /* cache */
00101     bool cache_read(CacheData& key);
00102     void cache_write(CacheData& key);
00103 
00104     /* triangles */
00105     void pack_triangles();
00106     void pack_triangle(int idx, float4 woop[3]);
00107 
00108     /* merge instance BVH's */
00109     void pack_instances(size_t nodes_size);
00110 
00111     /* for subclasses to implement */
00112     virtual void pack_nodes(const array<int>& prims, const BVHNode *root) = 0;
00113     virtual void refit_nodes() = 0;
00114 };
00115 
00116 /* Regular BVH
00117  *
00118  * Typical BVH with each node having two children. */
00119 
00120 class RegularBVH : public BVH {
00121 protected:
00122     /* constructor */
00123     friend class BVH;
00124     RegularBVH(const BVHParams& params, const vector<Object*>& objects);
00125 
00126     /* pack */
00127     void pack_nodes(const array<int>& prims, const BVHNode *root);
00128     void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf);
00129     void pack_inner(const BVHStackEntry& e, const BVHStackEntry& e0, const BVHStackEntry& e1);
00130     void pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int c0, int c1, uint visibility0, uint visibility1);
00131 
00132     /* refit */
00133     void refit_nodes();
00134     void refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility);
00135 };
00136 
00137 /* QBVH
00138  *
00139  * Quad BVH, with each node having four children, to use with SIMD instructions. */
00140 
00141 class QBVH : public BVH {
00142 protected:
00143     /* constructor */
00144     friend class BVH;
00145     QBVH(const BVHParams& params, const vector<Object*>& objects);
00146 
00147     /* pack */
00148     void pack_nodes(const array<int>& prims, const BVHNode *root);
00149     void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf);
00150     void pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num);
00151 
00152     /* refit */
00153     void refit_nodes();
00154 };
00155 
00156 CCL_NAMESPACE_END
00157 
00158 #endif /* __BVH_H__ */
00159