Subversion Repositories gelsvn

Rev

Rev 324 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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