FS2_Open
Open source remastering of the Freespace 2 engine
|
Go to the source code of this file.
Macros | |
#define | SMALL_NUM 1E-6 |
#define | UNINITIALIZED_VALUE -1234567.8f |
#define | WARN_DIST 1.0 |
#define | delta 0.0001f |
Functions | |
void | fvi_two_lines_in_3space (const vec3d *p1, const vec3d *v1, const vec3d *p2, const vec3d *v2, float *s, float *t) |
float | fvi_point_dist_plane (const vec3d *plane_pnt, const vec3d *plane_norm, const vec3d *point) |
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) |
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_segment_sphere (vec3d *intp, const vec3d *p0, const vec3d *p1, const vec3d *sphere_pos, float sphere_rad) |
int | fvi_ray_sphere (vec3d *intp, const vec3d *p0, const vec3d *p1, const vec3d *sphere_pos, float sphere_rad) |
int | fvi_ray_boundingbox (const vec3d *min, const vec3d *max, const vec3d *p0, const vec3d *pdir, vec3d *hitpt) |
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_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) |
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) |
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 | fvi_closest_point_on_line_segment (vec3d *closest_point, const vec3d *fixed_point, const vec3d *line_point1, const vec3d *line_point2) |
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) |
int | fvi_cull_polyface_sphere (const vec3d *poly_center, float poly_r, const vec3d *sphere_start, const vec3d *sphere_end, float sphere_r) |
void | fvi_closest_line_line (const vec3d *x0, const vec3d *vx, const vec3d *y0, const vec3d *vy, float *x_time, float *y_time) |
int | project_point_onto_bbox (const vec3d *mins, const vec3d *maxs, const vec3d *start, vec3d *box_pt) |
#define delta 0.0001f |
See if a point in inside a face by projecting into 2d. Also finds uv's if uvls is not NULL.
Returns 0 if point isn't on face, non-zero otherwise.
From Graphics Gems I, "An efficient Ray-Polygon intersection", p390
checkp | The point to check |
nv | How many verts in the poly |
verts | The vertives for the polygon |
norm1 | The polygon's normal |
u_out | If not null and v_out not null and uvls not_null and point is on face, the uv's of where it hit |
vout | If not null and v_out not null and uvls not_null and point is on face, the uv's of where it hit |
uvls | A list of uv pairs for each vertex |
This replaces the old check_point_to_face & find_hitpoint_uv WARNING!! In Gems, they use the code "if (u1==0)" in this function. I have found several cases where this will not detect collisions it should. I found two solutions:
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 | ||
) |
checks whether two spheres hit given initial and starting positions and radii does not check whether sphere are already touching.
x_p0 | polymodel sphere, start point |
x_p1 | polymodel sphere, end point |
x_s0 | other sphere, start point |
x_s1 | other sphere, end point |
radius_p | radius of polymodel sphere |
radius_s | radius of other sphere |
t1 | time pointer 1 |
t2 | time pointer 2 |
int fvi_cull_polyface_sphere | ( | const vec3d * | poly_center, |
float | poly_r, | ||
const vec3d * | sphere_start, | ||
const vec3d * | sphere_end, | ||
float | sphere_r | ||
) |
Culls polyfaces which moving sphere can not intersect
Polygon face is characterized by a center and a radius. This routine checks whether it is impossible for a moving sphere to intersect a fixed polygon face.
poly_center | center of polygon face to test |
poly_r | radius of polygon face in question |
sphere_start | start point of moving sphere |
sphere_end | end point of moving sphere |
sphere_r | radius of moving sphere |
int fvi_polyedge_sphereline | ( | vec3d * | hit_point, |
const vec3d * | xs0, | ||
const vec3d * | vs, | ||
float | Rs, | ||
int | nv, | ||
vec3d const *const * | verts, | ||
float * | hit_time | ||
) |
Given a polygon vertex list and a moving sphere, find the first contact the sphere makes with the edge, if any
hit_point | point on edge |
xs0 | starting point for sphere |
vs | sphere velocity |
Rs | sphere radius |
nv | number of vertices |
verts | vertices making up polygon edges |
hit_time | time the sphere hits an edge |
int fvi_ray_boundingbox | ( | const vec3d * | min, |
const vec3d * | max, | ||
const vec3d * | p0, | ||
const vec3d * | pdir, | ||
vec3d * | hitpt | ||
) |
Finds intersection of a ray and an axis-aligned bounding box
Given a ray with origin at p0, and direction pdir, this function returns non-zero if that ray intersects an axis-aligned bounding box from min to max. If there was an intersection, then hitpt will contain the point where the ray begins inside the box. Fast ray-box intersection taken from Graphics Gems I, pages 395,736.
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 | ||
) |
Finds the point on the specified plane where the infinite ray intersects.
new_pnt | A point to test |
plane_pnt | Plane description, a point |
plane_norm | Plane description, a normal |
ray_origin | Ray description, an origin |
ray_direction | Ray description, a direction |
rad | Radius |
Returns scaled-distance plane is from the ray_origin (t), so P = O + t*D, where P is the point of intersection, O is the ray origin, and D is the ray's direction. So 0.0 would mean the intersection is exactly on the ray origin, 1.0 would be on the ray origin plus the ray direction vector, anything negative would be behind the ray's origin. If you pass a pointer to the new_pnt, this routine will perform the P= calculation to calculate the point of intersection and put the result in *new_pnt.
If radius is anything other than 0.0, it assumes you want the intersection point to be that radius from the plane.
Note that ray_direction doesn't have to be normalized unless you want the return value to be in units from the ray origin.
Also note that new_pnt will always be filled in to some valid value, even if it is a point at infinity.
If the plane and line are parallel, this will return the largest negative float number possible.
So if you want to check a line segment from p0 to p1, you would pass p0 as ray_origin, p1-p0 as the ray_direction, and there would be an intersection if the return value is between 0 and 1.
int fvi_segment_plane | ( | vec3d * | new_pnt, |
const vec3d * | plane_pnt, | ||
const vec3d * | plane_norm, | ||
const vec3d * | p0, | ||
const vec3d * | p1, | ||
float | rad | ||
) |
Find the point on the specified plane where the line intersects
new_pnt | The found point on the plane |
plane_pnt | Plane description, a point |
plane_norm | Plane description, a normal |
p0 | The first end of the line |
p1 | The second end of the line |
rad | Radius |
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 | ||
) |
Returns whether a sphere hits and edge for the case the edge is perpendicular to sphere_velocity If two collisions occur, returns the earliest legal time returns the intersection point on the edge
intersect_point | position on plane where sphere makes first contact [RESULT] |
sphere_center_start | initial sphere center |
sphere_velocity | initial sphere velocity |
sphere_radius | radius of sphere |
edge_point1 | first edge point |
edge_point2 | second edge point |
collide_time | actual time of the collision |
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 | ||
) |
Returns whether a sphere hits a given plane in the time [0,1] If two collisions occur, returns earliest legal time returns the intersection point on the plane
intersect_point | position on plane where sphere makes first contact [if hit_time in range 0-1] |
sphere_center_start | initial sphere center |
sphere_velocity | initial sphere velocity |
sphere_radius | radius of sphere |
plane_normal | normal to the colliding plane |
plane_point | point in the colliding plane |
hit_time | time surface of sphere first hits plane |
crossing_time | time for sphere to cross plane (first to last contact) |
int project_point_onto_bbox | ( | const vec3d * | mins, |
const vec3d * | maxs, | ||
const vec3d * | start, | ||
vec3d * | box_pt | ||
) |
Project point on bounding box
NOTE: if a coordinate of start is inside the bbox, it is not moved to surface of bbox
mins | minimum extents of bbox |
maxs | maximum extents of bbox |
start | point in bbox reference frame |
box_pt | point in bbox reference frame. |