style cleanup: raytree code

This commit is contained in:
Campbell Barton
2012-05-15 18:45:20 +00:00
parent 7aa21d677a
commit e79c29a1d6
16 changed files with 441 additions and 464 deletions

View File

@@ -2301,7 +2301,7 @@ class VIEW3D_PT_view3d_cursor(Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
view = context.space_data view = context.space_data
return (view) return (view is not None)
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout

View File

@@ -366,12 +366,12 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
} }
//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
BVHTreeOverlap *overlap, CollPair *collpair, float UNUSED(dt) ) BVHTreeOverlap *overlap, CollPair *collpair, float UNUSED(dt))
{ {
ClothModifierData *clmd = (ClothModifierData *)md1; ClothModifierData *clmd = (ClothModifierData *)md1;
CollisionModifierData *collmd = (CollisionModifierData *) md2; CollisionModifierData *collmd = (CollisionModifierData *) md2;
Cloth *cloth = clmd->clothObject; /* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
MFace *face1=NULL, *face2 = NULL; MFace *face1=NULL, *face2 = NULL;
#ifdef USE_BULLET #ifdef USE_BULLET
ClothVertex *verts1 = clmd->clothObject->verts; ClothVertex *verts1 = clmd->clothObject->verts;

View File

@@ -59,12 +59,12 @@ inline int test_bb_group4(__m128 *bb_group, const Isect *isec)
copy_v3_v3(start, isec->start); copy_v3_v3(start, isec->start);
copy_v3_v3(idot_axis, isec->idot_axis); copy_v3_v3(idot_axis, isec->idot_axis);
const __m128 tmin1 = _mm_max_ps(tmin0, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[0]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) ); const __m128 tmin1 = _mm_max_ps(tmin0, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[0]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) );
const __m128 tmax1 = _mm_min_ps(tmax0, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[1]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) ); const __m128 tmax1 = _mm_min_ps(tmax0, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[1]], _mm_set_ps1(start[0]) ), _mm_set_ps1(idot_axis[0])) );
const __m128 tmin2 = _mm_max_ps(tmin1, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[2]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) ); const __m128 tmin2 = _mm_max_ps(tmin1, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[2]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) );
const __m128 tmax2 = _mm_min_ps(tmax1, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[3]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) ); const __m128 tmax2 = _mm_min_ps(tmax1, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[3]], _mm_set_ps1(start[1]) ), _mm_set_ps1(idot_axis[1])) );
const __m128 tmin3 = _mm_max_ps(tmin2, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[4]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) ); const __m128 tmin3 = _mm_max_ps(tmin2, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[4]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) );
const __m128 tmax3 = _mm_min_ps(tmax2, _mm_mul_ps( _mm_sub_ps( bb_group[isec->bv_index[5]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) ); const __m128 tmax3 = _mm_min_ps(tmax2, _mm_mul_ps(_mm_sub_ps(bb_group[isec->bv_index[5]], _mm_set_ps1(start[2]) ), _mm_set_ps1(idot_axis[2])) );
return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3)); return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3));
} }
@@ -142,7 +142,7 @@ static float bvh_cost(Tree *obj)
/* bvh tree nodes generics */ /* bvh tree nodes generics */
template<class Node> static inline int bvh_node_hit_test(Node *node, Isect *isec) template<class Node> static inline int bvh_node_hit_test(Node *node, Isect *isec)
{ {
return rayobject_bb_intersect_test(isec, (const float*)node->bb); return rayobject_bb_intersect_test(isec, (const float *)node->bb);
} }
@@ -185,7 +185,7 @@ static int bvh_node_stack_raycast(Node *root, Isect *isec)
} }
} }
else { else {
hit |= RE_rayobject_intersect( (RayObject*)node, isec); hit |= RE_rayobject_intersect( (RayObject *)node, isec);
if (SHADOW && hit) return hit; if (SHADOW && hit) return hit;
} }
} }
@@ -211,84 +211,84 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec)
if (!is_leaf(root->child)) if (!is_leaf(root->child))
bvh_node_push_childs(root, isec, stack, stack_pos); bvh_node_push_childs(root, isec, stack, stack_pos);
else else
return RE_rayobject_intersect( (RayObject*)root->child, isec); return RE_rayobject_intersect( (RayObject *)root->child, isec);
} }
else else
return RE_rayobject_intersect( (RayObject*)root, isec); return RE_rayobject_intersect( (RayObject *)root, isec);
} }
else { else {
if (!is_leaf(root)) if (!is_leaf(root))
stack[stack_pos++] = root; stack[stack_pos++] = root;
else else
return RE_rayobject_intersect( (RayObject*)root, isec); return RE_rayobject_intersect( (RayObject *)root, isec);
} }
while (true) { while (true) {
//Use SIMD 4 //Use SIMD 4
if (stack_pos >= 4) { if (stack_pos >= 4) {
__m128 t_bb[6]; __m128 t_bb[6];
Node * t_node[4]; Node *t_node[4];
stack_pos -= 4; stack_pos -= 4;
/* prepare the 4BB for SIMD */ /* prepare the 4BB for SIMD */
t_node[0] = stack[stack_pos+0]->child; t_node[0] = stack[stack_pos + 0]->child;
t_node[1] = stack[stack_pos+1]->child; t_node[1] = stack[stack_pos + 1]->child;
t_node[2] = stack[stack_pos+2]->child; t_node[2] = stack[stack_pos + 2]->child;
t_node[3] = stack[stack_pos+3]->child; t_node[3] = stack[stack_pos + 3]->child;
const float *bb0 = stack[stack_pos+0]->bb;
const float *bb1 = stack[stack_pos+1]->bb;
const float *bb2 = stack[stack_pos+2]->bb;
const float *bb3 = stack[stack_pos+3]->bb;
const __m128 x0y0x1y1 = _mm_shuffle_ps( _mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(1, 0, 1, 0) );
const __m128 x2y2x3y3 = _mm_shuffle_ps( _mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(1, 0, 1, 0) );
t_bb[0] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2, 0, 2, 0) );
t_bb[1] = _mm_shuffle_ps( x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3, 1, 3, 1) );
const __m128 z0X0z1X1 = _mm_shuffle_ps( _mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3, 2, 3, 2) ); const float *bb0 = stack[stack_pos + 0]->bb;
const __m128 z2X2z3X3 = _mm_shuffle_ps( _mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3, 2, 3, 2) ); const float *bb1 = stack[stack_pos + 1]->bb;
t_bb[2] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2, 0, 2, 0) ); const float *bb2 = stack[stack_pos + 2]->bb;
t_bb[3] = _mm_shuffle_ps( z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3, 1, 3, 1) ); const float *bb3 = stack[stack_pos + 3]->bb;
const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps( _mm_load_ps(bb0+4), _mm_load_ps(bb1+4), _MM_SHUFFLE(1, 0, 1, 0) ); const __m128 x0y0x1y1 = _mm_shuffle_ps(_mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(1, 0, 1, 0) );
const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps( _mm_load_ps(bb2+4), _mm_load_ps(bb3+4), _MM_SHUFFLE(1, 0, 1, 0) ); const __m128 x2y2x3y3 = _mm_shuffle_ps(_mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(1, 0, 1, 0) );
t_bb[4] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2, 0, 2, 0) ); t_bb[0] = _mm_shuffle_ps(x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(2, 0, 2, 0) );
t_bb[5] = _mm_shuffle_ps( Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3, 1, 3, 1) ); t_bb[1] = _mm_shuffle_ps(x0y0x1y1, x2y2x3y3, _MM_SHUFFLE(3, 1, 3, 1) );
const __m128 z0X0z1X1 = _mm_shuffle_ps(_mm_load_ps(bb0), _mm_load_ps(bb1), _MM_SHUFFLE(3, 2, 3, 2) );
const __m128 z2X2z3X3 = _mm_shuffle_ps(_mm_load_ps(bb2), _mm_load_ps(bb3), _MM_SHUFFLE(3, 2, 3, 2) );
t_bb[2] = _mm_shuffle_ps(z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(2, 0, 2, 0) );
t_bb[3] = _mm_shuffle_ps(z0X0z1X1, z2X2z3X3, _MM_SHUFFLE(3, 1, 3, 1) );
const __m128 Y0Z0Y1Z1 = _mm_shuffle_ps(_mm_load_ps(bb0 + 4), _mm_load_ps(bb1 + 4), _MM_SHUFFLE(1, 0, 1, 0) );
const __m128 Y2Z2Y3Z3 = _mm_shuffle_ps(_mm_load_ps(bb2 + 4), _mm_load_ps(bb3 + 4), _MM_SHUFFLE(1, 0, 1, 0) );
t_bb[4] = _mm_shuffle_ps(Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(2, 0, 2, 0) );
t_bb[5] = _mm_shuffle_ps(Y0Z0Y1Z1, Y2Z2Y3Z3, _MM_SHUFFLE(3, 1, 3, 1) );
#if 0 #if 0
for(int i=0; i<4; i++) for (int i = 0; i < 4; i++)
{ {
Node *t = stack[stack_pos+i]; Node *t = stack[stack_pos + i];
assert(!is_leaf(t)); assert(!is_leaf(t));
float *bb = ((float*)t_bb)+i; float *bb = ((float *)t_bb) + i;
bb[4*0] = t->bb[0]; bb[4 * 0] = t->bb[0];
bb[4*1] = t->bb[1]; bb[4 * 1] = t->bb[1];
bb[4*2] = t->bb[2]; bb[4 * 2] = t->bb[2];
bb[4*3] = t->bb[3]; bb[4 * 3] = t->bb[3];
bb[4*4] = t->bb[4]; bb[4 * 4] = t->bb[4];
bb[4*5] = t->bb[5]; bb[4 * 5] = t->bb[5];
t_node[i] = t->child; t_node[i] = t->child;
} }
#endif #endif
RE_RC_COUNT(isec->raycounter->simd_bb.test); RE_RC_COUNT(isec->raycounter->simd_bb.test);
int res = test_bb_group4( t_bb, isec ); int res = test_bb_group4(t_bb, isec);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
if (res & (1 << i)) { if (res & (1 << i)) {
RE_RC_COUNT(isec->raycounter->simd_bb.hit); RE_RC_COUNT(isec->raycounter->simd_bb.hit);
if (!is_leaf(t_node[i])) { if (!is_leaf(t_node[i])) {
for (Node *t = t_node[i]; t; t = t->sibling) { for (Node *t = t_node[i]; t; t = t->sibling) {
assert(stack_pos < MAX_STACK_SIZE); assert(stack_pos < MAX_STACK_SIZE);
stack[stack_pos++] = t; stack[stack_pos++] = t;
}
}
else {
hit |= RE_rayobject_intersect( (RayObject *)t_node[i], isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit;
} }
} }
else {
hit |= RE_rayobject_intersect( (RayObject*)t_node[i], isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit;
}
}
} }
else if (stack_pos > 0) { else if (stack_pos > 0) {
Node *node = stack[--stack_pos]; Node *node = stack[--stack_pos];
@@ -300,7 +300,7 @@ static int bvh_node_stack_raycast_simd(Node *root, Isect *isec)
assert(stack_pos <= MAX_STACK_SIZE); assert(stack_pos <= MAX_STACK_SIZE);
} }
else { else {
hit |= RE_rayobject_intersect( (RayObject*)node->child, isec); hit |= RE_rayobject_intersect( (RayObject *)node->child, isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit; if (hit && isec->mode == RE_RAY_SHADOW) return hit;
} }
} }
@@ -324,7 +324,7 @@ static int bvh_node_raycast(Node *node, Isect *isec)
if (isec->idot_axis[node->split_axis] > 0.0f) if (isec->idot_axis[node->split_axis] > 0.0f)
{ {
int i; int i;
for(i=0; i<BVH_NCHILDS; i++) for (i = 0; i < BVH_NCHILDS; i++)
if (!is_leaf(node->child[i])) if (!is_leaf(node->child[i]))
{ {
if (node->child[i] == 0) break; if (node->child[i] == 0) break;
@@ -332,16 +332,14 @@ static int bvh_node_raycast(Node *node, Isect *isec)
hit |= bvh_node_raycast(node->child[i], isec); hit |= bvh_node_raycast(node->child[i], isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit; if (hit && isec->mode == RE_RAY_SHADOW) return hit;
} }
else else {
{ hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec);
hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit; if (hit && isec->mode == RE_RAY_SHADOW) return hit;
} }
} }
else else {
{
int i; int i;
for(i=BVH_NCHILDS-1; i>=0; i--) for (i = BVH_NCHILDS - 1; i >= 0; i--)
if (!is_leaf(node->child[i])) if (!is_leaf(node->child[i]))
{ {
if (node->child[i]) if (node->child[i])
@@ -350,9 +348,8 @@ static int bvh_node_raycast(Node *node, Isect *isec)
if (hit && isec->mode == RE_RAY_SHADOW) return hit; if (hit && isec->mode == RE_RAY_SHADOW) return hit;
} }
} }
else else {
{ hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec);
hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit; if (hit && isec->mode == RE_RAY_SHADOW) return hit;
} }
} }
@@ -367,44 +364,44 @@ void bvh_dfs_make_hint(Node *node, LCTSHint *hint, int reserve_space, HintObject
assert(hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE); assert(hint->size + reserve_space + 1 <= RE_RAY_LCTS_MAX_SIZE);
if (is_leaf(node)) { if (is_leaf(node)) {
hint->stack[hint->size++] = (RayObject*)node; hint->stack[hint->size++] = (RayObject *)node;
} }
else { else {
int childs = count_childs(node); int childs = count_childs(node);
if (hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) { if (hint->size + reserve_space + childs <= RE_RAY_LCTS_MAX_SIZE) {
int result = hint_test_bb(hintObject, node->bb, node->bb+3); int result = hint_test_bb(hintObject, node->bb, node->bb + 3);
if (result == HINT_RECURSE) { if (result == HINT_RECURSE) {
/* We are 100% sure the ray will be pass inside this node */ /* We are 100% sure the ray will be pass inside this node */
bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject); bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject);
} }
else if (result == HINT_ACCEPT) { else if (result == HINT_ACCEPT) {
hint->stack[hint->size++] = (RayObject*)node; hint->stack[hint->size++] = (RayObject *)node;
} }
} }
else { else {
hint->stack[hint->size++] = (RayObject*)node; hint->stack[hint->size++] = (RayObject *)node;
} }
} }
} }
template<class Tree> template<class Tree>
static RayObjectAPI* bvh_get_api(int maxstacksize); static RayObjectAPI *bvh_get_api(int maxstacksize);
template<class Tree, int DFS_STACK_SIZE> template<class Tree, int DFS_STACK_SIZE>
static inline RayObject *bvh_create_tree(int size) static inline RayObject *bvh_create_tree(int size)
{ {
Tree *obj= (Tree*)MEM_callocN(sizeof(Tree), "BVHTree" ); Tree *obj = (Tree *)MEM_callocN(sizeof(Tree), "BVHTree");
assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */ assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */
obj->rayobj.api = bvh_get_api<Tree>(DFS_STACK_SIZE); obj->rayobj.api = bvh_get_api<Tree>(DFS_STACK_SIZE);
obj->root = NULL; obj->root = NULL;
obj->node_arena = NULL; obj->node_arena = NULL;
obj->builder = rtbuild_create( size ); obj->builder = rtbuild_create(size);
return RE_rayobject_unalignRayAPI((RayObject*) obj); return RE_rayobject_unalignRayAPI((RayObject *) obj);
} }
#endif #endif

View File

@@ -50,7 +50,7 @@
* because function is too long. Since this is code that is called billions * because function is too long. Since this is code that is called billions
* of times we really do want to inline. */ * of times we really do want to inline. */
MALWAYS_INLINE RayObject* rayface_from_coords(RayFace *rayface, void *ob, void *face, MALWAYS_INLINE RayObject *rayface_from_coords(RayFace *rayface, void *ob, void *face,
float *v1, float *v2, float *v3, float *v4) float *v1, float *v2, float *v3, float *v4)
{ {
rayface->ob = ob; rayface->ob = ob;
@@ -85,14 +85,14 @@ MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi,
} }
} }
RayObject* RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr) RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
{ {
return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0); return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
} }
/* VlakPrimitive */ /* VlakPrimitive */
RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr) RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr)
{ {
face->ob = obi; face->ob = obi;
face->face = vlr; face->face = vlr;
@@ -110,13 +110,13 @@ MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRe
return 0; return 0;
/* I know... cpu cycle waste, might do smarter once */ /* I know... cpu cycle waste, might do smarter once */
if (is->mode==RE_RAY_MIRROR) if (is->mode == RE_RAY_MIRROR)
return !(vlr->mat->mode & MA_ONLYCAST); return !(vlr->mat->mode & MA_ONLYCAST);
else else
return (is->lay & obi->lay); return (is->lay & obi->lay);
} }
MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen* UNUSED(obi), VlakRen *vlr) MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRen *UNUSED(obi), VlakRen *vlr)
{ {
/* solid material types only */ /* solid material types only */
if (vlr->mat->material_type == MA_TYPE_SURFACE) if (vlr->mat->material_type == MA_TYPE_SURFACE)
@@ -125,7 +125,7 @@ MALWAYS_INLINE int vlr_check_intersect_solid(Isect *UNUSED(is), ObjectInstanceRe
return 0; return 0;
} }
MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen* obi, VlakRen *UNUSED(vlr)) MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UNUSED(vlr))
{ {
return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT); return (obi->obr->ob != is->userdata) && (obi->obr->ob->flag & SELECT);
} }
@@ -138,7 +138,7 @@ MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, fl
float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1, l; float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1, l;
int quad; int quad;
quad= RE_rayface_isQuad(face); quad = RE_rayface_isQuad(face);
copy_v3_v3(co1, face->v1); copy_v3_v3(co1, face->v1);
copy_v3_v3(co2, face->v2); copy_v3_v3(co2, face->v2);
@@ -151,29 +151,29 @@ MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, fl
sub_v3_v3v3(t1, co3, co1); sub_v3_v3v3(t1, co3, co1);
cross_v3_v3v3(x, r, t1); cross_v3_v3v3(x, r, t1);
divdet= dot_v3v3(t0, x); divdet = dot_v3v3(t0, x);
sub_v3_v3v3(m, start, co3); sub_v3_v3v3(m, start, co3);
det1= dot_v3v3(m, x); det1 = dot_v3v3(m, x);
if (divdet != 0.0f) { if (divdet != 0.0f) {
divdet= 1.0f/divdet; divdet = 1.0f / divdet;
v= det1*divdet; v = det1 * divdet;
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) { if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
float cros[3]; float cros[3];
cross_v3_v3v3(cros, m, t0); cross_v3_v3v3(cros, m, t0);
u= divdet*dot_v3v3(cros, r); u = divdet * dot_v3v3(cros, r);
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON)) { if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
l= divdet*dot_v3v3(cros, t1); l = divdet * dot_v3v3(cros, t1);
/* check if intersection is within ray length */ /* check if intersection is within ray length */
if (l > -RE_RAYTRACE_EPSILON && l < *lambda) { if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
uv[0]= u; uv[0] = u;
uv[1]= v; uv[1] = v;
*lambda= l; *lambda = l;
return 1; return 1;
} }
} }
@@ -184,25 +184,25 @@ MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, fl
if (quad) { if (quad) {
copy_v3_v3(co4, face->v4); copy_v3_v3(co4, face->v4);
sub_v3_v3v3(t0, co3, co4); sub_v3_v3v3(t0, co3, co4);
divdet= dot_v3v3(t0, x); divdet = dot_v3v3(t0, x);
if (divdet != 0.0f) { if (divdet != 0.0f) {
divdet= 1.0f/divdet; divdet = 1.0f / divdet;
v = det1*divdet; v = det1 * divdet;
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) { if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
float cros[3]; float cros[3];
cross_v3_v3v3(cros, m, t0); cross_v3_v3v3(cros, m, t0);
u= divdet*dot_v3v3(cros, r); u = divdet * dot_v3v3(cros, r);
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON)) { if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
l= divdet*dot_v3v3(cros, t1); l = divdet * dot_v3v3(cros, t1);
if (l >- RE_RAYTRACE_EPSILON && l < *lambda) { if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
uv[0]= u; uv[0] = u;
uv[1]= -(1.0f + v + u); uv[1] = -(1.0f + v + u);
*lambda= l; *lambda = l;
return 2; return 2;
} }
} }
@@ -221,7 +221,7 @@ MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace
float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1; float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1;
int quad; int quad;
quad= RE_rayface_isQuad(face); quad = RE_rayface_isQuad(face);
copy_v3_v3(co1, face->v1); copy_v3_v3(co1, face->v1);
copy_v3_v3(co2, face->v2); copy_v3_v3(co2, face->v2);
@@ -234,22 +234,22 @@ MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace
sub_v3_v3v3(t1, co3, co1); sub_v3_v3v3(t1, co3, co1);
cross_v3_v3v3(x, r, t1); cross_v3_v3v3(x, r, t1);
divdet= dot_v3v3(t0, x); divdet = dot_v3v3(t0, x);
sub_v3_v3v3(m, start, co3); sub_v3_v3v3(m, start, co3);
det1= dot_v3v3(m, x); det1 = dot_v3v3(m, x);
if (divdet != 0.0f) { if (divdet != 0.0f) {
divdet= 1.0f/divdet; divdet = 1.0f / divdet;
v= det1*divdet; v = det1 * divdet;
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) { if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
float cros[3]; float cros[3];
cross_v3_v3v3(cros, m, t0); cross_v3_v3v3(cros, m, t0);
u= divdet*dot_v3v3(cros, r); u = divdet * dot_v3v3(cros, r);
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON)) if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
return 1; return 1;
} }
} }
@@ -258,19 +258,19 @@ MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace
if (quad) { if (quad) {
copy_v3_v3(co4, face->v4); copy_v3_v3(co4, face->v4);
sub_v3_v3v3(t0, co3, co4); sub_v3_v3v3(t0, co3, co4);
divdet= dot_v3v3(t0, x); divdet = dot_v3v3(t0, x);
if (divdet != 0.0f) { if (divdet != 0.0f) {
divdet= 1.0f/divdet; divdet = 1.0f / divdet;
v = det1*divdet; v = det1 * divdet;
if (v < RE_RAYTRACE_EPSILON && v > -(1.0f+RE_RAYTRACE_EPSILON)) { if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
float cros[3]; float cros[3];
cross_v3_v3v3(cros, m, t0); cross_v3_v3v3(cros, m, t0);
u= divdet*dot_v3v3(cros, r); u = divdet * dot_v3v3(cros, r);
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f+RE_RAYTRACE_EPSILON)) if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
return 2; return 2;
} }
} }
@@ -285,7 +285,7 @@ MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace
MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is) MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *is)
{ {
float dist, uv[2]; float dist, uv[2];
int ok= 0; int ok = 0;
/* avoid self-intersection */ /* avoid self-intersection */
if (is->orig.ob == face->ob && is->orig.face == face->face) if (is->orig.ob == face->ob && is->orig.face == face->face)
@@ -293,25 +293,25 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i
/* check if we should intersect this face */ /* check if we should intersect this face */
if (is->check == RE_CHECK_VLR_RENDER) { if (is->check == RE_CHECK_VLR_RENDER) {
if (vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
return 0; return 0;
} }
else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) { else if (is->check == RE_CHECK_VLR_NON_SOLID_MATERIAL) {
if (vlr_check_intersect(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) if (vlr_check_intersect(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
return 0; return 0;
if (vlr_check_intersect_solid(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) if (vlr_check_intersect_solid(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
return 0; return 0;
} }
else if (is->check == RE_CHECK_VLR_BAKE) { else if (is->check == RE_CHECK_VLR_BAKE) {
if (vlr_check_bake(is, (ObjectInstanceRen*)face->ob, (VlakRen*)face->face) == 0) if (vlr_check_bake(is, (ObjectInstanceRen *)face->ob, (VlakRen *)face->face) == 0)
return 0; return 0;
} }
/* ray counter */ /* ray counter */
RE_RC_COUNT(is->raycounter->faces.test); RE_RC_COUNT(is->raycounter->faces.test);
dist= is->dist; dist = is->dist;
ok= isec_tri_quad(is->start, is->dir, face, uv, &dist); ok = isec_tri_quad(is->start, is->dir, face, uv, &dist);
if (ok) { if (ok) {
@@ -319,21 +319,21 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i
* of it, causing intersection to be detected in its neighbor face */ * of it, causing intersection to be detected in its neighbor face */
if (is->skip & RE_SKIP_VLR_NEIGHBOUR) { if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
if (dist < 0.1f && is->orig.ob == face->ob) { if (dist < 0.1f && is->orig.ob == face->ob) {
VlakRen * a = (VlakRen*)is->orig.face; VlakRen *a = (VlakRen *)is->orig.face;
VlakRen * b = (VlakRen*)face->face; VlakRen *b = (VlakRen *)face->face;
/* so there's a shared edge or vertex, let's intersect ray with /* so there's a shared edge or vertex, let's intersect ray with
* face itself, if that's true we can safely return 1, otherwise * face itself, if that's true we can safely return 1, otherwise
* we assume the intersection is invalid, 0 */ * we assume the intersection is invalid, 0 */
if (a->v1==b->v1 || a->v2==b->v1 || a->v3==b->v1 || a->v4==b->v1 || if (a->v1 == b->v1 || a->v2 == b->v1 || a->v3 == b->v1 || a->v4 == b->v1 ||
a->v1==b->v2 || a->v2==b->v2 || a->v3==b->v2 || a->v4==b->v2 || a->v1 == b->v2 || a->v2 == b->v2 || a->v3 == b->v2 || a->v4 == b->v2 ||
a->v1==b->v3 || a->v2==b->v3 || a->v3==b->v3 || a->v4==b->v3 || a->v1 == b->v3 || a->v2 == b->v3 || a->v3 == b->v3 || a->v4 == b->v3 ||
(b->v4 && (a->v1==b->v4 || a->v2==b->v4 || a->v3==b->v4 || a->v4==b->v4))) (b->v4 && (a->v1 == b->v4 || a->v2 == b->v4 || a->v3 == b->v4 || a->v4 == b->v4)))
{ {
/* create RayFace from original face, transformed if necessary */ /* create RayFace from original face, transformed if necessary */
RayFace origface; RayFace origface;
ObjectInstanceRen *ob= (ObjectInstanceRen*)is->orig.ob; ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
rayface_from_vlak(&origface, ob, (VlakRen*)is->orig.face); rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face);
if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) { if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) {
return 0; return 0;
@@ -344,9 +344,9 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i
RE_RC_COUNT(is->raycounter->faces.hit); RE_RC_COUNT(is->raycounter->faces.hit);
is->isect= ok; // which half of the quad is->isect = ok; // which half of the quad
is->dist= dist; is->dist = dist;
is->u= uv[0]; is->v= uv[1]; is->u = uv[0]; is->v = uv[1];
is->hit.ob = face->ob; is->hit.ob = face->ob;
is->hit.face = face->face; is->hit.face = face->face;
@@ -368,19 +368,19 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec)
RE_RC_COUNT(isec->raycounter->raycast.test); RE_RC_COUNT(isec->raycounter->raycast.test);
/* setup vars used on raycast */ /* setup vars used on raycast */
for (i=0; i<3; i++) { for (i = 0; i < 3; i++) {
isec->idot_axis[i] = 1.0f / isec->dir[i]; isec->idot_axis[i] = 1.0f / isec->dir[i];
isec->bv_index[2*i] = isec->idot_axis[i] < 0.0 ? 1 : 0; isec->bv_index[2 * i] = isec->idot_axis[i] < 0.0 ? 1 : 0;
isec->bv_index[2*i+1] = 1 - isec->bv_index[2*i]; isec->bv_index[2 * i + 1] = 1 - isec->bv_index[2 * i];
isec->bv_index[2*i] = i+3*isec->bv_index[2*i]; isec->bv_index[2 * i] = i + 3 * isec->bv_index[2 * i];
isec->bv_index[2*i+1] = i+3*isec->bv_index[2*i+1]; isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
} }
#ifdef RT_USE_LAST_HIT #ifdef RT_USE_LAST_HIT
/* last hit heuristic */ /* last hit heuristic */
if (isec->mode==RE_RAY_SHADOW && isec->last_hit) { if (isec->mode == RE_RAY_SHADOW && isec->last_hit) {
RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test); RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.test);
if (RE_rayobject_intersect(isec->last_hit, isec)) { if (RE_rayobject_intersect(isec->last_hit, isec)) {
@@ -410,11 +410,11 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec)
int RE_rayobject_intersect(RayObject *r, Isect *i) int RE_rayobject_intersect(RayObject *r, Isect *i)
{ {
if (RE_rayobject_isRayFace(r)) { if (RE_rayobject_isRayFace(r)) {
return intersect_rayface(r, (RayFace*) RE_rayobject_align(r), i); return intersect_rayface(r, (RayFace *) RE_rayobject_align(r), i);
} }
else if (RE_rayobject_isVlakPrimitive(r)) { else if (RE_rayobject_isVlakPrimitive(r)) {
//TODO optimize (useless copy to RayFace to avoid duplicate code) //TODO optimize (useless copy to RayFace to avoid duplicate code)
VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r); VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
RayFace nface; RayFace nface;
rayface_from_vlak(&nface, face->ob, face->face); rayface_from_vlak(&nface, face->ob, face->face);
@@ -470,7 +470,7 @@ float RE_rayobject_cost(RayObject *r)
void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
{ {
if (RE_rayobject_isRayFace(r)) { if (RE_rayobject_isRayFace(r)) {
RayFace *face = (RayFace*) RE_rayobject_align(r); RayFace *face = (RayFace *) RE_rayobject_align(r);
DO_MINMAX(face->v1, min, max); DO_MINMAX(face->v1, min, max);
DO_MINMAX(face->v2, min, max); DO_MINMAX(face->v2, min, max);
@@ -478,7 +478,7 @@ void RE_rayobject_merge_bb(RayObject *r, float *min, float *max)
if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max); if (RE_rayface_isQuad(face)) DO_MINMAX(face->v4, min, max);
} }
else if (RE_rayobject_isVlakPrimitive(r)) { else if (RE_rayobject_isVlakPrimitive(r)) {
VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r); VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
RayFace nface; RayFace nface;
rayface_from_vlak(&nface, face->ob, face->face); rayface_from_vlak(&nface, face->ob, face->face);

View File

@@ -44,7 +44,7 @@ static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec);
static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob); static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob);
static void RE_rayobject_blibvh_done(RayObject *o); static void RE_rayobject_blibvh_done(RayObject *o);
static void RE_rayobject_blibvh_free(RayObject *o); static void RE_rayobject_blibvh_free(RayObject *o);
static void RE_rayobject_blibvh_bb(RayObject *o, float min[3], float max[3]); static void RE_rayobject_blibvh_bb(RayObject * o, float min[3], float max[3]);
static float RE_rayobject_blibvh_cost(RayObject *UNUSED(o)) static float RE_rayobject_blibvh_cost(RayObject *UNUSED(o))
{ {
@@ -69,8 +69,7 @@ static RayObjectAPI bvh_api =
RE_rayobject_blibvh_hint_bb RE_rayobject_blibvh_hint_bb
}; };
typedef struct BVHObject typedef struct BVHObject {
{
RayObject rayobj; RayObject rayobj;
RayObject **leafs, **next_leaf; RayObject **leafs, **next_leaf;
BVHTree *bvh; BVHTree *bvh;
@@ -79,26 +78,25 @@ typedef struct BVHObject
RayObject *RE_rayobject_blibvh_create(int size) RayObject *RE_rayobject_blibvh_create(int size)
{ {
BVHObject *obj= (BVHObject*)MEM_callocN(sizeof(BVHObject), "BVHObject"); BVHObject *obj = (BVHObject *)MEM_callocN(sizeof(BVHObject), "BVHObject");
assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */ assert(RE_rayobject_isAligned(obj)); /* RayObject API assumes real data to be 4-byte aligned */
obj->rayobj.api = &bvh_api; obj->rayobj.api = &bvh_api;
obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6); obj->bvh = BLI_bvhtree_new(size, 0.0, 4, 6);
obj->next_leaf = obj->leafs = (RayObject**)MEM_callocN(size*sizeof(RayObject*), "BVHObject leafs"); obj->next_leaf = obj->leafs = (RayObject **)MEM_callocN(size * sizeof(RayObject *), "BVHObject leafs");
INIT_MINMAX(obj->bb[0], obj->bb[1]); INIT_MINMAX(obj->bb[0], obj->bb[1]);
return RE_rayobject_unalignRayAPI((RayObject*) obj); return RE_rayobject_unalignRayAPI((RayObject *) obj);
} }
struct BVHCallbackUserData struct BVHCallbackUserData {
{
Isect *isec; Isect *isec;
RayObject **leafs; RayObject **leafs;
}; };
static void bvh_callback(void *userdata, int index, const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit) static void bvh_callback(void *userdata, int index, const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit)
{ {
struct BVHCallbackUserData *data = (struct BVHCallbackUserData*)userdata; struct BVHCallbackUserData *data = (struct BVHCallbackUserData *)userdata;
Isect *isec = data->isec; Isect *isec = data->isec;
RayObject *face = data->leafs[index]; RayObject *face = data->leafs[index];
@@ -114,7 +112,7 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *UNUSED(ray
static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec) static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec)
{ {
BVHObject *obj = (BVHObject*)o; BVHObject *obj = (BVHObject *)o;
BVHTreeRayHit hit; BVHTreeRayHit hit;
float dir[3]; float dir[3];
struct BVHCallbackUserData data; struct BVHCallbackUserData data;
@@ -126,15 +124,15 @@ static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec)
hit.index = 0; hit.index = 0;
hit.dist = isec->dist; hit.dist = isec->dist;
return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, (void*)&data); return BLI_bvhtree_ray_cast(obj->bvh, isec->start, dir, 0.0, &hit, bvh_callback, (void *)&data);
} }
static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob) static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob)
{ {
BVHObject *obj = (BVHObject*)o; BVHObject *obj = (BVHObject *)o;
float min_max[6]; float min_max[6];
INIT_MINMAX(min_max, min_max+3); INIT_MINMAX(min_max, min_max + 3);
RE_rayobject_merge_bb(ob, min_max, min_max+3); RE_rayobject_merge_bb(ob, min_max, min_max + 3);
DO_MIN(min_max, obj->bb[0]); DO_MIN(min_max, obj->bb[0]);
DO_MAX(min_max + 3, obj->bb[1]); DO_MAX(min_max + 3, obj->bb[1]);
@@ -145,13 +143,13 @@ static void RE_rayobject_blibvh_add(RayObject *o, RayObject *ob)
static void RE_rayobject_blibvh_done(RayObject *o) static void RE_rayobject_blibvh_done(RayObject *o)
{ {
BVHObject *obj = (BVHObject*)o; BVHObject *obj = (BVHObject *)o;
BLI_bvhtree_balance(obj->bvh); BLI_bvhtree_balance(obj->bvh);
} }
static void RE_rayobject_blibvh_free(RayObject *o) static void RE_rayobject_blibvh_free(RayObject *o)
{ {
BVHObject *obj = (BVHObject*)o; BVHObject *obj = (BVHObject *)o;
if (obj->bvh) if (obj->bvh)
BLI_bvhtree_free(obj->bvh); BLI_bvhtree_free(obj->bvh);
@@ -164,7 +162,7 @@ static void RE_rayobject_blibvh_free(RayObject *o)
static void RE_rayobject_blibvh_bb(RayObject *o, float min[3], float max[3]) static void RE_rayobject_blibvh_bb(RayObject *o, float min[3], float max[3])
{ {
BVHObject *obj = (BVHObject*)o; BVHObject *obj = (BVHObject *)o;
DO_MIN(obj->bb[0], min); DO_MIN(obj->bb[0], min);
DO_MAX(obj->bb[1], max); DO_MAX(obj->bb[1], max);
} }

View File

@@ -33,25 +33,23 @@
#ifndef __RAYOBJECT_HINT_H__ #ifndef __RAYOBJECT_HINT_H__
#define __RAYOBJECT_HINT_H__ #define __RAYOBJECT_HINT_H__
#define HINT_RECURSE 1 #define HINT_RECURSE 1
#define HINT_ACCEPT 0 #define HINT_ACCEPT 0
#define HINT_DISCARD -1 #define HINT_DISCARD -1
struct HintBB struct HintBB {
{
float bb[6]; float bb[6];
}; };
inline int hint_test_bb(HintBB *obj, float *Nmin, float *Nmax) inline int hint_test_bb(HintBB *obj, float *Nmin, float *Nmax)
{ {
if (bb_fits_inside( Nmin, Nmax, obj->bb, obj->bb+3 ) ) if (bb_fits_inside(Nmin, Nmax, obj->bb, obj->bb + 3) )
return HINT_RECURSE; return HINT_RECURSE;
else else
return HINT_ACCEPT; return HINT_ACCEPT;
} }
#if 0 #if 0
struct HintFrustum struct HintFrustum {
{
float co[3]; float co[3];
float no[4][3]; float no[4][3];
}; };

View File

@@ -40,10 +40,9 @@
#ifdef __SSE__ #ifdef __SSE__
#define DFS_STACK_SIZE 256 #define DFS_STACK_SIZE 256
struct QBVHTree struct QBVHTree {
{
RayObject rayobj; RayObject rayobj;
SVBVHNode *root; SVBVHNode *root;
@@ -61,11 +60,11 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
//TODO find a away to exactly calculate the needed memory //TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena"); MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena");
BLI_memarena_use_malloc(arena1); BLI_memarena_use_malloc(arena1);
MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena 2"); MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "qbvh arena 2");
BLI_memarena_use_malloc(arena2); BLI_memarena_use_malloc(arena2);
BLI_memarena_use_align(arena2, 16); BLI_memarena_use_align(arena2, 16);
//Build and optimize the tree //Build and optimize the tree
//TODO do this in 1 pass (half memory usage during building) //TODO do this in 1 pass (half memory usage during building)
@@ -95,7 +94,7 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
} }
template<int StackSize> template<int StackSize>
int intersect(QBVHTree *obj, Isect* isec) int intersect(QBVHTree *obj, Isect *isec)
{ {
//TODO renable hint support //TODO renable hint support
if (RE_rayobject_isAligned(obj->root)) { if (RE_rayobject_isAligned(obj->root)) {
@@ -105,7 +104,7 @@ int intersect(QBVHTree *obj, Isect* isec)
return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec); return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec);
} }
else else
return RE_rayobject_intersect((RayObject*)obj->root, isec); return RE_rayobject_intersect((RayObject *)obj->root, isec);
} }
template<class Tree> template<class Tree>
@@ -114,7 +113,7 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(m
//TODO renable hint support //TODO renable hint support
{ {
hint->size = 0; hint->size = 0;
hint->stack[hint->size++] = (RayObject*)tree->root; hint->stack[hint->size++] = (RayObject *)tree->root;
} }
} }
/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ /* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
@@ -123,20 +122,20 @@ RayObjectAPI make_api()
{ {
static RayObjectAPI api = static RayObjectAPI api =
{ {
(RE_rayobject_raycast_callback) ((int(*)(Tree*, Isect*)) &intersect<STACK_SIZE>), (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void(*)(Tree*, RayObject*)) &bvh_add<Tree>), (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
(RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>), (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
(RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>), (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void(*)(Tree*, float*, float*)) &bvh_bb<Tree>), (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
(RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost<Tree>), (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
(RE_rayobject_hint_bb_callback) ((void(*)(Tree*, LCTSHint*, float*, float*)) &bvh_hint_bb<Tree>) (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
}; };
return api; return api;
} }
template<class Tree> template<class Tree>
RayObjectAPI* bvh_get_api(int maxstacksize) RayObjectAPI *bvh_get_api(int maxstacksize)
{ {
static RayObjectAPI bvh_api256 = make_api<Tree, 1024>(); static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();

View File

@@ -54,19 +54,19 @@ static void rtbuild_init(RTBuilder *b)
b->primitives.end = 0; b->primitives.end = 0;
b->primitives.maxsize = 0; b->primitives.maxsize = 0;
for (int i=0; i<RTBUILD_MAX_CHILDS; i++) for (int i = 0; i < RTBUILD_MAX_CHILDS; i++)
b->child_offset[i] = 0; b->child_offset[i] = 0;
for (int i=0; i<3; i++) for (int i = 0; i < 3; i++)
b->sorted_begin[i] = b->sorted_end[i] = 0; b->sorted_begin[i] = b->sorted_end[i] = 0;
INIT_MINMAX(b->bb, b->bb+3); INIT_MINMAX(b->bb, b->bb + 3);
} }
RTBuilder* rtbuild_create(int size) RTBuilder *rtbuild_create(int size)
{ {
RTBuilder *builder = (RTBuilder*) MEM_mallocN( sizeof(RTBuilder), "RTBuilder" ); RTBuilder *builder = (RTBuilder *) MEM_mallocN(sizeof(RTBuilder), "RTBuilder");
RTBuilder::Object *memblock= (RTBuilder::Object*)MEM_mallocN( sizeof(RTBuilder::Object)*size, "RTBuilder.objects"); RTBuilder::Object *memblock = (RTBuilder::Object *)MEM_mallocN(sizeof(RTBuilder::Object) * size, "RTBuilder.objects");
rtbuild_init(builder); rtbuild_init(builder);
@@ -74,8 +74,8 @@ RTBuilder* rtbuild_create(int size)
builder->primitives.begin = builder->primitives.end = memblock; builder->primitives.begin = builder->primitives.end = memblock;
builder->primitives.maxsize = size; builder->primitives.maxsize = size;
for (int i=0; i<3; i++) { for (int i = 0; i < 3; i++) {
builder->sorted_begin[i] = (RTBuilder::Object**)MEM_mallocN( sizeof(RTBuilder::Object*)*size, "RTBuilder.sorted_objects"); builder->sorted_begin[i] = (RTBuilder::Object **)MEM_mallocN(sizeof(RTBuilder::Object *) * size, "RTBuilder.sorted_objects");
builder->sorted_end[i] = builder->sorted_begin[i]; builder->sorted_end[i] = builder->sorted_begin[i];
} }
@@ -87,7 +87,7 @@ void rtbuild_free(RTBuilder *b)
{ {
if (b->primitives.begin) MEM_freeN(b->primitives.begin); if (b->primitives.begin) MEM_freeN(b->primitives.begin);
for (int i=0; i<3; i++) for (int i = 0; i < 3; i++)
if (b->sorted_begin[i]) if (b->sorted_begin[i])
MEM_freeN(b->sorted_begin[i]); MEM_freeN(b->sorted_begin[i]);
@@ -98,10 +98,10 @@ void rtbuild_add(RTBuilder *b, RayObject *o)
{ {
float bb[6]; float bb[6];
assert( b->primitives.begin + b->primitives.maxsize != b->primitives.end ); assert(b->primitives.begin + b->primitives.maxsize != b->primitives.end);
INIT_MINMAX(bb, bb+3); INIT_MINMAX(bb, bb + 3);
RE_rayobject_merge_bb(o, bb, bb+3); RE_rayobject_merge_bb(o, bb, bb + 3);
/* skip objects with invalid bounding boxes, nan causes DO_MINMAX /* skip objects with invalid bounding boxes, nan causes DO_MINMAX
* to do nothing, so we get these invalid values. this shouldn't * to do nothing, so we get these invalid values. this shouldn't
@@ -114,16 +114,16 @@ void rtbuild_add(RTBuilder *b, RayObject *o)
if (!finite(bb[3]) || !finite(bb[4]) || !finite(bb[5])) if (!finite(bb[3]) || !finite(bb[4]) || !finite(bb[5]))
return; return;
/* skip objects with zero bounding box, they are of no use, and /* skip objects with zero bounding box, they are of no use, and
* will give problems in rtbuild_heuristic_object_split later */ * will give problems in rtbuild_heuristic_object_split later */
if (bb[0] == bb[3] && bb[1] == bb[4] && bb[2] == bb[5]) if (bb[0] == bb[3] && bb[1] == bb[4] && bb[2] == bb[5])
return; return;
copy_v3_v3(b->primitives.end->bb, bb); copy_v3_v3(b->primitives.end->bb, bb);
copy_v3_v3(b->primitives.end->bb+3, bb+3); copy_v3_v3(b->primitives.end->bb + 3, bb + 3);
b->primitives.end->obj = o; b->primitives.end->obj = o;
b->primitives.end->cost = RE_rayobject_cost(o); b->primitives.end->cost = RE_rayobject_cost(o);
for (int i=0; i<3; i++) { for (int i = 0; i < 3; i++) {
*(b->sorted_end[i]) = b->primitives.end; *(b->sorted_end[i]) = b->primitives.end;
b->sorted_end[i]++; b->sorted_end[i]++;
} }
@@ -153,32 +153,33 @@ static void object_sort(Item *begin, Item *end, int axis)
assert(false); assert(false);
} }
void rtbuild_done(RTBuilder *b, RayObjectControl* ctrl) void rtbuild_done(RTBuilder *b, RayObjectControl *ctrl)
{ {
for (int i=0; i<3; i++) for (int i = 0; i < 3; i++) {
if (b->sorted_begin[i]) { if (b->sorted_begin[i]) {
if (RE_rayobjectcontrol_test_break(ctrl)) break; if (RE_rayobjectcontrol_test_break(ctrl)) break;
object_sort( b->sorted_begin[i], b->sorted_end[i], i ); object_sort(b->sorted_begin[i], b->sorted_end[i], i);
}
} }
} }
RayObject* rtbuild_get_primitive(RTBuilder *b, int index) RayObject *rtbuild_get_primitive(RTBuilder *b, int index)
{ {
return b->sorted_begin[0][index]->obj; return b->sorted_begin[0][index]->obj;
} }
RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp) RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp)
{ {
rtbuild_init( tmp ); rtbuild_init(tmp);
for (int i=0; i<3; i++) for (int i = 0; i < 3; i++)
if (b->sorted_begin[i]) { if (b->sorted_begin[i]) {
tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child ]; tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child];
tmp->sorted_end [i] = b->sorted_begin[i] + b->child_offset[child+1]; tmp->sorted_end[i] = b->sorted_begin[i] + b->child_offset[child + 1];
} }
else { else {
tmp->sorted_begin[i] = 0; tmp->sorted_begin[i] = 0;
tmp->sorted_end [i] = 0; tmp->sorted_end[i] = 0;
} }
return tmp; return tmp;
@@ -188,7 +189,7 @@ void rtbuild_calc_bb(RTBuilder *b)
{ {
if (b->bb[0] == 1.0e30f) { if (b->bb[0] == 1.0e30f) {
for (RTBuilder::Object **index = b->sorted_begin[0]; index != b->sorted_end[0]; index++) for (RTBuilder::Object **index = b->sorted_begin[0]; index != b->sorted_end[0]; index++)
RE_rayobject_merge_bb( (*index)->obj, b->bb, b->bb+3); RE_rayobject_merge_bb( (*index)->obj, b->bb, b->bb + 3);
} }
} }
@@ -196,14 +197,14 @@ void rtbuild_merge_bb(RTBuilder *b, float *min, float *max)
{ {
rtbuild_calc_bb(b); rtbuild_calc_bb(b);
DO_MIN(b->bb, min); DO_MIN(b->bb, min);
DO_MAX(b->bb+3, max); DO_MAX(b->bb + 3, max);
} }
#if 0 #if 0
int rtbuild_get_largest_axis(RTBuilder *b) int rtbuild_get_largest_axis(RTBuilder *b)
{ {
rtbuild_calc_bb(b); rtbuild_calc_bb(b);
return bb_largest_axis(b->bb, b->bb+3); return bb_largest_axis(b->bb, b->bb + 3);
} }
//Left balanced tree //Left balanced tree
@@ -219,26 +220,25 @@ int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis)
assert(nchilds <= RTBUILD_MAX_CHILDS); assert(nchilds <= RTBUILD_MAX_CHILDS);
//TODO optimize calc of leafs_per_child //TODO optimize calc of leafs_per_child
for (s=nchilds; s<tot_leafs; s*=nchilds); for (s = nchilds; s < tot_leafs; s *= nchilds) ;
Mleafs_per_child = s/nchilds; Mleafs_per_child = s / nchilds;
mleafs_per_child = Mleafs_per_child/nchilds; mleafs_per_child = Mleafs_per_child / nchilds;
//split min leafs per child //split min leafs per child
b->child_offset[0] = 0; b->child_offset[0] = 0;
for (i=1; i<=nchilds; i++) for (i = 1; i <= nchilds; i++)
b->child_offset[i] = mleafs_per_child; b->child_offset[i] = mleafs_per_child;
//split remaining leafs //split remaining leafs
missing_leafs = tot_leafs - mleafs_per_child*nchilds; missing_leafs = tot_leafs - mleafs_per_child * nchilds;
for (i=1; i<=nchilds; i++) for (i = 1; i <= nchilds; i++)
{ {
if (missing_leafs > Mleafs_per_child - mleafs_per_child) if (missing_leafs > Mleafs_per_child - mleafs_per_child)
{ {
b->child_offset[i] += Mleafs_per_child - mleafs_per_child; b->child_offset[i] += Mleafs_per_child - mleafs_per_child;
missing_leafs -= Mleafs_per_child - mleafs_per_child; missing_leafs -= Mleafs_per_child - mleafs_per_child;
} }
else else {
{
b->child_offset[i] += missing_leafs; b->child_offset[i] += missing_leafs;
missing_leafs = 0; missing_leafs = 0;
break; break;
@@ -246,14 +246,14 @@ int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis)
} }
//adjust for accumulative offsets //adjust for accumulative offsets
for (i=1; i<=nchilds; i++) for (i = 1; i <= nchilds; i++)
b->child_offset[i] += b->child_offset[i-1]; b->child_offset[i] += b->child_offset[i - 1];
//Count created childs //Count created childs
for (i=nchilds; b->child_offset[i] == b->child_offset[i-1]; i--); for (i = nchilds; b->child_offset[i] == b->child_offset[i - 1]; i--) ;
split_leafs(b, b->child_offset, i, axis); split_leafs(b, b->child_offset, i, axis);
assert( b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs ); assert(b->child_offset[0] == 0 && b->child_offset[i] == tot_leafs);
return i; return i;
} }
@@ -279,20 +279,19 @@ int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis)
{ {
return rtbuild_mean_split(b, nchilds, axis); return rtbuild_mean_split(b, nchilds, axis);
} }
else else {
{
int i; int i;
b->split_axis = axis; b->split_axis = axis;
//Calculate child offsets //Calculate child offsets
b->child_offset[0] = 0; b->child_offset[0] = 0;
for (i=0; i<nchilds-1; i++) for (i = 0; i < nchilds - 1; i++)
b->child_offset[i+1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]); b->child_offset[i + 1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[i]);
b->child_offset[nchilds] = size; b->child_offset[nchilds] = size;
for (i=0; i<nchilds; i++) for (i = 0; i < nchilds; i++)
if (b->child_offset[i+1] - b->child_offset[i] == size) if (b->child_offset[i + 1] - b->child_offset[i] == size)
return rtbuild_mean_split(b, nchilds, axis); return rtbuild_mean_split(b, nchilds, axis);
return nchilds; return nchilds;
@@ -306,9 +305,9 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds)
rtbuild_calc_bb(b); rtbuild_calc_bb(b);
la = bb_largest_axis(b->bb, b->bb+3); la = bb_largest_axis(b->bb, b->bb + 3);
for (i=1; i<nchilds; i++) for (i = 1; i < nchilds; i++)
separators[i-1] = (b->bb[la+3]-b->bb[la])*i / nchilds; separators[i - 1] = (b->bb[la + 3] - b->bb[la]) * i / nchilds;
return rtbuild_median_split(b, separators, nchilds, la); return rtbuild_median_split(b, separators, nchilds, la);
} }
@@ -317,8 +316,7 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds)
//Heuristics Object Splitter //Heuristics Object Splitter
struct SweepCost struct SweepCost {
{
float bb[6]; float bb[6];
float cost; float cost;
}; };
@@ -333,30 +331,30 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
if (size > nchilds) { if (size > nchilds) {
float bcost = FLT_MAX; float bcost = FLT_MAX;
baxis = -1, boffset = size/2; baxis = -1, boffset = size / 2;
SweepCost *sweep = (SweepCost*)MEM_mallocN( sizeof(SweepCost)*size, "RTBuilder.HeuristicSweep" ); SweepCost *sweep = (SweepCost *)MEM_mallocN(sizeof(SweepCost) * size, "RTBuilder.HeuristicSweep");
for (int axis=0; axis<3; axis++) { for (int axis = 0; axis < 3; axis++) {
SweepCost sweep_left; SweepCost sweep_left;
RTBuilder::Object **obj = b->sorted_begin[axis]; RTBuilder::Object **obj = b->sorted_begin[axis];
// float right_cost = 0; // float right_cost = 0;
for (int i=size-1; i>=0; i--) { for (int i = size - 1; i >= 0; i--) {
if (i == size-1) { if (i == size - 1) {
copy_v3_v3(sweep[i].bb, obj[i]->bb); copy_v3_v3(sweep[i].bb, obj[i]->bb);
copy_v3_v3(sweep[i].bb+3, obj[i]->bb+3); copy_v3_v3(sweep[i].bb + 3, obj[i]->bb + 3);
sweep[i].cost = obj[i]->cost; sweep[i].cost = obj[i]->cost;
} }
else { else {
sweep[i].bb[0] = MIN2(obj[i]->bb[0], sweep[i+1].bb[0]); sweep[i].bb[0] = MIN2(obj[i]->bb[0], sweep[i + 1].bb[0]);
sweep[i].bb[1] = MIN2(obj[i]->bb[1], sweep[i+1].bb[1]); sweep[i].bb[1] = MIN2(obj[i]->bb[1], sweep[i + 1].bb[1]);
sweep[i].bb[2] = MIN2(obj[i]->bb[2], sweep[i+1].bb[2]); sweep[i].bb[2] = MIN2(obj[i]->bb[2], sweep[i + 1].bb[2]);
sweep[i].bb[3] = MAX2(obj[i]->bb[3], sweep[i+1].bb[3]); sweep[i].bb[3] = MAX2(obj[i]->bb[3], sweep[i + 1].bb[3]);
sweep[i].bb[4] = MAX2(obj[i]->bb[4], sweep[i+1].bb[4]); sweep[i].bb[4] = MAX2(obj[i]->bb[4], sweep[i + 1].bb[4]);
sweep[i].bb[5] = MAX2(obj[i]->bb[5], sweep[i+1].bb[5]); sweep[i].bb[5] = MAX2(obj[i]->bb[5], sweep[i + 1].bb[5]);
sweep[i].cost = obj[i]->cost + sweep[i+1].cost; sweep[i].cost = obj[i]->cost + sweep[i + 1].cost;
} }
// right_cost += obj[i]->cost; // right_cost += obj[i]->cost;
} }
@@ -371,7 +369,7 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
// right_cost -= obj[0]->cost; if (right_cost < 0) right_cost = 0; // right_cost -= obj[0]->cost; if (right_cost < 0) right_cost = 0;
for (int i=1; i<size; i++) { for (int i = 1; i < size; i++) {
//Worst case heuristic (cost of each child is linear) //Worst case heuristic (cost of each child is linear)
float hcost, left_side, right_side; float hcost, left_side, right_side;
@@ -379,24 +377,24 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
// makes tree construction quicker, left out for now to test (brecht) // makes tree construction quicker, left out for now to test (brecht)
// left_side = bb_area(sweep_left.bb, sweep_left.bb+3)*(sweep_left.cost+logf((float)i)); // left_side = bb_area(sweep_left.bb, sweep_left.bb+3)*(sweep_left.cost+logf((float)i));
// right_side= bb_area(sweep[i].bb, sweep[i].bb+3)*(sweep[i].cost+logf((float)size-i)); // right_side= bb_area(sweep[i].bb, sweep[i].bb+3)*(sweep[i].cost+logf((float)size-i));
left_side = bb_area(sweep_left.bb, sweep_left.bb+3)*(sweep_left.cost); left_side = bb_area(sweep_left.bb, sweep_left.bb + 3) * (sweep_left.cost);
right_side= bb_area(sweep[i].bb, sweep[i].bb+3)*(sweep[i].cost); right_side = bb_area(sweep[i].bb, sweep[i].bb + 3) * (sweep[i].cost);
hcost = left_side+right_side; hcost = left_side + right_side;
assert(left_side >= 0); assert(left_side >= 0);
assert(right_side >= 0); assert(right_side >= 0);
if (left_side > bcost) break; //No way we can find a better heuristic in this axis if (left_side > bcost) break; //No way we can find a better heuristic in this axis
assert(hcost >= 0); assert(hcost >= 0);
// this makes sure the tree built is the same whatever is the order of the sorting axis // this makes sure the tree built is the same whatever is the order of the sorting axis
if ( hcost < bcost || (hcost == bcost && axis < baxis)) { if (hcost < bcost || (hcost == bcost && axis < baxis)) {
bcost = hcost; bcost = hcost;
baxis = axis; baxis = axis;
boffset = i; boffset = i;
} }
DO_MIN( obj[i]->bb, sweep_left.bb ); DO_MIN(obj[i]->bb, sweep_left.bb);
DO_MAX( obj[i]->bb+3, sweep_left.bb+3 ); DO_MAX(obj[i]->bb + 3, sweep_left.bb + 3);
sweep_left.cost += obj[i]->cost; sweep_left.cost += obj[i]->cost;
// right_cost -= obj[i]->cost; if (right_cost < 0) right_cost = 0; // right_cost -= obj[i]->cost; if (right_cost < 0) right_cost = 0;
@@ -426,10 +424,10 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
/* Adjust sorted arrays for childs */ /* Adjust sorted arrays for childs */
for (int i=0; i<boffset; i++) b->sorted_begin[baxis][i]->selected = true; for (int i = 0; i < boffset; i++) b->sorted_begin[baxis][i]->selected = true;
for (int i=boffset; i<size; i++) b->sorted_begin[baxis][i]->selected = false; for (int i = boffset; i < size; i++) b->sorted_begin[baxis][i]->selected = false;
for (int i=0; i<3; i++) for (int i = 0; i < 3; i++)
std::stable_partition( b->sorted_begin[i], b->sorted_end[i], selected_node ); std::stable_partition(b->sorted_begin[i], b->sorted_end[i], selected_node);
return nchilds; return nchilds;
} }
@@ -445,13 +443,13 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
int i; int i;
b->split_axis = split_axis; b->split_axis = split_axis;
for (i=0; i < partitions-1; i++) for (i = 0; i < partitions - 1; i++)
{ {
assert(nth[i] < nth[i+1] && nth[i+1] < nth[partitions]); assert(nth[i] < nth[i + 1] && nth[i + 1] < nth[partitions]);
if (split_axis == 0) std::nth_element(b, nth[i], nth[i+1], nth[partitions], obj_bb_compare<RTBuilder::Object, 0>); if (split_axis == 0) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 0>);
if (split_axis == 1) std::nth_element(b, nth[i], nth[i+1], nth[partitions], obj_bb_compare<RTBuilder::Object, 1>); if (split_axis == 1) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 1>);
if (split_axis == 2) std::nth_element(b, nth[i], nth[i+1], nth[partitions], obj_bb_compare<RTBuilder::Object, 2>); if (split_axis == 2) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 2>);
} }
} }
#endif #endif
@@ -461,20 +459,20 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
*/ */
float bb_volume(float *min, float *max) float bb_volume(float *min, float *max)
{ {
return (max[0]-min[0])*(max[1]-min[1])*(max[2]-min[2]); return (max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2]);
} }
float bb_area(float *min, float *max) float bb_area(float *min, float *max)
{ {
float sub[3], a; float sub[3], a;
sub[0] = max[0]-min[0]; sub[0] = max[0] - min[0];
sub[1] = max[1]-min[1]; sub[1] = max[1] - min[1];
sub[2] = max[2]-min[2]; sub[2] = max[2] - min[2];
a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2; a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2;
/* used to have an assert() here on negative results /* used to have an assert() here on negative results
* however, in this case its likely some overflow or ffast math error. * however, in this case its likely some overflow or ffast math error.
* so just return 0.0f instead. */ * so just return 0.0f instead. */
return a < 0.0f ? 0.0f : a; return a < 0.0f ? 0.0f : a;
} }
@@ -482,9 +480,9 @@ int bb_largest_axis(float *min, float *max)
{ {
float sub[3]; float sub[3];
sub[0] = max[0]-min[0]; sub[0] = max[0] - min[0];
sub[1] = max[1]-min[1]; sub[1] = max[1] - min[1];
sub[2] = max[2]-min[2]; sub[2] = max[2] - min[2];
if (sub[0] > sub[1]) { if (sub[0] > sub[1]) {
if (sub[0] > sub[2]) if (sub[0] > sub[2])
return 0; return 0;
@@ -502,10 +500,10 @@ int bb_largest_axis(float *min, float *max)
int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max) int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max)
{ {
int i; int i;
for (i=0; i<3; i++) for (i = 0; i < 3; i++)
if (outer_min[i] > inner_min[i]) return 0; if (outer_min[i] > inner_min[i]) return 0;
for (i=0; i<3; i++) for (i = 0; i < 3; i++)
if (outer_max[i] < inner_max[i]) return 0; if (outer_max[i] < inner_max[i]) return 0;
return 1; return 1;

View File

@@ -52,10 +52,8 @@ extern "C" {
#define RTBUILD_MAX_CHILDS 32 #define RTBUILD_MAX_CHILDS 32
typedef struct RTBuilder typedef struct RTBuilder {
{ struct Object {
struct Object
{
RayObject *obj; RayObject *obj;
float cost; float cost;
float bb[6]; float bb[6];
@@ -63,8 +61,7 @@ typedef struct RTBuilder
}; };
/* list to all primitives added in this tree */ /* list to all primitives added in this tree */
struct struct {
{
Object *begin, *end; Object *begin, *end;
int maxsize; int maxsize;
} primitives; } primitives;
@@ -76,7 +73,7 @@ typedef struct RTBuilder
int split_axis; int split_axis;
/* child partitions calculated during splitting */ /* child partitions calculated during splitting */
int child_offset[RTBUILD_MAX_CHILDS+1]; int child_offset[RTBUILD_MAX_CHILDS + 1];
// int child_sorted_axis; /* -1 if not sorted */ // int child_sorted_axis; /* -1 if not sorted */
@@ -85,17 +82,17 @@ typedef struct RTBuilder
} RTBuilder; } RTBuilder;
/* used during creation */ /* used during creation */
RTBuilder* rtbuild_create(int size); RTBuilder *rtbuild_create(int size);
void rtbuild_free(RTBuilder *b); void rtbuild_free(RTBuilder *b);
void rtbuild_add(RTBuilder *b, RayObject *o); void rtbuild_add(RTBuilder *b, RayObject *o);
void rtbuild_done(RTBuilder *b, RayObjectControl *c); void rtbuild_done(RTBuilder *b, RayObjectControl *c);
void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); void rtbuild_merge_bb(RTBuilder *b, float *min, float *max);
int rtbuild_size(RTBuilder *b); int rtbuild_size(RTBuilder *b);
RayObject* rtbuild_get_primitive(RTBuilder *b, int offset); RayObject *rtbuild_get_primitive(RTBuilder *b, int offset);
/* used during tree reorganization */ /* used during tree reorganization */
RTBuilder* rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp); RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp);
/* Calculates child partitions and returns number of efectively needed partitions */ /* Calculates child partitions and returns number of efectively needed partitions */
int rtbuild_get_largest_axis(RTBuilder *b); int rtbuild_get_largest_axis(RTBuilder *b);

View File

@@ -40,10 +40,9 @@
#ifdef __SSE__ #ifdef __SSE__
#define DFS_STACK_SIZE 256 #define DFS_STACK_SIZE 256
struct SVBVHTree struct SVBVHTree {
{
RayObject rayobj; RayObject rayobj;
SVBVHNode *root; SVBVHNode *root;
@@ -56,11 +55,10 @@ struct SVBVHTree
/* /*
* Cost to test N childs * Cost to test N childs
*/ */
struct PackCost struct PackCost {
{
float operator()(int n) float operator()(int n)
{ {
return (n / 4) + ((n % 4) > 2 ? 1 : n%4); return (n / 4) + ((n % 4) > 2 ? 1 : n % 4);
} }
}; };
@@ -72,11 +70,11 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
//TODO find a away to exactly calculate the needed memory //TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena"); MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena");
BLI_memarena_use_malloc(arena1); BLI_memarena_use_malloc(arena1);
MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena2"); MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "svbvh arena2");
BLI_memarena_use_malloc(arena2); BLI_memarena_use_malloc(arena2);
BLI_memarena_use_align(arena2, 16); BLI_memarena_use_align(arena2, 16);
//Build and optimize the tree //Build and optimize the tree
if (0) { if (0) {
@@ -123,12 +121,12 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
obj->node_arena = arena2; obj->node_arena = arena2;
obj->cost = 1.0; obj->cost = 1.0;
rtbuild_free( obj->builder ); rtbuild_free(obj->builder);
obj->builder = NULL; obj->builder = NULL;
} }
template<int StackSize> template<int StackSize>
int intersect(SVBVHTree *obj, Isect* isec) int intersect(SVBVHTree *obj, Isect *isec)
{ {
//TODO renable hint support //TODO renable hint support
if (RE_rayobject_isAligned(obj->root)) { if (RE_rayobject_isAligned(obj->root)) {
@@ -138,7 +136,7 @@ int intersect(SVBVHTree *obj, Isect* isec)
return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec); return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec);
} }
else else
return RE_rayobject_intersect( (RayObject*) obj->root, isec ); return RE_rayobject_intersect( (RayObject *) obj->root, isec);
} }
template<class Tree> template<class Tree>
@@ -147,7 +145,7 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(m
//TODO renable hint support //TODO renable hint support
{ {
hint->size = 0; hint->size = 0;
hint->stack[hint->size++] = (RayObject*)tree->root; hint->stack[hint->size++] = (RayObject *)tree->root;
} }
} }
/* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */ /* the cast to pointer function is needed to workarround gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11407 */
@@ -156,20 +154,20 @@ RayObjectAPI make_api()
{ {
static RayObjectAPI api = static RayObjectAPI api =
{ {
(RE_rayobject_raycast_callback) ((int(*)(Tree*, Isect*)) &intersect<STACK_SIZE>), (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void(*)(Tree*, RayObject*)) &bvh_add<Tree>), (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
(RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>), (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
(RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>), (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void(*)(Tree*, float*, float*)) &bvh_bb<Tree>), (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
(RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost<Tree>), (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
(RE_rayobject_hint_bb_callback) ((void(*)(Tree*, LCTSHint*, float*, float*)) &bvh_hint_bb<Tree>) (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
}; };
return api; return api;
} }
template<class Tree> template<class Tree>
RayObjectAPI* bvh_get_api(int maxstacksize) RayObjectAPI *bvh_get_api(int maxstacksize)
{ {
static RayObjectAPI bvh_api256 = make_api<Tree, 1024>(); static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();

View File

@@ -55,10 +55,9 @@ int tot_hints = 0;
#include <queue> #include <queue>
#include <algorithm> #include <algorithm>
#define DFS_STACK_SIZE 256 #define DFS_STACK_SIZE 256
struct VBVHTree struct VBVHTree {
{
RayObject rayobj; RayObject rayobj;
VBVHNode *root; VBVHNode *root;
MemArena *node_arena; MemArena *node_arena;
@@ -69,8 +68,7 @@ struct VBVHTree
/* /*
* Cost to test N childs * Cost to test N childs
*/ */
struct PackCost struct PackCost {
{
float operator()(int n) float operator()(int n)
{ {
return n; return n;
@@ -84,7 +82,7 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
//TODO find a away to exactly calculate the needed memory //TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena"); MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena");
BLI_memarena_use_malloc(arena1); BLI_memarena_use_malloc(arena1);
//Build and optimize the tree //Build and optimize the tree
if (1) { if (1) {
@@ -107,10 +105,10 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
obj->root = NULL; obj->root = NULL;
} }
else { else {
/* /* TODO */
TODO #if 0
MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena2"); MemArena *arena2 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena2");
BLI_memarena_use_malloc(arena2); BLI_memarena_use_malloc(arena2);
//Finds the optimal packing of this tree using a given cost model //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 //TODO this uses quite a lot of memory, find ways to reduce memory usage during building
@@ -119,11 +117,11 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root); obj->root = Reorganize_VBVH<OVBVHNode>(arena1).transform(root);
BLI_memarena_free(arena2); BLI_memarena_free(arena2);
*/ #endif
} }
//Cleanup //Cleanup
rtbuild_free( obj->builder ); rtbuild_free(obj->builder);
obj->builder = NULL; obj->builder = NULL;
obj->node_arena = arena1; obj->node_arena = arena1;
@@ -131,17 +129,17 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
} }
template<int StackSize> template<int StackSize>
int intersect(VBVHTree *obj, Isect* isec) int intersect(VBVHTree *obj, Isect *isec)
{ {
//TODO renable hint support //TODO renable hint support
if (RE_rayobject_isAligned(obj->root)) { if (RE_rayobject_isAligned(obj->root)) {
if (isec->mode == RE_RAY_SHADOW) if (isec->mode == RE_RAY_SHADOW)
return bvh_node_stack_raycast<VBVHNode, StackSize, false, true>( obj->root, isec); return bvh_node_stack_raycast<VBVHNode, StackSize, false, true>(obj->root, isec);
else else
return bvh_node_stack_raycast<VBVHNode, StackSize, false, false>( obj->root, isec); return bvh_node_stack_raycast<VBVHNode, StackSize, false, false>(obj->root, isec);
} }
else else
return RE_rayobject_intersect( (RayObject*) obj->root, isec ); return RE_rayobject_intersect( (RayObject *) obj->root, isec);
} }
template<class Tree> template<class Tree>
@@ -150,7 +148,7 @@ void bvh_hint_bb(Tree *tree, LCTSHint *hint, float *UNUSED(min), float *UNUSED(m
//TODO renable hint support //TODO renable hint support
{ {
hint->size = 0; hint->size = 0;
hint->stack[hint->size++] = (RayObject*)tree->root; hint->stack[hint->size++] = (RayObject *)tree->root;
} }
} }
@@ -178,20 +176,20 @@ RayObjectAPI make_api()
{ {
static RayObjectAPI api = static RayObjectAPI api =
{ {
(RE_rayobject_raycast_callback) ((int(*)(Tree*, Isect*)) &intersect<STACK_SIZE>), (RE_rayobject_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void(*)(Tree*, RayObject*)) &bvh_add<Tree>), (RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
(RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>), (RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
(RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>), (RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void(*)(Tree*, float*, float*)) &bvh_bb<Tree>), (RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
(RE_rayobject_cost_callback) ((float(*)(Tree*)) &bvh_cost<Tree>), (RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
(RE_rayobject_hint_bb_callback) ((void(*)(Tree*, LCTSHint*, float*, float*)) &bvh_hint_bb<Tree>) (RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
}; };
return api; return api;
} }
template<class Tree> template<class Tree>
RayObjectAPI* bvh_get_api(int maxstacksize) RayObjectAPI *bvh_get_api(int maxstacksize)
{ {
static RayObjectAPI bvh_api256 = make_api<Tree, 1024>(); static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();

View File

@@ -57,13 +57,13 @@ extern int tot_pushdown;
template<class Node> template<class Node>
bool node_fits_inside(Node *a, Node *b) bool node_fits_inside(Node *a, Node *b)
{ {
return bb_fits_inside(b->bb, b->bb+3, a->bb, a->bb+3); return bb_fits_inside(b->bb, b->bb + 3, a->bb, a->bb + 3);
} }
template<class Node> template<class Node>
void reorganize_find_fittest_parent(Node *tree, Node *node, std::pair<float, Node*> &cost) void reorganize_find_fittest_parent(Node *tree, Node *node, std::pair<float, Node *> &cost)
{ {
std::queue<Node*> q; std::queue<Node *> q;
q.push(tree); q.push(tree);
while (!q.empty()) { while (!q.empty()) {
@@ -72,8 +72,8 @@ void reorganize_find_fittest_parent(Node *tree, Node *node, std::pair<float, Nod
if (parent == node) continue; if (parent == node) continue;
if (node_fits_inside(node, parent) && RE_rayobject_isAligned(parent->child) ) { if (node_fits_inside(node, parent) && RE_rayobject_isAligned(parent->child) ) {
float pcost = bb_area(parent->bb, parent->bb+3); float pcost = bb_area(parent->bb, parent->bb + 3);
cost = std::min( cost, std::make_pair(pcost, parent) ); cost = std::min(cost, std::make_pair(pcost, parent) );
for (Node *child = parent->child; child; child = child->sibling) for (Node *child = parent->child; child; child = child->sibling)
q.push(child); q.push(child);
} }
@@ -84,11 +84,11 @@ static int tot_moves = 0;
template<class Node> template<class Node>
void reorganize(Node *root) void reorganize(Node *root)
{ {
std::queue<Node*> q; std::queue<Node *> q;
q.push(root); q.push(root);
while (!q.empty()) { while (!q.empty()) {
Node * node = q.front(); Node *node = q.front();
q.pop(); q.pop();
if (RE_rayobject_isAligned(node->child)) { if (RE_rayobject_isAligned(node->child)) {
@@ -96,7 +96,7 @@ void reorganize(Node *root)
assert(RE_rayobject_isAligned(*prev)); assert(RE_rayobject_isAligned(*prev));
q.push(*prev); q.push(*prev);
std::pair<float, Node*> best(FLT_MAX, root); std::pair<float, Node *> best(FLT_MAX, root);
reorganize_find_fittest_parent(root, *prev, best); reorganize_find_fittest_parent(root, *prev, best);
if (best.second == node) { if (best.second == node) {
@@ -129,7 +129,7 @@ void reorganize(Node *root)
template<class Node> template<class Node>
void remove_useless(Node *node, Node **new_node) void remove_useless(Node *node, Node **new_node)
{ {
if ( RE_rayobject_isAligned(node->child) ) { if (RE_rayobject_isAligned(node->child) ) {
for (Node **prev = &node->child; *prev; ) { for (Node **prev = &node->child; *prev; ) {
Node *next = (*prev)->sibling; Node *next = (*prev)->sibling;
@@ -160,12 +160,12 @@ void pushup(Node *parent)
{ {
if (is_leaf(parent)) return; if (is_leaf(parent)) return;
float p_area = bb_area(parent->bb, parent->bb+3); float p_area = bb_area(parent->bb, parent->bb + 3);
Node **prev = &parent->child; Node **prev = &parent->child;
for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) { for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) {
const float c_area = bb_area(child->bb, child->bb + 3); const float c_area = bb_area(child->bb, child->bb + 3);
const int nchilds = count_childs(child); const int nchilds = count_childs(child);
float original_cost = ((p_area != 0.0f)? (c_area / p_area)*nchilds: 1.0f) + 1; float original_cost = ((p_area != 0.0f) ? (c_area / p_area) * nchilds : 1.0f) + 1;
float flatten_cost = nchilds; float flatten_cost = nchilds;
if (flatten_cost < original_cost && nchilds >= 2) { if (flatten_cost < original_cost && nchilds >= 2) {
append_sibling(child, child->child); append_sibling(child, child->child);
@@ -201,7 +201,7 @@ void pushup_simd(Node *parent)
Node **prev = &parent->child; Node **prev = &parent->child;
for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) { for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) {
int cn = count_childs(child); int cn = count_childs(child);
if (cn-1 <= (SSize - (n%SSize) ) % SSize && RE_rayobject_isAligned(child->child) ) { if (cn - 1 <= (SSize - (n % SSize) ) % SSize && RE_rayobject_isAligned(child->child) ) {
n += (cn - 1); n += (cn - 1);
append_sibling(child, child->child); append_sibling(child, child->child);
child = child->sibling; child = child->sibling;
@@ -227,7 +227,7 @@ template<class Node>
void pushdown(Node *parent) void pushdown(Node *parent)
{ {
Node **s_child = &parent->child; Node **s_child = &parent->child;
Node * child = parent->child; Node *child = parent->child;
while (child && RE_rayobject_isAligned(child)) { while (child && RE_rayobject_isAligned(child)) {
Node *next = child->sibling; Node *next = child->sibling;
@@ -236,18 +236,18 @@ void pushdown(Node *parent)
//assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3)); //assert(bb_fits_inside(parent->bb, parent->bb+3, child->bb, child->bb+3));
for (Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling) for (Node *i = parent->child; RE_rayobject_isAligned(i) && i; i = i->sibling)
if (child != i && bb_fits_inside(i->bb, i->bb+3, child->bb, child->bb+3) && RE_rayobject_isAligned(i->child)) { if (child != i && bb_fits_inside(i->bb, i->bb + 3, child->bb, child->bb + 3) && RE_rayobject_isAligned(i->child)) {
// todo optimize (should the one with the smallest area?) // todo optimize (should the one with the smallest area?)
// float ia = bb_area(i->bb, i->bb+3) // float ia = bb_area(i->bb, i->bb+3)
// if (child->i) // if (child->i)
*s_child = child->sibling; *s_child = child->sibling;
child->sibling = i->child; child->sibling = i->child;
i->child = child; i->child = child;
next_s_child = s_child; next_s_child = s_child;
tot_pushdown++; tot_pushdown++;
break; break;
} }
child = next; child = next;
s_child = next_s_child; s_child = next_s_child;
} }
@@ -273,13 +273,13 @@ float bvh_refit(Node *node)
for (Node *child = node->child; child; child = child->sibling) for (Node *child = node->child; child; child = child->sibling)
total += bvh_refit(child); total += bvh_refit(child);
float old_area = bb_area(node->bb, node->bb+3); float old_area = bb_area(node->bb, node->bb + 3);
INIT_MINMAX(node->bb, node->bb+3); INIT_MINMAX(node->bb, node->bb + 3);
for (Node *child = node->child; child; child = child->sibling) { for (Node *child = node->child; child; child = child->sibling) {
DO_MIN(child->bb, node->bb); DO_MIN(child->bb, node->bb);
DO_MAX(child->bb+3, node->bb+3); DO_MAX(child->bb + 3, node->bb + 3);
} }
total += old_area - bb_area(node->bb, node->bb+3); total += old_area - bb_area(node->bb, node->bb + 3);
return total; return total;
} }
@@ -289,12 +289,11 @@ float bvh_refit(Node *node)
* with the purpose to reduce the expected cost (eg.: number of BB tests). * with the purpose to reduce the expected cost (eg.: number of BB tests).
*/ */
#include <vector> #include <vector>
#define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */ #define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */
#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE #define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE
struct OVBVHNode struct OVBVHNode {
{ float bb[6];
float bb[6];
OVBVHNode *child; OVBVHNode *child;
OVBVHNode *sibling; OVBVHNode *sibling;
@@ -306,7 +305,7 @@ struct OVBVHNode
float cut_cost[MAX_CUT_SIZE]; float cut_cost[MAX_CUT_SIZE];
float get_cost(int cutsize) float get_cost(int cutsize)
{ {
return cut_cost[cutsize-1]; return cut_cost[cutsize - 1];
} }
/* /*
@@ -316,7 +315,7 @@ struct OVBVHNode
int cut_size[MAX_CUT_SIZE]; int cut_size[MAX_CUT_SIZE];
int get_cut_size(int parent_cut_size) int get_cut_size(int parent_cut_size)
{ {
return cut_size[parent_cut_size-1]; return cut_size[parent_cut_size - 1];
} }
/* /*
@@ -327,19 +326,21 @@ struct OVBVHNode
{ {
if (cutsize == 1) { if (cutsize == 1) {
**cut = this; **cut = this;
*cut = &(**cut)->sibling; *cut = &(**cut)->sibling;
} }
else { else {
if (cutsize > MAX_CUT_SIZE) { if (cutsize > MAX_CUT_SIZE) {
for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) { for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
child->set_cut( 1, cut ); child->set_cut(1, cut);
cutsize--; cutsize--;
} }
assert(cutsize == 0); assert(cutsize == 0);
} }
else else {
for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
child->set_cut( child->get_cut_size( cutsize ), cut ); child->set_cut(child->get_cut_size(cutsize), cut);
}
}
} }
} }
@@ -365,8 +366,7 @@ struct OVBVHNode
* *
*/ */
template<class Node, class TestCost> template<class Node, class TestCost>
struct VBVH_optimalPackSIMD struct VBVH_optimalPackSIMD {
{
TestCost testcost; TestCost testcost;
VBVH_optimalPackSIMD(TestCost testcost) VBVH_optimalPackSIMD(TestCost testcost)
@@ -377,8 +377,7 @@ struct VBVH_optimalPackSIMD
/* /*
* calc best cut on a node * calc best cut on a node
*/ */
struct calc_best struct calc_best {
{
Node *child[MAX_OPTIMIZE_CHILDS]; Node *child[MAX_OPTIMIZE_CHILDS];
float child_hit_prob[MAX_OPTIMIZE_CHILDS]; float child_hit_prob[MAX_OPTIMIZE_CHILDS];
@@ -387,10 +386,10 @@ struct VBVH_optimalPackSIMD
int nchilds = 0; int nchilds = 0;
//Fetch childs and needed data //Fetch childs and needed data
{ {
float parent_area = bb_area(node->bb, node->bb+3); float parent_area = bb_area(node->bb, node->bb + 3);
for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) { for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
this->child[nchilds] = child; this->child[nchilds] = child;
this->child_hit_prob[nchilds] = (parent_area != 0.0f)? bb_area(child->bb, child->bb+3) / parent_area: 1.0f; this->child_hit_prob[nchilds] = (parent_area != 0.0f) ? bb_area(child->bb, child->bb + 3) / parent_area : 1.0f;
nchilds++; nchilds++;
} }
@@ -399,7 +398,7 @@ struct VBVH_optimalPackSIMD
//Build DP table to find minimum cost to represent this node with a given cutsize //Build DP table to find minimum cost to represent this node with a given cutsize
int bt [MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //backtrace table int bt[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //backtrace table
float cost[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //cost table (can be reduced to float[2][MAX_CUT_COST]) float cost[MAX_OPTIMIZE_CHILDS + 1][MAX_CUT_SIZE + 1]; //cost table (can be reduced to float[2][MAX_CUT_COST])
for (int i = 0; i <= nchilds; i++) { for (int i = 0; i <= nchilds; i++) {
@@ -410,13 +409,13 @@ struct VBVH_optimalPackSIMD
cost[0][0] = 0; cost[0][0] = 0;
for (int i = 1; i<=nchilds; i++) { for (int i = 1; i <= nchilds; i++) {
for (int size = i - 1; size/*+(nchilds-i)*/<=MAX_CUT_SIZE; size++) { for (int size = i - 1; size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; size++) {
for (int cut = 1; cut+size/*+(nchilds-i)*/<=MAX_CUT_SIZE; cut++) { for (int cut = 1; cut + size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; cut++) {
float new_cost = cost[i - 1][size] + child_hit_prob[i - 1] * child[i - 1]->get_cost(cut); float new_cost = cost[i - 1][size] + child_hit_prob[i - 1] * child[i - 1]->get_cost(cut);
if (new_cost < cost[i][size+cut]) { if (new_cost < cost[i][size + cut]) {
cost[i][size+cut] = new_cost; cost[i][size + cut] = new_cost;
bt[i][size+cut] = cut; bt[i][size + cut] = cut;
} }
} }
} }
@@ -424,11 +423,11 @@ struct VBVH_optimalPackSIMD
//Save the ways to archieve the minimum cost with a given cutsize //Save the ways to archieve the minimum cost with a given cutsize
for (int i = nchilds; i <= MAX_CUT_SIZE; i++) { for (int i = nchilds; i <= MAX_CUT_SIZE; i++) {
node->cut_cost[i-1] = cost[nchilds][i]; node->cut_cost[i - 1] = cost[nchilds][i];
if (cost[nchilds][i] < INFINITY) { if (cost[nchilds][i] < INFINITY) {
int current_size = i; int current_size = i;
for (int j=nchilds; j>0; j--) { for (int j = nchilds; j > 0; j--) {
child[j-1]->cut_size[i-1] = bt[j][current_size]; child[j - 1]->cut_size[i - 1] = bt[j][current_size];
current_size -= bt[j][current_size]; current_size -= bt[j][current_size];
} }
} }
@@ -439,23 +438,23 @@ struct VBVH_optimalPackSIMD
void calc_costs(Node *node) void calc_costs(Node *node)
{ {
if ( RE_rayobject_isAligned(node->child) ) { if (RE_rayobject_isAligned(node->child) ) {
int nchilds = 0; int nchilds = 0;
for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) { for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
calc_costs(child); calc_costs(child);
nchilds++; nchilds++;
} }
for (int i=0; i<MAX_CUT_SIZE; i++) for (int i = 0; i < MAX_CUT_SIZE; i++)
node->cut_cost[i] = INFINITY; node->cut_cost[i] = INFINITY;
//We are not allowed to look on nodes with with so many childs //We are not allowed to look on nodes with with so many childs
if (nchilds > MAX_CUT_SIZE) { if (nchilds > MAX_CUT_SIZE) {
float cost = 0; float cost = 0;
float parent_area = bb_area(node->bb, node->bb+3); float parent_area = bb_area(node->bb, node->bb + 3);
for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) { for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
cost += ((parent_area != 0.0f)? ( bb_area(child->bb, child->bb+3) / parent_area ): 1.0f) * child->get_cost(1); cost += ((parent_area != 0.0f) ? (bb_area(child->bb, child->bb + 3) / parent_area) : 1.0f) * child->get_cost(1);
} }
cost += testcost(nchilds); cost += testcost(nchilds);
@@ -466,7 +465,7 @@ struct VBVH_optimalPackSIMD
calc_best calc(node); calc_best calc(node);
//calc expected cost if we optimaly pack this node //calc expected cost if we optimaly pack this node
for (int cutsize=nchilds; cutsize<=MAX_CUT_SIZE; cutsize++) { for (int cutsize = nchilds; cutsize <= MAX_CUT_SIZE; cutsize++) {
float m = node->get_cost(cutsize) + testcost(cutsize); float m = node->get_cost(cutsize) + testcost(cutsize);
if (m < node->cut_cost[0]) { if (m < node->cut_cost[0]) {
node->cut_cost[0] = m; node->cut_cost[0] = m;
@@ -491,7 +490,7 @@ struct VBVH_optimalPackSIMD
if (num == 0) { num++; first = true; } if (num == 0) { num++; first = true; }
calc_costs(node); calc_costs(node);
if ((G.debug & G_DEBUG) && first) printf("expected cost = %f (%d)\n", node->cut_cost[0], node->best_cutsize ); if ((G.debug & G_DEBUG) && first) printf("expected cost = %f (%d)\n", node->cut_cost[0], node->best_cutsize);
node->optimize(); node->optimize();
} }
return node; return node;

View File

@@ -41,8 +41,7 @@
#include <stdio.h> #include <stdio.h>
#include <algorithm> #include <algorithm>
struct SVBVHNode struct SVBVHNode {
{
float child_bb[24]; float child_bb[24];
SVBVHNode *child[4]; SVBVHNode *child[4];
int nchilds; int nchilds;
@@ -120,12 +119,12 @@ static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec)
node = stack[--stack_pos]; node = stack[--stack_pos];
if (!svbvh_node_is_leaf(node)) { if (!svbvh_node_is_leaf(node)) {
int nchilds= node->nchilds; int nchilds = node->nchilds;
if (nchilds == 4) { if (nchilds == 4) {
float *child_bb= node->child_bb; float *child_bb = node->child_bb;
int res = svbvh_bb_intersect_test_simd4(isec, ((__m128*) (child_bb))); int res = svbvh_bb_intersect_test_simd4(isec, ((__m128 *) (child_bb)));
SVBVHNode **child= node->child; SVBVHNode **child = node->child;
RE_RC_COUNT(isec->raycounter->simd_bb.test); RE_RC_COUNT(isec->raycounter->simd_bb.test);
@@ -135,8 +134,8 @@ static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec)
if (res & 8) { stack[stack_pos++] = child[3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); } if (res & 8) { stack[stack_pos++] = child[3]; RE_RC_COUNT(isec->raycounter->simd_bb.hit); }
} }
else { else {
float *child_bb= node->child_bb; float *child_bb = node->child_bb;
SVBVHNode **child= node->child; SVBVHNode **child = node->child;
int i; int i;
for (i = 0; i < nchilds; i++) { for (i = 0; i < nchilds; i++) {
@@ -147,7 +146,7 @@ static int svbvh_node_stack_raycast(SVBVHNode *root, Isect *isec)
} }
} }
else { else {
hit |= RE_rayobject_intersect((RayObject*)node, isec); hit |= RE_rayobject_intersect((RayObject *)node, isec);
if (SHADOW && hit) break; if (SHADOW && hit) break;
} }
} }
@@ -160,7 +159,7 @@ template<>
inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float min[3], float max[3]) inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float min[3], float max[3])
{ {
if (is_leaf(node)) { if (is_leaf(node)) {
RE_rayobject_merge_bb((RayObject*)node, min, max); RE_rayobject_merge_bb((RayObject *)node, min, max);
} }
else { else {
int i; int i;
@@ -180,7 +179,7 @@ inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float min[3], float ma
} }
} }
for ( ; i < node->nchilds; i++) { for (; i < node->nchilds; i++) {
DO_MIN(node->child_bb + 6 * i, min); DO_MIN(node->child_bb + 6 * i, min);
DO_MAX(node->child_bb + 3 + 6 * i, max); DO_MAX(node->child_bb + 3 + 6 * i, max);
} }
@@ -193,8 +192,7 @@ inline void bvh_node_merge_bb<SVBVHNode>(SVBVHNode *node, float min[3], float ma
* Builds a SVBVH tree form a VBVHTree * Builds a SVBVH tree form a VBVHTree
*/ */
template<class OldNode> template<class OldNode>
struct Reorganize_SVBVH struct Reorganize_SVBVH {
{
MemArena *arena; MemArena *arena;
float childs_per_node; float childs_per_node;
@@ -220,14 +218,14 @@ struct Reorganize_SVBVH
printf("%f childs per node\n", childs_per_node / nodes); printf("%f childs per node\n", childs_per_node / nodes);
printf("%d childs BB are useless\n", useless_bb); printf("%d childs BB are useless\n", useless_bb);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i]/float(nodes)); printf("%i childs per node: %d/%d = %f\n", i, nodes_with_childs[i], nodes, nodes_with_childs[i] / float(nodes));
} }
} }
} }
SVBVHNode *create_node(int nchilds) SVBVHNode *create_node(int nchilds)
{ {
SVBVHNode *node = (SVBVHNode*)BLI_memarena_alloc(arena, sizeof(SVBVHNode)); SVBVHNode *node = (SVBVHNode *)BLI_memarena_alloc(arena, sizeof(SVBVHNode));
node->nchilds = nchilds; node->nchilds = nchilds;
return node; return node;
@@ -235,22 +233,22 @@ struct Reorganize_SVBVH
void copy_bb(float *bb, const float *old_bb) void copy_bb(float *bb, const float *old_bb)
{ {
std::copy(old_bb, old_bb+6, bb); std::copy(old_bb, old_bb + 6, bb);
} }
void prepare_for_simd(SVBVHNode *node) void prepare_for_simd(SVBVHNode *node)
{ {
int i=0; int i = 0;
while (i + 4 <= node->nchilds) { while (i + 4 <= node->nchilds) {
float vec_tmp[4*6]; float vec_tmp[4 * 6];
float *res = node->child_bb+6*i; float *res = node->child_bb + 6 * i;
std::copy(res, res+6*4, vec_tmp); std::copy(res, res + 6 * 4, vec_tmp);
for (int j=0; j<6; j++) { for (int j = 0; j < 6; j++) {
res[4*j+0] = vec_tmp[6*0+j]; res[4 * j + 0] = vec_tmp[6 * 0 + j];
res[4*j+1] = vec_tmp[6*1+j]; res[4 * j + 1] = vec_tmp[6 * 1 + j];
res[4*j+2] = vec_tmp[6*2+j]; res[4 * j + 2] = vec_tmp[6 * 2 + j];
res[4*j+3] = vec_tmp[6*3+j]; res[4 * j + 3] = vec_tmp[6 * 3 + j];
} }
i += 4; i += 4;
@@ -260,15 +258,15 @@ struct Reorganize_SVBVH
/* amt must be power of two */ /* amt must be power of two */
inline int padup(int num, int amt) inline int padup(int num, int amt)
{ {
return ((num+(amt-1))&~(amt-1)); return ((num + (amt - 1)) & ~(amt - 1));
} }
SVBVHNode *transform(OldNode *old) SVBVHNode *transform(OldNode *old)
{ {
if (is_leaf(old)) if (is_leaf(old))
return (SVBVHNode*)old; return (SVBVHNode *)old;
if (is_leaf(old->child)) if (is_leaf(old->child))
return (SVBVHNode*)old->child; return (SVBVHNode *)old->child;
int nchilds = count_childs(old); int nchilds = count_childs(old);
int alloc_childs = nchilds; int alloc_childs = nchilds;
@@ -282,27 +280,27 @@ struct Reorganize_SVBVH
if (nchilds < 16) if (nchilds < 16)
nodes_with_childs[nchilds]++; nodes_with_childs[nchilds]++;
useless_bb += alloc_childs-nchilds; useless_bb += alloc_childs - nchilds;
while (alloc_childs > nchilds) { while (alloc_childs > nchilds) {
const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN }; const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN };
alloc_childs--; alloc_childs--;
node->child[alloc_childs] = NULL; node->child[alloc_childs] = NULL;
copy_bb(node->child_bb+alloc_childs*6, def_bb); copy_bb(node->child_bb + alloc_childs * 6, def_bb);
} }
int i=nchilds; int i = nchilds;
for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling) { for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling) {
i--; i--;
node->child[i] = transform(o_child); node->child[i] = transform(o_child);
if (is_leaf(o_child)) { if (is_leaf(o_child)) {
float bb[6]; float bb[6];
INIT_MINMAX(bb, bb+3); INIT_MINMAX(bb, bb + 3);
RE_rayobject_merge_bb((RayObject*)o_child, bb, bb+3); RE_rayobject_merge_bb((RayObject *)o_child, bb, bb + 3);
copy_bb(node->child_bb+i*6, bb); copy_bb(node->child_bb + i * 6, bb);
break; break;
} }
else { else {
copy_bb(node->child_bb+i*6, o_child->bb); copy_bb(node->child_bb + i * 6, o_child->bb);
} }
} }
assert(i == 0); assert(i == 0);

View File

@@ -40,9 +40,8 @@
/* /*
* VBVHNode represents a BVHNode with support for a variable number of childrens * VBVHNode represents a BVHNode with support for a variable number of childrens
*/ */
struct VBVHNode struct VBVHNode {
{ float bb[6];
float bb[6];
VBVHNode *child; VBVHNode *child;
VBVHNode *sibling; VBVHNode *sibling;
@@ -107,8 +106,7 @@ void append_sibling(Node *node, Node *sibling)
* Builds a binary VBVH from a rtbuild * Builds a binary VBVH from a rtbuild
*/ */
template<class Node> template<class Node>
struct BuildBinaryVBVH struct BuildBinaryVBVH {
{
MemArena *arena; MemArena *arena;
RayObjectControl *control; RayObjectControl *control;
@@ -126,7 +124,7 @@ struct BuildBinaryVBVH
Node *create_node() Node *create_node()
{ {
Node *node = (Node*)BLI_memarena_alloc( arena, sizeof(Node) ); Node *node = (Node *)BLI_memarena_alloc(arena, sizeof(Node) );
assert(RE_rayobject_isAligned(node)); assert(RE_rayobject_isAligned(node));
node->sibling = NULL; node->sibling = NULL;
@@ -146,7 +144,7 @@ struct BuildBinaryVBVH
{ {
return _transform(builder); return _transform(builder);
} catch(...) } catch (...)
{ {
} }
return NULL; return NULL;
@@ -161,8 +159,8 @@ struct BuildBinaryVBVH
} }
else if (size == 1) { else if (size == 1) {
Node *node = create_node(); Node *node = create_node();
INIT_MINMAX(node->bb, node->bb+3); INIT_MINMAX(node->bb, node->bb + 3);
rtbuild_merge_bb(builder, node->bb, node->bb+3); rtbuild_merge_bb(builder, node->bb, node->bb + 3);
node->child = (Node *) rtbuild_get_primitive(builder, 0); node->child = (Node *) rtbuild_get_primitive(builder, 0);
return node; return node;
} }
@@ -174,7 +172,7 @@ struct BuildBinaryVBVH
Node **child = &node->child; Node **child = &node->child;
int nc = rtbuild_split(builder); int nc = rtbuild_split(builder);
INIT_MINMAX(node->bb, node->bb+3); INIT_MINMAX(node->bb, node->bb + 3);
assert(nc == 2); assert(nc == 2);
for (int i = 0; i < nc; i++) { for (int i = 0; i < nc; i++) {
@@ -183,7 +181,7 @@ struct BuildBinaryVBVH
*child = _transform(&tmp); *child = _transform(&tmp);
DO_MIN((*child)->bb, node->bb); DO_MIN((*child)->bb, node->bb);
DO_MAX((*child)->bb+3, node->bb+3); DO_MAX((*child)->bb + 3, node->bb + 3);
child = &((*child)->sibling); child = &((*child)->sibling);
} }
@@ -194,9 +192,8 @@ struct BuildBinaryVBVH
}; };
#if 0 #if 0
template<class Tree,class OldNode> template<class Tree, class OldNode>
struct Reorganize_VBVH struct Reorganize_VBVH {
{
Tree *tree; Tree *tree;
Reorganize_VBVH(Tree *t) Reorganize_VBVH(Tree *t)
@@ -206,27 +203,27 @@ struct Reorganize_VBVH
VBVHNode *create_node() VBVHNode *create_node()
{ {
VBVHNode *node = (VBVHNode*)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode)); VBVHNode *node = (VBVHNode *)BLI_memarena_alloc(tree->node_arena, sizeof(VBVHNode));
return node; return node;
} }
void copy_bb(VBVHNode *node, OldNode *old) void copy_bb(VBVHNode *node, OldNode *old)
{ {
std::copy( old->bb, old->bb+6, node->bb ); std::copy(old->bb, old->bb + 6, node->bb);
} }
VBVHNode *transform(OldNode *old) VBVHNode *transform(OldNode *old)
{ {
if (is_leaf(old)) if (is_leaf(old))
return (VBVHNode*)old; return (VBVHNode *)old;
VBVHNode *node = create_node(); VBVHNode *node = create_node();
VBVHNode **child_ptr = &node->child; VBVHNode **child_ptr = &node->child;
node->sibling = 0; node->sibling = 0;
copy_bb(node,old); copy_bb(node, old);
for(OldNode *o_child = old->child; o_child; o_child = o_child->sibling) for (OldNode *o_child = old->child; o_child; o_child = o_child->sibling)
{ {
VBVHNode *n_child = transform(o_child); VBVHNode *n_child = transform(o_child);
*child_ptr = n_child; *child_ptr = n_child;

View File

@@ -56,7 +56,7 @@ extern struct Render R;
/* ***** actual texture sampling ***** */ /* ***** actual texture sampling ***** */
int ocean_texture(Tex *tex, float *texvec, TexResult *texres) int ocean_texture(Tex *tex, float *texvec, TexResult *texres)
{ {
OceanTex *ot= tex->ot; OceanTex *ot = tex->ot;
ModifierData *md; ModifierData *md;
OceanModifierData *omd; OceanModifierData *omd;
@@ -64,8 +64,8 @@ int ocean_texture(Tex *tex, float *texvec, TexResult *texres)
if ( !(ot) || if ( !(ot) ||
!(ot->object) || !(ot->object) ||
!(md = (ModifierData *)modifiers_findByType(ot->object, eModifierType_Ocean)) || !(md = (ModifierData *)modifiers_findByType(ot->object, eModifierType_Ocean)) ||
!(omd= (OceanModifierData *)md)->ocean) !(omd = (OceanModifierData *)md)->ocean)
{ {
return 0; return 0;
} }
@@ -75,10 +75,10 @@ int ocean_texture(Tex *tex, float *texvec, TexResult *texres)
int retval = TEX_INT; int retval = TEX_INT;
OceanResult ocr; OceanResult ocr;
const float u = 0.5f+0.5f*texvec[0]; const float u = 0.5f + 0.5f * texvec[0];
const float v = 0.5f+0.5f*texvec[1]; const float v = 0.5f + 0.5f * texvec[1];
if (omd->oceancache && omd->cached==TRUE) { if (omd->oceancache && omd->cached == TRUE) {
CLAMP(cfra, omd->bakestart, omd->bakeend); CLAMP(cfra, omd->bakestart, omd->bakeend);
cfra -= omd->bakestart; // shift to 0 based cfra -= omd->bakestart; // shift to 0 based

View File

@@ -932,7 +932,7 @@ static int wm_window_timer(const bContext *C)
wtnext = wt->next; /* in case timer gets removed */ wtnext = wt->next; /* in case timer gets removed */
win = wt->win; win = wt->win;
if (wt->sleep== 0) { if (wt->sleep == 0) {
if (time > wt->ntime) { if (time > wt->ntime) {
wt->delta = time - wt->ltime; wt->delta = time - wt->ltime;
wt->duration += wt->delta; wt->duration += wt->delta;