304 |
jab |
1 |
// Created by Bent Dalgaard Larsen, Nov, 2003
|
|
|
2 |
|
|
|
3 |
#include "Ray.h"
|
|
|
4 |
#include "BBox.h"
|
|
|
5 |
|
|
|
6 |
using namespace std;
|
|
|
7 |
using namespace CGLA;
|
|
|
8 |
|
|
|
9 |
#define my_min(x,y) (x<y?x:y)
|
|
|
10 |
#define my_max(x,y) (x>y?x:y)
|
|
|
11 |
|
|
|
12 |
namespace Geometry
|
|
|
13 |
{
|
|
|
14 |
void BBox::intersect_min_max(Ray &ray, double &t_min, double &t_max) const
|
|
|
15 |
{
|
|
|
16 |
double tx1 = (min_corner[0]-ray.origin[0])/ray.direction[0];
|
|
|
17 |
double ty1 = (min_corner[1]-ray.origin[1])/ray.direction[1];
|
|
|
18 |
double tz1 = (min_corner[2]-ray.origin[2])/ray.direction[2];
|
|
|
19 |
|
|
|
20 |
double tx2 = (max_corner[0]-ray.origin[0])/ray.direction[0];
|
|
|
21 |
double ty2 = (max_corner[1]-ray.origin[1])/ray.direction[1];
|
|
|
22 |
double tz2 = (max_corner[2]-ray.origin[2])/ray.direction[2];
|
|
|
23 |
|
|
|
24 |
t_min = my_max(my_min(tx1, tx2), my_max(my_min(ty1, ty2), my_min(tz1,tz2)));
|
|
|
25 |
t_max = my_min(my_max(tx1, tx2), my_min(my_max(ty1, ty2), my_max(tz1,tz2)));
|
|
|
26 |
}
|
|
|
27 |
|
|
|
28 |
bool BBox::intersect(Ray &ray)
|
|
|
29 |
{
|
|
|
30 |
double t_min, t_max;
|
|
|
31 |
intersect_min_max(ray, t_min, t_max);
|
|
|
32 |
|
|
|
33 |
if(t_min <= t_max && t_min < ray.dist && t_min > f_eps)
|
|
|
34 |
return true;
|
|
|
35 |
else
|
|
|
36 |
return false;
|
|
|
37 |
}
|
|
|
38 |
|
|
|
39 |
bool BBox::ray_triangle(Vec3f &ray_start, Vec3f &ray_end, ISectTri &tri)
|
|
|
40 |
{
|
|
|
41 |
Vec3f origin = ray_start;
|
|
|
42 |
Vec3f direction = ray_end - ray_start;
|
|
|
43 |
double dist = direction.length();
|
|
|
44 |
direction.normalize();
|
|
|
45 |
|
|
|
46 |
Vec3f p;
|
|
|
47 |
Vec3f q;
|
|
|
48 |
Vec3f s;
|
|
|
49 |
double a, f, u, v, t;
|
|
|
50 |
|
|
|
51 |
p = cross(direction, Vec3f(tri.edge1));
|
|
|
52 |
a = dot(Vec3f(tri.edge0),p);
|
|
|
53 |
if (a>-f_eps && a<f_eps)
|
|
|
54 |
return false;
|
|
|
55 |
f = 1/a;
|
|
|
56 |
s = origin - Vec3f(tri.point0);
|
|
|
57 |
u = f*dot(s,p);
|
|
|
58 |
if (u<0.0 || u>1.0)
|
|
|
59 |
return false;
|
|
|
60 |
q = cross(s, Vec3f(tri.edge0));
|
|
|
61 |
v = f * dot(direction, q);
|
|
|
62 |
if (v<0.0 || u+v>1.0)
|
|
|
63 |
return false;
|
|
|
64 |
t = f*dot(Vec3f(tri.edge1), q);
|
|
|
65 |
if (t<0)
|
|
|
66 |
return false;
|
|
|
67 |
// if (t<eps)
|
|
|
68 |
// return false;
|
|
|
69 |
if (t>dist)
|
|
|
70 |
return false;
|
|
|
71 |
|
|
|
72 |
return true;
|
|
|
73 |
}
|
|
|
74 |
|
|
|
75 |
|
|
|
76 |
bool BBox::intersect_edge_box(Vec3f &ray_start, Vec3f &ray_end)
|
|
|
77 |
{
|
|
|
78 |
Ray test_ray;
|
|
|
79 |
test_ray.origin = ray_start;
|
|
|
80 |
test_ray.direction = ray_end - ray_start;
|
|
|
81 |
test_ray.dist = test_ray.direction.length();
|
|
|
82 |
test_ray.direction.normalize();
|
|
|
83 |
return intersect(test_ray);
|
|
|
84 |
}
|
|
|
85 |
|
|
|
86 |
bool BBox::in_interval(double min_limit, double test_value, double max_limit)
|
|
|
87 |
{
|
|
|
88 |
if (min_limit<=test_value && test_value<=max_limit)
|
|
|
89 |
return true;
|
|
|
90 |
return false;
|
|
|
91 |
}
|
|
|
92 |
/*
|
|
|
93 |
|
|
|
94 |
bool BBox::intersect_triangle_left(ISectTri &tri, double plane, int axis) {
|
|
|
95 |
if (tri.point0[axis]<=plane)
|
|
|
96 |
return true;
|
|
|
97 |
if (tri.point1[axis]<=plane)
|
|
|
98 |
return true;
|
|
|
99 |
if (tri.point2[axis]<=plane)
|
|
|
100 |
return true;
|
|
|
101 |
return false;
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
bool BBox::intersect_triangle_right(ISectTri &tri, double plane, int axis) {
|
|
|
105 |
if (tri.point0[axis]>=plane)
|
|
|
106 |
return true;
|
|
|
107 |
if (tri.point1[axis]>=plane)
|
|
|
108 |
return true;
|
|
|
109 |
if (tri.point2[axis]>=plane)
|
|
|
110 |
return true;
|
|
|
111 |
return false;
|
|
|
112 |
}
|
|
|
113 |
*/
|
|
|
114 |
bool BBox::intersect_triangle(ISectTri &tri)
|
|
|
115 |
{
|
313 |
jrf |
116 |
Vec3f tmin_corner = min_corner - Vec3f(f_eps);
|
|
|
117 |
Vec3f tmax_corner = max_corner + Vec3f(f_eps);
|
304 |
jab |
118 |
|
|
|
119 |
// Vertex in box test:
|
|
|
120 |
// If any of the triangle vertices are inside the box then
|
|
|
121 |
// the triangle intersects the box
|
|
|
122 |
if (in_interval(tmin_corner[0],tri.point0[0],tmax_corner[0]) && in_interval(tmin_corner[1],tri.point0[1],tmax_corner[1]) && in_interval(tmin_corner[2],tri.point0[2],tmax_corner[2]))
|
|
|
123 |
return true;
|
|
|
124 |
if (in_interval(tmin_corner[0],tri.point1[0],tmax_corner[0]) && in_interval(tmin_corner[1],tri.point1[1],tmax_corner[1]) && in_interval(tmin_corner[2],tri.point1[2],tmax_corner[2]))
|
|
|
125 |
return true;
|
|
|
126 |
if (in_interval(tmin_corner[0],tri.point2[0],tmax_corner[0]) && in_interval(tmin_corner[1],tri.point2[1],tmax_corner[1]) && in_interval(tmin_corner[2],tri.point2[2],tmax_corner[2]))
|
|
|
127 |
return true;
|
|
|
128 |
|
|
|
129 |
// Triangle outside box test:
|
|
|
130 |
// If all of the triangle vertices are outside one of the planes
|
|
|
131 |
// defining the sides of the box then the triangle can be trivially
|
|
|
132 |
// rejected as outside
|
|
|
133 |
int i;
|
|
|
134 |
for(i=0;i<3;i++)
|
|
|
135 |
if (tri.point0[i]<tmin_corner[i] && tri.point1[i]<tmin_corner[i] && tri.point2[i]<tmin_corner[i])
|
|
|
136 |
return false;
|
|
|
137 |
|
|
|
138 |
for(i=0;i<3;i++)
|
|
|
139 |
if (tri.point0[i]>tmax_corner[i] && tri.point1[i]>tmax_corner[i] && tri.point2[i]>tmax_corner[i])
|
|
|
140 |
return false;
|
|
|
141 |
|
|
|
142 |
// Triangle edges - box intersection test
|
|
|
143 |
if (intersect_edge_box(tri.point0, tri.point1))
|
|
|
144 |
return true;
|
|
|
145 |
|
|
|
146 |
if (intersect_edge_box(tri.point1, tri.point2))
|
|
|
147 |
return true;
|
|
|
148 |
|
|
|
149 |
if (intersect_edge_box(tri.point2, tri.point0))
|
|
|
150 |
return true;
|
|
|
151 |
|
|
|
152 |
// Box diagonal - triangle intersection test, 4 tests in total
|
|
|
153 |
Vec3f corner0;
|
|
|
154 |
Vec3f corner1;
|
|
|
155 |
|
|
|
156 |
Vec3f tmin_corner_e = tmin_corner;
|
|
|
157 |
Vec3f tmax_corner_e = tmax_corner;
|
|
|
158 |
|
|
|
159 |
corner0.set(tmin_corner_e[0],tmin_corner_e[1],tmin_corner_e[2]);
|
|
|
160 |
corner1.set(tmax_corner_e[0],tmax_corner_e[1],tmax_corner_e[2]);
|
|
|
161 |
if (ray_triangle(corner0, corner1, tri))
|
|
|
162 |
return true;
|
|
|
163 |
|
|
|
164 |
corner0.set(tmax_corner_e[0],tmin_corner_e[1],tmin_corner_e[2]);
|
|
|
165 |
corner1.set(tmin_corner_e[0],tmax_corner_e[1],tmax_corner_e[2]);
|
|
|
166 |
if (ray_triangle(corner0, corner1, tri))
|
|
|
167 |
return true;
|
|
|
168 |
|
|
|
169 |
corner0.set(tmin_corner_e[0],tmax_corner_e[1],tmin_corner_e[2]);
|
|
|
170 |
corner1.set(tmax_corner_e[0],tmin_corner_e[1],tmax_corner_e[2]);
|
|
|
171 |
if (ray_triangle(corner0, corner1, tri))
|
|
|
172 |
return true;
|
|
|
173 |
|
|
|
174 |
corner0.set(tmin_corner_e[0],tmin_corner_e[1],tmax_corner_e[2]);
|
|
|
175 |
corner1.set(tmax_corner_e[0],tmax_corner_e[1],tmin_corner_e[2]);
|
|
|
176 |
if (ray_triangle(corner0, corner1, tri))
|
|
|
177 |
return true;
|
|
|
178 |
|
|
|
179 |
// None succeded
|
|
|
180 |
return false;
|
|
|
181 |
}
|
|
|
182 |
|
|
|
183 |
void BBox::compute_bbox(vector<ISectTri> &isectmesh)
|
|
|
184 |
{
|
|
|
185 |
min_corner.set(CGLA::BIG,CGLA::BIG,CGLA::BIG);
|
|
|
186 |
max_corner.set(-CGLA::BIG,-CGLA::BIG,-CGLA::BIG);
|
|
|
187 |
|
|
|
188 |
for(unsigned int i=0;i<isectmesh.size(); ++i)
|
|
|
189 |
{
|
|
|
190 |
const ISectTri& tri = isectmesh[i];
|
|
|
191 |
for(int j=0;j<3;j++) {
|
|
|
192 |
if (min_corner[j]>tri.point0[j])
|
|
|
193 |
min_corner[j]=tri.point0[j];
|
|
|
194 |
if (min_corner[j]>tri.point1[j])
|
|
|
195 |
min_corner[j]=tri.point1[j];
|
|
|
196 |
if (min_corner[j]>tri.point2[j])
|
|
|
197 |
min_corner[j]=tri.point2[j];
|
|
|
198 |
if (max_corner[j]<tri.point0[j])
|
|
|
199 |
max_corner[j]=tri.point0[j];
|
|
|
200 |
if (max_corner[j]<tri.point1[j])
|
|
|
201 |
max_corner[j]=tri.point1[j];
|
|
|
202 |
if (max_corner[j]<tri.point2[j])
|
|
|
203 |
max_corner[j]=tri.point2[j];
|
|
|
204 |
}
|
|
|
205 |
}
|
|
|
206 |
}
|
|
|
207 |
|
|
|
208 |
double BBox::area()
|
|
|
209 |
{
|
|
|
210 |
Vec3f size = max_corner - min_corner;
|
|
|
211 |
return size[0]*size[1]*2 +
|
|
|
212 |
size[1]*size[2]*2 +
|
|
|
213 |
size[0]*size[2]*2;
|
|
|
214 |
}
|
|
|
215 |
}
|
|
|
216 |
|