forked from bartvdbraak/blender
style cleanup: raytree code
This commit is contained in:
parent
7aa21d677a
commit
e79c29a1d6
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user