16 #define SMALL_NUM       1E-6 
   18 #define UNINITIALIZED_VALUE     -1234567.8f 
   21 static void accurate_square_root( 
float A, 
float B, 
float C, 
float discriminant, 
float *root1, 
float *root2 ) 
__UNUSED;
 
   51         if (denominator > 1e-10) {
 
   52                 num_s = matrix_determinant_from_vectors(&delta, v2, &cross);
 
   55                 num_t = matrix_determinant_from_vectors(&delta, v1, &cross);
 
  119                     const vec3d *plane_pnt, 
const vec3d *plane_norm,
 
  120                     const vec3d *ray_origin, 
const vec3d *ray_direction,
 
  131                         new_pnt->
xyz.x = -FLT_MAX;
 
  132                         new_pnt->
xyz.y = -FLT_MAX;
 
  133                         new_pnt->
xyz.z = -FLT_MAX;
 
  163                                                                                 const vec3d *plane_pnt, 
const vec3d *plane_norm,
 
  172                     plane_pnt,plane_norm,               
 
  176         if ( t < 0.0
f ) 
return 0;               
 
  177         if ( t > 1.0
f ) 
return 0;               
 
  190         vec3d d,dn,
w,closest_point;
 
  191         float mag_d,dist,w_dist,int_dist;
 
  203                 return (int_dist<sphere_rad)?1:0;
 
  207         dn.
xyz.x = d.
xyz.x / mag_d;
 
  208         dn.
xyz.y = d.
xyz.y / mag_d;
 
  209         dn.
xyz.z = d.
xyz.z / mag_d;
 
  213         if (w_dist < -sphere_rad)               
 
  216         if (w_dist > mag_d+sphere_rad)
 
  223         if (dist < sphere_rad) {
 
  224                 float dist2,rad2,shorten;
 
  227                 rad2 = sphere_rad*sphere_rad;
 
  229                 shorten = 
fl_sqrt(rad2 - dist2);
 
  231                 int_dist = w_dist-shorten;
 
  233                 if (int_dist > mag_d || int_dist < 0.0
f) {
 
  257         vec3d d,dn,
w,closest_point;
 
  258         float mag_d,dist,w_dist,int_dist;
 
  270                 return (int_dist<sphere_rad)?1:0;
 
  274         dn.
xyz.x = d.
xyz.x / mag_d;
 
  275         dn.
xyz.y = d.
xyz.y / mag_d;
 
  276         dn.
xyz.z = d.
xyz.z / mag_d;
 
  280         if (w_dist < -sphere_rad)               
 
  287         if (dist < sphere_rad) {
 
  288                 float dist2,rad2,shorten;
 
  291                 rad2 = sphere_rad*sphere_rad;
 
  293                 shorten = 
fl_sqrt(rad2 - dist2);
 
  295                 int_dist = w_dist-shorten;
 
  297                 if (int_dist < 0.0
f) {
 
  323         int middle = ((1<<0) | (1<<1) | (1<<2));
 
  327         float candidate_plane[3];
 
  329         for (i = 0; i < 3; i++) {
 
  330                 if (p0->
a1d[i] < min->
a1d[i]) {
 
  331                         candidate_plane[
i] = min->
a1d[
i];
 
  333                 } 
else if (p0->
a1d[i] > max->
a1d[i]) {
 
  334                         candidate_plane[
i] = max->
a1d[
i];
 
  341         if (middle == ((1<<0) | (1<<1) | (1<<2))) {
 
  347         for (i = 0; i < 3; i++) {
 
  348                 if ( (middle & (1<<i)) || (pdir->
a1d[i] == 0.0f) ) {
 
  351                         maxt[
i] = (candidate_plane[
i] - p0->
a1d[
i]) / pdir->
a1d[i];
 
  357         for (i = 1; i < 3; i++) {
 
  358                 if (maxt[which_plane] < maxt[i]) {
 
  364         if (maxt[which_plane] < 0.0
f) {
 
  368         for (i = 0; i < 3; i++) {
 
  369                 if (which_plane == i) {
 
  370                         hitpt->
a1d[
i] = candidate_plane[
i];
 
  372                         hitpt->
a1d[
i] = (maxt[which_plane] * pdir->
a1d[
i]) + p0->
a1d[i];
 
  387 static int ij_table[3][2] =        {
 
  418 #define delta 0.0001f 
  426         norm = (
float *)norm1;
 
  433         if (t.
xyz.x > t.
xyz.y) 
if (t.
xyz.x > t.
xyz.z) i0=0; 
else i0=2;
 
  434         else if (t.
xyz.y > t.
xyz.z) i0=1; 
else i0=2;
 
  436         if (norm[i0] > 0.0
f) {
 
  437                 i1 = ij_table[i0][0];
 
  438                 i2 = ij_table[i0][1];
 
  441                 i1 = ij_table[i0][1];
 
  442                 i2 = ij_table[i0][0];
 
  453         u0 = P[i1] - verts[0]->
a1d[i1];
 
  454         v0 = P[i2] - verts[0]->
a1d[i2];
 
  458                 u1 = verts[
i-1]->
a1d[i1] - verts[0]->
a1d[i1]; 
 
  459                 u2 = verts[
i  ]->
a1d[i1] - verts[0]->
a1d[i1];
 
  461                 v1 = verts[
i-1]->
a1d[i2] - verts[0]->
a1d[i2];
 
  462                 v2 = verts[
i  ]->
a1d[i2] - verts[0]->
a1d[i2];
 
  467                         if ((beta >=0.0
f) && (beta<=1.0f))      {
 
  468                                 alpha = (v0 - beta*
v2)/v1;
 
  469                                 inter = ((alpha>=0.0f)&&(alpha+beta<=1.0
f));
 
  473                         beta = (v0*u1 - u0*
v1) / (v2*u1 - u2*v1);
 
  474                         if ((beta >=0.0
f) && (beta<=1.0f))      {
 
  476                                 alpha = (u0 - beta*
u2)/u1;
 
  477                                 inter = ((alpha>=0.0f)&&(alpha+beta<=1.0
f));
 
  481         } 
while ((!inter) && (++
i < nv) );
 
  483         if ( inter &&  uvls && u_out && v_out ) {
 
  484                 gamma = 1.0f - (alpha+beta);
 
  485                 *u_out = gamma * uvls[0].
u + alpha*uvls[
i-1].
u + beta*uvls[
i].
u;
 
  486                 *v_out = gamma * uvls[0].
v + alpha*uvls[
i-1].
v + beta*uvls[
i].
v;
 
  498 static int check_sphere_point(
const vec3d *point, 
const vec3d *sphere_start, 
const vec3d *sphere_vel, 
float radius, 
float *collide_time );
 
  517                                                         const vec3d *plane_normal, 
const vec3d *plane_point, 
float *hit_time, 
float *crossing_time)
 
  519         float   D, xs0_dot_norm, vs_dot_norm;
 
  524         xs0_dot_norm = 
vm_vec_dot( plane_normal, sphere_center_start );
 
  525         vs_dot_norm  = 
vm_vec_dot( plane_normal, sphere_velocity);
 
  528         if (
fl_abs(vs_dot_norm) > 1e-30) {
 
  529                 t1 = (-D - xs0_dot_norm + sphere_radius) / vs_dot_norm;
 
  530                 t2 = (-D - xs0_dot_norm - sphere_radius) / vs_dot_norm;
 
  545         if (t1 > 0 && t1 < 1) {
 
  552         *crossing_time = t2 - 
t1;
 
  554         return ( (t1 < 1) && (t2 > 0) );
 
  571                                                                  float sphere_radius, 
vec3d *edge_point1, 
vec3d *edge_point2, 
float *collide_time)
 
  580         vec3d Xe_proj, Xs_proj;
 
  587         vec3d x_hat, y_hat, z_hat;
 
  588         float max_edge_parameter;
 
  593         max_edge_parameter = 
vm_vec_mag( &edge_velocity );
 
  619         float edge_parameter;
 
  622         vm_vec_sub( &temp_vec, intersect_point, &V0 );
 
  623         edge_parameter = 
vm_vec_dot( &temp_vec, &x_hat );
 
  625         if ( edge_parameter < 0 || edge_parameter > max_edge_parameter ) {
 
  629         return ( check_sphere_point(intersect_point, sphere_center_start, sphere_velocity, sphere_radius, collide_time) );
 
  642 static int check_sphere_point(
const vec3d *point, 
const vec3d *sphere_start, 
const vec3d *sphere_vel, 
float radius, 
float *collide_time )
 
  645         float delta_x_sqr, vs_sqr, delta_x_dot_vs;
 
  650         delta_x_dot_vs = 
vm_vec_dot( &delta_x, sphere_vel );
 
  652         float discriminant = delta_x_dot_vs*delta_x_dot_vs - vs_sqr*(delta_x_sqr - radius*radius);
 
  653         if (discriminant < 0) {
 
  657         float radical, time1, time2;
 
  658         radical = 
fl_sqrt(discriminant);
 
  659         time1 = (-delta_x_dot_vs + radical) / vs_sqr;
 
  660         time2 = (-delta_x_dot_vs - radical) / vs_sqr;
 
  668         if (time1 >= 0 && time1 <= 1.0) {
 
  669                 *collide_time = time1;
 
  673         if (time2 >= 0 && time2 <= 1.0) {
 
  674                 *collide_time = time2;
 
  699         float best_sphere_time;         
 
  701         float delta_x_dot_ve, delta_x_dot_vs, ve_dot_vs, ve_sqr, vs_sqr, delta_x_sqr;
 
  702         vec3d temp_edge_hit, temp_sphere_hit;
 
  703         float t_sphere_hit = 0.0f;
 
  704         float A, 
B, C, 
temp, discriminant, invA;
 
  705         float root, root1, root2;
 
  706         float Rs2 = (Rs * Rs);
 
  707         float Rs_point2 = (0.2f * Rs);
 
  709         best_sphere_time = FLT_MAX;
 
  713         for (i = 0; i < nv; i++) {
 
  748                 A = ve_dot_vs*ve_dot_vs - ve_sqr*vs_sqr;
 
  749                 B = delta_x_dot_ve*ve_dot_vs - delta_x_dot_vs*ve_sqr;
 
  750                 C = delta_x_dot_ve*delta_x_dot_ve + Rs2*ve_sqr - delta_x_sqr*ve_sqr;
 
  752                 discriminant = B*B - A*C;
 
  753                 if (discriminant > 0.0
f) {
 
  755                         root = sqrt(discriminant);
 
  756                         root1 = (-B + root) * invA;
 
  757                         root2 = (-B - root) * invA;
 
  766                         if ( (root1 < 0.0
f) && (root1 >= -0.05f) )
 
  770                         if ( (root1 <= 1.0
f) && (root1 >= 0.0f) ) {
 
  771                                 t_sphere_hit = root1;
 
  781                 if (t_sphere_hit >= best_sphere_time)
 
  788                 B = ve_sqr * (delta_x_dot_ve*vs_sqr - delta_x_dot_vs*ve_dot_vs);
 
  789                 C = 2.0f*delta_x_dot_ve*delta_x_dot_vs*ve_dot_vs + Rs2*ve_dot_vs*ve_dot_vs 
 
  790                          - delta_x_sqr*ve_dot_vs*ve_dot_vs - delta_x_dot_ve*delta_x_dot_ve*vs_sqr;
 
  792                 discriminant = B*B - A*C;
 
  796                 if (discriminant < 0.0
f)
 
  801                 root1 = (-B + root) * invA;
 
  802                 root2 = (-B - root) * invA;
 
  805                 if ( (root1 <= 1.0
f) && (root1 >= 0.0f) ) {
 
  809                         if ( 
fl_abs(q - Rs2) < Rs_point2 ) {    
 
  814                 if ( (root2 <= 1.0
f) && (root2 >= 0.0
f) ) {
 
  818                         if ( 
fl_abs(q - Rs2) < Rs_point2 ) {    
 
  830                 C = delta_x_sqr - Rs2;
 
  832                 float sphere_v0, sphere_v1;
 
  839                 discriminant = B*B - A*C;
 
  840                 if (discriminant > 0.0
f) {
 
  842                         root1 = (-B + root) * invA;
 
  843                         root2 = (-B - root) * invA;
 
  852                         if ( (root1 < 1.0
f) && (root1 > 0.0f) ) {
 
  865                 C = delta_x_sqr - Rs2;
 
  868                 discriminant = B*B - A*C;
 
  869                 if (discriminant > 0.0
f) {
 
  871                         root1 = (-B + root) * invA;
 
  872                         root2 = (-B - root) * invA;
 
  881                         if ( (root1 < 1.0
f) && (root1 > 0.0f) ) {
 
  890                         t_sphere_hit = sphere_v0;
 
  895                                 if (sphere_v1 < sphere_v0) {
 
  896                                         t_sphere_hit = sphere_v1;
 
  900                 } 
else if ( v1_hit ) {
 
  902                         t_sphere_hit = sphere_v1;
 
  913                 if (t_sphere_hit < best_sphere_time) {
 
  914                         best_sphere_time = t_sphere_hit;
 
  915                         *hit_point = temp_edge_hit;
 
  919         if (best_sphere_time <= 1.0
f) {
 
  920                 *hit_time = best_sphere_time;
 
  937         vec3d delta_x, line_velocity;
 
  940         vm_vec_sub(&line_velocity, line_point2, line_point1);
 
  941         vm_vec_sub(&delta_x, line_point1, fixed_point);
 
  971         vec3d delta_x, delta_v;
 
  972         float discriminant, separation, delta_x_dot_delta_v, delta_v_sqr, delta_x_sqr;
 
  976         Assert( (!(t1) && !(t2)) || (t1 && t2) );
 
  980         separation = radius_p + radius_s;
 
  983         if (delta_x_sqr < separation*separation) {
 
  995         delta_x_dot_delta_v = 
vm_vec_dot(&delta_x, &delta_v);
 
  998         discriminant = delta_x_dot_delta_v*delta_x_dot_delta_v - delta_v_sqr*(delta_x_sqr - separation*separation);
 
 1000         if (discriminant < 0) {
 
 1004         float radical = 
fl_sqrt(discriminant);
 
 1006         time1 = (-delta_x_dot_delta_v + radical) / delta_v_sqr;
 
 1007         time2 = (-delta_x_dot_delta_v - radical) / delta_v_sqr;
 
 1011         if (time1 > time2) {
 
 1023         if (time1 > 1 || time2 < 0) {
 
 1046         vec3d closest_point, closest_separation;
 
 1050         vm_vec_sub(&closest_separation, &closest_point, poly_center);
 
 1052         max_sep = 
vm_vec_mag(&closest_separation) + poly_r;
 
 1054         if ( max_sep > sphere_r ) {
 
 1066         vec3d vx_cross_vy, delta_l, delta_l_cross_vx, delta_l_cross_vy;
 
 1082 static void accurate_square_root( 
float A, 
float B, 
float C, 
float discriminant, 
float *root1, 
float *root2 )
 
 1084         float root = 
fl_sqrt(discriminant);
 
 1087                 *root1 = 2.0f*C / (-B - root);
 
 1088                 *root2 = (-B - root) / (2.0
f*A);
 
 1090                 *root1 = (-B + root) / (2.0
f*A);
 
 1091                 *root2 = 2.0f*C / (-B + root);
 
 1111         if (start->
xyz.x > maxs->
xyz.x) {
 
 1112                 box_pt->
xyz.x = maxs->
xyz.x;
 
 1114         } 
else if (start->
xyz.x < mins->
xyz.x) {
 
 1115                 box_pt->
xyz.x = mins->
xyz.x;
 
 1118                 box_pt->
xyz.x = start->
xyz.x;
 
 1121         if (start->
xyz.y > maxs->
xyz.y) {
 
 1122                 box_pt->
xyz.y = maxs->
xyz.y;
 
 1124         } 
else if (start->
xyz.y < mins->
xyz.y) {
 
 1125                 box_pt->
xyz.y = mins->
xyz.y;
 
 1128                 box_pt->
xyz.y = start->
xyz.y;
 
 1131         if (start->
xyz.z > maxs->
xyz.z) {
 
 1132                 box_pt->
xyz.z = maxs->
xyz.z;
 
 1134         } 
else if (start->
xyz.z < mins->
xyz.z) {
 
 1135                 box_pt->
xyz.z = mins->
xyz.z;
 
 1138                 box_pt->
xyz.z = start->
xyz.z;
 
void vm_vec_projection_onto_plane(vec3d *projection, const vec3d *src, const vec3d *unit_normal)
 
int fvi_polyedge_sphereline(vec3d *hit_point, const vec3d *xs0, const vec3d *vs, float Rs, int nv, vec3d const *const *verts, float *hit_time)
 
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
 
float vm_vec_mag(const vec3d *v)
 
struct vec3d::@225::@227 xyz
 
void fvi_closest_point_on_line_segment(vec3d *closest_point, const vec3d *fixed_point, const vec3d *line_point1, const vec3d *line_point2)
 
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
 
GLfloat GLfloat GLfloat v2
 
float vm_vec_mag_squared(const vec3d *v)
 
float fvi_point_dist_plane(const vec3d *plane_pnt, const vec3d *plane_norm, const vec3d *point)
 
int fvi_sphere_plane(vec3d *intersect_point, const vec3d *sphere_center_start, const vec3d *sphere_velocity, float sphere_radius, const vec3d *plane_normal, const vec3d *plane_point, float *hit_time, float *crossing_time)
 
void vm_vec_add2(vec3d *dest, const vec3d *src)
 
int fvi_point_face(const vec3d *checkp, int nv, vec3d const *const *verts, const vec3d *norm1, float *u_out, float *v_out, const uv_pair *uvls)
 
int fvi_sphere_perp_edge(vec3d *intersect_point, const vec3d *sphere_center_start, const vec3d *sphere_velocity, float sphere_radius, vec3d *edge_point1, vec3d *edge_point2, float *collide_time)
 
void vm_vec_sub2(vec3d *dest, const vec3d *src)
 
float vm_vec_dist(const vec3d *v0, const vec3d *v1)
 
float vm_vec_dist_squared(const vec3d *v0, const vec3d *v1)
 
int fvi_ray_sphere(vec3d *intp, const vec3d *p0, const vec3d *p1, const vec3d *sphere_pos, float sphere_rad)
 
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
 
int fvi_cull_polyface_sphere(const vec3d *poly_center, float poly_r, const vec3d *sphere_start, const vec3d *sphere_end, float sphere_r)
 
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
 
#define UNINITIALIZED_VALUE
 
INT32 INT32 * denominator
 
GLdouble GLdouble GLdouble GLdouble q
 
void fvi_closest_line_line(const vec3d *x0, const vec3d *vx, const vec3d *y0, const vec3d *vy, float *x_time, float *y_time)
 
void fvi_two_lines_in_3space(const vec3d *p1, const vec3d *v1, const vec3d *p2, const vec3d *v2, float *s, float *t)
 
int fvi_check_sphere_sphere(const vec3d *x_p0, const vec3d *x_p1, const vec3d *x_s0, const vec3d *x_s1, float radius_p, float radius_s, float *t1, float *t2)
 
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
 
int fvi_segment_sphere(vec3d *intp, const vec3d *p0, const vec3d *p1, const vec3d *sphere_pos, float sphere_rad)
 
void vm_project_point_onto_plane(vec3d *new_point, const vec3d *point, const vec3d *plane_normal, const vec3d *plane_point)
 
int vm_vec_cmp(const vec3d *a, const vec3d *b)
 
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
 
float fvi_ray_plane(vec3d *new_pnt, const vec3d *plane_pnt, const vec3d *plane_norm, const vec3d *ray_origin, const vec3d *ray_direction, float rad)
 
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
 
GLclampf GLclampf GLclampf alpha
 
int fvi_segment_plane(vec3d *new_pnt, const vec3d *plane_pnt, const vec3d *plane_norm, const vec3d *p0, const vec3d *p1, float rad)
 
int fvi_ray_boundingbox(const vec3d *min, const vec3d *max, const vec3d *p0, const vec3d *pdir, vec3d *hitpt)
 
int project_point_onto_bbox(const vec3d *mins, const vec3d *maxs, const vec3d *start, vec3d *box_pt)
 
GLfloat GLfloat GLfloat GLfloat v3