00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <volume_io/internal_volume_io.h>
00016
#include <bicpl/geom.h>
00017
#include <bicpl/numerical.h>
00018
00019 #define MAX_POINTS 30
00020
#ifndef lint
00021
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Geometry/ray_intersect.c,v 1.31 2000/02/06 15:30:17 stever Exp $";
00022
#endif
00023
00024
00025 #define TOLERANCE 1.0e-2
00026 #define TRIANGLE_TOLERANCE 1.0e-3
00027
00028
private BOOLEAN
point_within_triangle_2d(
00029 Point *pt,
00030 Point points[] );
00031
private BOOLEAN
point_within_polygon_2d(
00032 Point *pt,
00033
int n_points,
00034 Point points[],
00035 Vector *polygon_normal );
00036
00037 private int n_dirs = -1;
00038 private Real *
dirs = NULL;
00039
00040 public void initialize_intersect_directions(
void )
00041 {
00042
if(
n_dirs > 0 )
00043 {
00044 FREE(
dirs );
00045 }
00046
n_dirs = 0;
00047 }
00048
00049 public Real *
get_intersect_directions(
void )
00050 {
00051
int i;
00052 Real *d;
00053
00054
if(
n_dirs > 0 )
00055 {
00056 ALLOC( d,
n_dirs );
00057 for_less( i, 0,
n_dirs )
00058 d[i] =
dirs[i];
00059
00060 FREE(
dirs );
00061 }
00062
00063
n_dirs = -1;
00064
00065
return( d );
00066 }
00067
00068 private BOOLEAN
intersect_ray_triangle(
00069 Point *ray_origin,
00070 Vector *ray_direction,
00071 Point *point0,
00072 Point *point1,
00073 Point *point2,
00074 Real *dist )
00075 {
00076 Real n_dot_d, d;
00077 Real v01x, v01y, v01z, v02x, v02y, v02z,
nx,
ny,
nz, rx, ry, rz;
00078 Real vx, vy, vz;
00079 Real tx0, ty0, tz0, tx1, ty1, tz1, tx2, ty2, tz2;
00080 Real sign;
00081
00082 tx0 = RPoint_x( *point0 ) - RPoint_x( *ray_origin );
00083 ty0 = RPoint_y( *point0 ) - RPoint_y( *ray_origin );
00084 tz0 = RPoint_z( *point0 ) - RPoint_z( *ray_origin );
00085
00086 tx1 = RPoint_x( *point1 ) - RPoint_x( *ray_origin );
00087 ty1 = RPoint_y( *point1 ) - RPoint_y( *ray_origin );
00088 tz1 = RPoint_z( *point1 ) - RPoint_z( *ray_origin );
00089
00090 tx2 = RPoint_x( *point2 ) - RPoint_x( *ray_origin );
00091 ty2 = RPoint_y( *point2 ) - RPoint_y( *ray_origin );
00092 tz2 = RPoint_z( *point2 ) - RPoint_z( *ray_origin );
00093
00094 v01x = tx1 - tx0;
00095 v01y = ty1 - ty0;
00096 v01z = tz1 - tz0;
00097 v02x = tx2 - tx0;
00098 v02y = ty2 - ty0;
00099 v02z = tz2 - tz0;
00100
00101
nx = v01y * v02z - v01z * v02y;
00102
ny = v01z * v02x - v01x * v02z;
00103
nz = v01x * v02y - v01y * v02x;
00104
00105 rx = RVector_x(*ray_direction);
00106 ry = RVector_y(*ray_direction);
00107 rz = RVector_z(*ray_direction);
00108
00109 n_dot_d = rx *
nx + ry *
ny + rz *
nz;
00110
00111
if( n_dot_d == 0.0 )
00112
return(
FALSE );
00113
00114 vx = ty1 * tz0 - tz1 * ty0;
00115 vy = tz1 * tx0 - tx1 * tz0;
00116 vz = tx1 * ty0 - ty1 * tx0;
00117 d = rx * vx + ry * vy + rz * vz;
00118
if( n_dot_d * d > 0.0 )
00119
return(
FALSE );
00120
00121 vx = ty2 * tz1 - tz2 * ty1;
00122 vy = tz2 * tx1 - tx2 * tz1;
00123 vz = tx2 * ty1 - ty2 * tx1;
00124 d = rx * vx + ry * vy + rz * vz;
00125
if( n_dot_d * d > 0.0 )
00126
return(
FALSE );
00127
00128 vx = ty0 * tz2 - tz0 * ty2;
00129 vy = tz0 * tx2 - tx0 * tz2;
00130 vz = tx0 * ty2 - ty0 * tx2;
00131 d = rx * vx + ry * vy + rz * vz;
00132
if( n_dot_d * d > 0.0 )
00133
return(
FALSE );
00134
00135 *dist = (
nx * tx0 +
ny * ty0 +
nz * tz0)/ n_dot_d;
00136
00137
if( *dist >= 0.0 )
00138 {
00139
if( n_dot_d < 0.0 )
00140 sign = -1.0;
00141
else if( n_dot_d == 0.0 )
00142 sign = 0.0;
00143
else
00144 sign = 1.0;
00145
00146
if(
n_dirs >= 0 )
00147 {
00148 ADD_ELEMENT_TO_ARRAY(
dirs,
n_dirs, sign, DEFAULT_CHUNK_SIZE );
00149 }
00150 }
00151
00152
return( *dist >= 0.0 );
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 private BOOLEAN
intersect_ray_polygon_points(
00173 Point *ray_origin,
00174 Vector *ray_direction,
00175
int n_points,
00176 Point points[],
00177 Real *dist )
00178 {
00179 BOOLEAN intersects;
00180
int p;
00181
00182 intersects =
FALSE;
00183
00184 for_less( p, 1, n_points-1 )
00185 {
00186 intersects =
intersect_ray_triangle( ray_origin, ray_direction,
00187 &points[0], &points[p], &points[p+1], dist );
00188
00189
if( intersects )
00190
break;
00191 }
00192
00193
return( intersects );
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 private BOOLEAN
intersect_ray_polygon(
00213 Point *ray_origin,
00214 Vector *ray_direction,
00215 Real *dist,
00216
polygons_struct *polygons,
00217
int poly_index )
00218 {
00219 BOOLEAN intersects;
00220 Point points[
MAX_POINTS];
00221
int ind, p, start_index, end_index, size;
00222
00223 intersects =
FALSE;
00224
00225
if( polygons->
visibilities == (Smallest_int *) 0 ||
00226 polygons->
visibilities[poly_index] )
00227 {
00228 start_index =
START_INDEX( polygons->
end_indices, poly_index );
00229 end_index = polygons->
end_indices[poly_index];
00230
00231 size = end_index - start_index;
00232
00233
if( size == 3 )
00234 {
00235 intersects =
intersect_ray_triangle( ray_origin, ray_direction,
00236 &polygons->
points[polygons->
indices[start_index]],
00237 &polygons->
points[polygons->
indices[start_index+1]],
00238 &polygons->
points[polygons->
indices[start_index+2]],
00239 dist );
00240 }
00241
else
00242 {
00243
if( size >
MAX_POINTS )
00244 {
00245 print_error(
"Warning: awfully big polygon, size = %d\n", size);
00246 size =
MAX_POINTS;
00247 end_index = start_index + size - 1;
00248 }
00249
00250 for_less( p, start_index, end_index )
00251 {
00252 ind = polygons->
indices[p];
00253 points[p-start_index] = polygons->
points[ind];
00254 }
00255
00256 intersects =
intersect_ray_polygon_points( ray_origin,
00257 ray_direction, size, points, dist );
00258 }
00259 }
00260
00261
return( intersects );
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 public BOOLEAN
point_within_polygon(
00281 Point *pt,
00282
int n_points,
00283 Point points[],
00284 Vector *polygon_normal )
00285 {
00286 BOOLEAN intersects;
00287
00288
if( n_points == 3 )
00289 intersects =
point_within_triangle_2d( pt, points );
00290
else
00291 intersects =
point_within_polygon_2d( pt, n_points, points,
00292 polygon_normal );
00293
00294
return( intersects );
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 private BOOLEAN
point_within_triangle_2d(
00313 Point *pt,
00314 Point points[] )
00315 {
00316 Real x_pos, y_pos, sum, bottom;
00317 Real x_dot_x, x_dot_y, x_dot_v, y_dot_y, y_dot_v;
00318 Vector x_axis, y_axis, v;
00319
00320 SUB_VECTORS( x_axis, points[1], points[0] );
00321 SUB_VECTORS( y_axis, points[2], points[0] );
00322 SUB_VECTORS( v, *pt, points[0] );
00323
00324 x_dot_x = DOT_VECTORS( x_axis, x_axis );
00325 x_dot_y = DOT_VECTORS( x_axis, y_axis );
00326 x_dot_v = DOT_VECTORS( x_axis, v );
00327 y_dot_y = DOT_VECTORS( y_axis, y_axis );
00328 y_dot_v = DOT_VECTORS( y_axis, v );
00329
00330 bottom = x_dot_x * y_dot_y - x_dot_y * x_dot_y;
00331
00332
if( bottom == 0.0 )
00333
return(
FALSE );
00334
00335 x_pos = (x_dot_v * y_dot_y - y_dot_v * x_dot_y) / bottom;
00336
00337
if( x_pos < -
TRIANGLE_TOLERANCE || x_pos > 1.0 +
TRIANGLE_TOLERANCE )
00338
return(
FALSE );
00339
00340 y_pos = (y_dot_v * x_dot_x - x_dot_v * x_dot_y) / bottom;
00341
00342
if( y_pos < -
TRIANGLE_TOLERANCE || y_pos > 1.0 +
TRIANGLE_TOLERANCE )
00343
return(
FALSE );
00344
00345 sum = x_pos + y_pos;
00346
return( sum >= -
TRIANGLE_TOLERANCE && sum <= 1.0 +
TRIANGLE_TOLERANCE );
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 private BOOLEAN
point_within_polygon_2d(
00367 Point *pt,
00368
int n_points,
00369 Point points[],
00370 Vector *polygon_normal )
00371 {
00372 BOOLEAN intersects, cross;
00373 Real x,
y, x1, y1, x2, y2, x_inter, dx, dy, tx, ty, len, t;
00374 Real
nx,
ny,
nz, max_val;
00375
int i1, i2;
00376
int i;
00377
00378
nx = FABS( (Real) Vector_x(*polygon_normal) );
00379
ny = FABS( (Real) Vector_y(*polygon_normal) );
00380
nz = FABS( (Real) Vector_z(*polygon_normal) );
00381
00382 max_val = MAX3(
nx,
ny,
nz );
00383
00384
if(
nx == max_val )
00385 {
00386 i1 = Y;
00387 i2 = Z;
00388 }
00389
else if(
ny == max_val )
00390 {
00391 i1 = Z;
00392 i2 = X;
00393 }
00394
else
00395 {
00396 i1 = X;
00397 i2 = Y;
00398 }
00399
00400 x = (Real) Point_coord( *pt, i1 );
00401
y = (Real) Point_coord( *pt, i2 );
00402
00403 cross =
FALSE;
00404
00405 x2 = (Real) Point_coord(points[n_points-1],i1);
00406 y2 = (Real) Point_coord(points[n_points-1],i2);
00407
00408 for_less( i, 0, n_points )
00409 {
00410 x1 = x2;
00411 y1 = y2;
00412
00413 x2 = (Real) Point_coord(points[i],i1);
00414 y2 = (Real) Point_coord(points[i],i2);
00415
00416
if( !( (y1 >
y && y2 >
y ) ||
00417 (y1 <
y && y2 <
y ) ||
00418 (x1 > x && x2 > x )) )
00419 {
00420 dy = y2 - y1;
00421
if( dy != 0.0 )
00422 {
00423
if( y1 ==
y )
00424 {
00425
if( y2 > y1 && x1 <= x )
00426 {
00427 cross = !cross;
00428 }
00429 }
00430
else if( y2 ==
y )
00431 {
00432
if( y1 > y2 && x2 <= x )
00433 {
00434 cross = !cross;
00435 }
00436 }
00437
else if( x1 <= x && x2 <= x )
00438 {
00439 cross = !cross;
00440 }
00441
else
00442 {
00443 x_inter = x1 + (
y - y1) / dy * (x2 - x1);
00444
00445
if( x_inter < x )
00446 {
00447 cross = !cross;
00448 }
00449 }
00450 }
00451 }
00452 }
00453
00454 intersects = cross;
00455
00456
if( !intersects )
00457 {
00458 x2 = (Real) Point_coord(points[n_points-1],i1);
00459 y2 = (Real) Point_coord(points[n_points-1],i2);
00460
00461 for_less( i, 0, n_points )
00462 {
00463 x1 = x2;
00464 y1 = y2;
00465
00466 x2 = (Real) Point_coord(points[i],i1);
00467 y2 = (Real) Point_coord(points[i],i2);
00468
00469
if( x1 -
TOLERANCE <= x && x <= x1 +
TOLERANCE &&
00470 y1 -
TOLERANCE <=
y &&
y <= y1 +
TOLERANCE )
00471 {
00472 intersects =
TRUE;
00473
break;
00474 }
00475
00476 dx = x2 - x1;
00477 dy = y2 - y1;
00478 tx = x - x1;
00479 ty =
y - y1;
00480
00481 len = dx * dx + dy * dy;
00482
if( len == 0.0 )
00483
continue;
00484
00485 t = (tx * dx + ty * dy) / len;
00486
00487
if( t < 0.0 || t > 1.0 )
00488
continue;
00489
00490 tx = tx - t * dx;
00491 ty = ty - t * dy;
00492
00493
if( tx * tx + ty * ty <
TOLERANCE *
TOLERANCE )
00494 {
00495 intersects =
TRUE;
00496
break;
00497 }
00498 }
00499 }
00500
00501
return( intersects );
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 private BOOLEAN
intersect_ray_quadmesh_patch(
00522 Point *ray_origin,
00523 Vector *ray_direction,
00524 Real *dist,
00525
quadmesh_struct *quadmesh,
00526
int obj_index )
00527 {
00528 BOOLEAN intersects;
00529 Point points[4];
00530
int i, j, m, n;
00531
00532
get_quadmesh_n_objects( quadmesh, &m, &n );
00533
00534 i = obj_index / n;
00535 j = obj_index % n;
00536
00537
get_quadmesh_patch( quadmesh, i, j, points );
00538
00539 intersects =
intersect_ray_polygon_points( ray_origin, ray_direction,
00540 4, points, dist );
00541
00542
return( intersects );
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 public BOOLEAN
line_intersects_ellipsoid(
00566 Point *line_origin,
00567 Vector *line_direction,
00568 Point *sphere_centre,
00569 Real x_size,
00570 Real y_size,
00571 Real z_size,
00572 Real *t_min,
00573 Real *t_max )
00574 {
00575 BOOLEAN intersects;
00576
int n_solutions;
00577 Real a, b, c, ox, oy, oz, dx, dy, dz, t1, t2;
00578
00579 ox = ((Real) Point_x(*line_origin) - (Real) Point_x(*sphere_centre)) /
00580 x_size;
00581 oy = ((Real) Point_y(*line_origin) - (Real) Point_y(*sphere_centre)) /
00582 y_size;
00583 oz = ((Real) Point_z(*line_origin) - (Real) Point_z(*sphere_centre)) /
00584 z_size;
00585
00586 dx = (Real) Vector_x(*line_direction) / x_size;
00587 dy = (Real) Vector_y(*line_direction) / y_size;
00588 dz = (Real) Vector_z(*line_direction) / z_size;
00589
00590 a = dx * dx + dy * dy + dz * dz;
00591 b = 2.0 * ( ox * dx + oy * dy + oz * dz);
00592 c = ox * ox + oy * oy + oz * oz - 1.0;
00593
00594 n_solutions =
solve_quadratic( a, b, c, &t1, &t2 );
00595
00596
if( n_solutions == 0 )
00597 intersects =
FALSE;
00598
else if( n_solutions == 1 )
00599 {
00600 intersects =
TRUE;
00601 *t_min = t1;
00602 *t_max = t2;
00603 }
00604
else
00605 {
00606 intersects =
TRUE;
00607 *t_min = MIN( t1, t2 );
00608 *t_max = MAX( t1, t2 );
00609 }
00610
00611
return( intersects );
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 public BOOLEAN
ray_intersects_sphere(
00631 Point *origin,
00632 Vector *direction,
00633 Point *centre,
00634 Real radius,
00635 Real *dist )
00636 {
00637 BOOLEAN intersects;
00638 Real t_min, t_max;
00639
00640 intersects =
line_intersects_ellipsoid( origin, direction, centre,
00641 radius, radius, radius,
00642 &t_min, &t_max );
00643
00644
if( intersects )
00645 {
00646
if( t_min >= 0.0 )
00647 *dist = t_min;
00648
else if( t_max >= 0.0 )
00649 *dist = t_max;
00650
else
00651 intersects =
FALSE;
00652 }
00653
00654
return( intersects );
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 private BOOLEAN
ray_intersects_tube(
00676 Point *origin,
00677 Vector *direction,
00678 Point *p1,
00679 Point *p2,
00680 Real radius,
00681 Real *dist )
00682 {
00683 Point point;
00684
int n_sols;
00685 Real a, b, c, sols[2], t_min, t_max;
00686 Real len_axis, x,
y, z, dx, dy, ox, oy;
00687 Point trans_origin;
00688 Vector tube_axis, hor, vert, trans_direction;
00689 Transform transform;
00690
00691
if( EQUAL_POINTS( *p1, *p2 ) )
00692
return(
FALSE );
00693
00694 SUB_POINTS( tube_axis, *p2, *p1 );
00695 create_two_orthogonal_vectors( &tube_axis, &hor, &vert );
00696 len_axis = MAGNITUDE( tube_axis );
00697 SCALE_VECTOR( tube_axis, tube_axis, 1.0 / len_axis );
00698 NORMALIZE_VECTOR( hor, hor );
00699 NORMALIZE_VECTOR( vert, vert );
00700 make_change_from_bases_transform( p1, &hor, &vert, &tube_axis, &transform );
00701
00702 transform_point( &transform,
00703 RPoint_x(*origin), RPoint_y(*origin), RPoint_z(*origin),
00704 &x, &
y, &z );
00705 fill_Point( trans_origin, x,
y, z );
00706
00707 transform_vector( &transform,
00708 RVector_x(*direction), RVector_y(*direction), RVector_z(*direction),
00709 &x, &
y, &z );
00710 fill_Vector( trans_direction, x,
y, z );
00711
00712
if( !
clip_line_to_box( &trans_origin, &trans_direction,
00713 -radius, radius, -radius, radius,
00714 -radius, len_axis + radius, &t_min, &t_max ) )
00715 {
00716
return(
FALSE );
00717 }
00718
00719 ox = RPoint_x( trans_origin );
00720 oy = RPoint_y( trans_origin );
00721 dx = RVector_x( trans_direction );
00722 dy = RVector_y( trans_direction );
00723
00724 a = dx * dx + dy * dy;
00725 b = 2.0 * (ox * dx + oy * dy);
00726 c = ox * ox + oy * oy - radius * radius;
00727
00728 n_sols =
solve_quadratic( a, b, c, &sols[0], &sols[1] );
00729
00730
if( n_sols == 0 )
00731 *dist = -1.0;
00732
else if( n_sols == 1 )
00733 *dist = sols[0];
00734
else
00735 {
00736 t_min = MIN( sols[0], sols[1] );
00737 t_max = MAX( sols[0], sols[1] );
00738
if( t_min >= 0.0 )
00739 *dist = t_min;
00740
else if( t_max >= 0.0 )
00741 *dist = t_max;
00742
else
00743 *dist = -1.0;
00744 }
00745
00746
00747
00748
00749
if( *dist >= 0.0 )
00750 {
00751 GET_POINT_ON_RAY( point, trans_origin, trans_direction, *dist );
00752
if( RPoint_z(point) < 0.0 || RPoint_z(point) > len_axis )
00753 *dist = -1.0;
00754 }
00755
00756
return( *dist >= 0.0 );
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 private BOOLEAN
intersect_ray_tube_segment(
00777 Point *origin,
00778 Vector *direction,
00779 Real *dist,
00780
lines_struct *lines,
00781
int obj_index )
00782 {
00783 Real a_dist;
00784
int line, seg, p1, p2;
00785 BOOLEAN found;
00786
00787
get_line_segment_index( lines, obj_index, &line, &seg );
00788
00789 p1 = lines->
indices[
POINT_INDEX(lines->
end_indices,line,seg)];
00790 p2 = lines->
indices[
POINT_INDEX(lines->
end_indices,line,seg+1)];
00791
00792 found =
ray_intersects_sphere( origin, direction, &lines->
points[p1],
00793 (Real) lines->
line_thickness, dist );
00794
00795
if(
ray_intersects_sphere( origin, direction, &lines->
points[p2],
00796 (Real) lines->
line_thickness, &a_dist ) &&
00797 (!found || a_dist < *dist ) )
00798 {
00799 found =
TRUE;
00800 *dist = a_dist;
00801 }
00802
00803
if(
ray_intersects_tube( origin, direction,
00804 &lines->
points[p1],
00805 &lines->
points[p2],
00806 (Real) lines->
line_thickness, &a_dist ) &&
00807 (!found || a_dist < *dist ) )
00808 {
00809 found =
TRUE;
00810 *dist = a_dist;
00811 }
00812
00813
return( found );
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 private BOOLEAN
intersect_ray_with_cube(
00833 Point *ray_origin,
00834 Vector *ray_direction,
00835 Point *centre,
00836 Real size,
00837 Real *dist )
00838 {
00839 Real t_min, t_max;
00840 BOOLEAN intersects;
00841
00842 intersects =
clip_line_to_box( ray_origin, ray_direction,
00843 (Real) Point_x(*centre) - size / 2.0,
00844 (Real) Point_x(*centre) + size / 2.0,
00845 (Real) Point_y(*centre) - size / 2.0,
00846 (Real) Point_y(*centre) + size / 2.0,
00847 (Real) Point_z(*centre) - size / 2.0,
00848 (Real) Point_z(*centre) + size / 2.0,
00849 &t_min, &t_max );
00850
00851
if( intersects )
00852 {
00853
if( t_min >= 0.0 )
00854 *dist = t_min;
00855
else if( t_max >= 0.0 )
00856 *dist = t_max;
00857
else
00858 intersects =
FALSE;
00859 }
00860
00861
return( intersects );
00862 }
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 private BOOLEAN
intersect_ray_with_marker(
00881 Point *ray_origin,
00882 Vector *ray_direction,
00883
marker_struct *marker,
00884 Real *dist )
00885 {
00886
if( marker->
type ==
BOX_MARKER )
00887 {
00888
return(
intersect_ray_with_cube( ray_origin, ray_direction,
00889 &marker->
position, marker->
size, dist));
00890 }
00891
else
00892 {
00893
return(
ray_intersects_sphere( ray_origin, ray_direction,
00894 &marker->
position, marker->
size, dist) );
00895 }
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 public void intersect_ray_object(
00918 Point *origin,
00919 Vector *direction,
00920
object_struct *object,
00921
int obj_index,
00922
int *closest_obj_index,
00923 Real *closest_dist,
00924
int *n_intersections,
00925 Real *distances[] )
00926 {
00927 BOOLEAN found;
00928 Real dist;
00929
00930
if(
get_object_type( object ) ==
POLYGONS )
00931 {
00932 found =
intersect_ray_polygon( origin, direction, &dist,
00933
get_polygons_ptr(object), obj_index );
00934 }
00935
else if(
get_object_type( object ) ==
QUADMESH )
00936 {
00937 found =
intersect_ray_quadmesh_patch( origin, direction, &dist,
00938
get_quadmesh_ptr(object), obj_index );
00939 }
00940
else if(
get_object_type( object ) ==
LINES )
00941 {
00942 found =
intersect_ray_tube_segment( origin, direction, &dist,
00943
get_lines_ptr(object), obj_index );
00944 }
00945
else if(
get_object_type( object ) ==
MARKER )
00946 {
00947 found =
intersect_ray_with_marker( origin, direction,
00948
get_marker_ptr(object), &dist );
00949 }
00950
00951
if( found )
00952 {
00953
if( distances != (Real **) NULL )
00954 {
00955 SET_ARRAY_SIZE( *distances, *n_intersections,
00956 *n_intersections + 1, DEFAULT_CHUNK_SIZE );
00957 (*distances)[*n_intersections] = dist;
00958 }
00959
00960
if( closest_obj_index != (
int *) NULL &&
00961 ((*n_intersections == 0) || dist < *closest_dist ) )
00962 {
00963 *closest_obj_index = obj_index;
00964 *closest_dist = dist;
00965 }
00966
00967 ++(*n_intersections);
00968 }
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 public int intersect_ray_with_object(
00989 Point *origin,
00990 Vector *direction,
00991
object_struct *object,
00992
int *obj_index,
00993 Real *dist,
00994 Real *distances[] )
00995 {
00996
lines_struct *lines;
00997
polygons_struct *polygons;
00998
quadmesh_struct *quadmesh;
00999
int i, n_intersections, m, n, n_objects;
01000
01001 n_intersections = 0;
01002
if( obj_index != (
int *) NULL )
01003 *obj_index = -1;
01004
01005
switch(
get_object_type( object ) )
01006 {
01007
case LINES:
01008 lines =
get_lines_ptr( object );
01009
if( lines->
n_items == 0 )
01010 {
01011 n_objects = 0;
01012
break;
01013 }
01014
01015
if( lines->
bintree != (
bintree_struct_ptr) NULL )
01016 {
01017
return(
intersect_ray_with_bintree( origin, direction,
01018 lines->
bintree, object,
01019 obj_index, dist, distances ) );
01020 }
01021
01022 n_objects = lines->
end_indices[lines->
n_items-1] - lines->
n_items;
01023
break;
01024
01025
case POLYGONS:
01026 polygons =
get_polygons_ptr( object );
01027
if( polygons->
bintree != (
bintree_struct_ptr) NULL )
01028 {
01029
return(
intersect_ray_with_bintree( origin, direction,
01030 polygons->
bintree, object,
01031 obj_index, dist, distances ) );
01032 }
01033 n_objects = polygons->
n_items;
01034
break;
01035
01036
case QUADMESH:
01037 quadmesh =
get_quadmesh_ptr( object );
01038
if( quadmesh->
bintree != (
bintree_struct_ptr) NULL )
01039 {
01040
return(
intersect_ray_with_bintree( origin, direction,
01041 quadmesh->
bintree, object,
01042 obj_index, dist, distances ) );
01043 }
01044
get_quadmesh_n_objects( quadmesh, &m, &n );
01045 n_objects = m * n;
01046
break;
01047
01048
case MARKER:
01049 n_objects = 1;
01050
break;
01051
01052
default:
01053 n_objects = 0;
01054
break;
01055 }
01056
01057 for_less( i, 0, n_objects )
01058 {
01059
intersect_ray_object( origin, direction, object, i, obj_index,
01060 dist, &n_intersections, distances );
01061 }
01062
01063
return( n_intersections );
01064 }