diff options
author | Andre Susano Pinto <andresusanopinto@gmail.com> | 2009-10-01 22:30:59 +0400 |
---|---|---|
committer | Andre Susano Pinto <andresusanopinto@gmail.com> | 2009-10-01 22:30:59 +0400 |
commit | 8da55763b541075dae4b1f7713c43af2b609e332 (patch) | |
tree | 11ffca85cc606440a6268de7ea9afb5db806e426 /source/blender/render/intern/raytrace | |
parent | 04fdec2017461bc9f85b24a74782e6049c0f2df9 (diff) |
*Updated UI options and added UI options to:
control whether instances are used or not
control whether vertexs are stored localy or not
*Removed unsused code
Diffstat (limited to 'source/blender/render/intern/raytrace')
6 files changed, 76 insertions, 528 deletions
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index c32f61e8f0a..34faa2951ce 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -142,7 +142,7 @@ static int intersection2(VlakRen *face, float r0, float r1, float r2, float rx1, return 0; } -static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) +static inline int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) { /* for baking selected to active non-traceable materials might still * be in the raytree */ @@ -156,7 +156,7 @@ static int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRen *vlr) return (is->lay & obi->lay); } -static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) +static inline int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen *vlr) { /* solid material types only */ if (vlr->mat->material_type == MA_TYPE_SURFACE) @@ -165,7 +165,7 @@ static int vlr_check_intersect_solid(Isect *is, ObjectInstanceRen* obi, VlakRen return 0; } -static int rayface_check_cullface(RayFace *face, Isect *is) +static inline int rayface_check_cullface(RayFace *face, Isect *is) { float nor[3]; @@ -189,7 +189,7 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) if(is->orig.ob == face->ob && is->orig.face == face->face) return 0; -/* + if(is->skip & RE_SKIP_VLR_RENDER_CHECK) { if(vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face ) == 0) @@ -205,7 +205,7 @@ static int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) if(rayface_check_cullface(face, is) == 0) return 0; } -*/ + RE_RC_COUNT(is->raycounter->faces.test); //Load coords diff --git a/source/blender/render/intern/raytrace/rayobject_bih.cpp b/source/blender/render/intern/raytrace/rayobject_bih.cpp deleted file mode 100644 index efbf70616b7..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_bih.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include <assert.h> -#include <stdio.h> - -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" - -#define BIH_NCHILDS 4 -typedef struct BIHTree BIHTree; - -static int bih_intersect(BIHTree *obj, Isect *isec); -static void bih_add(BIHTree *o, RayObject *ob); -static void bih_done(BIHTree *o); -static void bih_free(BIHTree *o); -static void bih_bb(BIHTree *o, float *min, float *max); - -static RayObjectAPI bih_api = -{ - (RE_rayobject_raycast_callback) bih_intersect, - (RE_rayobject_add_callback) bih_add, - (RE_rayobject_done_callback) bih_done, - (RE_rayobject_free_callback) bih_free, - (RE_rayobject_merge_bb_callback)bih_bb -}; - -typedef struct BIHNode BIHNode; -struct BIHNode -{ - BIHNode *child[BIH_NCHILDS]; - float bi[BIH_NCHILDS][2]; - int split_axis; -}; - -struct BIHTree -{ - RayObject rayobj; - - BIHNode *root; - - BIHNode *node_alloc, *node_next; - RTBuilder *builder; - - float bb[2][3]; -}; - - -RayObject *RE_rayobject_bih_create(int size) -{ - BIHTree *obj= (BIHTree*)MEM_callocN(sizeof(BIHTree), "BIHTree"); - assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bih_api; - obj->root = NULL; - - obj->node_alloc = obj->node_next = NULL; - obj->builder = rtbuild_create( size ); - - return RE_rayobject_unalignRayAPI((RayObject*) obj); -} - -static void bih_free(BIHTree *obj) -{ - if(obj->builder) - rtbuild_free(obj->builder); - - if(obj->node_alloc) - MEM_freeN(obj->node_alloc); - - MEM_freeN(obj); -} - -static void bih_bb(BIHTree *obj, float *min, float *max) -{ - DO_MIN(obj->bb[0], min); - DO_MAX(obj->bb[1], max); -} - -/* - * Tree transverse - */ -static int dfs_raycast(const BIHNode *const node, Isect *isec, float tmin, float tmax) -{ - int i; - int hit = 0; - - const int *const offset = isec->bv_index + node->split_axis*2; - - //TODO diving heuristic - for(i=0; i<BIH_NCHILDS; i++) - { - - float t1 = (node->bi[i][offset[0]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; - float t2 = (node->bi[i][offset[1]] - isec->start[node->split_axis]) * isec->idot_axis[node->split_axis]; - - if(t1 < tmin) t1 = tmin; //t1 = MAX2(t1, tmin); - if(t2 > tmax) t2 = tmax; //t2 = MIN2(t2, tmax); - - if(t1 <= t2) - { - if(RE_rayobject_isAligned(node->child[i])) - { - if(node->child[i] == 0) break; - - hit |= dfs_raycast(node->child[i], isec, t1, t2); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - else - { - hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec); - if(hit && isec->mode == RE_RAY_SHADOW) return hit; - } - - if(tmax > isec->labda) - tmax = isec->labda; - } - } - - return hit; -} - -static int bih_intersect(BIHTree *obj, Isect *isec) -{ - if(RE_rayobject_isAligned(obj->root)) - return dfs_raycast(obj->root, isec, 0, isec->labda); - else - return RE_rayobject_intersect( (RayObject*)obj->root, isec); -} - - -/* - * Builds a BIH tree from builder object - */ -static void bih_add(BIHTree *obj, RayObject *ob) -{ - rtbuild_add( obj->builder, ob ); -} - -static BIHNode *bih_new_node(BIHTree *tree, int nid) -{ - BIHNode *node = tree->node_alloc + nid - 1; - assert(RE_rayobject_isAligned(node)); - if(node+1 > tree->node_next) - tree->node_next = node+1; - - return node; -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BIH_NCHILDS+(2-BIH_NCHILDS)+nchild; -} - -static BIHNode *bih_rearrange(BIHTree *tree, RTBuilder *builder, int nid, float *bb) -{ - if(rtbuild_size(builder) == 1) - { - RayObject *child = rtbuild_get_primitive( builder, 0 ); - assert(!RE_rayobject_isAligned(child)); - - INIT_MINMAX(bb, bb+3); - RE_rayobject_merge_bb( (RayObject*)child, bb, bb+3); - - return (BIHNode*)child; - } - else - { - int i; - int nc = rtbuild_mean_split_largest_axis(builder, BIH_NCHILDS); - RTBuilder tmp; - - BIHNode *parent = bih_new_node(tree, nid); - - INIT_MINMAX(bb, bb+3); - parent->split_axis = builder->split_axis; - for(i=0; i<nc; i++) - { - float cbb[6]; - parent->child[i] = bih_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), cbb ); - - parent->bi[i][0] = cbb[parent->split_axis]; - parent->bi[i][1] = cbb[parent->split_axis+3]; - - DO_MIN(cbb , bb); - DO_MAX(cbb+3, bb+3); - } - for(; i<BIH_NCHILDS; i++) - { - parent->bi[i][0] = 1.0; - parent->bi[i][1] = -1.0; - parent->child[i] = 0; - } - - return parent; - } -} - -static void bih_done(BIHTree *obj) -{ - int needed_nodes; - assert(obj->root == NULL && obj->node_alloc == NULL && obj->builder); - - //TODO exact calculate needed nodes - needed_nodes = (rtbuild_size(obj->builder)+1)*2; - assert(needed_nodes > 0); - - obj->node_alloc = (BIHNode*)MEM_mallocN( sizeof(BIHNode)*needed_nodes, "BIHTree.Nodes"); - obj->node_next = obj->node_alloc; - - obj->root = bih_rearrange( obj, obj->builder, 1, (float*)obj->bb ); - - rtbuild_free( obj->builder ); - obj->builder = NULL; - - assert(obj->node_alloc+needed_nodes >= obj->node_next); -} - diff --git a/source/blender/render/intern/raytrace/rayobject_bvh.cpp b/source/blender/render/intern/raytrace/rayobject_bvh.cpp deleted file mode 100644 index a7e96f6d3fc..00000000000 --- a/source/blender/render/intern/raytrace/rayobject_bvh.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): André Pinto. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#include <assert.h> - -#include "RE_raytrace.h" -#include "rayobject_rtbuild.h" -#include "rayobject.h" -#include "MEM_guardedalloc.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "BLI_memarena.h" -#include "bvh.h" - -#define BVH_NCHILDS 2 -#define RAY_BB_TEST_COST (0.2f) -#define DFS_STACK_SIZE 64 -#define DYNAMIC_ALLOC - -//#define rtbuild_split rtbuild_mean_split_largest_axis /* objects mean split on the longest axis, childs BB are allowed to overlap */ -//#define rtbuild_split rtbuild_median_split_largest_axis /* space median split on the longest axis, childs BB are allowed to overlap */ -#define rtbuild_split rtbuild_heuristic_object_split /* split objects using heuristic */ - -struct BVHNode -{ - BVHNode *child[BVH_NCHILDS]; - float bb[6]; - int split_axis; -}; - -struct BVHTree -{ - RayObject rayobj; - - BVHNode *root; - - MemArena *node_arena; - - float cost; - RTBuilder *builder; -}; - -/* - * Push nodes (used on dfs) - */ -template<class Node> -inline static void bvh_node_push_childs(Node *node, Isect *isec, Node **stack, int &stack_pos) -{ - //push nodes in reverse visit order - if(isec->idot_axis[node->split_axis] < 0.0f) - { - int i; - for(i=0; i<BVH_NCHILDS; i++) - if(node->child[i] == 0) - break; - else - stack[stack_pos++] = node->child[i]; - } - else - { - int i; - for(i=BVH_NCHILDS-1; i>=0; i--) - if(node->child[i] != 0) - stack[stack_pos++] = node->child[i]; - } -} - -/* - * BVH done - */ -static BVHNode *bvh_new_node(BVHTree *tree, int nid) -{ - BVHNode *node = (BVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(BVHNode)); - return node; -} - -static int child_id(int pid, int nchild) -{ - //N child of node A = A * K + (2 - K) + N, (0 <= N < K) - return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild; -} - - -static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost) -{ - *cost = 0; - if(rtbuild_size(builder) == 0) - return 0; - - if(rtbuild_size(builder) == 1) - { - RayObject *child = rtbuild_get_primitive( builder, 0 ); - - if(RE_rayobject_isRayFace(child)) - { - int i; - BVHNode *parent = bvh_new_node(tree, nid); - parent->split_axis = 0; - - INIT_MINMAX(parent->bb, parent->bb+3); - - for(i=0; i<1; i++) - { - parent->child[i] = (BVHNode*)rtbuild_get_primitive( builder, i ); - bvh_node_merge_bb(parent->child[i], parent->bb, parent->bb+3); - } - for(; i<BVH_NCHILDS; i++) - parent->child[i] = 0; - - *cost = RE_rayobject_cost(child)+RAY_BB_TEST_COST; - return parent; - } - else - { - assert(!RE_rayobject_isAligned(child)); - //Its a sub-raytrace structure, assume it has it own raycast - //methods and adding a Bounding Box arround is unnecessary - - *cost = RE_rayobject_cost(child); - return (BVHNode*)child; - } - } - else - { - int i; - RTBuilder tmp; - BVHNode *parent = bvh_new_node(tree, nid); - int nc = rtbuild_split(builder, BVH_NCHILDS); - - - INIT_MINMAX(parent->bb, parent->bb+3); - parent->split_axis = builder->split_axis; - for(i=0; i<nc; i++) - { - float cbb[6]; - float tcost; - parent->child[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost ); - - INIT_MINMAX(cbb, cbb+3); - bvh_node_merge_bb(parent->child[i], cbb, cbb+3); - DO_MIN(cbb, parent->bb); - DO_MAX(cbb+3, parent->bb+3); - - *cost += tcost*bb_area(cbb, cbb+3); - } - for(; i<BVH_NCHILDS; i++) - parent->child[i] = 0; - - *cost /= bb_area(parent->bb, parent->bb+3); - *cost += nc*RAY_BB_TEST_COST; - return parent; - } - - assert(false); -} - -template<> -void bvh_done<BVHTree>(BVHTree *obj) -{ - int needed_nodes = (rtbuild_size(obj->builder)+1)*2; - if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE) - needed_nodes = BLI_MEMARENA_STD_BUFSIZE; - - obj->node_arena = BLI_memarena_new(needed_nodes); - BLI_memarena_use_malloc(obj->node_arena); - - - obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost ); - - rtbuild_free( obj->builder ); - obj->builder = NULL; -} - -template<> -int bvh_intersect<BVHTree>(BVHTree *obj, Isect* isec) -{ - if(RE_rayobject_isAligned(obj->root)) - return bvh_node_stack_raycast<BVHNode,64,true>(obj->root, isec); - else - return RE_rayobject_intersect( (RayObject*) obj->root, isec ); -} - - -/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ -static RayObjectAPI bvh_api = -{ - (RE_rayobject_raycast_callback) ((int(*)(BVHTree*,Isect*)) &bvh_intersect<BVHTree>), - (RE_rayobject_add_callback) ((void(*)(BVHTree*,RayObject*)) &bvh_add<BVHTree>), - (RE_rayobject_done_callback) ((void(*)(BVHTree*)) &bvh_done<BVHTree>), - (RE_rayobject_free_callback) ((void(*)(BVHTree*)) &bvh_free<BVHTree>), - (RE_rayobject_merge_bb_callback)((void(*)(BVHTree*,float*,float*)) &bvh_bb<BVHTree>), - (RE_rayobject_cost_callback) ((float(*)(BVHTree*)) &bvh_cost<BVHTree>) -}; - - -RayObject *RE_rayobject_bvh_create(int size) -{ - BVHTree *obj= (BVHTree*)MEM_callocN(sizeof(BVHTree), "BVHTree"); - assert( RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ - - obj->rayobj.api = &bvh_api; - obj->root = NULL; - - obj->node_arena = NULL; - obj->builder = rtbuild_create( size ); - - return RE_rayobject_unalignRayAPI((RayObject*) obj); -} diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp index 53579d2915f..59daf9dc962 100644 --- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp @@ -44,17 +44,6 @@ struct QBVHTree }; -/* - * Cost to test N childs - */ -struct PackCost -{ - float operator()(int n) - { - return (n / 4) + ((n % 4) > 2 ? 1 : n%4); - } -}; - template<> void bvh_done<QBVHTree>(QBVHTree *obj) { @@ -68,21 +57,11 @@ void bvh_done<QBVHTree>(QBVHTree *obj) BLI_memarena_use_malloc(arena2); BLI_memarena_use_align(arena2, 16); - //Build and optimize the tree - - if(0) - { - VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder); - pushup_simd<VBVHNode,4>(root); - obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root); - } - else - { - //Finds the optimal packing of this tree using a given cost model - OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1).transform(obj->builder); - VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root); - obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root); - } + //Build and optimize the tree + //TODO do this in 1 pass (half memory usage during building) + VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder); + pushup_simd<VBVHNode,4>(root); + obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root); //Cleanup BLI_memarena_free(arena1); diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp index 1bcffddd0ac..f806fcf93ef 100644 --- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp @@ -43,6 +43,17 @@ struct SVBVHTree RTBuilder *builder; }; +/* + * Cost to test N childs + */ +struct PackCost +{ + float operator()(int n) + { + return (n / 4) + ((n % 4) > 2 ? 1 : n%4); + } +}; + template<> void bvh_done<SVBVHTree>(SVBVHTree *obj) @@ -58,16 +69,27 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj) BLI_memarena_use_align(arena2, 16); //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder); - reorganize(root); - remove_useless(root, &root); - bvh_refit(root); + if(0) + { + VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder); + reorganize(root); + remove_useless(root, &root); + bvh_refit(root); - pushup(root); - pushdown(root); - pushup_simd<VBVHNode,4>(root); + pushup(root); + pushdown(root); + pushup_simd<VBVHNode,4>(root); - obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root); + obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root); + } + else + { + //Finds the optimal packing of this tree using a given cost model + //TODO this uses quite a lot of memory, find ways to reduce memory usage during building + OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena1).transform(obj->builder); + VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root); + obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root); + } //Free data diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp index 4e51de0da07..5260abf67ae 100644 --- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp +++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp @@ -58,6 +58,16 @@ struct VBVHTree RTBuilder *builder; }; +/* + * Cost to test N childs + */ +struct PackCost +{ + float operator()(int n) + { + return n; + } +}; template<> void bvh_done<VBVHTree>(VBVHTree *obj) @@ -67,24 +77,42 @@ void bvh_done<VBVHTree>(VBVHTree *obj) //TODO find a away to exactly calculate the needed memory MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); BLI_memarena_use_malloc(arena1); - //Build and optimize the tree - VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder); + if(1) + { + VBVHNode *root = BuildBinaryVBVH<VBVHNode>(arena1).transform(obj->builder); - reorganize(root); - remove_useless(root, &root); - bvh_refit(root); + reorganize(root); + remove_useless(root, &root); + bvh_refit(root); - pushup(root); - pushdown(root); + pushup(root); + pushdown(root); + obj->root = root; + } + else + { +/* + TODO + MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_malloc(arena2); + + //Finds the optimal packing of this tree using a given cost model + //TODO this uses quite a lot of memory, find ways to reduce memory usage during building + OVBVHNode *root = BuildBinaryVBVH<OVBVHNode>(arena2).transform(obj->builder); + VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root); + obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root); + + BLI_memarena_free(arena2); + */ + } //Cleanup rtbuild_free( obj->builder ); obj->builder = NULL; obj->node_arena = arena1; - obj->root = root; obj->cost = 1.0; } |