decide it it's close enough to hit determine if and where a vector intersects with a sphere vector defined by p0,p1 if there is an intersection this function returns 1, fills in intp, and col_dist else it returns 0 NOTE: Caller should account for the radius of the vector (i.e. no rad. for the vector is passed to this function -- the 2 radii are additive to it is trial and it saves 1 parameter
| 1172 | // NOTE: Caller should account for the radius of the vector (i.e. no rad. for the vector is passed |
| 1173 | // to this function -- the 2 radii are additive to it is trial and it saves 1 parameter |
| 1174 | int check_vector_to_sphere_1(vector *intp, float *col_dist, const vector *p0, const vector *p1, vector *sphere_pos, |
| 1175 | float sphere_rad, bool f_correcting, bool f_init_collisions) { |
| 1176 | vector line_vec; // Vector direction of line from p0 to p1 |
| 1177 | vector normalized_line_vec; // Normalized line vector |
| 1178 | float mag_line; // Length of the line |
| 1179 | |
| 1180 | vector point_to_center_vec; // Vector from p0 to the center of the sphere |
| 1181 | vector closest_point; // Location the sphere's centerpoint parallel projected onto the line |
| 1182 | float closest_point_dist; // Distance from p0 to the closest_point |
| 1183 | float closest_mag_to_center; // Distance from the clostest_point to the center of the sphere |
| 1184 | |
| 1185 | float shorten; // How much to subtract from the closest_point_dist to get the actual intersection |
| 1186 | // point |
| 1187 | |
| 1188 | ASSERT(sphere_rad > 0.0); |
| 1189 | |
| 1190 | // Get the vectors as usual |
| 1191 | line_vec = *p1 - *p0; |
| 1192 | point_to_center_vec = *sphere_pos - *p0; |
| 1193 | |
| 1194 | if (line_vec * point_to_center_vec <= 0.0f) |
| 1195 | return 0; |
| 1196 | |
| 1197 | // Get the magnitude and direction of the line vector |
| 1198 | normalized_line_vec = line_vec; |
| 1199 | mag_line = vm_NormalizeVector(&normalized_line_vec); |
| 1200 | |
| 1201 | // Compute the location of the point on the line that is perpendicular to the center of the sphere |
| 1202 | closest_point_dist = normalized_line_vec * point_to_center_vec; |
| 1203 | |
| 1204 | // We check for an initial hit, so if closest_point is negative distance, it was a miss (think about it) |
| 1205 | // Otherwise, make sure it is not any farther than would for a collision to happen |
| 1206 | if (closest_point_dist < 0.0 || closest_point_dist >= mag_line + sphere_rad) |
| 1207 | return 0; |
| 1208 | |
| 1209 | // Is the initial p0 position an intersection? If so, warn us and collide immediately. |
| 1210 | if (point_to_center_vec * point_to_center_vec < sphere_rad * sphere_rad) { |
| 1211 | if (f_correcting) { |
| 1212 | /* |
| 1213 | // chrishack |
| 1214 | mprintf(0, "FVI WARNING: Start point is inside of a checked sphere %f %f\n", |
| 1215 | point_to_center_vec * point_to_center_vec, |
| 1216 | sphere_rad * sphere_rad); |
| 1217 | */ |
| 1218 | // chrishack this movement intersection fix is a hack... How do we do correct cylinder/vector interestion? |
| 1219 | vector n_ptc = point_to_center_vec; |
| 1220 | vm_NormalizeVector(&n_ptc); |
| 1221 | |
| 1222 | *intp = |
| 1223 | *p0 - n_ptc * (sphere_rad - (float)sqrt(sphere_rad * sphere_rad - point_to_center_vec * point_to_center_vec)); |
| 1224 | |
| 1225 | *col_dist = 0.0; |
| 1226 | return 1; |
| 1227 | } else if (f_init_collisions) { |
| 1228 | *intp = *p0; |
| 1229 | *col_dist = 0.0; |
| 1230 | |
| 1231 | return 1; |
no test coverage detected