Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2009 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): André Pinto. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 int tot_pushup = 0; 00034 int tot_pushdown = 0; 00035 int tot_hints = 0; 00036 00037 #include <assert.h> 00038 00039 #include "MEM_guardedalloc.h" 00040 00041 #include "BKE_global.h" 00042 00043 #include "BLI_math.h" 00044 #include "BLI_memarena.h" 00045 #include "BLI_utildefines.h" 00046 00047 #include "rayintersection.h" 00048 #include "rayobject.h" 00049 #include "rayobject_rtbuild.h" 00050 00051 #include "reorganize.h" 00052 #include "bvh.h" 00053 #include "vbvh.h" 00054 00055 #include <queue> 00056 #include <algorithm> 00057 00058 #define DFS_STACK_SIZE 256 00059 00060 struct VBVHTree 00061 { 00062 RayObject rayobj; 00063 VBVHNode *root; 00064 MemArena *node_arena; 00065 float cost; 00066 RTBuilder *builder; 00067 }; 00068 00069 /* 00070 * Cost to test N childs 00071 */ 00072 struct PackCost 00073 { 00074 float operator()(int n) 00075 { 00076 return n; 00077 } 00078 }; 00079 00080 template<> 00081 void bvh_done<VBVHTree>(VBVHTree *obj) 00082 { 00083 rtbuild_done(obj->builder, &obj->rayobj.control); 00084 00085 //TODO find a away to exactly calculate the needed memory 00086 MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena"); 00087 BLI_memarena_use_malloc(arena1); 00088 00089 //Build and optimize the tree 00090 if(1) 00091 { 00092 VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1,&obj->rayobj.control).transform(obj->builder); 00093 if(RE_rayobjectcontrol_test_break(&obj->rayobj.control)) 00094 { 00095 BLI_memarena_free(arena1); 00096 return; 00097 } 00098 00099 if(root) { 00100 reorganize(root); 00101 remove_useless(root, &root); 00102 bvh_refit(root); 00103 00104 pushup(root); 00105 pushdown(root); 00106 obj->root = root; 00107 } 00108 else 00109 obj->root = NULL; 00110 } 00111 else 00112 { 00113 /* 00114 TODO 00115 MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena2"); 00116 BLI_memarena_use_malloc(arena2); 00117 00118 //Finds the optimal packing of this tree using a given cost model 00119 //TODO this uses quite a lot of memory, find ways to reduce memory usage during building 00120 OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena2).transform(obj->builder); 00121 VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root); 00122 obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root); 00123 00124 BLI_memarena_free(arena2); 00125 */ 00126 } 00127 00128 //Cleanup 00129 rtbuild_free( obj->builder ); 00130 obj->builder = NULL; 00131 00132 obj->node_arena = arena1; 00133 obj->cost = 1.0; 00134 } 00135 00136 template<int StackSize> 00137 int intersect(VBVHTree *obj, Isect* isec) 00138 { 00139 //TODO renable hint support 00140 if(RE_rayobject_isAligned(obj->root)) { 00141 if(isec->mode == RE_RAY_SHADOW) 00142 return bvh_node_stack_raycast<VBVHNode,StackSize,false,true>( obj->root, isec); 00143 else 00144 return bvh_node_stack_raycast<VBVHNode,StackSize,false,false>( obj->root, isec); 00145 } 00146 else 00147 return RE_rayobject_intersect( (RayObject*) obj->root, isec ); 00148 } 00149 00150 template<class Tree> 00151 void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(max)) 00152 { 00153 //TODO renable hint support 00154 { 00155 hint->size = 0; 00156 hint->stack[hint->size++] = (RayObject*)tree->root; 00157 } 00158 } 00159 00160 void bfree(VBVHTree *tree) 00161 { 00162 if(tot_pushup + tot_pushdown + tot_hints + tot_moves) 00163 { 00164 if(G.f & G_DEBUG) { 00165 printf("tot pushups: %d\n", tot_pushup); 00166 printf("tot pushdowns: %d\n", tot_pushdown); 00167 printf("tot moves: %d\n", tot_moves); 00168 printf("tot hints created: %d\n", tot_hints); 00169 } 00170 00171 tot_pushup = 0; 00172 tot_pushdown = 0; 00173 tot_hints = 0; 00174 tot_moves = 0; 00175 } 00176 bvh_free(tree); 00177 } 00178 00179 /* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ 00180 template<class Tree, int STACK_SIZE> 00181 RayObjectAPI make_api() 00182 { 00183 static RayObjectAPI api = 00184 { 00185 (RE_rayobject_raycast_callback) ((int(*)(Tree*,Isect*)) &intersect<STACK_SIZE>), 00186 (RE_rayobject_add_callback) ((void(*)(Tree*,RayObject*)) &bvh_add<Tree>), 00187 (RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>), 00188 (RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>), 00189 (RE_rayobject_merge_bb_callback)((void(*)(Tree*,float*,float*)) &bvh_bb<Tree>), 00190 (RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost<Tree>), 00191 (RE_rayobject_hint_bb_callback) ((void(*)(Tree*,LCTSHint*,float*,float*)) &bvh_hint_bb<Tree>) 00192 }; 00193 00194 return api; 00195 } 00196 00197 template<class Tree> 00198 RayObjectAPI* bvh_get_api(int maxstacksize) 00199 { 00200 static RayObjectAPI bvh_api256 = make_api<Tree,1024>(); 00201 00202 if(maxstacksize <= 1024) return &bvh_api256; 00203 assert(maxstacksize <= 256); 00204 return 0; 00205 } 00206 00207 RayObject *RE_rayobject_vbvh_create(int size) 00208 { 00209 return bvh_create_tree<VBVHTree,DFS_STACK_SIZE>(size); 00210 }