Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2009-10-01 22:30:59 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2009-10-01 22:30:59 +0400
commit8da55763b541075dae4b1f7713c43af2b609e332 (patch)
tree11ffca85cc606440a6268de7ea9afb5db806e426 /source/blender/render/intern
parent04fdec2017461bc9f85b24a74782e6049c0f2df9 (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')
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp10
-rw-r--r--source/blender/render/intern/raytrace/rayobject_bih.cpp248
-rw-r--r--source/blender/render/intern/raytrace/rayobject_bvh.cpp233
-rw-r--r--source/blender/render/intern/raytrace/rayobject_qbvh.cpp31
-rw-r--r--source/blender/render/intern/raytrace/rayobject_svbvh.cpp38
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp44
-rw-r--r--source/blender/render/intern/source/rayobject_blibvh.c15
-rw-r--r--source/blender/render/intern/source/rayobject_octree.c17
-rw-r--r--source/blender/render/intern/source/rayshade.c46
9 files changed, 128 insertions, 554 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;
}
diff --git a/source/blender/render/intern/source/rayobject_blibvh.c b/source/blender/render/intern/source/rayobject_blibvh.c
index 6e789862207..487193ef1f2 100644
--- a/source/blender/render/intern/source/rayobject_blibvh.c
+++ b/source/blender/render/intern/source/rayobject_blibvh.c
@@ -42,13 +42,26 @@ static void RE_rayobject_blibvh_done(RayObject *o);
static void RE_rayobject_blibvh_free(RayObject *o);
static void RE_rayobject_blibvh_bb(RayObject *o, float *min, float *max);
+static float RE_rayobject_blibvh_cost(RayObject *o)
+{
+ //TODO calculate the expected cost to raycast on this structure
+ return 1.0;
+}
+
+static void RE_rayobject_blibvh_hint_bb(RayObject *o, RayHint *hint, float *min, float *max)
+{
+ return;
+}
+
static RayObjectAPI bvh_api =
{
RE_rayobject_blibvh_intersect,
RE_rayobject_blibvh_add,
RE_rayobject_blibvh_done,
RE_rayobject_blibvh_free,
- RE_rayobject_blibvh_bb
+ RE_rayobject_blibvh_bb,
+ RE_rayobject_blibvh_cost,
+ RE_rayobject_blibvh_hint_bb
};
typedef struct BVHObject
diff --git a/source/blender/render/intern/source/rayobject_octree.c b/source/blender/render/intern/source/rayobject_octree.c
index 4246dd522db..2f0a1a3f53b 100644
--- a/source/blender/render/intern/source/rayobject_octree.c
+++ b/source/blender/render/intern/source/rayobject_octree.c
@@ -90,13 +90,28 @@ static void RE_rayobject_octree_done(RayObject *o);
static void RE_rayobject_octree_free(RayObject *o);
static void RE_rayobject_octree_bb(RayObject *o, float *min, float *max);
+/*
+ * This function is not expected to be called by current code state.
+ */
+static float RE_rayobject_octree_cost(RayObject *o)
+{
+ return 1.0;
+}
+
+static void RE_rayobject_octree_hint_bb(RayObject *o, RayHint *hint, float *min, float *max)
+{
+ return;
+}
+
static RayObjectAPI octree_api =
{
RE_rayobject_octree_intersect,
RE_rayobject_octree_add,
RE_rayobject_octree_done,
RE_rayobject_octree_free,
- RE_rayobject_octree_bb
+ RE_rayobject_octree_bb,
+ RE_rayobject_octree_cost,
+ RE_rayobject_octree_hint_bb
};
/* **************** ocval method ******************* */
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index d84a2d9210a..641085d8cd6 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -62,7 +62,6 @@
#include "raycounter.h"
-#define USE_VLAK_PRIMITIVES 1
#define RAY_TRA 1
#define RAY_TRAFLIP 2
@@ -78,15 +77,12 @@ RayObject * RE_rayobject_create(int type, int size)
if(type == R_RAYSTRUCTURE_AUTO)
{
//TODO
-// if(detect_simd())
-// type = R_RAYSTRUCTURE_SIMD_SVBVH;
-// else
-// type = R_RAYSTRUCTURE_VBVH;
-
- type = R_RAYSTRUCTURE_SIMD_QBVH;
+ //if(detect_simd())
+ type = R_RAYSTRUCTURE_SIMD_SVBVH;
+ //else
+ // type = R_RAYSTRUCTURE_VBVH;
}
-
-
+
if(type == R_RAYSTRUCTURE_OCTREE)
{
//TODO dynamic ocres
@@ -108,10 +104,7 @@ RayObject * RE_rayobject_create(int type, int size)
{
return RE_rayobject_qbvh_create(size);
}
- if(type == R_RAYSTRUCTURE_BIH)
- {
-// return RE_rayobject_bih_create(size);
- }
+ assert( NULL );
return NULL;
}
@@ -209,8 +202,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
if(obr->raytree == NULL)
{
RayObject *raytree;
- RayFace *face;
- VlakPrimitive *vlakprimitive;
+ RayFace *face = NULL;
+ VlakPrimitive *vlakprimitive = NULL;
int v;
//Count faces
@@ -224,8 +217,8 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
assert( faces > 0 );
//Create Ray cast accelaration structure
- raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces );
- if(USE_VLAK_PRIMITIVES)
+ raytree = obr->raytree = RE_rayobject_create( re->r.raytrace_structure, faces );
+ if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives");
else
face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
@@ -237,7 +230,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
if(is_raytraceable_vlr(re, vlr))
{
- if(USE_VLAK_PRIMITIVES)
+ if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
{
RE_rayobject_add( raytree, RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr ) );
vlakprimitive++;
@@ -266,7 +259,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
static int has_special_rayobject(Render *re, ObjectInstanceRen *obi)
{
- if( (obi->flag & R_TRANSFORMED) )
+ if( (obi->flag & R_TRANSFORMED) && (re->r.raytrace_options & R_RAYTRACE_USE_INSTANCES) )
{
ObjectRen *obr = obi->obr;
int v, faces = 0;
@@ -291,8 +284,8 @@ static void makeraytree_single(Render *re)
{
ObjectInstanceRen *obi;
RayObject *raytree;
- RayFace *face;
- VlakPrimitive *vlakprimitive;
+ RayFace *face = NULL;
+ VlakPrimitive *vlakprimitive = NULL;
int faces = 0, obs = 0, special = 0;
for(obi=re->instancetable.first; obi; obi=obi->next)
@@ -318,9 +311,9 @@ static void makeraytree_single(Render *re)
}
//Create raytree
- raytree = re->raytree = RE_rayobject_create( re->r.raytrace_tree_type, faces+special );
+ raytree = re->raytree = RE_rayobject_create( re->r.raytrace_structure, faces+special );
- if(USE_VLAK_PRIMITIVES)
+ if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
{
vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives");
}
@@ -352,7 +345,7 @@ static void makeraytree_single(Render *re)
VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
if(is_raytraceable_vlr(re, vlr))
{
- if(USE_VLAK_PRIMITIVES)
+ if( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) )
{
RayObject *obj = RE_vlakprimitive_from_vlak( vlakprimitive, obi, vlr );
RE_rayobject_add( raytree, obj );
@@ -392,6 +385,11 @@ void makeraytree(Render *re)
re->i.infostr= "Raytree.. preparing";
re->stats_draw(re->sdh, &re->i);
+ /* disable options not yet suported by octree,
+ they might actually never be supported (unless people really need it) */
+ if(re->r.raytrace_structure == R_RAYSTRUCTURE_OCTREE)
+ re->r.raytrace_options &= ~( R_RAYTRACE_USE_INSTANCES | R_RAYTRACE_USE_LOCAL_COORDS);
+
BENCH(makeraytree_single(re), tree_build);
//Calculate raytree max_size