Subversion Repositories gelsvn

Rev

Rev 291 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
290 jrf 1
#include <cfloat>
2
#include <GL/gl.h>
3
#include "AABox.h"
4
 
5
using namespace std;
6
using namespace CGLA;
7
 
8
bool AABox::intersect(const CGLA::Vec3f& p, const CGLA::Vec3f& dir) const
9
{
10
	Vec3f t0,t1;
11
	for(int i=0;i<3;++i)
12
		{
13
			t0[i] = (pmin[i]-p[i])/dir[i];
14
			t1[i] = (pmax[i]-p[i])/dir[i];
15
		}
16
	float tmin = max(min(t0[0],t1[0]),max(min(t0[1],t1[1]),min(t0[2],t1[2])));
17
	float tmax = min(max(t0[0],t1[0]),min(max(t0[1],t1[1]),max(t0[2],t1[2])));
18
 
19
	return ( (tmin + CGLA::TINY) <tmax);
20
}
21
 
22
void AABox::gl_draw() const
23
{
24
	glBegin(GL_QUADS);
25
	Vec3f norm_neg[] = {Vec3f(0,0,-1), Vec3f(-1,0,0), Vec3f(0,-1,0)};
26
	Vec3f norm_pos[] = {Vec3f(0,0, 1), Vec3f( 1,0,0), Vec3f(0, 1,0)};
27
	for(int j=0;j<3;++j)
28
		{
29
			glNormal3fv(norm_neg[j].get());
30
			Vec3f p = pmin;
31
			glVertex3f(p[0], p[1], p[2]);
32
			p[(j+1)%3] = pmax[(j+1)%3];
33
			glVertex3f(p[0], p[1], p[2]);
34
			p[j] = pmax[j];
35
			glVertex3f(p[0], p[1], p[2]);
36
			p[(j+1)%3] = pmin[(j+1)%3];
37
			glVertex3f(p[0], p[1], p[2]);
38
		}
39
	glEnd();
40
	glBegin(GL_QUADS);
41
	for(int j=0;j<3;++j)
42
		{
43
			glNormal3fv(norm_pos[j].get());
44
			Vec3f p = pmax;
45
			glVertex3f(p[0], p[1], p[2]);
46
			p[j] = pmin[j];
47
			glVertex3f(p[0], p[1], p[2]);
48
			p[(j+1)%3] = pmin[(j+1)%3];
49
			glVertex3f(p[0], p[1], p[2]);
50
			p[j] = pmax[j];
51
			glVertex3f(p[0], p[1], p[2]);
52
		}
53
	glEnd();
54
}
55
 
56
void AABox::minmax_sq_dist(const CGLA::Vec3f& p, 
57
													 float& dmin, float& dmax) const
58
{
59
	const Vec3f a = 0.5*pmax-0.5*pmin;
60
	const Vec3f p0 = pmin + a;
61
 	Vec3f d = p-p0;
62
 	Vec3f f(d);
63
 
64
	for(int i=0;i<3;++i)
65
		{
66
 			if(f[i]>=0) 
67
 				f[i] = p[i]-pmin[i];
68
 			else
69
 				f[i] = p[i]-pmax[i];
70
 
71
			if(d[i]<-a[i])
72
				d[i] = p[i]-pmin[i];
73
			else if(d[i]>a[i])
74
				d[i] = p[i]-pmax[i];
75
			else 
76
				d[i] = 0;
77
		}
78
	dmin = sqr_length(d);
79
//  	dmax = sqr_length(p-interior_point);
80
	dmax = sqr_length(f);
81
	assert(dmin<=dmax);
82
}
83
 
84
AABox AABox::box_triangle(const Triangle& t)
85
{
86
	return AABox(t.get_pmin(), t.get_pmax(), t.get_centre());
87
}
88
 
89
 
90
AABox AABox::box_and_split(const std::vector<Triangle>& invec,
91
													 std::vector<Triangle>& lvec,
92
													 std::vector<Triangle>& rvec)
93
{
94
	const int N = invec.size();
95
	Vec3f tri_pmin(FLT_MAX), tri_pmax(-FLT_MAX);
96
 
97
	for(int i=0;i<N;++i)
98
		{
99
			tri_pmin = v_min(invec[i].get_pmin(), tri_pmin);
100
			tri_pmax = v_max(invec[i].get_pmax(), tri_pmax);
101
		}
102
	Vec3f diff = tri_pmax - tri_pmin;
103
 
104
	// Find the point closest to the centre.
105
	Vec3f centre = tri_pmin + diff;
106
	Vec3f centre_close = invec[0].get_v0();
107
	float min_dist = FLT_MAX;
108
	for(int i=0;i<N;++i)
109
		{
110
			Vec3f v0 = invec[i].get_v0();
111
			Vec3f v1 = invec[i].get_v1();
112
			Vec3f v2 = invec[i].get_v2();
113
			float sl0 = sqr_length(centre-v0);
114
			if(sl0 < min_dist)
115
				{
116
					min_dist = sl0;
117
					centre_close = v0;
118
				}
119
			float sl1 = sqr_length(centre-v1);
120
			if(sl1 < min_dist)
121
				{
122
					min_dist = sl1;
123
					centre_close = v1;
124
				}
125
			float sl2 = sqr_length(centre-v2);
126
			if(sl2 < min_dist)
127
				{
128
					min_dist = sl2;
129
					centre_close = v2;
130
				}
131
		}
132
 
133
	int k;
134
	if(diff[0]>diff[1])
135
		{
136
			if(diff[0]>diff[2]) 
137
				k = 0;
138
			else 
139
				k = 2;
140
		}
141
	else
142
		{
143
			if(diff[1]>diff[2]) 
144
				k = 1;
145
			else 
146
				k = 2;
147
		}
148
 
149
	float thresh = diff[k]/2.0f + tri_pmin[k];
150
 
151
 	for(int i=0;i<N;++i)
152
		{
153
			if(invec[i].get_centre()[k] > thresh)
154
				rvec.push_back(invec[i]);
155
			else
156
				lvec.push_back(invec[i]);
157
		}
158
	if(lvec.empty() || rvec.empty())
159
		{
160
			lvec.clear();
161
			lvec.insert(lvec.end(),
162
									invec.begin(),
163
									invec.begin()+N/2);
164
			rvec.clear();
165
			rvec.insert(rvec.end(),
166
									invec.begin()+N/2,
167
									invec.end());
168
		}
169
	assert(!lvec.empty());
170
	assert(!rvec.empty());
171
	assert(lvec.size()+rvec.size() == invec.size());
172
	return AABox(tri_pmin, tri_pmax, centre_close);
173
}
174