Subversion Repositories gelsvn

Rev

Rev 291 | Rev 373 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
290 jrf 1
#include "CGLA/Vec4f.h"
2
#include "Triangle.h"
3
 
4
 
5
using namespace std;
6
using namespace CGLA;
7
 
291 jrf 8
namespace Geometry
9
{
290 jrf 10
 
291 jrf 11
const float EPSILON = 0.000001f;
12
 
290 jrf 13
Triangle::Triangle(const CGLA::Vec3f& _v0, 
14
									 const CGLA::Vec3f& _v1, 
15
									 const CGLA::Vec3f& _v2,
16
 
17
									 const CGLA::Vec3f& _vn0,
18
									 const CGLA::Vec3f& _vn1,
19
									 const CGLA::Vec3f& _vn2,
20
 
21
									 const CGLA::Vec3f& _en0,
22
									 const CGLA::Vec3f& _en1,
23
									 const CGLA::Vec3f& _en2)
24
{
25
	vert[0]  =_v0;
26
	vert[1]  =_v1;
27
	vert[2]  =_v2;
28
 
29
#ifdef COMPUTE_SIGN
30
	vert_norm[0] = _vn0;
31
	vert_norm[1] = _vn1;
32
	vert_norm[2] = _vn2;
33
 
34
	edge_norm[0] = _en0;
35
	edge_norm[1] = _en1;
36
	edge_norm[2] = _en2;
37
#endif
38
 
39
	face_norm = normalize(cross(vert[1]-vert[0], vert[2]-vert[0]));
40
	for(int i=0;i<3;++i)
41
		{
42
			int j= (i+1)%3;
43
			edge[i] = vert[j]-vert[i];
44
			tri_plane_edge_norm[i] = cross(face_norm, edge[i]);
45
			edge_len[i] = edge[i].length();
46
		}
47
}
48
 
49
 
50
// Moellers method
51
bool Triangle::intersect(const CGLA::Vec3f& orig,
52
												 const CGLA::Vec3f& dir, float&t) const
53
{
54
	Vec3f tvec, pvec, qvec;
55
	float det,inv_det;
56
 
57
   /* begin calculating determinant - also used to calculate U parameter */
58
   pvec = cross(dir, -edge[2]);
59
 
60
   /* if determinant is near zero, ray lies in plane of triangle */
61
   det = dot(edge[0], pvec);
62
 
63
   if (det > -EPSILON && det < EPSILON)
64
     return 0;
65
   inv_det = 1.0 / det;
66
 
67
   /* calculate distance from v0 to ray origin */
68
   tvec =  orig - vert[0];
69
 
70
   /* calculate U parameter and test bounds */
71
   float u = dot(tvec, pvec) * inv_det;
72
   if (u < 0.0 || u > 1.0)
73
     return false;
74
 
75
   /* prepare to test V parameter */
76
   qvec = cross(tvec, edge[0]);
77
 
78
   /* calculate V parameter and test bounds */
79
   float v = dot(dir, qvec) * inv_det;
80
   if (v < 0.0 || u + v > 1.0)
81
     return false;
82
 
83
   /* calculate t, ray intersects triangle */
84
   t = dot(-edge[2], qvec) * inv_det;
85
 
86
   return true;
87
}
88
 
89
 
90
 
91
 
92
bool Triangle::signed_distance(const Vec3f& p, 
93
															 float& sq_dist, float& sgn) const
94
{
95
	int vertex_scores[3] = {0,0,0};
96
	Vec3f closest_pnt, normal;
97
	int idx_0;
98
 
99
	// Loop over all three edges.
100
	for(idx_0=0; idx_0<3; ++idx_0)
101
		{
102
			const int idx_1 = (idx_0+1) % 3;
103
			const Vec3f dir_3d = edge[idx_0]/edge_len[idx_0];
104
			const float t = dot(p - vert[idx_0], dir_3d);
105
			if(t <= 0)
106
				{
107
					++vertex_scores[idx_0];
108
					if(vertex_scores[idx_0] == 2)
109
						{
110
							closest_pnt = vert[idx_0];
111
#ifdef COMPUTE_SIGN
112
							normal = vert_norm[idx_0];
113
#endif
114
							break;
115
						}
116
				}
117
			else if(t >= edge_len[idx_0])
118
				{
119
					++vertex_scores[idx_1];
120
					if(vertex_scores[idx_1] == 2)
121
						{
122
							closest_pnt = vert[idx_1];
123
#ifdef COMPUTE_SIGN
124
							normal = vert_norm[idx_1];
125
#endif
126
							break;
127
						}
128
				}
129
			else if(dot(tri_plane_edge_norm[idx_0], p-vert[idx_0]) <=0)
130
				{
131
					closest_pnt=vert[idx_0]+t*dir_3d;
132
#ifdef COMPUTE_SIGN
133
					normal = edge_norm[idx_0];
134
#endif
135
					break;
136
				}
137
		}
138
	if(idx_0 == 3)
139
		{
140
			closest_pnt = p - face_norm*(dot(p-vert[0],face_norm));
141
#ifdef COMPUTE_SIGN
142
			normal = face_norm;
143
#endif
144
		}
145
	sq_dist = sqr_length(p-closest_pnt);
146
 
147
#ifdef COMPUTE_SIGN
148
	// Compute dot product with angle weighted normal, and
149
	// assign the sign based on the result.
150
	if(dot(normal, p-closest_pnt) >=0)
151
		sgn = 1.0f;
152
	else
153
		sgn = -1.0f;
154
#else
155
	sgn = 1.0f;
156
#endif
157
 
158
	return true;
159
}
160
 
291 jrf 161
}