Esempio n. 1
0
int RE_rayobject_raycast(RayObject *r, Isect *isec)
{
    int i;

    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];

        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];
    }

#ifdef RT_USE_LAST_HIT
    /* last hit heuristic */
    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))
        {
            RE_RC_COUNT(isec->raycounter->raycast.hit);
            RE_RC_COUNT(isec->raycounter->rayshadow_last_hit.hit);
            return 1;
        }
    }
#endif

#ifdef RT_USE_HINT
    isec->hit_hint = 0;
#endif

    if(RE_rayobject_intersect(r, isec))
    {
        RE_RC_COUNT(isec->raycounter->raycast.hit);

#ifdef RT_USE_HINT
        isec->hint = isec->hit_hint;
#endif
        return 1;
    }

    return 0;
}
Esempio n. 2
0
int intersect(SVBVHTree *obj, Isect* isec)
{
	//TODO renable hint support
	if(RE_rayobject_isAligned(obj->root))
		return bvh_node_stack_raycast<SVBVHNode,StackSize,false>( obj->root, isec);
	else
		return RE_rayobject_intersect( (RayObject*) obj->root, isec );
}
Esempio n. 3
0
static int intersect(QBVHTree *obj, Isect *isec)
{
	//TODO renable hint support
	if (RE_rayobject_isAligned(obj->root)) {
		if (isec->mode == RE_RAY_SHADOW)
			return svbvh_node_stack_raycast<StackSize, true>(obj->root, isec);
		else
			return svbvh_node_stack_raycast<StackSize, false>(obj->root, isec);
	}
	else
		return RE_rayobject_intersect((RayObject *)obj->root, isec);
}
Esempio n. 4
0
static void bvh_callback(void *userdata, int index, const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit)
{
	struct BVHCallbackUserData *data = (struct BVHCallbackUserData*)userdata;
	Isect *isec = data->isec;
	RayObject *face = data->leafs[index];
	
	if (RE_rayobject_intersect(face, isec)) {
		hit->index = index;

		if (isec->mode == RE_RAY_SHADOW)
			hit->dist = 0;
		else
			hit->dist = isec->dist;
	}
}
static int  RE_rayobject_instance_intersect(RayObject *o, Isect *isec)
{
    InstanceRayObject *obj = (InstanceRayObject *)o;
    float start[3], dir[3], idot_axis[3], dist;
    int changed = 0, i, res;

    // TODO - this is disabling self intersection on instances
    if (isec->orig.ob == obj->ob && obj->ob) {
        changed = 1;
        isec->orig.ob = obj->target_ob;
    }

    // backup old values
    copy_v3_v3(start, isec->start);
    copy_v3_v3(dir, isec->dir);
    copy_v3_v3(idot_axis, isec->idot_axis);
    dist = isec->dist;

    // transform to target coordinates system
    mul_m4_v3(obj->global2target, isec->start);
    mul_mat3_m4_v3(obj->global2target, isec->dir);
    isec->dist *= normalize_v3(isec->dir);

    // update idot_axis and bv_index
    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.0f ? 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];
    }

    // raycast
    res = RE_rayobject_intersect(obj->target, isec);

    // map dist into original coordinate space
    if (res == 0) {
        isec->dist = dist;
    }
    else {
        // note we don't just multiply dist, because of possible
        // non-uniform scaling in the transform matrix
        float vec[3];

        mul_v3_v3fl(vec, isec->dir, isec->dist);
        mul_mat3_m4_v3(obj->target2global, vec);

        isec->dist = len_v3(vec);
        isec->hit.ob = obj->ob;

#ifdef RT_USE_LAST_HIT
        // TODO support for last hit optimization in instances that can jump
        // directly to the last hit face.
        // For now it jumps directly to the last-hit instance root node.
        isec->last_hit = RE_rayobject_unalignRayAPI((RayObject *) obj);
#endif
    }

    // restore values
    copy_v3_v3(isec->start, start);
    copy_v3_v3(isec->dir, dir);
    copy_v3_v3(isec->idot_axis, idot_axis);

    if (changed)
        isec->orig.ob = obj->ob;

    // restore bv_index
    for (i = 0; i < 3; i++) {
        isec->bv_index[2 * i]     = isec->idot_axis[i] < 0.0f ? 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];
    }

    return res;
}