summaryrefslogtreecommitdiff
path: root/intersect.cu
blob: d7fdaa50488ff8ea57fa008da97bd5303bf948bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//-*-c-*-

__device__ __host__ Matrix inv(const Matrix&m, float& determinant)
{
	determinant = det(m);

	return make_matrix(m.a11*m.a22 - m.a12*m.a21,
			   m.a02*m.a21 - m.a01*m.a22,
			   m.a01*m.a12 - m.a02*m.a11,
			   m.a12*m.a20 - m.a10*m.a22,
			   m.a00*m.a22 - m.a02*m.a20,
			   m.a02*m.a10 - m.a00*m.a12,
			   m.a10*m.a21 - m.a11*m.a20,
			   m.a01*m.a20 - m.a00*m.a21,
			   m.a00*m.a11 - m.a01*m.a10)/determinant;
}

__device__ bool intersect_triangle(const float3 &x, const float3 &p, float3 *vertex, float3 &intersection)
{
	float determinant;

	float3 u = inv(make_matrix(vertex[0]-vertex[2],vertex[1]-vertex[2],-p), determinant)*(x-vertex[2]);

	if (determinant == 0.0)
		return false;

	if (u.x < 0.0 || u.y < 0.0 || u.z < 0.0 || (1-u.x-u.y) < 0.0)
		return false;

	intersection = x + p*u.z;

	return true;
}

extern "C"
{

__global__ void intersect_triangle_mesh(float3 *x, float3 *p, int n, float3 *mesh, int *state, float3 *w)
{
	int idx = blockIdx.x*blockDim.x + threadIdx.x;

	bool hit = false;

	float distance, min_distance;
	float3 intersection, min_intersection;

	int i;
	for (i=0; i < n; i++)
	{
		if (intersect_triangle(x[idx], p[idx], mesh+3*i, intersection))
		{
			if (!hit)
			{
				state[idx] = 1;
				min_distance = norm(intersection-x[idx]);
				min_intersection = intersection;
				continue;
			}

			distance = norm(w[idx]-x[idx]);

			if (distance < min_distance)
			{
				state[idx] = 1;
				min_distance = distance;
				min_intersection = intersection;
			}
		}
	}
}

} // extern "c"