/* * Copyright (c), Recep Aslantas. * * MIT License (MIT), http://opensource.org/licenses/MIT * Full license can be found in the LICENSE file */ #ifndef cglms_boxs_h #define cglms_boxs_h #include "../common.h" #include "../types-struct.h" #include "../box.h" #include "vec3.h" #include "vec4.h" #include "mat4.h" /*! * @brief apply transform to Axis-Aligned Bounding Box * * @param[in] box bounding box * @param[in] m transform matrix * @param[out] dest transformed bounding box */ CGLM_INLINE void glms_aabb_transform(vec3s box[2], mat4s m, vec3s dest[2]) { vec3 rawBox[2]; vec3 rawDest[2]; glms_vec3_unpack(rawBox, box, 2); glm_aabb_transform(rawBox, m.raw, rawDest); glms_vec3_pack(dest, rawDest, 2); } /*! * @brief merges two AABB bounding box and creates new one * * two box must be in same space, if one of box is in different space then * you should consider to convert it's space by glm_box_space * * @param[in] box1 bounding box 1 * @param[in] box2 bounding box 2 * @param[out] dest merged bounding box */ CGLM_INLINE void glms_aabb_merge(vec3s box1[2], vec3s box2[2], vec3s dest[2]) { vec3 rawBox1[2]; vec3 rawBox2[2]; vec3 rawDest[2]; glms_vec3_unpack(rawBox1, box1, 2); glms_vec3_unpack(rawBox2, box2, 2); glm_aabb_merge(rawBox1, rawBox2, rawDest); glms_vec3_pack(dest, rawDest, 2); } /*! * @brief crops a bounding box with another one. * * this could be useful for gettng a bbox which fits with view frustum and * object bounding boxes. In this case you crop view frustum box with objects * box * * @param[in] box bounding box 1 * @param[in] cropBox crop box * @param[out] dest cropped bounding box */ CGLM_INLINE void glms_aabb_crop(vec3s box[2], vec3s cropBox[2], vec3s dest[2]) { vec3 rawBox[2]; vec3 rawCropBox[2]; vec3 rawDest[2]; glms_vec3_unpack(rawBox, box, 2); glms_vec3_unpack(rawCropBox, cropBox, 2); glm_aabb_crop(rawBox, rawCropBox, rawDest); glms_vec3_pack(dest, rawDest, 2); } /*! * @brief crops a bounding box with another one. * * this could be useful for gettng a bbox which fits with view frustum and * object bounding boxes. In this case you crop view frustum box with objects * box * * @param[in] box bounding box * @param[in] cropBox crop box * @param[in] clampBox miniumum box * @param[out] dest cropped bounding box */ CGLM_INLINE void glms_aabb_crop_until(vec3s box[2], vec3s cropBox[2], vec3s clampBox[2], vec3s dest[2]) { glms_aabb_crop(box, cropBox, dest); glms_aabb_merge(clampBox, dest, dest); } /*! * @brief check if AABB intersects with frustum planes * * this could be useful for frustum culling using AABB. * * OPTIMIZATION HINT: * if planes order is similar to LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR * then this method should run even faster because it would only use two * planes if object is not inside the two planes * fortunately cglm extracts planes as this order! just pass what you got! * * @param[in] box bounding box * @param[in] planes frustum planes */ CGLM_INLINE bool glms_aabb_frustum(vec3s box[2], vec4s planes[6]) { vec3 rawBox[2]; vec4 rawPlanes[6]; glms_vec3_unpack(rawBox, box, 2); glms_vec4_unpack(rawPlanes, planes, 6); return glm_aabb_frustum(rawBox, rawPlanes); } /*! * @brief invalidate AABB min and max values * * @param[in, out] box bounding box */ CGLM_INLINE void glms_aabb_invalidate(vec3s box[2]) { box[0] = glms_vec3_broadcast(FLT_MAX); box[1] = glms_vec3_broadcast(-FLT_MAX); } /*! * @brief check if AABB is valid or not * * @param[in] box bounding box */ CGLM_INLINE bool glms_aabb_isvalid(vec3s box[2]) { vec3 rawBox[2]; glms_vec3_unpack(rawBox, box, 2); return glm_aabb_isvalid(rawBox); } /*! * @brief distance between of min and max * * @param[in] box bounding box */ CGLM_INLINE float glms_aabb_size(vec3s box[2]) { return glm_vec3_distance(box[0].raw, box[1].raw); } /*! * @brief radius of sphere which surrounds AABB * * @param[in] box bounding box */ CGLM_INLINE float glms_aabb_radius(vec3s box[2]) { return glms_aabb_size(box) * 0.5f; } /*! * @brief computes center point of AABB * * @param[in] box bounding box * @returns center of bounding box */ CGLM_INLINE vec3s glms_aabb_center(vec3s box[2]) { return glms_vec3_center(box[0], box[1]); } /*! * @brief check if two AABB intersects * * @param[in] box bounding box * @param[in] other other bounding box */ CGLM_INLINE bool glms_aabb_aabb(vec3s box[2], vec3s other[2]) { vec3 rawBox[2]; vec3 rawOther[2]; glms_vec3_unpack(rawBox, box, 2); glms_vec3_unpack(rawOther, other, 2); return glm_aabb_aabb(rawBox, rawOther); } /*! * @brief check if AABB intersects with sphere * * https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c * Solid Box - Solid Sphere test. * * @param[in] box solid bounding box * @param[in] s solid sphere */ CGLM_INLINE bool glms_aabb_sphere(vec3s box[2], vec4s s) { vec3 rawBox[2]; glms_vec3_unpack(rawBox, box, 2); return glm_aabb_sphere(rawBox, s.raw); } /*! * @brief check if point is inside of AABB * * @param[in] box bounding box * @param[in] point point */ CGLM_INLINE bool glms_aabb_point(vec3s box[2], vec3s point) { vec3 rawBox[2]; glms_vec3_unpack(rawBox, box, 2); return glm_aabb_point(rawBox, point.raw); } /*! * @brief check if AABB contains other AABB * * @param[in] box bounding box * @param[in] other other bounding box */ CGLM_INLINE bool glms_aabb_contains(vec3s box[2], vec3s other[2]) { vec3 rawBox[2]; vec3 rawOther[2]; glms_vec3_unpack(rawBox, box, 2); glms_vec3_unpack(rawOther, other, 2); return glm_aabb_contains(rawBox, rawOther); } #endif /* cglms_boxs_h */