aabb2d functions

This commit is contained in:
duarm
2023-11-11 08:13:28 -03:00
parent 58a4b47830
commit 53bde05bd9
8 changed files with 889 additions and 0 deletions

269
include/cglm/aabb2d.h Normal file
View File

@@ -0,0 +1,269 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_aabb2d_h
#define cglm_aabb2d_h
#include "common.h"
#include "vec2.h"
#include "vec4.h"
#include "util.h"
/*!
* @brief apply transform to Axis-Aligned Bounding aabb
*
* @param[in] aabb bounding aabb
* @param[in] m transform matrix
* @param[out] dest transformed bounding aabb
*/
CGLM_INLINE
void
glm_aabb2d_transform(vec2 aabb[2], mat4 m, vec2 dest[2]) {
vec2 v[2], xa, xb, ya, yb, za, zb;
glm_vec2_scale(m[0], aabb[0][0], xa);
glm_vec2_scale(m[0], aabb[1][0], xb);
glm_vec2_scale(m[1], aabb[0][1], ya);
glm_vec2_scale(m[1], aabb[1][1], yb);
/* translation + min(xa, xb) + min(ya, yb) + min(za, zb) */
glm_vec2(m[3], v[0]);
glm_vec2_minadd(xa, xb, v[0]);
glm_vec2_minadd(ya, yb, v[0]);
glm_vec2_minadd(za, zb, v[0]);
/* translation + max(xa, xb) + max(ya, yb) + max(za, zb) */
glm_vec2(m[3], v[1]);
glm_vec2_maxadd(xa, xb, v[1]);
glm_vec2_maxadd(ya, yb, v[1]);
glm_vec2_maxadd(za, zb, v[1]);
glm_vec2_copy(v[0], dest[0]);
glm_vec2_copy(v[1], dest[1]);
}
/*!
* @brief merges two AABB bounding aabb and creates new one
*
* two aabb must be in same space, if one of aabb is in different space then
* you should consider to convert it's space by glm_aabb_space
*
* @param[in] aabb1 bounding aabb 1
* @param[in] aabb2 bounding aabb 2
* @param[out] dest merged bounding aabb
*/
CGLM_INLINE
void
glm_aabb2d_merge(vec2 aabb1[2], vec2 aabb2[2], vec2 dest[2]) {
dest[0][0] = glm_min(aabb1[0][0], aabb2[0][0]);
dest[0][1] = glm_min(aabb1[0][1], aabb2[0][1]);
dest[1][0] = glm_max(aabb1[1][0], aabb2[1][0]);
dest[1][1] = glm_max(aabb1[1][1], aabb2[1][1]);
}
/*!
* @brief crops a bounding aabb with another one.
*
* this could be useful for gettng a baabb which fits with view frustum and
* object bounding aabbes. In this case you crop view frustum aabb with objects
* aabb
*
* @param[in] aabb bounding aabb 1
* @param[in] cropaabb crop aabb
* @param[out] dest cropped bounding aabb
*/
CGLM_INLINE
void
glm_aabb2d_crop(vec2 aabb[2], vec2 cropAabb[2], vec2 dest[2]) {
dest[0][0] = glm_max(aabb[0][0], cropAabb[0][0]);
dest[0][1] = glm_max(aabb[0][1], cropAabb[0][1]);
dest[1][0] = glm_min(aabb[1][0], cropAabb[1][0]);
dest[1][1] = glm_min(aabb[1][1], cropAabb[1][1]);
}
/*!
* @brief crops a bounding aabb with another one.
*
* this could be useful for gettng a baabb which fits with view frustum and
* object bounding aabbes. In this case you crop view frustum aabb with objects
* aabb
*
* @param[in] aabb bounding aabb
* @param[in] cropaabb crop aabb
* @param[in] clampaabb miniumum aabb
* @param[out] dest cropped bounding aabb
*/
CGLM_INLINE
void
glm_aabb2d_crop_until(vec2 aabb[2],
vec2 cropAabb[2],
vec2 clampAabb[2],
vec2 dest[2]) {
glm_aabb2d_crop(aabb, cropAabb, dest);
glm_aabb2d_merge(clampAabb, 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] aabb bounding aabb
* @param[in] planes frustum planes
*/
CGLM_INLINE
bool
glm_aabb2d_frustum(vec2 aabb[2], vec4 planes[6]) {
float *p, dp;
int i;
for (i = 0; i < 6; i++) {
p = planes[i];
dp = p[0] * aabb[p[0] > 0.0f][0]
+ p[1] * aabb[p[1] > 0.0f][1];
if (dp < -p[3])
return false;
}
return true;
}
/*!
* @brief invalidate AABB min and max values
*
* @param[in, out] aabb bounding aabb
*/
CGLM_INLINE
void
glm_aabb2d_invalidate(vec2 aabb[2]) {
glm_vec2_fill(aabb[0], FLT_MAX);
glm_vec2_fill(aabb[1], -FLT_MAX);
}
/*!
* @brief check if AABB is valid or not
*
* @param[in] aabb bounding aabb
*/
CGLM_INLINE
bool
glm_aabb2d_isvalid(vec2 aabb[2]) {
return glm_vec2_max(aabb[0]) != FLT_MAX
&& glm_vec2_min(aabb[1]) != -FLT_MAX;
}
/*!
* @brief distance between of min and max
*
* @param[in] aabb bounding aabb
*/
CGLM_INLINE
float
glm_aabb2d_size(vec2 aabb[2]) {
return glm_vec2_distance(aabb[0], aabb[1]);
}
/*!
* @brief radius of sphere which surrounds AABB
*
* @param[in] aabb bounding aabb
*/
CGLM_INLINE
float
glm_aabb2d_radius(vec2 aabb[2]) {
return glm_aabb2d_size(aabb) * 0.5f;
}
/*!
* @brief computes center point of AABB
*
* @param[in] aabb bounding aabb
* @param[out] dest center of bounding aabb
*/
CGLM_INLINE
void
glm_aabb2d_center(vec2 aabb[2], vec2 dest) {
glm_vec2_center(aabb[0], aabb[1], dest);
}
/*!
* @brief check if two AABB intersects
*
* @param[in] aabb bounding aabb
* @param[in] other other bounding aabb
*/
CGLM_INLINE
bool
glm_aabb2d_aabb(vec2 aabb[2], vec2 other[2]) {
return (aabb[0][0] <= other[1][0] && aabb[1][0] >= other[0][0])
&& (aabb[0][1] <= other[1][1] && aabb[1][1] >= other[0][1]);
}
/*!
* @brief check if AABB intersects with sphere
*
* https://github.com/erich666/GraphicsGems/blob/master/gems/aabbSphere.c
* Solid aabb - Solid Sphere test.
*
* Sphere Representation in cglm: [center.x, center.y, center.z, radii]
*
* @param[in] aabb solid bounding aabb
* @param[in] s solid sphere
*/
CGLM_INLINE
bool
glm_aabb2d_sphere(vec2 aabb[2], vec4 s) {
float dmin;
int a, b;
a = (s[0] < aabb[0][0]) + (s[0] > aabb[1][0]);
b = (s[1] < aabb[0][1]) + (s[1] > aabb[1][1]);
dmin = glm_pow2((s[0] - aabb[!(a - 1)][0]) * (a != 0))
+ glm_pow2((s[1] - aabb[!(b - 1)][1]) * (b != 0));
return dmin <= glm_pow2(s[3]);
}
/*!
* @brief check if point is inside of AABB
*
* @param[in] aabb bounding aabb
* @param[in] point point
*/
CGLM_INLINE
bool
glm_aabb2d_point(vec2 aabb[2], vec2 point) {
return (point[0] >= aabb[0][0] && point[0] <= aabb[1][0])
&& (point[1] >= aabb[0][1] && point[1] <= aabb[1][1]);
}
/*!
* @brief check if AABB contains other AABB
*
* @param[in] aabb bounding aabb
* @param[in] other other bounding aabb
*/
CGLM_INLINE
bool
glm_aabb2d_contains(vec2 aabb[2], vec2 other[2]) {
return (aabb[0][0] <= other[0][0] && aabb[1][0] >= other[1][0])
&& (aabb[0][1] <= other[0][1] && aabb[1][1] >= other[1][1]);
}
#endif /* cglm_aabb2d_h */

View File

@@ -33,6 +33,7 @@ extern "C" {
#include "call/euler.h"
#include "call/plane.h"
#include "call/frustum.h"
#include "call/aabb2d.h"
#include "call/box.h"
#include "call/io.h"
#include "call/project.h"

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_aabb2d_h
#define cglmc_aabb2d_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_aabb2d_transform(vec2 aabb[2], mat4 m, vec2 dest[2]);
CGLM_EXPORT
void
glmc_aabb2d_merge(vec2 aabb1[2], vec2 aabb2[2], vec2 dest[2]);
CGLM_EXPORT
void
glmc_aabb2d_crop(vec2 aabb[2], vec2 cropAabb[2], vec2 dest[2]);
CGLM_EXPORT
void
glmc_aabb2d_crop_until(vec2 aabb[2],
vec2 cropAabb[2],
vec2 clampAabb[2],
vec2 dest[2]);
CGLM_EXPORT
bool
glmc_aabb2d_frustum(vec2 aabb[2], vec4 planes[6]);
CGLM_EXPORT
void
glmc_aabb2d_invalidate(vec2 aabb[2]);
CGLM_EXPORT
bool
glmc_aabb2d_isvalid(vec2 aabb[2]);
CGLM_EXPORT
float
glmc_aabb2d_size(vec2 aabb[2]);
CGLM_EXPORT
float
glmc_aabb2d_radius(vec2 aabb[2]);
CGLM_EXPORT
void
glmc_aabb2d_center(vec2 aabb[2], vec2 dest);
CGLM_EXPORT
bool
glmc_aabb2d_aabb(vec2 aabb[2], vec2 other[2]);
CGLM_EXPORT
bool
glmc_aabb2d_point(vec2 aabb[2], vec2 point);
CGLM_EXPORT
bool
glmc_aabb2d_contains(vec2 aabb[2], vec2 other[2]);
CGLM_EXPORT
bool
glmc_aabb2d_sphere(vec2 aabb[2], vec4 s);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_aabb2d_h */

View File

@@ -30,6 +30,7 @@
#include "quat.h"
#include "euler.h"
#include "plane.h"
#include "aabb2d.h"
#include "box.h"
#include "color.h"
#include "util.h"

View File

@@ -0,0 +1,260 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_aabb2ds_h
#define cglms_aabb2ds_h
#include "../common.h"
#include "../types-struct.h"
#include "../aabb2d.h"
#include "vec2.h"
#include "vec4.h"
#include "mat4.h"
/* api definition */
#define glms_aabb2d_(NAME) CGLM_STRUCTAPI(aabb, NAME)
/*!
* @brief apply transform to Axis-Aligned Bounding Box
*
* @param[in] aabb bounding box
* @param[in] m transform matrix
* @param[out] dest transformed bounding box
*/
CGLM_INLINE
void
glms_aabb2d_(transform)(vec2s aabb[2], mat4s m, vec2s dest[2]) {
vec2 rawAabb[2];
vec2 rawDest[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
glm_aabb2d_transform(rawAabb, m.raw, rawDest);
glms_vec2_(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] aabb1 bounding box 1
* @param[in] aabb2 bounding box 2
* @param[out] dest merged bounding box
*/
CGLM_INLINE
void
glms_aabb2d_(merge)(vec2s aabb1[2], vec2s aabb2[2], vec2s dest[2]) {
vec2 rawAabb1[2];
vec2 rawAabb2[2];
vec2 rawDest[2];
glms_vec2_(unpack)(rawAabb1, aabb1, 2);
glms_vec2_(unpack)(rawAabb2, aabb2, 2);
glm_aabb2d_merge(rawAabb1, rawAabb2, rawDest);
glms_vec2_(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] aabb bounding box 1
* @param[in] cropAabb crop box
* @param[out] dest cropped bounding box
*/
CGLM_INLINE
void
glms_aabb2d_(crop)(vec2s aabb[2], vec2s cropAabb[2], vec2s dest[2]) {
vec2 rawAabb[2];
vec2 rawCropAabb[2];
vec2 rawDest[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
glms_vec2_(unpack)(rawCropAabb, cropAabb, 2);
glm_aabb2d_crop(rawAabb, rawCropAabb, rawDest);
glms_vec2_(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] aabb bounding box
* @param[in] cropAabb crop box
* @param[in] clampAabb miniumum box
* @param[out] dest cropped bounding box
*/
CGLM_INLINE
void
glms_aabb2d_(crop_until)(vec2s aabb[2],
vec2s cropAabb[2],
vec2s clampAabb[2],
vec2s dest[2]) {
glms_aabb2d_(crop)(aabb, cropAabb, dest);
glms_aabb2d_(merge)(clampAabb, 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] aabb bounding box
* @param[in] planes frustum planes
*/
CGLM_INLINE
bool
glms_aabb2d_(frustum)(vec2s box[2], vec4s planes[6]) {
vec2 rawBox[2];
vec4 rawPlanes[6];
glms_vec2_(unpack)(rawBox, box, 2);
glms_vec4_(unpack)(rawPlanes, planes, 6);
return glm_aabb2d_frustum(rawBox, rawPlanes);
}
/*!
* @brief invalidate AABB min and max values
*
* @param[in, out] aabb bounding box
*/
CGLM_INLINE
void
glms_aabb2d_(invalidate)(vec2s box[2]) {
box[0] = glms_vec2_(fill)(FLT_MAX);
box[1] = glms_vec2_(fill)(-FLT_MAX);
}
/*!
* @brief check if AABB is valid or not
*
* @param[in] aabb bounding box
*/
CGLM_INLINE
bool
glms_aabb2d_(isvalid)(vec2s aabb[2]) {
vec2 rawAabb[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
return glm_aabb2d_isvalid(rawAabb);
}
/*!
* @brief distance between of min and max
*
* @param[in] aabb bounding box
*/
CGLM_INLINE
float
glms_aabb2d_(size)(vec2s aabb[2]) {
return glm_vec2_distance(aabb[0].raw, aabb[1].raw);
}
/*!
* @brief radius of sphere which surrounds AABB
*
* @param[in] aabb bounding box
*/
CGLM_INLINE
float
glms_aabb2d_(radius)(vec2s aabb[2]) {
return glms_aabb2d_(size)(aabb) * 0.5f;
}
/*!
* @brief computes center point of AABB
*
* @param[in] aabb bounding box
* @returns center of bounding box
*/
CGLM_INLINE
vec2s
glms_aabb2d_(center)(vec2s aabb[2]) {
return glms_vec2_(center)(aabb[0], aabb[1]);
}
/*!
* @brief check if two AABB intersects
*
* @param[in] aabb bounding box
* @param[in] other other bounding box
*/
CGLM_INLINE
bool
glms_aabb2d_(aabb)(vec2s aabb[2], vec2s other[2]) {
vec2 rawAabb[2];
vec2 rawOther[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
glms_vec2_(unpack)(rawOther, other, 2);
return glm_aabb2d_aabb(rawAabb, 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] aabb solid bounding box
* @param[in] s solid sphere
*/
CGLM_INLINE
bool
glms_aabb2d_(sphere)(vec2s aabb[2], vec4s s) {
vec2 rawAabb[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
return glm_aabb2d_sphere(rawAabb, s.raw);
}
/*!
* @brief check if point is inside of AABB
*
* @param[in] aabb bounding box
* @param[in] point point
*/
CGLM_INLINE
bool
glms_aabb2d_(point)(vec2s aabb[2], vec2s point) {
vec2 rawAabb[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
return glm_aabb2d_point(rawAabb, point.raw);
}
/*!
* @brief check if AABB contains other AABB
*
* @param[in] box bounding box
* @param[in] other other bounding box
*/
CGLM_INLINE
bool
glms_aabb2d_(contains)(vec2s aabb[2], vec2s other[2]) {
vec2 rawAabb[2];
vec2 rawOther[2];
glms_vec2_(unpack)(rawAabb, aabb, 2);
glms_vec2_(unpack)(rawOther, other, 2);
return glm_aabb2d_contains(rawAabb, rawOther);
}
#endif /* cglms_aabb2ds_h */