Subversion Repositories gelsvn

Rev

Rev 319 | Rev 350 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 319 Rev 349
Line 1... Line 1...
1
#include "CGLA/Vec3d.h"
1
#include "CGLA/Vec3d.h"
2
#include "Geometry/TriMesh.h"
2
#include "Geometry/TriMesh.h"
3
 
3
 
4
#include "BSPTree.h"
4
#include "BSPTree.h"
5
 
5
 
6
using namespace std;
6
using namespace std;
7
using namespace CGLA;
7
using namespace CGLA;
8
 
8
 
9
namespace Geometry
9
namespace Geometry
10
{
10
{
11
  int BSPTree::node_calls;
11
  int BSPTree::node_calls;
12
  int BSPTree::tri_calls;
12
  int BSPTree::tri_calls;
13
 
13
 
14
  void create_tri_accel(Vec3f A, Vec3f B, Vec3f C, TriAccel &tri_accel) 
14
  void create_tri_accel(Vec3f A, Vec3f B, Vec3f C, TriAccel &tri_accel) 
15
  {
15
  {
16
    Vec3f N = normalize(cross(B-A, C-A));
16
    Vec3f N = normalize(cross(B-A, C-A));
17
    // Find projection dir
17
    // Find projection dir
18
    int k,u,v;
18
    int k,u,v;
19
    if (fabs(N[0]) > fabs(N[1]))
19
    if (fabs(N[0]) > fabs(N[1]))
20
      if (fabs(N[0]) > fabs(N[2])) 
20
      if (fabs(N[0]) > fabs(N[2])) 
21
	k = 0; /* X */ 
21
    k = 0; /* X */ 
22
      else 
22
      else 
23
	k=2;   /* Z */
23
    k=2;   /* Z */
24
    else
24
    else
25
      if (fabs(N[1]) > fabs(N[2])) 
25
      if (fabs(N[1]) > fabs(N[2])) 
26
	k = 1; /* Y */ 
26
    k = 1; /* Y */ 
27
      else 
27
      else 
28
	k=2;   /* Z */
28
    k=2;   /* Z */
29
    
29
    
30
    u = (k+1)% 3; 
30
    u = (k+1)% 3; 
31
    v = (k+2)% 3;
31
    v = (k+2)% 3;
32
 
32
 
33
    Vec3f b = C - A;
33
    Vec3f b = C - A;
34
    Vec3f c = B - A;
34
    Vec3f c = B - A;
35
	
35
    
36
    double div = (b[u]*c[v]-b[v]*c[u]);
36
    double div = (b[u]*c[v]-b[v]*c[u]);
37
 
37
 
38
    tri_accel.n_u = N[u]/N[k];
38
    tri_accel.n_u = N[u]/N[k];
39
    tri_accel.n_v = N[v]/N[k];
39
    tri_accel.n_v = N[v]/N[k];
40
    tri_accel.n_d = dot(A, N/N[k]);
40
    tri_accel.n_d = dot(A, N/N[k]);
41
    tri_accel.k = k;
41
    tri_accel.k = k;
42
    
42
    
43
    tri_accel.b_nu = -b[v]/div;
43
    tri_accel.b_nu = -b[v]/div;
44
    tri_accel.b_nv = b[u]/div;
44
    tri_accel.b_nv = b[u]/div;
45
    tri_accel.b_d = (b[v]*A[u]-b[u]*A[v])/div;
45
    tri_accel.b_d = (b[v]*A[u]-b[u]*A[v])/div;
46
    
46
    
47
    tri_accel.c_nu = c[v]/div;
47
    tri_accel.c_nu = c[v]/div;
48
    tri_accel.c_nv = -c[u]/div;
48
    tri_accel.c_nv = -c[u]/div;
49
    tri_accel.c_d = (c[u]*A[v]-c[v]*A[u])/div;
49
    tri_accel.c_d = (c[u]*A[v]-c[v]*A[u])/div;
50
  }
50
  }
51
  
51
  
52
  // Most of this file is a direct copy from Henrik's notes
52
  // Most of this file is a direct copy from Henrik's notes
53
  BSPTree::BSPTree() 
53
  BSPTree::BSPTree() 
54
  {
54
  {
55
    root=0;
55
    root=0;
56
    b_is_build = false;
56
    b_is_build = false;
57
  }
57
  }
58
 
58
 
59
  BSPTree::~BSPTree() 
59
  BSPTree::~BSPTree() 
60
  {
60
  {
61
    clear();		
61
    clear();        
62
  }
62
  }
63
 
63
 
64
  void BSPTree::clear() 
64
  void BSPTree::clear() 
65
  {
65
  {
66
    if (root!=0) 
66
    if (root!=0) 
67
    {
67
    {
68
      delete_node(root);
68
      delete_node(root);
69
      root=0;
69
      root=0;
70
      b_is_build=false;
70
      b_is_build=false;
71
    }
71
    }
72
    isecttris.clear();
72
    isecttris.clear();
73
    all_objects.clear();
73
    all_objects.clear();
74
    all_triaccel.clear();
74
    all_triaccel.clear();
75
  }
75
  }
76
 
76
 
77
  void BSPTree::delete_node(BSPNode *node) 
77
  void BSPTree::delete_node(BSPNode *node) 
78
  {
78
  {
79
    if (node->left!=0)
79
    if (node->left!=0)
80
      delete_node(node->left);
80
      delete_node(node->left);
81
    if (node->right!=0)
81
    if (node->right!=0)
82
      delete_node(node->right);
82
      delete_node(node->right);
83
    delete node;
83
    delete node;
84
  }
84
  }
85
 
85
 
86
  void BSPTree::subdivide_node(BSPNode &node, BBox &bbox, 
86
  void BSPTree::subdivide_node(BSPNode &node, BBox &bbox, 
87
			       unsigned int level, 
87
                   unsigned int level, 
88
			       vector<ISectTri*>& objects, 
88
                   vector<ISectTri*>& objects, 
89
			       vector<TriAccel*>& tri_objects) 
89
                   vector<TriAccel*>& tri_objects) 
90
  {
90
  {
91
    const int TESTS = 2;
91
    const int TESTS = 2;
92
    
92
    
93
    if (objects.size()<=max_objects || level==max_level) 
93
    if (objects.size()<=max_objects || level==max_level) 
94
    {
94
    {
95
      node.axis_leaf = 4; // Means that this is a leaf
95
      node.axis_leaf = 4; // Means that this is a leaf
96
      node.plane = 0;
96
      node.plane = 0;
97
      node.left = 0;
97
      node.left = 0;
98
      node.right = 0;
98
      node.right = 0;
99
      node.id = all_objects.size();
99
      node.id = all_objects.size();
100
      node.count = objects.size();
100
      node.count = objects.size();
101
		
101
        
102
      for(unsigned int i = 0; i < objects.size(); ++i) 
102
      for(unsigned int i = 0; i < objects.size(); ++i) 
103
      {
103
      {
104
	all_objects.push_back(objects[i]);
104
    all_objects.push_back(objects[i]);
105
	all_triaccel.push_back(tri_objects[i]);
105
    all_triaccel.push_back(tri_objects[i]);
106
      }  
106
      }  
107
    } 
107
    } 
108
    else 
108
    else 
109
    {
109
    {
110
      bool right_zero=false;
110
      bool right_zero=false;
111
      bool left_zero=false;
111
      bool left_zero=false;
112
      unsigned int i;
112
      unsigned int i;
113
      BSPNode* left_node  = new BSPNode();
113
      BSPNode* left_node  = new BSPNode();
114
      BSPNode* right_node = new BSPNode();
114
      BSPNode* right_node = new BSPNode();
115
      vector<ISectTri*> left_objects;
115
      vector<ISectTri*> left_objects;
116
      vector<ISectTri*> right_objects;
116
      vector<ISectTri*> right_objects;
117
      vector<TriAccel*> tri_left_objects;
117
      vector<TriAccel*> tri_left_objects;
118
      vector<TriAccel*> tri_right_objects;
118
      vector<TriAccel*> tri_right_objects;
119
      
119
      
120
      node.left = left_node;
120
      node.left = left_node;
121
      node.right = right_node;
121
      node.right = right_node;
122
 
122
 
123
      int new_axis=-1;
123
      int new_axis=-1;
124
      double min_cost=CGLA::BIG;
124
      double min_cost=CGLA::BIG;
125
      int new_pos = -1;      
125
      int new_pos = -1;      
126
 
126
 
127
	  for(i=0;i<3;i++) 
127
      for(i=0;i<3;i++) 
128
      {
128
      {
129
	for(int k=1;k<TESTS;k++) 
129
    for(int k=1;k<TESTS;k++) 
130
	{
130
    {
131
	  BBox left_bbox = bbox;
131
      BBox left_bbox = bbox;
132
	  BBox right_bbox = bbox;
132
      BBox right_bbox = bbox;
133
				
133
                
134
	  double center = (bbox.max_corner[i]- bbox.min_corner[i])*(double)k/(double)TESTS + bbox.min_corner[i];
134
      double center = (bbox.max_corner[i]- bbox.min_corner[i])*(double)k/(double)TESTS + bbox.min_corner[i];
135
	  node.plane = center;
135
      node.plane = center;
136
	  
136
      
137
	  left_bbox.max_corner[i] = center; 
137
      left_bbox.max_corner[i] = center; 
138
	  right_bbox.min_corner[i] = center; 
138
      right_bbox.min_corner[i] = center; 
139
 
139
 
140
	  // Try putting the triangles in the left and right boxes
140
      // Try putting the triangles in the left and right boxes
141
	  int left_count = 0;
141
      int left_count = 0;
142
	  int right_count = 0;
142
      int right_count = 0;
143
	  for(unsigned int j=0;j<objects.size();j++) 
143
      for(unsigned int j=0;j<objects.size();j++) 
144
	  {
144
      {
145
	    ISectTri* tri = objects[j];
145
        ISectTri* tri = objects[j];
146
	    left_count += left_bbox.intersect_triangle(*tri);
146
        left_count += left_bbox.intersect_triangle(*tri);
147
	    right_count += right_bbox.intersect_triangle(*tri);
147
        right_count += right_bbox.intersect_triangle(*tri);
148
	  }
148
      }
149
 
149
 
150
	  //double len = bbox.max_corner[i] - bbox.min_corner[i];
150
      //double len = bbox.max_corner[i] - bbox.min_corner[i];
151
	  double cost = left_count*left_bbox.area() + right_count*right_bbox.area(); // - len*len;
151
      double cost = left_count*left_bbox.area() + right_count*right_bbox.area(); // - len*len;
152
	  if(cost < min_cost) 
152
      if(cost < min_cost) 
153
	  {
153
      {
154
	    min_cost = cost;
154
        min_cost = cost;
155
	    new_axis = i;
155
        new_axis = i;
156
	    new_pos = k;
156
        new_pos = k;
157
	    right_zero = (right_count==0);
157
        right_zero = (right_count==0);
158
	    left_zero = (left_count==0);
158
        left_zero = (left_count==0);
159
	  }
159
      }
160
	}
160
    }
161
      }
161
      }
162
      node.axis_leaf = new_axis;
162
      node.axis_leaf = new_axis;
163
      left_node->axis_leaf = static_cast<unsigned char>(-1); 
163
      left_node->axis_leaf = static_cast<unsigned char>(-1); 
164
      right_node->axis_leaf = static_cast<unsigned char>(-1); 
164
      right_node->axis_leaf = static_cast<unsigned char>(-1); 
165
 
165
 
166
      // Now chose the right splitting plane
166
      // Now chose the right splitting plane
167
      BBox left_bbox = bbox;
167
      BBox left_bbox = bbox;
168
      BBox right_bbox = bbox;
168
      BBox right_bbox = bbox;
169
 
169
 
170
      double size = bbox.max_corner[node.axis_leaf]- bbox.min_corner[node.axis_leaf];
170
      double size = bbox.max_corner[node.axis_leaf]- bbox.min_corner[node.axis_leaf];
171
      double center = size*(double)new_pos/(double)TESTS + bbox.min_corner[node.axis_leaf];
171
      double center = size*(double)new_pos/(double)TESTS + bbox.min_corner[node.axis_leaf];
172
      double diff = f_eps < size/8.0 ? f_eps : size/8.0;
172
      double diff = f_eps < size/8.0 ? f_eps : size/8.0;
173
      
173
      
174
      if (left_zero) 
174
      if (left_zero) 
175
      {
175
      {
176
	// Find min position of all triangle vertices and place the center there
176
    // Find min position of all triangle vertices and place the center there
177
	center = bbox.max_corner[node.axis_leaf];
177
    center = bbox.max_corner[node.axis_leaf];
178
	for(unsigned int j=0;j<objects.size();j++) 
178
    for(unsigned int j=0;j<objects.size();j++) 
179
	{
179
    {
180
	  ISectTri* tri = objects[j];
180
      ISectTri* tri = objects[j];
181
	  if (tri->point0[node.axis_leaf]<center)
181
      if (tri->point0[node.axis_leaf]<center)
182
	    center=tri->point0[node.axis_leaf];
182
        center=tri->point0[node.axis_leaf];
183
	  if (tri->point1[node.axis_leaf]<center)
183
      if (tri->point1[node.axis_leaf]<center)
184
	    center=tri->point1[node.axis_leaf];
184
        center=tri->point1[node.axis_leaf];
185
	  if (tri->point2[node.axis_leaf]<center)
185
      if (tri->point2[node.axis_leaf]<center)
186
	    center=tri->point2[node.axis_leaf];
186
        center=tri->point2[node.axis_leaf];
187
	}
187
    }
188
	center -= diff;
188
    center -= diff;
189
      }
189
      }
190
      if (right_zero) 
190
      if (right_zero) 
191
      {
191
      {
192
	// Find max position of all triangle vertices and place the center there
192
    // Find max position of all triangle vertices and place the center there
193
	center = bbox.min_corner[node.axis_leaf];
193
    center = bbox.min_corner[node.axis_leaf];
194
	for(unsigned int j=0;j<objects.size();j++) 
194
    for(unsigned int j=0;j<objects.size();j++) 
195
	{
195
    {
196
	  ISectTri* tri = objects[j];
196
      ISectTri* tri = objects[j];
197
	  if (tri->point0[node.axis_leaf]>center)
197
      if (tri->point0[node.axis_leaf]>center)
198
	    center=tri->point0[node.axis_leaf];
198
        center=tri->point0[node.axis_leaf];
199
	  if (tri->point1[node.axis_leaf]>center)
199
      if (tri->point1[node.axis_leaf]>center)
200
	    center=tri->point1[node.axis_leaf];
200
        center=tri->point1[node.axis_leaf];
201
	  if (tri->point2[node.axis_leaf]>center)
201
      if (tri->point2[node.axis_leaf]>center)
202
	    center=tri->point2[node.axis_leaf];
202
        center=tri->point2[node.axis_leaf];
203
	}
203
    }
204
	center += diff;
204
    center += diff;
205
      }
205
      }
206
 
206
 
207
      node.plane = center;
207
      node.plane = center;
208
      left_bbox.max_corner[node.axis_leaf] = center; 
208
      left_bbox.max_corner[node.axis_leaf] = center; 
209
      right_bbox.min_corner[node.axis_leaf] = center;  
209
      right_bbox.min_corner[node.axis_leaf] = center;  
210
            
210
            
211
      // Now put the triangles in the right and left node
211
      // Now put the triangles in the right and left node
212
      for(i=0;i<objects.size();i++) 
212
      for(i=0;i<objects.size();i++) 
213
      {
213
      {
214
	ISectTri* tri = objects[i];
214
    ISectTri* tri = objects[i];
215
	TriAccel *tri_accel = tri_objects[i];
215
    TriAccel *tri_accel = tri_objects[i];
216
	if (left_bbox.intersect_triangle(*tri)) 
216
    if (left_bbox.intersect_triangle(*tri)) 
217
	{
217
    {
218
	  left_objects.push_back(tri);
218
      left_objects.push_back(tri);
219
	  tri_left_objects.push_back(tri_accel);
219
      tri_left_objects.push_back(tri_accel);
220
	}
220
    }
221
	if (right_bbox.intersect_triangle(*tri)) 
221
    if (right_bbox.intersect_triangle(*tri)) 
222
	{
222
    {
223
	  right_objects.push_back(tri);
223
      right_objects.push_back(tri);
224
	  tri_right_objects.push_back(tri_accel);
224
      tri_right_objects.push_back(tri_accel);
225
	}
225
    }
226
      }
226
      }
227
    //if (left_zero||right_zero)
227
    //if (left_zero||right_zero)
228
	//  cout << left_objects.size() << "," << right_objects.size() << "," << level << endl;
228
    //  cout << left_objects.size() << "," << right_objects.size() << "," << level << endl;
229
 
229
 
230
      objects.clear();
230
      objects.clear();
231
      subdivide_node(*left_node , left_bbox , level+1, left_objects, tri_left_objects);
231
      subdivide_node(*left_node , left_bbox , level+1, left_objects, tri_left_objects);
232
      subdivide_node(*right_node, right_bbox, level+1, right_objects, tri_right_objects);
232
      subdivide_node(*right_node, right_bbox, level+1, right_objects, tri_right_objects);
233
    }
233
    }
234
  }
234
  }
235
 
235
 
236
  void BSPTree::init() 
236
  void BSPTree::init() 
237
  {
237
  {
238
    root = new BSPNode();
238
    root = new BSPNode();
239
    bbox.compute_bbox(isecttris);
239
    bbox.compute_bbox(isecttris);
240
    bbox.min_corner-=Vec3f(1.0);
240
    bbox.min_corner-=Vec3f(1.0);
241
    bbox.max_corner+=Vec3f(1.0);
241
    bbox.max_corner+=Vec3f(1.0);
242
  }
242
  }
243
 
243
 
244
  void BSPTree::init(vector<const TriMesh*>& _trimesh, 
244
  void BSPTree::init(vector<const TriMesh*>& _trimesh, 
245
		     vector<Mat4x4f>& _transforms, 
245
             vector<Mat4x4f>& _transforms, 
246
		     int _max_objects, int _max_level) 
246
             int _max_objects, int _max_level) 
247
  {
247
  {
248
    trimesh = _trimesh;
248
    trimesh = _trimesh;
249
    transforms = _transforms;
249
    transforms = _transforms;
250
    for(unsigned int i=0;i<trimesh.size();i++) 
250
    for(unsigned int i=0;i<trimesh.size();i++) 
251
    {
251
    {
252
      const TriMesh *mesh = trimesh[i];
252
      const TriMesh *mesh = trimesh[i];
253
      // Loop through all triangles and add them to intersection structure
253
      // Loop through all triangles and add them to intersection structure
254
      for(int j=0;j<mesh->geometry.no_faces();j++) 
254
      for(int j=0;j<mesh->geometry.no_faces();j++) 
255
      {
255
      {
256
	Vec3i face = mesh->geometry.face(j);
256
    Vec3i face = mesh->geometry.face(j);
257
	ISectTri new_tri;
257
    ISectTri new_tri;
258
	new_tri.point0 = transforms[i].mul_3D_point(mesh->geometry.vertex(face[0]));
258
    new_tri.point0 = transforms[i].mul_3D_point(mesh->geometry.vertex(face[0]));
259
	new_tri.point1 = transforms[i].mul_3D_point(mesh->geometry.vertex(face[1]));
259
    new_tri.point1 = transforms[i].mul_3D_point(mesh->geometry.vertex(face[1]));
260
	new_tri.point2 = transforms[i].mul_3D_point(mesh->geometry.vertex(face[2]));
260
    new_tri.point2 = transforms[i].mul_3D_point(mesh->geometry.vertex(face[2]));
261
	new_tri.edge0 = new_tri.point1 - new_tri.point0;
261
    new_tri.edge0 = new_tri.point1 - new_tri.point0;
262
	new_tri.edge1 = new_tri.point2 - new_tri.point0;
262
    new_tri.edge1 = new_tri.point2 - new_tri.point0;
263
	new_tri.mesh_id = i;
263
    new_tri.mesh_id = i;
264
	new_tri.tri_id = j;
264
    new_tri.tri_id = j;
265
	isecttris.push_back(new_tri);
265
    isecttris.push_back(new_tri);
266
	TriAccel ta;
266
    TriAccel ta;
267
	create_tri_accel(new_tri.point0, new_tri.point1, new_tri.point2, ta);
267
    create_tri_accel(new_tri.point0, new_tri.point1, new_tri.point2, ta);
268
	ta.mesh_id = i;
268
    ta.mesh_id = i;
269
	ta.tri_id = j;
269
    ta.tri_id = j;
270
	triaccel.push_back(ta);
270
    triaccel.push_back(ta);
271
      }
271
      }
272
    }
272
    }
273
 
273
 
274
    max_objects = _max_objects;
274
    max_objects = _max_objects;
275
    max_level = _max_level;
275
    max_level = _max_level;
276
    init();
276
    init();
277
  }
277
  }
278
 
278
 
279
  void BSPTree::init(const TriMesh* mesh, Mat4x4f transform, 
279
  void BSPTree::init(const TriMesh* mesh, Mat4x4f transform, 
280
		     vector<int> &trilist, 
280
             vector<int> &trilist, 
281
		     int _max_objects, int _max_level) 
281
             int _max_objects, int _max_level) 
282
  {
282
  {
283
    trimesh.push_back(mesh);
283
    trimesh.push_back(mesh);
284
    transforms.push_back(transform);
284
    transforms.push_back(transform);
285
    // Loop through all triangles and add them to intersection structure
285
    // Loop through all triangles and add them to intersection structure
286
    for(unsigned int j=0;j<trilist.size();j++) 
286
    for(unsigned int j=0;j<trilist.size();j++) 
287
    {
287
    {
288
      Vec3i face = mesh->geometry.face(trilist[j]);
288
      Vec3i face = mesh->geometry.face(trilist[j]);
289
      ISectTri new_tri;
289
      ISectTri new_tri;
290
      new_tri.point0 = transform.mul_3D_point(mesh->geometry.vertex(face[0]));
290
      new_tri.point0 = transform.mul_3D_point(mesh->geometry.vertex(face[0]));
291
      new_tri.point1 = transform.mul_3D_point(mesh->geometry.vertex(face[1]));
291
      new_tri.point1 = transform.mul_3D_point(mesh->geometry.vertex(face[1]));
292
      new_tri.point2 = transform.mul_3D_point(mesh->geometry.vertex(face[2]));
292
      new_tri.point2 = transform.mul_3D_point(mesh->geometry.vertex(face[2]));
293
      new_tri.edge0 = new_tri.point1 - new_tri.point0;
293
      new_tri.edge0 = new_tri.point1 - new_tri.point0;
294
      new_tri.edge1 = new_tri.point2 - new_tri.point0;
294
      new_tri.edge1 = new_tri.point2 - new_tri.point0;
295
      new_tri.mesh_id = 0;
295
      new_tri.mesh_id = 0;
296
      new_tri.tri_id = trilist[j];
296
      new_tri.tri_id = trilist[j];
297
      isecttris.push_back(new_tri);
297
      isecttris.push_back(new_tri);
298
      TriAccel ta;
298
      TriAccel ta;
299
      create_tri_accel(new_tri.point0, new_tri.point1, new_tri.point2, ta);
299
      create_tri_accel(new_tri.point0, new_tri.point1, new_tri.point2, ta);
300
      ta.mesh_id = 0;
300
      ta.mesh_id = 0;
301
      ta.tri_id = trilist[j];
301
      ta.tri_id = trilist[j];
302
      triaccel.push_back(ta);
302
      triaccel.push_back(ta);
303
    }
303
    }
304
 
304
 
305
    max_objects = _max_objects;
305
    max_objects = _max_objects;
306
    max_level = _max_level;
306
    max_level = _max_level;
307
    init();
307
    init();
308
  }
308
  }
309
 
309
 
310
  void BSPTree::build() 
310
  void BSPTree::build() 
311
  {
311
  {
312
    if (!b_is_build) 
312
    if (!b_is_build) 
313
    {
313
    {
314
      vector<ISectTri*> objects;
314
      vector<ISectTri*> objects;
315
      vector<TriAccel*> tri_objects;
315
      vector<TriAccel*> tri_objects;
316
      for(unsigned int i=0;i<isecttris.size();i++) 
316
      for(unsigned int i=0;i<isecttris.size();i++) 
317
      {
317
      {
318
	ISectTri* tri = &isecttris[i];
318
    ISectTri* tri = &isecttris[i];
319
	TriAccel* tri_accel = &triaccel[i];
319
    TriAccel* tri_accel = &triaccel[i];
320
	objects.push_back(tri);
320
    objects.push_back(tri);
321
	tri_objects.push_back(tri_accel);
321
    tri_objects.push_back(tri_accel);
322
      }
322
      }
323
      subdivide_node(*root, bbox, 0, objects, tri_objects);
323
      subdivide_node(*root, bbox, 0, objects, tri_objects);
324
      b_is_build = true;
324
      b_is_build = true;
325
    }
325
    }
326
    isecttris.clear();
326
    isecttris.clear();
327
    all_objects.clear();
327
    all_objects.clear();
328
    make_fast_tree(root);
328
    make_fast_tree(root);
329
  }
329
  }
330
 
330
 
331
  bool BSPTree::is_build() 
331
  bool BSPTree::is_build() 
332
  {
332
  {
333
    return b_is_build;
333
    return b_is_build;
334
  }
334
  }
335
 
335
 
336
  void BSPTree::print(BSPNode *node, int depth) 
336
  void BSPTree::print(BSPNode *node, int depth) 
337
  {
337
  {
338
    if (node==0)
338
    if (node==0)
339
      return;
339
      return;
340
    for(int i=0;i<depth;i++)
340
    for(int i=0;i<depth;i++)
341
      cout << " ";
341
      cout << " ";
342
//	cout << "axis:" << node->axis_leaf << ", count:" << node->objects.size() << ", plane:" << node->plane << ", " << endl;
342
//  cout << "axis:" << node->axis_leaf << ", count:" << node->objects.size() << ", plane:" << node->plane << ", " << endl;
343
    print(node->left, depth+1);
343
    print(node->left, depth+1);
344
    print(node->right, depth+1);
344
    print(node->right, depth+1);
345
  }
345
  }
346
 
346
 
347
  int BSPTree::size(BSPNode *node) 
347
  int BSPTree::size(BSPNode *node) 
348
  {
348
  {
349
    if (node==0)
349
    if (node==0)
350
      return 0;
350
      return 0;
351
    int s = sizeof(BSPNode);
351
    int s = sizeof(BSPNode);
352
    s+= node->count * sizeof(ISectTri);
352
    s+= node->count * sizeof(ISectTri);
353
    s+=size(node->left);
353
    s+=size(node->left);
354
    s+=size(node->right);
354
    s+=size(node->right);
355
    return s;
355
    return s;
356
  }
356
  }
357
 
357
 
358
  int BSPTree::size() 
358
  int BSPTree::size() 
359
  {
359
  {
360
    return size(root);
360
    return size(root);
361
  }
361
  }
362
 
362
 
363
/*__declspec(align(16))*/ static const unsigned int modulo[] = {0,1,2,0,1};
363
/*__declspec(align(16))*/ static const unsigned int modulo[] = {0,1,2,0,1};
364
 
364
 
365
  inline bool intersect2(Ray &ray, const TriAccel &acc, double t_max) 
365
  inline bool intersect2(Ray &ray, const TriAccel &acc, double t_max) 
366
  {
366
  {
367
//	cout << "Acc: " << (int)&acc << " ";
367
//  cout << "Acc: " << (int)&acc << " ";
368
//inline bool Intersect(TriAccel &acc,Ray &ray)
368
//inline bool Intersect(TriAccel &acc,Ray &ray)
369
#define ku modulo[acc.k+1]
369
#define ku modulo[acc.k+1]
370
#define kv modulo[acc.k+2]
370
#define kv modulo[acc.k+2]
371
    // don’t prefetch here, assume data has already been prefetched
371
    // don’t prefetch here, assume data has already been prefetched
372
    // start high-latency division as early as possible
372
    // start high-latency division as early as possible
373
    const double nd = 1.0/((double)ray.direction[acc.k]	+ (double)acc.n_u * (double)ray.direction[ku] + (double)acc.n_v * (double)ray.direction[kv]);
373
    const double nd = 1.0/((double)ray.direction[acc.k] + (double)acc.n_u * (double)ray.direction[ku] + (double)acc.n_v * (double)ray.direction[kv]);
374
    const double f = ((double)acc.n_d - (double)ray.origin[acc.k]	- (double)acc.n_u * (double)ray.origin[ku] - (double)acc.n_v * (double)ray.origin[kv]) * nd;
374
    const double f = ((double)acc.n_d - (double)ray.origin[acc.k]   - (double)acc.n_u * (double)ray.origin[ku] - (double)acc.n_v * (double)ray.origin[kv]) * nd;
375
    // check for valid distance.
375
    // check for valid distance.
376
    if (!(t_max > f && f > 0.001)||ray.dist<f) return false;
376
    if (!(t_max > f && f > 0.001)||ray.dist<f) return false;
377
    // compute hitpoint positions on uv plane
377
    // compute hitpoint positions on uv plane
378
    const double hu = (ray.origin[ku] + f * ray.direction[ku]);
378
    const double hu = (ray.origin[ku] + f * ray.direction[ku]);
379
    const double hv = (ray.origin[kv] + f * ray.direction[kv]);
379
    const double hv = (ray.origin[kv] + f * ray.direction[kv]);
380
    // check first barycentric coordinate
380
    // check first barycentric coordinate
381
    const double lambda = (hu * (double)acc.b_nu + hv * (double)acc.b_nv + (double)acc.b_d);
381
    const double lambda = (hu * (double)acc.b_nu + hv * (double)acc.b_nv + (double)acc.b_d);
382
    if (lambda < 0.0) return false;
382
    if (lambda < 0.0) return false;
383
    // check second barycentric coordinate
383
    // check second barycentric coordinate
384
    const double mue = (hu * (double)acc.c_nu + hv * (double)acc.c_nv + (double)acc.c_d);
384
    const double mue = (hu * (double)acc.c_nu + hv * (double)acc.c_nv + (double)acc.c_d);
385
    if (mue < 0.0) return false;
385
    if (mue < 0.0) return false;
386
    // check third barycentric coordinate
386
    // check third barycentric coordinate
387
    if (lambda+mue > 1.0) return false;
387
    if (lambda+mue > 1.0) return false;
388
    // have a valid hitpoint here. store it.
388
    // have a valid hitpoint here. store it.
389
    ray.dist = f;
389
    ray.dist = f;
390
    ray.u = lambda;
390
    ray.u = lambda;
391
    ray.v = mue;
391
    ray.v = mue;
392
    ray.hit_object = (TriMesh*)acc.mesh_id;
392
    ray.hit_object = (TriMesh*)acc.mesh_id;
393
    ray.hit_face_id = acc.tri_id;
393
    ray.hit_face_id = acc.tri_id;
394
    ray.has_hit=true;
394
    ray.has_hit=true;
395
    return true;
395
    return true;
396
  }
396
  }
397
 
397
 
398
  bool BSPTree::intersect_node(Ray &ray, const BSPNode &node, double t_min, double t_max) const 
398
  bool BSPTree::intersect_node(Ray &ray, const BSPNode &node, double t_min, double t_max) const 
399
  {
399
  {
400
//    cout << node.plane << endl;
400
//    cout << node.plane << endl;
401
    node_calls++;
401
    node_calls++;
402
    static bool found;
402
    static bool found;
403
    static int i;
403
    static int i;
404
    
404
    
405
    if (node.axis_leaf==4) 
405
    if (node.axis_leaf==4) 
406
    {
406
    {
407
      found = false; 
407
      found = false; 
408
      for(i=0;i<node.count;i++) 
408
      for(i=0;i<node.count;i++) 
409
      {
409
      {
410
//	const TriAccel* tri2 = all_triaccel[node.id+i];
410
//  const TriAccel* tri2 = all_triaccel[node.id+i];
411
	const ISectTri* tri = all_objects[node.id+i];
411
    const ISectTri* tri = all_objects[node.id+i];
412
//			if (intersect2(ray, *tri2, t_max))  
412
//          if (intersect2(ray, *tri2, t_max))  
413
//				found=true;
413
//              found=true;
414
	if (intersect(ray, *tri, t_max))  
414
    if (intersect(ray, *tri, t_max))  
415
	  found=true;
415
      found=true;
416
      }
416
      }
417
      if (found)
417
      if (found)
418
	return true;
418
    return true;
419
      else 
419
      else 
420
	return false;
420
    return false;
421
    } 
421
    } 
422
    else 
422
    else 
423
    {
423
    {
424
      BSPNode *near_node;
424
      BSPNode *near_node;
425
      BSPNode *far_node;
425
      BSPNode *far_node;
426
      if (ray.direction[node.axis_leaf]>=0) 
426
      if (ray.direction[node.axis_leaf]>=0) 
427
      {
427
      {
428
	near_node = node.left;
428
    near_node = node.left;
429
	far_node = node.right;
429
    far_node = node.right;
430
      } 
430
      } 
431
      else 
431
      else 
432
      {
432
      {
433
	near_node = node.right;
433
    near_node = node.right;
434
	far_node = node.left;
434
    far_node = node.left;
435
      }
435
      }
436
 
436
 
437
      // In order to avoid instability
437
      // In order to avoid instability
438
      double t;
438
      double t;
439
      if (fabs(ray.direction[node.axis_leaf])<d_eps)
439
      if (fabs(ray.direction[node.axis_leaf])<d_eps)
440
	t = (node.plane - ray.origin[node.axis_leaf])/d_eps;// intersect node plane;
440
    t = (node.plane - ray.origin[node.axis_leaf])/d_eps;// intersect node plane;
441
      else
441
      else
442
	t = (node.plane - ray.origin[node.axis_leaf])/ray.direction[node.axis_leaf];// intersect node plane;
442
    t = (node.plane - ray.origin[node.axis_leaf])/ray.direction[node.axis_leaf];// intersect node plane;
443
      
443
      
444
      if (t>t_max) 
444
      if (t>t_max) 
445
      	return intersect_node(ray, *near_node, t_min, t_max);
445
        return intersect_node(ray, *near_node, t_min, t_max);
446
      
446
      
447
      else if (t<t_min) 
447
      else if (t<t_min) 
448
	return intersect_node(ray, *far_node, t_min, t_max);
448
    return intersect_node(ray, *far_node, t_min, t_max);
449
      else 
449
      else 
450
      {
450
      {
451
	if (intersect_node(ray, *near_node, t_min, t))
451
    if (intersect_node(ray, *near_node, t_min, t))
452
	  return true;
452
      return true;
453
	else 
453
    else 
454
	  return intersect_node(ray, *far_node, t, t_max);
454
      return intersect_node(ray, *far_node, t, t_max);
455
      }
455
      }
456
    }
456
    }
457
  }
457
  }
458
 
458
 
459
  bool BSPTree::intersect(Ray &ray) const 
459
  bool BSPTree::intersect(Ray &ray) const 
460
  {
460
  {
461
    double t_min, t_max;
461
    double t_min, t_max;
462
    bbox.intersect_min_max(ray, t_min, t_max);
462
    bbox.intersect_min_max(ray, t_min, t_max);
463
    if (t_min>t_max)
463
    if (t_min>t_max)
464
      return false;
464
      return false;
465
//    if (!intersect_node(ray, *root, t_min, t_max))
465
 
466
//      return false;
466
    printf("%.2f %.2f %.2f\n", ray.dist, t_min, t_max);
467
//	cout << "____" << endl;
467
//    if (!intersect_node(ray, *root, t_min, t_max))
468
//	ray.reset();
468
//      return false;
469
//	cout << "Here " << endl;
469
//  cout << "____" << endl;
470
    intersect_fast_node(ray, &fast_tree[0], t_min, t_max);
470
//  ray.reset();
471
    if (!ray.has_hit)
471
//  cout << "Here " << endl;
472
      return false;
472
    intersect_fast_node(ray, &fast_tree[0], t_min, t_max);
473
    else 
473
    if (!ray.has_hit)
474
    {
474
      return false;
475
      // Calculate the normal at the intersection
475
    else 
476
		ray.id = (int)ray.hit_object;
476
    {
477
		ray.hit_object = trimesh[ray.id];
477
 
478
		
478
        printf("HIT\n");
479
		Vec3i face = ray.hit_object->normals.face(ray.hit_face_id);
479
 
480
		Vec3f normal0 = ray.hit_object->normals.vertex(face[0]);
480
 
481
		Vec3f normal1 = ray.hit_object->normals.vertex(face[1]);
481
      // Calculate the normal at the intersection
482
		Vec3f normal2 = ray.hit_object->normals.vertex(face[2]);
482
        ray.id = (int)ray.hit_object;
483
		ray.hit_normal = transforms[ray.id].mul_3D_vector(
483
        ray.hit_object = trimesh[ray.id];
484
			normalize(normal0*(1 - ray.u - ray.v)
484
        
485
			+normal1*ray.u
485
        Vec3i face = ray.hit_object->normals.face(ray.hit_face_id);
486
			+normal2*ray.v));
486
        Vec3f normal0 = ray.hit_object->normals.vertex(face[0]);
487
		
487
        Vec3f normal1 = ray.hit_object->normals.vertex(face[1]);
488
		ray.hit_pos = ray.origin + ray.direction*ray.dist;
488
        Vec3f normal2 = ray.hit_object->normals.vertex(face[2]);
489
/*
489
        ray.hit_normal = transforms[ray.id].mul_3D_vector(
490
      Vec3i face = ray.hit_object->normals.face(ray.hit_face_id);
490
            normalize(normal0*(1 - ray.u - ray.v)
491
      Vec3f normal0 = ray.hit_object->normals.vertex(face[0]);
491
            +normal1*ray.u
492
      Vec3f normal1 = ray.hit_object->normals.vertex(face[1]);
492
            +normal2*ray.v));
493
      Vec3f normal2 = ray.hit_object->normals.vertex(face[2]);
493
        
494
      ray.hit_normal = normalize(normal0*(1 - ray.u - ray.v)
494
        ray.hit_pos = ray.origin + ray.direction*ray.dist;
495
				 +normal1*ray.u
495
/*
496
				 +normal2*ray.v);
496
      Vec3i face = ray.hit_object->normals.face(ray.hit_face_id);
497
      ray.hit_pos = ray.origin + ray.direction*ray.dist;
497
      Vec3f normal0 = ray.hit_object->normals.vertex(face[0]);
498
*/
498
      Vec3f normal1 = ray.hit_object->normals.vertex(face[1]);
499
 
499
      Vec3f normal2 = ray.hit_object->normals.vertex(face[2]);
500
	  return true;
500
      ray.hit_normal = normalize(normal0*(1 - ray.u - ray.v)
501
    }
501
                 +normal1*ray.u
502
  }
502
                 +normal2*ray.v);
503
 
503
      ray.hit_pos = ray.origin + ray.direction*ray.dist;
504
  const int MAX_DEPTH=25;
504
*/
505
 
505
 
506
  void BSPTree::make_fast_tree(BSPNode *node) 
506
      return true;
507
  {
507
    }
508
    fast_tree.resize(1000000); // 
508
  }
509
    FastBSPNode f_node;
509
 
510
    fast_tree.push_back(f_node);
510
  const int MAX_DEPTH=25;
511
    push_fast_bsp_node(node,0);
511
 
512
  }
512
  void BSPTree::make_fast_tree(BSPNode *node) 
513
 
513
  {
514
  void BSPTree::push_fast_bsp_node(BSPNode *node, int id) 
514
    fast_tree.resize(1000000); // 
515
  {
515
    FastBSPNode f_node;
516
    if (node->axis_leaf==4)  // It is a leaf
516
    fast_tree.push_back(f_node);
517
    {
517
    push_fast_bsp_node(node,0);
518
      fast_tree[id].leaf.flagAndOffset = (unsigned int)1<<31 | (unsigned int)(&all_triaccel[node->id]);
518
  }
519
      fast_tree[id].leaf.count = node->count;
519
 
520
    } 
520
  void BSPTree::push_fast_bsp_node(BSPNode *node, int id) 
521
    else // It is an inner node
521
  {
522
    { 
522
    if (node->axis_leaf==4)  // It is a leaf
523
      FastBSPNode fnode;
523
    {
524
      int p_l = fast_tree.size();
524
      fast_tree[id].leaf.flagAndOffset = (unsigned int)1<<31 | (unsigned int)(&all_triaccel[node->id]);
525
      fast_tree.push_back(fnode); // left
525
      fast_tree[id].leaf.count = node->count;
526
      fast_tree.push_back(fnode); // right
526
    } 
527
      push_fast_bsp_node(node->left, p_l);
527
    else // It is an inner node
528
      push_fast_bsp_node(node->right, p_l+1);
528
    { 
529
      fast_tree[id].inner.flagAndOffset = (unsigned int) &fast_tree[p_l] | node->axis_leaf;
529
      FastBSPNode fnode;
530
      fast_tree[id].inner.splitCoordinate = node->plane;
530
      int p_l = fast_tree.size();
531
      node->ref = fast_tree[id].inner.flagAndOffset;
531
      fast_tree.push_back(fnode); // left
532
    }
532
      fast_tree.push_back(fnode); // right
533
  }
533
      push_fast_bsp_node(node->left, p_l);
534
 
534
      push_fast_bsp_node(node->right, p_l+1);
535
#define ABSP_ISLEAF(n)       (n->inner.flagAndOffset & (unsigned int)1<<31)
535
      fast_tree[id].inner.flagAndOffset = (unsigned int) &fast_tree[p_l] | node->axis_leaf;
536
#define ABSP_DIMENSION(n)    (n->inner.flagAndOffset & 0x3)
536
      fast_tree[id].inner.splitCoordinate = node->plane;
537
#define ABSP_OFFSET(n)       (n->inner.flagAndOffset & (0x7FFFFFFC))
537
      node->ref = fast_tree[id].inner.flagAndOffset;
538
#define ABSP_NEARNODE(n)     (FastBSPNode*)(ray.direction[dimension]>=0?ABSP_OFFSET(node):ABSP_OFFSET(node)+sizeof(*node))
538
    }
539
#define ABSP_FARNODE(n)      (FastBSPNode*)(ray.direction[dimension]>=0?ABSP_OFFSET(node)+sizeof(*node):ABSP_OFFSET(node))
539
  }
540
#define ABSP_TRIANGLENODE(n) (vector<TriAccel*>::iterator)(n->flagAndOffset & (0x7FFFFFFF))
540
 
541
  
541
#define ABSP_ISLEAF(n)       (n->inner.flagAndOffset & (unsigned int)1<<31)
542
  struct Stack 
542
#define ABSP_DIMENSION(n)    (n->inner.flagAndOffset & 0x3)
543
  {
543
#define ABSP_OFFSET(n)       (n->inner.flagAndOffset & (0x7FFFFFFC))
544
    FastBSPNode *node;
544
#define ABSP_NEARNODE(n)     (FastBSPNode*)(ray.direction[dimension]>=0?ABSP_OFFSET(node):ABSP_OFFSET(node)+sizeof(*node))
545
    double t_min;
545
#define ABSP_FARNODE(n)      (FastBSPNode*)(ray.direction[dimension]>=0?ABSP_OFFSET(node)+sizeof(*node):ABSP_OFFSET(node))
546
    double t_max;
546
#define ABSP_TRIANGLENODE(n) (vector<TriAccel*>::iterator)(n->flagAndOffset & (0x7FFFFFFF))
547
  };
547
  
548
 
548
  struct Stack 
549
  inline void IntersectAlltrianglesInLeaf(const BSPLeaf* leaf, Ray &ray, double t_max) {
549
  {
550
    TriAccel** tri_acc_ptr = reinterpret_cast<TriAccel**>(leaf->flagAndOffset & (0x7FFFFFFF));
550
    FastBSPNode *node;
551
    vector<TriAccel*>::iterator acc = vector<TriAccel*>::iterator(tri_acc_ptr);
551
    double t_min;
552
//	vector<TriAccel*>::iterator acc = ABSP_TRIANGLENODE(leaf);
552
    double t_max;
553
    for(unsigned int i=0;i<leaf->count;++i)
553
  };
554
      intersect2(ray, *(*acc++), t_max);
554
 
555
  }
555
  inline void IntersectAlltrianglesInLeaf(const BSPLeaf* leaf, Ray &ray, double t_max) {
556
 
556
    TriAccel** tri_acc_ptr = reinterpret_cast<TriAccel**>(leaf->flagAndOffset & (0x7FFFFFFF));
557
  void BSPTree::intersect_fast_node(Ray &ray, const FastBSPNode *node, double t_min, double t_max) const 
557
    vector<TriAccel*>::iterator acc = vector<TriAccel*>::iterator(tri_acc_ptr);
558
  {
558
//  vector<TriAccel*>::iterator acc = ABSP_TRIANGLENODE(leaf);
559
    Stack stack[MAX_DEPTH];
559
    for(unsigned int i=0;i<leaf->count;++i)
560
    int stack_id=0;
560
      intersect2(ray, *(*acc++), t_max);
561
    double t;
561
  }
562
    // Precalculate one over dir
562
 
563
    double one_over_dir[3];
563
  void BSPTree::intersect_fast_node(Ray &ray, const FastBSPNode *node, double t_min, double t_max) const 
564
    for(int i=0;i<3;i++) 
564
  {
565
    {
565
    Stack stack[MAX_DEPTH];
566
      if (ray.direction[i]!=0)
566
    int stack_id=0;
567
	one_over_dir[i]=1.0/ray.direction[i];
567
    double t;
568
      else
568
    // Precalculate one over dir
569
	one_over_dir[i]=1.0/d_eps;
569
    double one_over_dir[3];
570
    }
570
    for(int i=0;i<3;i++) 
571
 
571
    {
572
    int dimension;
572
      if (ray.direction[i]!=0)
573
    while(1) 
573
    one_over_dir[i]=1.0/ray.direction[i];
574
    {
574
      else
575
      while(!ABSP_ISLEAF(node)) 
575
    one_over_dir[i]=1.0/d_eps;
576
      {
576
    }
577
	dimension = ABSP_DIMENSION(node);
577
 
578
	t = (node->inner.splitCoordinate - ray.origin[dimension])*one_over_dir[dimension];
578
    int dimension;
579
	if (t>=t_max) 
579
    while(1) 
580
	  node = ABSP_NEARNODE(node);
580
    {
581
	else if (t<=t_min)
581
      while(!ABSP_ISLEAF(node)) 
582
	  node = ABSP_FARNODE(node);
582
      {
583
	else 
583
    dimension = ABSP_DIMENSION(node);
584
	{
584
    t = (node->inner.splitCoordinate - ray.origin[dimension])*one_over_dir[dimension];
585
	  // Stack push
585
    if (t>=t_max) 
586
	  stack[stack_id].node = ABSP_FARNODE(node);
586
      node = ABSP_NEARNODE(node);
587
	  stack[stack_id].t_min = t;
587
    else if (t<=t_min)
588
	  stack[stack_id++].t_max = t_max;
588
      node = ABSP_FARNODE(node);
589
	  // Set current node to near side
589
    else 
590
	  node = ABSP_NEARNODE(node);
590
    {
591
	  t_max = t;
591
      // Stack push
592
	}
592
      stack[stack_id].node = ABSP_FARNODE(node);
593
      }
593
      stack[stack_id].t_min = t;
594
      
594
      stack[stack_id++].t_max = t_max;
595
      IntersectAlltrianglesInLeaf(&node->leaf, ray, t_max);
595
      // Set current node to near side
596
      if (ray.dist<t_max)
596
      node = ABSP_NEARNODE(node);
597
	return;
597
      t_max = t;
598
      if (stack_id==0)
598
    }
599
	return;
599
      }
600
      // Stack pop
600
      
601
      
601
      IntersectAlltrianglesInLeaf(&node->leaf, ray, t_max);
602
      node = stack[--stack_id].node;
602
      if (ray.dist<t_max)
603
      t_min = stack[stack_id].t_min;
603
    return;
604
      t_max = stack[stack_id].t_max;
604
      if (stack_id==0)
605
    }
605
    return;
606
  }
606
      // Stack pop
607
 
607
      
608
  bool BSPTree::intersect(Ray &ray, const ISectTri &isecttri, double t_max) const 
608
      node = stack[--stack_id].node;
609
  {
609
      t_min = stack[stack_id].t_min;
610
    tri_calls++;
610
      t_max = stack[stack_id].t_max;
611
    // This is the Möller-Trumbore method
611
    }
612
    static Vec3d direction; // = Vec3d(ray.direction);
612
  }
613
    static Vec3d origin; // = Vec3d(ray.direction);
613
 
614
    static Vec3d edge1; // = Vec3d(ray.direction);
614
  bool BSPTree::intersect(Ray &ray, const ISectTri &isecttri, double t_max) const 
615
    static Vec3d edge0; // = Vec3d(ray.direction);
615
  {
616
    static Vec3d point0; // = Vec3d(ray.direction);
616
    tri_calls++;
617
    static Vec3d p;
617
    // This is the Möller-Trumbore method
618
    static Vec3d q;
618
    static Vec3d direction; // = Vec3d(ray.direction);
619
    static Vec3d s;
619
    static Vec3d origin; // = Vec3d(ray.direction);
620
    static Vec3f point;
620
    static Vec3d edge1; // = Vec3d(ray.direction);
621
    static double a, f, u, v, t;
621
    static Vec3d edge0; // = Vec3d(ray.direction);
622
    static double ray_dist_sq;
622
    static Vec3d point0; // = Vec3d(ray.direction);
623
    
623
    static Vec3d p;
624
    static double dist_sq;
624
    static Vec3d q;
625
    
625
    static Vec3d s;
626
    static Vec3f found_point;
626
    static Vec3f point;
627
    
627
    static double a, f, u, v, t;
628
    direction.set((double)ray.direction[0], (double)ray.direction[1], (double)ray.direction[2]);
628
    static double ray_dist_sq;
629
    edge0.set((double)isecttri.edge0[0], (double)isecttri.edge0[1], (double)isecttri.edge0[2]);
629
    
630
    edge1.set((double)isecttri.edge1[0], (double)isecttri.edge1[1], (double)isecttri.edge1[2]);
630
    static double dist_sq;
631
 
631
    
632
// Ray-tri intersection
632
    static Vec3f found_point;
633
//		const double eps = 0.001f;
633
    
634
/********* Complain!!!!!!!!!!!!!!!! *****************/		
634
    direction.set((double)ray.direction[0], (double)ray.direction[1], (double)ray.direction[2]);
635
	//p = cross(direction, edge1);
635
    edge0.set((double)isecttri.edge0[0], (double)isecttri.edge0[1], (double)isecttri.edge0[2]);
636
	// Why the &%¤/ is this so much faster????? - Because of MS Compiler - the intel compiler does it right!!
636
    edge1.set((double)isecttri.edge1[0], (double)isecttri.edge1[1], (double)isecttri.edge1[2]);
637
    p.set(direction[1] * edge1[2] - direction[2] * edge1[1], 
637
 
638
	  direction[2] * edge1[0] - direction[0] * edge1[2], 
638
// Ray-tri intersection
639
	  direction[0] * edge1[1] - direction[1] * edge1[0]);
639
//      const double eps = 0.001f;
640
/****************************************************/
640
/********* Complain!!!!!!!!!!!!!!!! *****************/      
641
    a = dot(edge0,p);
641
    //p = cross(direction, edge1);
642
    if (a>-d_eps && a<d_eps)
642
    // Why the &%¤/ is this so much faster????? - Because of MS Compiler - the intel compiler does it right!!
643
      return false;
643
    p.set(direction[1] * edge1[2] - direction[2] * edge1[1], 
644
  // Just delay these 
644
      direction[2] * edge1[0] - direction[0] * edge1[2], 
645
    origin.set((double)ray.origin[0], (double)ray.origin[1], (double)ray.origin[2]);
645
      direction[0] * edge1[1] - direction[1] * edge1[0]);
646
    point0.set((double)isecttri.point0[0], (double)isecttri.point0[1], (double)isecttri.point0[2]);
646
/****************************************************/
647
    
647
    a = dot(edge0,p);
648
    f = 1.0/a;
648
    if (a>-d_eps && a<d_eps)
649
    s = origin - point0;
649
      return false;
650
    u = f*dot(s,p);
650
  // Just delay these 
651
    if (u<0.0 || u>1.0)
651
    origin.set((double)ray.origin[0], (double)ray.origin[1], (double)ray.origin[2]);
652
      return false;
652
    point0.set((double)isecttri.point0[0], (double)isecttri.point0[1], (double)isecttri.point0[2]);
653
/********* Complain!!!!!!!!!!!!!!!! *****************/		
653
    
654
  //q = cross(s, edge0);
654
    f = 1.0/a;
655
  // Why the &%¤/ is this so much faster?????
655
    s = origin - point0;
656
    q.set(s[1] * edge0[2] - s[2] * edge0[1], 
656
    u = f*dot(s,p);
657
	  s[2] * edge0[0] - s[0] * edge0[2], 
657
    if (u<0.0 || u>1.0)
658
	  s[0] * edge0[1] - s[1] * edge0[0]);
658
      return false;
659
/****************************************************/
659
/********* Complain!!!!!!!!!!!!!!!! *****************/      
660
	
660
  //q = cross(s, edge0);
661
    v = f * dot(direction, q);  
661
  // Why the &%¤/ is this so much faster?????
662
    if (v<0.0 || u+v>1.0)
662
    q.set(s[1] * edge0[2] - s[2] * edge0[1], 
663
      return false;
663
      s[2] * edge0[0] - s[0] * edge0[2], 
664
    t = f*dot(edge1, q);
664
      s[0] * edge0[1] - s[1] * edge0[0]);
665
    if (t<0)
665
/****************************************************/
666
      return false;
666
    
667
    if (fabs(t)<d_eps)
667
    v = f * dot(direction, q);  
668
      return false;
668
    if (v<0.0 || u+v>1.0)
669
    if (t_max<t)
669
      return false;
670
      return false;
670
    t = f*dot(edge1, q);
671
    point = ray.origin + ray.direction*t;
671
    if (t<0)
672
    
672
      return false;
673
    dist_sq = dot(point-ray.origin, point-ray.origin);
673
    if (fabs(t)<d_eps)
674
    ray_dist_sq = ray.dist * ray.dist;
674
      return false;
675
    
675
    if (t_max<t)
676
    if (dist_sq<f_eps)
676
      return false;
677
      return false;
677
    point = ray.origin + ray.direction*t;
678
    if (dist_sq>ray_dist_sq)
678
    
679
      return false;
679
    dist_sq = dot(point-ray.origin, point-ray.origin);
680
  
680
    ray_dist_sq = ray.dist * ray.dist;
681
    ray.dist = sqrt(dist_sq);
681
    
682
    ray.u = u;
682
    if (dist_sq<f_eps)
683
    ray.v = v;
683
      return false;
684
    ray.hit_object = (TriMesh*)isecttri.mesh_id;
684
    if (dist_sq>ray_dist_sq)
685
    ray.hit_face_id = isecttri.tri_id;
685
      return false;
686
    ray.has_hit=true;
686
  
687
    return true; 
687
    ray.dist = sqrt(dist_sq);
688
  }
688
    ray.u = u;
689
}
689
    ray.v = v;
-
 
690
    ray.hit_object = (TriMesh*)isecttri.mesh_id;
-
 
691
    ray.hit_face_id = isecttri.tri_id;
-
 
692
    ray.has_hit=true;
-
 
693
    return true; 
-
 
694
  }
-
 
695
}