Esempio n. 1
0
bool Manipulator::canManipulate(Ray3f ray,Box3f box,Mat4f* T)
{
	//nothing to do
	if (!box.isValid())
		return false;

	Vec3f size=box.size();

	Mat4f Direct=(*T) * getTransformationToBox(box);
    Mat4f Inverse=Direct.invert();

    // the ray is in world coordinate
    Vec3f P1=Inverse * (ray.origin        );
    Vec3f P2=Inverse * (ray.origin+ray.dir);
    
    // should be the unit bounding ball not the bounding box, but seems good enough (probably better)
    // is objects does not overlap too much!
	float epsilon=1e-4f;
	Box3f unit_box(
		Vec3f(
			size[0]?-1:-epsilon,
			size[1]?-1:-epsilon,
			size[2]?-1:-epsilon),
		Vec3f(
			size[0]?+1:+epsilon,
			size[1]?+1:+epsilon,
			size[2]?+1:+epsilon));


	float tmin,tmax;
    return (Ray3f(P1,P2-P1).intersectBox(tmin,tmax,unit_box) && tmin>0);
}
Esempio n. 2
0
void	test_cast_against_tree(const array<kd_tree_dynamic*>& treelist)
// Shoot a ton of random rays against the kdtrees.
{
	assert(treelist.size() > 0);

	static const int	RAY_COUNT = 100000;

	printf("building kd_tree_packed...\n");

	uint64	start_build_ticks = tu_timer::get_profile_ticks();

	// Make a list of packed trees, and get an overall bound.
	array<kd_tree_packed*>	kds;
	axial_box	bound(axial_box::INVALID, vec3::flt_max, vec3::minus_flt_max);
	for (int i = 0; i < treelist.size(); i++)
	{
		kd_tree_packed*	kd = kd_tree_packed::build(treelist[i]);
		kds.push_back(kd);

		bound.set_enclosing(kd->get_bound());
	}

	uint64	end_build_ticks = tu_timer::get_profile_ticks();

	printf("built %d trees in %3.3f seconds\n",
	       kds.size(),
	       tu_timer::profile_ticks_to_seconds(end_build_ticks - start_build_ticks));

	printf("starting to cast...\n");

	uint64	start_cast_ticks = tu_timer::get_profile_ticks();

	int	hit_count = 0;

	axial_box	unit_box(vec3(-0.5f, -0.5f, -0.5f), vec3(0.5f, 0.5f, 0.5f));

	for (int i = 0; i < RAY_COUNT; i++)
	{
#define RANDOM_RAY
#ifdef RANDOM_RAY
		// Ray between two random points within the volume.
		vec3	start = bound.get_random_point();
		vec3	end = bound.get_random_point();

		// Avoid near-zero-length ray tests.
		while ((start - end).sqrmag() < 1e-3f)
		{
			end = bound.get_random_point();
		}
#else  // SHORT_RAY
		// Short rays at some random point within the volume.
		vec3	start = bound.get_random_point();
		vec3	disp = unit_box.get_random_point() * 100.f;
		while (disp.sqrmag() < 1e-6f)
		{
			disp = unit_box.get_random_point() * 100.f;
		}
		vec3	end = start + disp;
#endif

		ray_query	ray(ray_query::start_end, start, end);

		bool	result = false;
		for (int ti = 0, tn = kds.size(); ti < tn; ti++)
		{
			result = kds[ti]->ray_test(ray);
			if (result)
			{
				hit_count++;
				break;	// early out on hit
			}
		}
	}

	uint64	end_ticks = tu_timer::get_profile_ticks();

	print_ray_stats(start_cast_ticks, end_ticks, RAY_COUNT, hit_count);
}