diff --git a/code/game/bg_misc.c b/code/game/bg_misc.c index 5ef0eda..4e8a5b6 100644 --- a/code/game/bg_misc.c +++ b/code/game/bg_misc.c @@ -1848,3 +1848,58 @@ char *EndWord(char *pos) return pos; } + +void BG_PrepareRay(bgRay_t* ray, vec3_t origin, vec3_t dir) { + if(ray == NULL) { + return; + } + + VectorCopy(origin, ray->origin); + VectorCopy(dir, ray->direction); + VectorCopy(dir, ray->inverse_direction); + VectorInverse(ray->inverse_direction); + + ray->sign[0] = (ray->inverse_direction[0] < 0); + ray->sign[1] = (ray->inverse_direction[1] < 0); + ray->sign[2] = (ray->inverse_direction[2] < 0); +} + +int BG_RayIntersect(bgRay_t* ray, bgBBox_t* bbox) { + double tmin = 0.0; + double tmax = 0.0; + double tymin = 0.0; + double tymax = 0.0; + double tzmin = 0.0; + double tzmax = 0.0; + + if(ray == NULL || bbox == NULL) { + return 0; + } + + tmin = (bbox->bounds[ray->sign[0]][0] - ray->origin[0]) * ray->inverse_direction[0]; + tmax = (bbox->bounds[1 - ray->sign[0]][0] - ray->origin[0]) * ray->inverse_direction[0]; + tymin = (bbox->bounds[ray->sign[1]][1] - ray->origin[1]) * ray->inverse_direction[1]; + tymax = (bbox->bounds[1 - ray->sign[1]][1] - ray->origin[1]) * ray->inverse_direction[1]; + + if((tmin > tymax) || (tymin > tmax)) { + return 0; + } + + if(tymin > tmin) { + tmin = tymin; + } + + if(tymax < tmax) { + tmax = tymax; + } + + tzmin = (bbox->bounds[ray->sign[2]][2] - ray->origin[2]) * ray->inverse_direction[2]; + tzmax = (bbox->bounds[1 - ray->sign[2]][2] - ray->origin[2]) * ray->inverse_direction[2]; + + if((tmin > tzmax) || (tzmin > tmax)) { + return 0; + } + + return 1; +} + diff --git a/code/game/bg_misc.h b/code/game/bg_misc.h index 0c575d1..a227879 100644 --- a/code/game/bg_misc.h +++ b/code/game/bg_misc.h @@ -1,7 +1,37 @@ #ifndef _BG_MISC_H #define _BG_MISC_H +#include "q_shared.h" + void BG_LanguageFilename(char *baseName,char *baseExtension,char *finalName); char* BG_RegisterRace( const char *name ); +typedef struct bgRay_s bgRay_t; +struct bgRay_s { + vec3_t origin; + vec3_t direction; + vec3_t inverse_direction; + int sign[3]; +}; + +/** + * @brief Prepares a ray with a given origin and direction. + * @param ray The ray. + * @param origin The origin. + * @param dir The direction. + */ +void BG_PrepareRay(bgRay_t* ray, vec3_t origin, vec3_t dir); + +typedef struct bgBBox_s bgBBox_t; +struct bgBBox_s { + vec3_t bounds[2]; +}; + +/** + * @brief Checks is a given ray intersects with a given bounding box. + * @param ray The ray. + * @param bbox The bounding box. + */ +int BG_RayIntersect(bgRay_t* ray, bgBBox_t* bbox); + #endif /* _BG_MISC_H */ \ No newline at end of file