示例#1
0
RayObject *RE_rayobject_blibvh_create(int size)
{
	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");
	
	INIT_MINMAX(obj->bb[0], obj->bb[1]);
	return RE_rayobject_unalignRayAPI((RayObject*) obj);
}
RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob)
{
    InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject");
    assert(RE_rayobject_isAligned(obj) );  /* RayObject API assumes real data to be 4-byte aligned */

    obj->rayobj.api = &instance_api;
    obj->target = target;
    obj->ob = ob;
    obj->target_ob = target_ob;

    copy_m4_m4(obj->target2global, transform);
    invert_m4_m4(obj->global2target, obj->target2global);

    return RE_rayobject_unalignRayAPI((RayObject *) obj);
}
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;
}
示例#4
0
RayObject *RE_rayobject_empty_create()
{
    return RE_rayobject_unalignRayAPI( &empty_raytree );
}