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

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

@ -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
static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2,
BVHTreeOverlap *overlap, CollPair *collpair, float UNUSED(dt) )
static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
BVHTreeOverlap *overlap, CollPair *collpair, float UNUSED(dt))
{
ClothModifierData *clmd = (ClothModifierData *)md1;
CollisionModifierData *collmd = (CollisionModifierData *) md2;
Cloth *cloth = clmd->clothObject;
/* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
MFace *face1=NULL, *face2 = NULL;
#ifdef USE_BULLET
ClothVertex *verts1 = clmd->clothObject->verts;

@ -59,12 +59,12 @@ inline int test_bb_group4(__m128 *bb_group, const Isect *isec)
copy_v3_v3(start, isec->start);
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 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 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 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 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 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 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])) );
return _mm_movemask_ps(_mm_cmpge_ps(tmax3, tmin3));
}
@ -142,7 +142,7 @@ static float bvh_cost(Tree *obj)
/* bvh tree nodes generics */
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 {
hit |= RE_rayobject_intersect( (RayObject*)node, isec);
hit |= RE_rayobject_intersect( (RayObject *)node, isec);
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))
bvh_node_push_childs(root, isec, stack, stack_pos);
else
return RE_rayobject_intersect( (RayObject*)root->child, isec);
return RE_rayobject_intersect( (RayObject *)root->child, isec);
}
else
return RE_rayobject_intersect( (RayObject*)root, isec);
return RE_rayobject_intersect( (RayObject *)root, isec);
}
else {
if (!is_leaf(root))
stack[stack_pos++] = root;
else
return RE_rayobject_intersect( (RayObject*)root, isec);
return RE_rayobject_intersect( (RayObject *)root, isec);
}
while (true) {
//Use SIMD 4
if (stack_pos >= 4) {
__m128 t_bb[6];
Node * t_node[4];
Node *t_node[4];
stack_pos -= 4;
/* prepare the 4BB for SIMD */
t_node[0] = stack[stack_pos+0]->child;
t_node[1] = stack[stack_pos+1]->child;
t_node[2] = stack[stack_pos+2]->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) );
t_node[0] = stack[stack_pos + 0]->child;
t_node[1] = stack[stack_pos + 1]->child;
t_node[2] = stack[stack_pos + 2]->child;
t_node[3] = stack[stack_pos + 3]->child;
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 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 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) );
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 __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
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));
float *bb = ((float*)t_bb)+i;
bb[4*0] = t->bb[0];
bb[4*1] = t->bb[1];
bb[4*2] = t->bb[2];
bb[4*3] = t->bb[3];
bb[4*4] = t->bb[4];
bb[4*5] = t->bb[5];
float *bb = ((float *)t_bb) + i;
bb[4 * 0] = t->bb[0];
bb[4 * 1] = t->bb[1];
bb[4 * 2] = t->bb[2];
bb[4 * 3] = t->bb[3];
bb[4 * 4] = t->bb[4];
bb[4 * 5] = t->bb[5];
t_node[i] = t->child;
}
#endif
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++)
if (res & (1 << i)) {
RE_RC_COUNT(isec->raycounter->simd_bb.hit);
if (!is_leaf(t_node[i])) {
for (Node *t = t_node[i]; t; t = t->sibling) {
assert(stack_pos < MAX_STACK_SIZE);
stack[stack_pos++] = t;
if (res & (1 << i)) {
RE_RC_COUNT(isec->raycounter->simd_bb.hit);
if (!is_leaf(t_node[i])) {
for (Node *t = t_node[i]; t; t = t->sibling) {
assert(stack_pos < MAX_STACK_SIZE);
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) {
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);
}
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;
}
}
@ -324,7 +324,7 @@ static int bvh_node_raycast(Node *node, Isect *isec)
if (isec->idot_axis[node->split_axis] > 0.0f)
{
int i;
for(i=0; i<BVH_NCHILDS; i++)
for (i = 0; i < BVH_NCHILDS; i++)
if (!is_leaf(node->child[i]))
{
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);
if (hit && isec->mode == RE_RAY_SHADOW) return hit;
}
else
{
hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec);
else {
hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec);
if (hit && isec->mode == RE_RAY_SHADOW) return hit;
}
}
else
{
else {
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 (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;
}
}
else
{
hit |= RE_rayobject_intersect( (RayObject*)node->child[i], isec);
else {
hit |= RE_rayobject_intersect( (RayObject *)node->child[i], isec);
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);
if (is_leaf(node)) {
hint->stack[hint->size++] = (RayObject*)node;
hint->stack[hint->size++] = (RayObject *)node;
}
else {
int childs = count_childs(node);
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) {
/* We are 100% sure the ray will be pass inside this node */
bvh_dfs_make_hint_push_siblings(node->child, hint, reserve_space, hintObject);
}
else if (result == HINT_ACCEPT) {
hint->stack[hint->size++] = (RayObject*)node;
hint->stack[hint->size++] = (RayObject *)node;
}
}
else {
hint->stack[hint->size++] = (RayObject*)node;
hint->stack[hint->size++] = (RayObject *)node;
}
}
}
template<class Tree>
static RayObjectAPI* bvh_get_api(int maxstacksize);
static RayObjectAPI *bvh_get_api(int maxstacksize);
template<class Tree, int DFS_STACK_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 */
obj->rayobj.api = bvh_get_api<Tree>(DFS_STACK_SIZE);
obj->root = 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

@ -50,7 +50,7 @@
* because function is too long. Since this is code that is called billions
* 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)
{
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);
}
/* 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->face = vlr;
@ -110,13 +110,13 @@ MALWAYS_INLINE int vlr_check_intersect(Isect *is, ObjectInstanceRen *obi, VlakRe
return 0;
/* 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);
else
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 */
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;
}
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);
}
@ -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;
int quad;
quad= RE_rayface_isQuad(face);
quad = RE_rayface_isQuad(face);
copy_v3_v3(co1, face->v1);
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);
cross_v3_v3v3(x, r, t1);
divdet= dot_v3v3(t0, x);
divdet = dot_v3v3(t0, x);
sub_v3_v3v3(m, start, co3);
det1= dot_v3v3(m, x);
det1 = dot_v3v3(m, x);
if (divdet != 0.0f) {
divdet= 1.0f/divdet;
v= det1*divdet;
divdet = 1.0f / 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];
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)) {
l= divdet*dot_v3v3(cros, t1);
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
l = divdet * dot_v3v3(cros, t1);
/* check if intersection is within ray length */
if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
uv[0]= u;
uv[1]= v;
*lambda= l;
uv[0] = u;
uv[1] = v;
*lambda = l;
return 1;
}
}
@ -184,25 +184,25 @@ MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, fl
if (quad) {
copy_v3_v3(co4, face->v4);
sub_v3_v3v3(t0, co3, co4);
divdet= dot_v3v3(t0, x);
divdet = dot_v3v3(t0, x);
if (divdet != 0.0f) {
divdet= 1.0f/divdet;
v = det1*divdet;
divdet = 1.0f / 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];
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)) {
l= divdet*dot_v3v3(cros, t1);
if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
l = divdet * dot_v3v3(cros, t1);
if (l >- RE_RAYTRACE_EPSILON && l < *lambda) {
uv[0]= u;
uv[1]= -(1.0f + v + u);
*lambda= l;
if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
uv[0] = u;
uv[1] = -(1.0f + v + u);
*lambda = l;
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;
int quad;
quad= RE_rayface_isQuad(face);
quad = RE_rayface_isQuad(face);
copy_v3_v3(co1, face->v1);
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);
cross_v3_v3v3(x, r, t1);
divdet= dot_v3v3(t0, x);
divdet = dot_v3v3(t0, x);
sub_v3_v3v3(m, start, co3);
det1= dot_v3v3(m, x);
det1 = dot_v3v3(m, x);
if (divdet != 0.0f) {
divdet= 1.0f/divdet;
v= det1*divdet;
divdet = 1.0f / 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];
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;
}
}
@ -258,19 +258,19 @@ MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace
if (quad) {
copy_v3_v3(co4, face->v4);
sub_v3_v3v3(t0, co3, co4);
divdet= dot_v3v3(t0, x);
divdet = dot_v3v3(t0, x);
if (divdet != 0.0f) {
divdet= 1.0f/divdet;
v = det1*divdet;
divdet = 1.0f / 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];
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;
}
}
@ -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)
{
float dist, uv[2];
int ok= 0;
int ok = 0;
/* avoid self-intersection */
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 */
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;
}
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;
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;
}
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;
}
/* ray counter */
RE_RC_COUNT(is->raycounter->faces.test);
dist= is->dist;
ok= isec_tri_quad(is->start, is->dir, face, uv, &dist);
dist = is->dist;
ok = isec_tri_quad(is->start, is->dir, face, uv, &dist);
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 */
if (is->skip & RE_SKIP_VLR_NEIGHBOUR) {
if (dist < 0.1f && is->orig.ob == face->ob) {
VlakRen * a = (VlakRen*)is->orig.face;
VlakRen * b = (VlakRen*)face->face;
VlakRen *a = (VlakRen *)is->orig.face;
VlakRen *b = (VlakRen *)face->face;
/* 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
* we assume the intersection is invalid, 0 */
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->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)))
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->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)))
{
/* create RayFace from original face, transformed if necessary */
RayFace origface;
ObjectInstanceRen *ob= (ObjectInstanceRen*)is->orig.ob;
rayface_from_vlak(&origface, ob, (VlakRen*)is->orig.face);
ObjectInstanceRen *ob = (ObjectInstanceRen *)is->orig.ob;
rayface_from_vlak(&origface, ob, (VlakRen *)is->orig.face);
if (!isec_tri_quad_neighbour(is->start, is->dir, &origface)) {
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);
is->isect= ok; // which half of the quad
is->dist= dist;
is->u= uv[0]; is->v= uv[1];
is->isect = ok; // which half of the quad
is->dist = dist;
is->u = uv[0]; is->v = uv[1];
is->hit.ob = face->ob;
is->hit.face = face->face;
@ -368,19 +368,19 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec)
RE_RC_COUNT(isec->raycounter->raycast.test);
/* setup vars used on raycast */
for (i=0; i<3; i++) {
isec->idot_axis[i] = 1.0f / isec->dir[i];
for (i = 0; i < 3; 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+1] = 1 - isec->bv_index[2*i];
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] = 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] = i + 3 * isec->bv_index[2 * i];
isec->bv_index[2 * i + 1] = i + 3 * isec->bv_index[2 * i + 1];
}
#ifdef RT_USE_LAST_HIT
/* 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);
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)
{
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)) {
//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_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)
{
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->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);
}
else if (RE_rayobject_isVlakPrimitive(r)) {
VlakPrimitive *face = (VlakPrimitive*) RE_rayobject_align(r);
VlakPrimitive *face = (VlakPrimitive *) RE_rayobject_align(r);
RayFace nface;
rayface_from_vlak(&nface, face->ob, face->face);

@ -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_done(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))
{
@ -69,8 +69,7 @@ static RayObjectAPI bvh_api =
RE_rayobject_blibvh_hint_bb
};
typedef struct BVHObject
{
typedef struct BVHObject {
RayObject rayobj;
RayObject **leafs, **next_leaf;
BVHTree *bvh;
@ -79,26 +78,25 @@ typedef struct BVHObject
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 */
obj->rayobj.api = &bvh_api;
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]);
return RE_rayobject_unalignRayAPI((RayObject*) obj);
return RE_rayobject_unalignRayAPI((RayObject *) obj);
}
struct BVHCallbackUserData
{
struct BVHCallbackUserData {
Isect *isec;
RayObject **leafs;
};
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;
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)
{
BVHObject *obj = (BVHObject*)o;
BVHObject *obj = (BVHObject *)o;
BVHTreeRayHit hit;
float dir[3];
struct BVHCallbackUserData data;
@ -126,15 +124,15 @@ static int RE_rayobject_blibvh_intersect(RayObject *o, Isect *isec)
hit.index = 0;
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)
{
BVHObject *obj = (BVHObject*)o;
BVHObject *obj = (BVHObject *)o;
float min_max[6];
INIT_MINMAX(min_max, min_max+3);
RE_rayobject_merge_bb(ob, min_max, min_max+3);
INIT_MINMAX(min_max, min_max + 3);
RE_rayobject_merge_bb(ob, min_max, min_max + 3);
DO_MIN(min_max, obj->bb[0]);
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)
{
BVHObject *obj = (BVHObject*)o;
BVHObject *obj = (BVHObject *)o;
BLI_bvhtree_balance(obj->bvh);
}
static void RE_rayobject_blibvh_free(RayObject *o)
{
BVHObject *obj = (BVHObject*)o;
BVHObject *obj = (BVHObject *)o;
if (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])
{
BVHObject *obj = (BVHObject*)o;
BVHObject *obj = (BVHObject *)o;
DO_MIN(obj->bb[0], min);
DO_MAX(obj->bb[1], max);
}

@ -33,25 +33,23 @@
#ifndef __RAYOBJECT_HINT_H__
#define __RAYOBJECT_HINT_H__
#define HINT_RECURSE 1
#define HINT_ACCEPT 0
#define HINT_DISCARD -1
#define HINT_RECURSE 1
#define HINT_ACCEPT 0
#define HINT_DISCARD -1
struct HintBB
{
struct HintBB {
float bb[6];
};
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;
else
return HINT_ACCEPT;
}
#if 0
struct HintFrustum
{
struct HintFrustum {
float co[3];
float no[4][3];
};

@ -40,10 +40,9 @@
#ifdef __SSE__
#define DFS_STACK_SIZE 256
#define DFS_STACK_SIZE 256
struct QBVHTree
{
struct QBVHTree {
RayObject rayobj;
SVBVHNode *root;
@ -61,11 +60,11 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
//TODO find a away to exactly calculate the needed memory
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");
BLI_memarena_use_malloc(arena2);
BLI_memarena_use_align(arena2, 16);
BLI_memarena_use_malloc(arena2);
BLI_memarena_use_align(arena2, 16);
//Build and optimize the tree
//TODO do this in 1 pass (half memory usage during building)
@ -95,7 +94,7 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
}
template<int StackSize>
int intersect(QBVHTree *obj, Isect* isec)
int intersect(QBVHTree *obj, Isect *isec)
{
//TODO renable hint support
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);
}
else
return RE_rayobject_intersect((RayObject*)obj->root, isec);
return RE_rayobject_intersect((RayObject *)obj->root, isec);
}
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
{
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 */
@ -123,20 +122,20 @@ RayObjectAPI make_api()
{
static RayObjectAPI api =
{
(RE_rayobject_raycast_callback) ((int(*)(Tree*, Isect*)) &intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void(*)(Tree*, RayObject*)) &bvh_add<Tree>),
(RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>),
(RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void(*)(Tree*, float*, float*)) &bvh_bb<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_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
(RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
(RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
(RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
(RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
};
return api;
}
template<class Tree>
RayObjectAPI* bvh_get_api(int maxstacksize)
RayObjectAPI *bvh_get_api(int maxstacksize)
{
static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();

@ -54,19 +54,19 @@ static void rtbuild_init(RTBuilder *b)
b->primitives.end = 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;
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
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::Object *memblock= (RTBuilder::Object*)MEM_mallocN( sizeof(RTBuilder::Object)*size, "RTBuilder.objects");
RTBuilder *builder = (RTBuilder *) MEM_mallocN(sizeof(RTBuilder), "RTBuilder");
RTBuilder::Object *memblock = (RTBuilder::Object *)MEM_mallocN(sizeof(RTBuilder::Object) * size, "RTBuilder.objects");
rtbuild_init(builder);
@ -74,8 +74,8 @@ RTBuilder* rtbuild_create(int size)
builder->primitives.begin = builder->primitives.end = memblock;
builder->primitives.maxsize = size;
for (int i=0; i<3; i++) {
builder->sorted_begin[i] = (RTBuilder::Object**)MEM_mallocN( sizeof(RTBuilder::Object*)*size, "RTBuilder.sorted_objects");
for (int i = 0; i < 3; i++) {
builder->sorted_begin[i] = (RTBuilder::Object **)MEM_mallocN(sizeof(RTBuilder::Object *) * size, "RTBuilder.sorted_objects");
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);
for (int i=0; i<3; i++)
for (int i = 0; i < 3; i++)
if (b->sorted_begin[i])
MEM_freeN(b->sorted_begin[i]);
@ -98,10 +98,10 @@ void rtbuild_add(RTBuilder *b, RayObject *o)
{
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);
RE_rayobject_merge_bb(o, bb, bb+3);
INIT_MINMAX(bb, bb + 3);
RE_rayobject_merge_bb(o, bb, bb + 3);
/* skip objects with invalid bounding boxes, nan causes DO_MINMAX
* 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]))
return;
/* 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])
return;
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->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]++;
}
@ -153,32 +153,33 @@ static void object_sort(Item *begin, Item *end, int axis)
assert(false);
}
void rtbuild_done(RTBuilder *b, RayObjectControl* ctrl)
void rtbuild_done(RTBuilder *b, RayObjectControl *ctrl)
{
for (int i=0; i<3; i++)
if (b->sorted_begin[i]) {
if (RE_rayobjectcontrol_test_break(ctrl)) break;
object_sort( b->sorted_begin[i], b->sorted_end[i], i );
for (int i = 0; i < 3; i++) {
if (b->sorted_begin[i]) {
if (RE_rayobjectcontrol_test_break(ctrl)) break;
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;
}
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]) {
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_begin[i] = b->sorted_begin[i] + b->child_offset[child];
tmp->sorted_end[i] = b->sorted_begin[i] + b->child_offset[child + 1];
}
else {
tmp->sorted_begin[i] = 0;
tmp->sorted_end [i] = 0;
tmp->sorted_end[i] = 0;
}
return tmp;
@ -188,7 +189,7 @@ void rtbuild_calc_bb(RTBuilder *b)
{
if (b->bb[0] == 1.0e30f) {
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);
DO_MIN(b->bb, min);
DO_MAX(b->bb+3, max);
DO_MAX(b->bb + 3, max);
}
#if 0
int rtbuild_get_largest_axis(RTBuilder *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
@ -219,26 +220,25 @@ int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis)
assert(nchilds <= RTBUILD_MAX_CHILDS);
//TODO optimize calc of leafs_per_child
for (s=nchilds; s<tot_leafs; s*=nchilds);
Mleafs_per_child = s/nchilds;
mleafs_per_child = Mleafs_per_child/nchilds;
for (s = nchilds; s < tot_leafs; s *= nchilds) ;
Mleafs_per_child = s / nchilds;
mleafs_per_child = Mleafs_per_child / nchilds;
//split min leafs per child
b->child_offset[0] = 0;
for (i=1; i<=nchilds; i++)
for (i = 1; i <= nchilds; i++)
b->child_offset[i] = mleafs_per_child;
//split remaining leafs
missing_leafs = tot_leafs - mleafs_per_child*nchilds;
for (i=1; i<=nchilds; i++)
missing_leafs = tot_leafs - mleafs_per_child * nchilds;
for (i = 1; i <= nchilds; i++)
{
if (missing_leafs > Mleafs_per_child - mleafs_per_child)
{
b->child_offset[i] += Mleafs_per_child - mleafs_per_child;
missing_leafs -= Mleafs_per_child - mleafs_per_child;
}
else
{
else {
b->child_offset[i] += missing_leafs;
missing_leafs = 0;
break;
@ -246,14 +246,14 @@ int rtbuild_mean_split(RTBuilder *b, int nchilds, int axis)
}
//adjust for accumulative offsets
for (i=1; i<=nchilds; i++)
b->child_offset[i] += b->child_offset[i-1];
for (i = 1; i <= nchilds; i++)
b->child_offset[i] += b->child_offset[i - 1];
//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);
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;
}
@ -279,20 +279,19 @@ int rtbuild_median_split(RTBuilder *b, float *separators, int nchilds, int axis)
{
return rtbuild_mean_split(b, nchilds, axis);
}
else
{
else {
int i;
b->split_axis = axis;
//Calculate child offsets
b->child_offset[0] = 0;
for (i=0; i<nchilds-1; i++)
b->child_offset[i+1] = split_leafs_by_plane(b, b->child_offset[i], size, separators[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[nchilds] = size;
for (i=0; i<nchilds; i++)
if (b->child_offset[i+1] - b->child_offset[i] == size)
for (i = 0; i < nchilds; i++)
if (b->child_offset[i + 1] - b->child_offset[i] == size)
return rtbuild_mean_split(b, nchilds, axis);
return nchilds;
@ -306,9 +305,9 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds)
rtbuild_calc_bb(b);
la = bb_largest_axis(b->bb, b->bb+3);
for (i=1; i<nchilds; i++)
separators[i-1] = (b->bb[la+3]-b->bb[la])*i / nchilds;
la = bb_largest_axis(b->bb, b->bb + 3);
for (i = 1; i < nchilds; i++)
separators[i - 1] = (b->bb[la + 3] - b->bb[la]) * i / nchilds;
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
struct SweepCost
{
struct SweepCost {
float bb[6];
float cost;
};
@ -333,30 +331,30 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
if (size > nchilds) {
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;
RTBuilder::Object **obj = b->sorted_begin[axis];
// float right_cost = 0;
for (int i=size-1; i>=0; i--) {
if (i == size-1) {
for (int i = size - 1; i >= 0; i--) {
if (i == size - 1) {
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;
}
else {
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[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[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].cost = obj[i]->cost + sweep[i+1].cost;
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[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[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].cost = obj[i]->cost + sweep[i + 1].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;
for (int i=1; i<size; i++) {
for (int i = 1; i < size; i++) {
//Worst case heuristic (cost of each child is linear)
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)
// 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));
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);
hcost = left_side+right_side;
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);
hcost = left_side + right_side;
assert(left_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);
// 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;
baxis = axis;
boffset = i;
}
DO_MIN( obj[i]->bb, sweep_left.bb );
DO_MAX( obj[i]->bb+3, sweep_left.bb+3 );
DO_MIN(obj[i]->bb, sweep_left.bb);
DO_MAX(obj[i]->bb + 3, sweep_left.bb + 3);
sweep_left.cost += obj[i]->cost;
// 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 */
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=0; i<3; i++)
std::stable_partition( b->sorted_begin[i], b->sorted_end[i], selected_node );
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 = 0; i < 3; i++)
std::stable_partition(b->sorted_begin[i], b->sorted_end[i], selected_node);
return nchilds;
}
@ -445,13 +443,13 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis)
int i;
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 == 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 == 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 == 2) std::nth_element(b, nth[i], nth[i + 1], nth[partitions], obj_bb_compare<RTBuilder::Object, 2>);
}
}
#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)
{
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 sub[3], a;
sub[0] = max[0]-min[0];
sub[1] = max[1]-min[1];
sub[2] = max[2]-min[2];
sub[0] = max[0] - min[0];
sub[1] = max[1] - min[1];
sub[2] = max[2] - min[2];
a = (sub[0]*sub[1] + sub[0]*sub[2] + sub[1]*sub[2])*2;
/* used to have an assert() here on negative results
* however, in this case its likely some overflow or ffast math error.
* so just return 0.0f instead. */
a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2;
/* used to have an assert() here on negative results
* however, in this case its likely some overflow or ffast math error.
* so just return 0.0f instead. */
return a < 0.0f ? 0.0f : a;
}
@ -482,9 +480,9 @@ int bb_largest_axis(float *min, float *max)
{
float sub[3];
sub[0] = max[0]-min[0];
sub[1] = max[1]-min[1];
sub[2] = max[2]-min[2];
sub[0] = max[0] - min[0];
sub[1] = max[1] - min[1];
sub[2] = max[2] - min[2];
if (sub[0] > sub[1]) {
if (sub[0] > sub[2])
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 i;
for (i=0; i<3; i++)
for (i = 0; i < 3; i++)
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;
return 1;

@ -52,10 +52,8 @@ extern "C" {
#define RTBUILD_MAX_CHILDS 32
typedef struct RTBuilder
{
struct Object
{
typedef struct RTBuilder {
struct Object {
RayObject *obj;
float cost;
float bb[6];
@ -63,8 +61,7 @@ typedef struct RTBuilder
};
/* list to all primitives added in this tree */
struct
{
struct {
Object *begin, *end;
int maxsize;
} primitives;
@ -76,7 +73,7 @@ typedef struct RTBuilder
int split_axis;
/* 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 */
@ -85,17 +82,17 @@ typedef struct RTBuilder
} RTBuilder;
/* used during creation */
RTBuilder* rtbuild_create(int size);
RTBuilder *rtbuild_create(int size);
void rtbuild_free(RTBuilder *b);
void rtbuild_add(RTBuilder *b, RayObject *o);
void rtbuild_done(RTBuilder *b, RayObjectControl *c);
void rtbuild_merge_bb(RTBuilder *b, float *min, float *max);
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 */
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 */
int rtbuild_get_largest_axis(RTBuilder *b);

@ -40,10 +40,9 @@
#ifdef __SSE__
#define DFS_STACK_SIZE 256
#define DFS_STACK_SIZE 256
struct SVBVHTree
{
struct SVBVHTree {
RayObject rayobj;
SVBVHNode *root;
@ -56,11 +55,10 @@ struct SVBVHTree
/*
* Cost to test N childs
*/
struct PackCost
{
struct PackCost {
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
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");
BLI_memarena_use_malloc(arena2);
BLI_memarena_use_align(arena2, 16);
BLI_memarena_use_malloc(arena2);
BLI_memarena_use_align(arena2, 16);
//Build and optimize the tree
if (0) {
@ -123,12 +121,12 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
obj->node_arena = arena2;
obj->cost = 1.0;
rtbuild_free( obj->builder );
rtbuild_free(obj->builder);
obj->builder = NULL;
}
template<int StackSize>
int intersect(SVBVHTree *obj, Isect* isec)
int intersect(SVBVHTree *obj, Isect *isec)
{
//TODO renable hint support
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);
}
else
return RE_rayobject_intersect( (RayObject*) obj->root, isec );
return RE_rayobject_intersect( (RayObject *) obj->root, isec);
}
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
{
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 */
@ -156,20 +154,20 @@ RayObjectAPI make_api()
{
static RayObjectAPI api =
{
(RE_rayobject_raycast_callback) ((int(*)(Tree*, Isect*)) &intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void(*)(Tree*, RayObject*)) &bvh_add<Tree>),
(RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>),
(RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void(*)(Tree*, float*, float*)) &bvh_bb<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_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
(RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
(RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
(RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
(RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
};
return api;
}
template<class Tree>
RayObjectAPI* bvh_get_api(int maxstacksize)
RayObjectAPI *bvh_get_api(int maxstacksize)
{
static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();

@ -55,10 +55,9 @@ int tot_hints = 0;
#include <queue>
#include <algorithm>
#define DFS_STACK_SIZE 256
#define DFS_STACK_SIZE 256
struct VBVHTree
{
struct VBVHTree {
RayObject rayobj;
VBVHNode *root;
MemArena *node_arena;
@ -69,8 +68,7 @@ struct VBVHTree
/*
* Cost to test N childs
*/
struct PackCost
{
struct PackCost {
float operator()(int n)
{
return n;
@ -84,7 +82,7 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
//TODO find a away to exactly calculate the needed memory
MemArena *arena1 = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "vbvh arena");
BLI_memarena_use_malloc(arena1);
BLI_memarena_use_malloc(arena1);
//Build and optimize the tree
if (1) {
@ -107,10 +105,10 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
obj->root = NULL;
}
else {
/*
TODO
/* TODO */
#if 0
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
//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);
BLI_memarena_free(arena2);
*/
#endif
}
//Cleanup
rtbuild_free( obj->builder );
rtbuild_free(obj->builder);
obj->builder = NULL;
obj->node_arena = arena1;
@ -131,17 +129,17 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
}
template<int StackSize>
int intersect(VBVHTree *obj, Isect* isec)
int intersect(VBVHTree *obj, Isect *isec)
{
//TODO renable hint support
if (RE_rayobject_isAligned(obj->root)) {
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
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
return RE_rayobject_intersect( (RayObject*) obj->root, isec );
return RE_rayobject_intersect( (RayObject *) obj->root, isec);
}
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
{
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 =
{
(RE_rayobject_raycast_callback) ((int(*)(Tree*, Isect*)) &intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void(*)(Tree*, RayObject*)) &bvh_add<Tree>),
(RE_rayobject_done_callback) ((void(*)(Tree*)) &bvh_done<Tree>),
(RE_rayobject_free_callback) ((void(*)(Tree*)) &bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void(*)(Tree*, float*, float*)) &bvh_bb<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_raycast_callback) ((int (*)(Tree *, Isect *)) & intersect<STACK_SIZE>),
(RE_rayobject_add_callback) ((void (*)(Tree *, RayObject *)) & bvh_add<Tree>),
(RE_rayobject_done_callback) ((void (*)(Tree *)) & bvh_done<Tree>),
(RE_rayobject_free_callback) ((void (*)(Tree *)) & bvh_free<Tree>),
(RE_rayobject_merge_bb_callback)((void (*)(Tree *, float *, float *)) & bvh_bb<Tree>),
(RE_rayobject_cost_callback) ((float (*)(Tree *)) & bvh_cost<Tree>),
(RE_rayobject_hint_bb_callback) ((void (*)(Tree *, LCTSHint *, float *, float *)) & bvh_hint_bb<Tree>)
};
return api;
}
template<class Tree>
RayObjectAPI* bvh_get_api(int maxstacksize)
RayObjectAPI *bvh_get_api(int maxstacksize)
{
static RayObjectAPI bvh_api256 = make_api<Tree, 1024>();

@ -57,13 +57,13 @@ extern int tot_pushdown;
template<class Node>
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>
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);
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 (node_fits_inside(node, parent) && RE_rayobject_isAligned(parent->child) ) {
float pcost = bb_area(parent->bb, parent->bb+3);
cost = std::min( cost, std::make_pair(pcost, parent) );
float pcost = bb_area(parent->bb, parent->bb + 3);
cost = std::min(cost, std::make_pair(pcost, parent) );
for (Node *child = parent->child; child; child = child->sibling)
q.push(child);
}
@ -84,11 +84,11 @@ static int tot_moves = 0;
template<class Node>
void reorganize(Node *root)
{
std::queue<Node*> q;
std::queue<Node *> q;
q.push(root);
while (!q.empty()) {
Node * node = q.front();
Node *node = q.front();
q.pop();
if (RE_rayobject_isAligned(node->child)) {
@ -96,7 +96,7 @@ void reorganize(Node *root)
assert(RE_rayobject_isAligned(*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);
if (best.second == node) {
@ -129,7 +129,7 @@ void reorganize(Node *root)
template<class 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; ) {
Node *next = (*prev)->sibling;
@ -160,12 +160,12 @@ void pushup(Node *parent)
{
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;
for (Node *child = parent->child; RE_rayobject_isAligned(child) && child; ) {
const float c_area = bb_area(child->bb, child->bb + 3);
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;
if (flatten_cost < original_cost && nchilds >= 2) {
append_sibling(child, child->child);
@ -201,7 +201,7 @@ void pushup_simd(Node *parent)
Node **prev = &parent->child;
for (Node *child = parent->child; RE_rayobject_isAligned(child) && 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);
append_sibling(child, child->child);
child = child->sibling;
@ -227,7 +227,7 @@ template<class Node>
void pushdown(Node *parent)
{
Node **s_child = &parent->child;
Node * child = parent->child;
Node *child = parent->child;
while (child && RE_rayobject_isAligned(child)) {
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));
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?)
// float ia = bb_area(i->bb, i->bb+3)
// if (child->i)
*s_child = child->sibling;
child->sibling = i->child;
i->child = child;
next_s_child = s_child;
*s_child = child->sibling;
child->sibling = i->child;
i->child = child;
next_s_child = s_child;
tot_pushdown++;
break;
}
tot_pushdown++;
break;
}
child = next;
s_child = next_s_child;
}
@ -273,13 +273,13 @@ float bvh_refit(Node *node)
for (Node *child = node->child; child; child = child->sibling)
total += bvh_refit(child);
float old_area = bb_area(node->bb, node->bb+3);
INIT_MINMAX(node->bb, node->bb+3);
float old_area = bb_area(node->bb, node->bb + 3);
INIT_MINMAX(node->bb, node->bb + 3);
for (Node *child = node->child; child; child = child->sibling) {
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;
}
@ -289,12 +289,11 @@ float bvh_refit(Node *node)
* with the purpose to reduce the expected cost (eg.: number of BB tests).
*/
#include <vector>
#define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */
#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE
#define MAX_CUT_SIZE 4 /* svbvh assumes max 4 children! */
#define MAX_OPTIMIZE_CHILDS MAX_CUT_SIZE
struct OVBVHNode
{
float bb[6];
struct OVBVHNode {
float bb[6];
OVBVHNode *child;
OVBVHNode *sibling;
@ -306,7 +305,7 @@ struct OVBVHNode
float cut_cost[MAX_CUT_SIZE];
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 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) {
**cut = this;
*cut = &(**cut)->sibling;
*cut = &(**cut)->sibling;
}
else {
if (cutsize > MAX_CUT_SIZE) {
for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
child->set_cut( 1, cut );
child->set_cut(1, cut);
cutsize--;
}
assert(cutsize == 0);
}
else
for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling)
child->set_cut( child->get_cut_size( cutsize ), cut );
else {
for (OVBVHNode *child = this->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
child->set_cut(child->get_cut_size(cutsize), cut);
}
}
}
}
@ -365,8 +366,7 @@ struct OVBVHNode
*
*/
template<class Node, class TestCost>
struct VBVH_optimalPackSIMD
{
struct VBVH_optimalPackSIMD {
TestCost testcost;
VBVH_optimalPackSIMD(TestCost testcost)
@ -377,8 +377,7 @@ struct VBVH_optimalPackSIMD
/*
* calc best cut on a node
*/
struct calc_best
{
struct calc_best {
Node *child[MAX_OPTIMIZE_CHILDS];
float child_hit_prob[MAX_OPTIMIZE_CHILDS];
@ -387,10 +386,10 @@ struct VBVH_optimalPackSIMD
int nchilds = 0;
//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) {
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++;
}
@ -399,7 +398,7 @@ struct VBVH_optimalPackSIMD
//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])
for (int i = 0; i <= nchilds; i++) {
@ -410,13 +409,13 @@ struct VBVH_optimalPackSIMD
cost[0][0] = 0;
for (int i = 1; i<=nchilds; i++) {
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 i = 1; i <= nchilds; i++) {
for (int size = i - 1; size /*+(nchilds-i)*/ <= MAX_CUT_SIZE; size++) {
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);
if (new_cost < cost[i][size+cut]) {
cost[i][size+cut] = new_cost;
bt[i][size+cut] = cut;
if (new_cost < cost[i][size + cut]) {
cost[i][size + cut] = new_cost;
bt[i][size + cut] = cut;
}
}
}
@ -424,11 +423,11 @@ struct VBVH_optimalPackSIMD
//Save the ways to archieve the minimum cost with a given cutsize
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) {
int current_size = i;
for (int j=nchilds; j>0; j--) {
child[j-1]->cut_size[i-1] = bt[j][current_size];
for (int j = nchilds; j > 0; j--) {
child[j - 1]->cut_size[i - 1] = bt[j][current_size];
current_size -= bt[j][current_size];
}
}
@ -439,23 +438,23 @@ struct VBVH_optimalPackSIMD
void calc_costs(Node *node)
{
if ( RE_rayobject_isAligned(node->child) ) {
if (RE_rayobject_isAligned(node->child) ) {
int nchilds = 0;
for (Node *child = node->child; child && RE_rayobject_isAligned(child); child = child->sibling) {
calc_costs(child);
nchilds++;
}
for (int i=0; i<MAX_CUT_SIZE; i++)
for (int i = 0; i < MAX_CUT_SIZE; i++)
node->cut_cost[i] = INFINITY;
//We are not allowed to look on nodes with with so many childs
if (nchilds > MAX_CUT_SIZE) {
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) {
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);
@ -466,7 +465,7 @@ struct VBVH_optimalPackSIMD
calc_best calc(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);
if (m < node->cut_cost[0]) {
node->cut_cost[0] = m;
@ -491,7 +490,7 @@ struct VBVH_optimalPackSIMD
if (num == 0) { num++; first = true; }
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();
}
return node;

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

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

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

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