/* * Adapted from code copyright 2009-2010 NVIDIA Corporation * Modifications Copyright 2011, 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 __BVH_PARAMS_H__ #define __BVH_PARAMS_H__ #include "util_boundbox.h" CCL_NAMESPACE_BEGIN /* BVH Parameters */ class BVHParams { public: /* spatial split area threshold */ bool use_spatial_split; float spatial_split_alpha; /* SAH costs */ float sah_node_cost; float sah_primitive_cost; /* number of primitives in leaf */ int min_leaf_size; int max_triangle_leaf_size; int max_curve_leaf_size; /* object or mesh level bvh */ bool top_level; /* disk cache */ bool use_cache; /* QBVH */ bool use_qbvh; /* fixed parameters */ enum { MAX_DEPTH = 64, MAX_SPATIAL_DEPTH = 48, NUM_SPATIAL_BINS = 32 }; BVHParams() { use_spatial_split = true; spatial_split_alpha = 1e-5f; /* todo: see if splitting up primitive cost to be separate for triangles * and curves can help. so far in tests it doesn't help, but why? */ sah_node_cost = 1.0f; sah_primitive_cost = 1.0f; min_leaf_size = 1; max_triangle_leaf_size = 8; max_curve_leaf_size = 2; top_level = false; use_cache = false; use_qbvh = false; } /* SAH costs */ __forceinline float cost(int num_nodes, int num_primitives) const { return node_cost(num_nodes) + primitive_cost(num_primitives); } __forceinline float primitive_cost(int n) const { return n*sah_primitive_cost; } __forceinline float node_cost(int n) const { return n*sah_node_cost; } __forceinline bool small_enough_for_leaf(int size, int level) { return (size <= min_leaf_size || level >= MAX_DEPTH); } }; /* BVH Reference * * Reference to a primitive. Primitive index and object are sneakily packed * into BoundBox to reduce memory usage and align nicely */ class BVHReference { public: __forceinline BVHReference() {} __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type) : rbounds(bounds_) { rbounds.min.w = __int_as_float(prim_index_); rbounds.max.w = __int_as_float(prim_object_); type = prim_type; } __forceinline const BoundBox& bounds() const { return rbounds; } __forceinline int prim_index() const { return __float_as_int(rbounds.min.w); } __forceinline int prim_object() const { return __float_as_int(rbounds.max.w); } __forceinline int prim_type() const { return type; } BVHReference& operator=(const BVHReference &arg) { memcpy(this, &arg, sizeof(BVHReference)); return *this; } protected: BoundBox rbounds; uint type; }; /* BVH Range * * Build range used during construction, to indicate the bounds and place in * the reference array of a subset of primitives Again uses trickery to pack * integers into BoundBox for alignment purposes. */ class BVHRange { public: __forceinline BVHRange() { rbounds.min.w = __int_as_float(0); rbounds.max.w = __int_as_float(0); } __forceinline BVHRange(const BoundBox& bounds_, int start_, int size_) : rbounds(bounds_) { rbounds.min.w = __int_as_float(start_); rbounds.max.w = __int_as_float(size_); } __forceinline BVHRange(const BoundBox& bounds_, const BoundBox& cbounds_, int start_, int size_) : rbounds(bounds_), cbounds(cbounds_) { rbounds.min.w = __int_as_float(start_); rbounds.max.w = __int_as_float(size_); } __forceinline void set_start(int start_) { rbounds.min.w = __int_as_float(start_); } __forceinline const BoundBox& bounds() const { return rbounds; } __forceinline const BoundBox& cent_bounds() const { return cbounds; } __forceinline int start() const { return __float_as_int(rbounds.min.w); } __forceinline int size() const { return __float_as_int(rbounds.max.w); } __forceinline int end() const { return start() + size(); } protected: BoundBox rbounds; BoundBox cbounds; }; /* BVH Spatial Bin */ struct BVHSpatialBin { BoundBox bounds; int enter; int exit; __forceinline BVHSpatialBin() { } }; CCL_NAMESPACE_END #endif /* __BVH_PARAMS_H__ */