[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21439] branches/soc-2009-jaguarandi/ source/blender/render/intern: *Added support for variable cost per RayObject
André Pinto
andresusanopinto at gmail.com
Wed Jul 8 22:04:41 CEST 2009
Revision: 21439
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21439
Author: jaguarandi
Date: 2009-07-08 22:04:40 +0200 (Wed, 08 Jul 2009)
Log Message:
-----------
*Added support for variable cost per RayObject
Suposedly usefull for creating trees of objects (where objects have very diferent size-NumFaces and shape-BB)
Altought the implemented costs maybe not be very correct (for now), as i didnt cared about following a specific "corrected" model
Modified Paths:
--------------
branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject.h
branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject.c
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c
branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject.h
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject.h 2009-07-08 19:39:37 UTC (rev 21438)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject.h 2009-07-08 20:04:40 UTC (rev 21439)
@@ -86,11 +86,13 @@
};
+
typedef int (*RE_rayobject_raycast_callback)(RayObject *, Isect *);
-typedef void (*RE_rayobject_add_callback)(RayObject *, RayObject *);
+typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject);
typedef void (*RE_rayobject_done_callback)(RayObject *);
typedef void (*RE_rayobject_free_callback)(RayObject *);
typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max);
+typedef float (*RE_rayobject_cost_callback)(RayObject *);
typedef struct RayObjectAPI
{
@@ -99,6 +101,7 @@
RE_rayobject_done_callback done;
RE_rayobject_free_callback free;
RE_rayobject_merge_bb_callback bb;
+ RE_rayobject_cost_callback cost;
} RayObjectAPI;
@@ -128,6 +131,12 @@
*/
float RE_rayobject_bb_intersect(const Isect *i, const float *bb);
+/*
+ * Returns the expected cost of raycast on this node, primitives have a cost of 1
+ */
+float RE_rayobject_cost(RayObject *r);
+
+
#define ISECT_EPSILON ((float)FLT_EPSILON)
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h 2009-07-08 19:39:37 UTC (rev 21438)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/include/rayobject_rtbuild.h 2009-07-08 20:04:40 UTC (rev 21439)
@@ -80,4 +80,7 @@
int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds);
+/* bb utils */
+float bb_area(float *min, float *max);
+
#endif
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject.c
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject.c 2009-07-08 19:39:37 UTC (rev 21438)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject.c 2009-07-08 20:04:40 UTC (rev 21439)
@@ -400,6 +400,20 @@
else assert(0);
}
+float RE_rayobject_cost(RayObject *r)
+{
+ if(RayObject_isRayFace(r))
+ {
+ return 1.0;
+ }
+ else if(RayObject_isRayAPI(r))
+ {
+ r = RayObject_align( r );
+ return r->api->cost( r );
+ }
+ else assert(0);
+}
+
#ifdef RE_RAYCOUNTER
void RE_RC_INFO(RayCounter *info)
{
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c 2009-07-08 19:39:37 UTC (rev 21438)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_bvh.c 2009-07-08 20:04:40 UTC (rev 21439)
@@ -53,6 +53,7 @@
static void bvh_done(BVHTree *o);
static void bvh_free(BVHTree *o);
static void bvh_bb(BVHTree *o, float *min, float *max);
+static float bvh_cost(BVHTree *o);
static RayObjectAPI bvh_api =
{
@@ -64,7 +65,8 @@
(RE_rayobject_add_callback) bvh_add,
(RE_rayobject_done_callback) bvh_done,
(RE_rayobject_free_callback) bvh_free,
- (RE_rayobject_merge_bb_callback)bvh_bb
+ (RE_rayobject_merge_bb_callback)bvh_bb,
+ (RE_rayobject_cost_callback) bvh_cost
};
typedef struct BVHNode BVHNode;
@@ -91,6 +93,7 @@
BVHNode *node_alloc, *node_next;
float *bb_alloc, *bb_next;
#endif
+ float cost;
RTBuilder *builder;
};
@@ -153,6 +156,12 @@
bvh_merge_bb(obj->root, min, max);
}
+static float bvh_cost(BVHTree *obj)
+{
+ assert(obj->cost >= 0.0);
+ return obj->cost;
+}
+
/*
* Tree transverse
*/
@@ -336,8 +345,9 @@
return pid*BVH_NCHILDS+(2-BVH_NCHILDS)+nchild;
}
-static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid)
+static BVHNode *bvh_rearrange(BVHTree *tree, RTBuilder *builder, int nid, float *cost)
{
+ *cost = 0;
if(rtbuild_size(builder) == 0)
return 0;
@@ -361,6 +371,7 @@
for(; i<BVH_NCHILDS; i++)
parent->child[i] = 0;
+ *cost = bb_area(parent->bb, parent->bb+3)*RE_rayobject_cost(child);
return parent;
}
else
@@ -368,6 +379,8 @@
assert(!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;
}
}
@@ -392,12 +405,16 @@
parent->split_axis = builder->split_axis;
for(i=0; i<nc; i++)
{
- parent->child[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i) );
+ float tcost;
+ parent->child[i] = bvh_rearrange( tree, rtbuild_get_child(builder, i, &tmp), child_id(nid,i), &tcost );
bvh_merge_bb(parent->child[i], parent->bb, parent->bb+3);
+
+ *cost += tcost;
}
for(; i<BVH_NCHILDS; i++)
parent->child[i] = 0;
+ *cost *= bb_area(parent->bb, parent->bb+3);
return parent;
}
}
@@ -412,7 +429,6 @@
static void bvh_done(BVHTree *obj)
{
-
#ifdef DYNAMIC_ALLOC
int needed_nodes = (rtbuild_size(obj->builder)+1)*2;
if(needed_nodes > BLI_MEMARENA_STD_BUFSIZE)
@@ -437,7 +453,7 @@
obj->bb_next = obj->bb_alloc;
#endif
- obj->root = bvh_rearrange( obj, obj->builder, 1 );
+ obj->root = bvh_rearrange( obj, obj->builder, 1, &obj->cost );
#ifndef DYNAMIC_ALLOC
assert(obj->node_alloc+needed_nodes >= obj->node_next);
Modified: branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c
===================================================================
--- branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c 2009-07-08 19:39:37 UTC (rev 21438)
+++ branches/soc-2009-jaguarandi/source/blender/render/intern/source/rayobject_rtbuild.c 2009-07-08 20:04:40 UTC (rev 21439)
@@ -216,6 +216,7 @@
struct CostObject
{
RayObject *obj;
+ float cost;
float bb[6];
};
@@ -278,6 +279,7 @@
else
{
float bcost = FLT_MAX;
+ float childrens_cost = 0;
int i, axis, baxis, boffset, k, try_axis[3];
CostObject *cost = MEM_mallocN( sizeof(CostObject)*size, "RTBuilder.HeuristicObjectSplitter" );
float *acc_bb = MEM_mallocN( sizeof(float)*6*size, "RTBuilder.HeuristicObjectSplitterBB" );
@@ -286,12 +288,14 @@
{
cost[i].obj = b->begin[i];
INIT_MINMAX(cost[i].bb, cost[i].bb+3);
- RE_rayobject_merge_bb(b->begin[i], cost[i].bb, cost[i].bb+3);
+ RE_rayobject_merge_bb(cost[i].obj, cost[i].bb, cost[i].bb+3);
+ cost[i].cost = RE_rayobject_cost(cost[i].obj);
+ childrens_cost += cost[i].cost;
}
if(b->child_sorted_axis >= 0 && b->child_sorted_axis < 3)
{
- try_axis[0] = b->child_sorted_axis;
+ try_axis[0] = b->child_sorted_axis;
try_axis[1] = (b->child_sorted_axis+1)%3;
try_axis[2] = (b->child_sorted_axis+2)%3;
}
@@ -304,8 +308,11 @@
for(axis=try_axis[k=0]; k<3; axis=try_axis[++k])
{
+ float left_cost, right_cost;
float other_bb[6];
+
+
costobject_sort(cost, cost+size, axis);
for(i=size-1; i>=0; i--)
{
@@ -330,18 +337,22 @@
INIT_MINMAX(other_bb, other_bb+3);
DO_MIN( cost[0].bb, other_bb );
DO_MAX( cost[0].bb+3, other_bb+3 );
+ left_cost = cost[0].cost;
+ right_cost = childrens_cost-cost[0].cost;
+ if(right_cost < 0) right_cost = 0;
for(i=1; i<size; i++)
{
//Worst case heuristic (cost of each child is linear)
float hcost, left_side, right_side;
- left_side = bb_area(other_bb, other_bb+3)*(i+logf(i));
- right_side= bb_area(acc_bb+i*6, acc_bb+i*6+3)*(size-i+logf(size-i));
+ left_side = bb_area(other_bb, other_bb+3)*left_cost; //(i+logf(i));
+ right_side= bb_area(acc_bb+i*6, acc_bb+i*6+3)*right_cost; //(size-i+logf(size-i));
if(left_side > bcost) break; //No way we can find a better heuristic in this axis
hcost = left_side+right_side;
+ assert(hcost >= 0);
if( hcost < bcost
|| (hcost == bcost && axis < baxis)) //this makes sure the tree built is the same whatever is the order of the sorting axis
{
@@ -351,6 +362,9 @@
}
DO_MIN( cost[i].bb, other_bb );
DO_MAX( cost[i].bb+3, other_bb+3 );
+ left_cost += cost[i].cost;
+ right_cost -= cost[i].cost;
+ if(right_cost < 0.0f) right_cost = 0.0;
}
if(baxis == axis)
More information about the Bf-blender-cvs
mailing list