From 8b2c74b0cc8e29c989fe989ce331d6cb782267fd Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 18 Jan 2018 16:36:58 +0300 Subject: [PATCH] bounding box --- LICENSE | 5 ++ include/cglm/box.h | 123 +++++++++++++++++++++++++++++++++++++++ include/cglm/call.h | 1 + include/cglm/call/box.h | 39 +++++++++++++ include/cglm/cglm.h | 1 + makefile.am | 9 ++- src/box.c | 36 ++++++++++++ win/cglm.vcxproj | 3 + win/cglm.vcxproj.filters | 9 +++ 9 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 include/cglm/box.h create mode 100644 include/cglm/call/box.h create mode 100644 src/box.c diff --git a/LICENSE b/LICENSE index 2367e77..4e2f7f6 100644 --- a/LICENSE +++ b/LICENSE @@ -58,3 +58,8 @@ Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix Authors: Gil Gribb (ggribb@ravensoft.com) Klaus Hartmann (k_hartmann@osnabrueck.netsurf.de) + +5. Transform AABB +Transform Axis Aligned Bounding Boxes: +http://dev.theomader.com/transform-bounding-boxes/ +https://github.com/erich666/GraphicsGems/blob/master/gems/TransBox.c diff --git a/include/cglm/box.h b/include/cglm/box.h new file mode 100644 index 0000000..892b60c --- /dev/null +++ b/include/cglm/box.h @@ -0,0 +1,123 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_box_h +#define cglm_box_h + +#include "common.h" +#include "vec3.h" +#include "vec4.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 +glm_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2]) { + vec3 v[2], xa, xb, ya, yb, za, zb, tmp; + + glm_vec_scale(m[0], box[0][0], xa); + glm_vec_scale(m[0], box[1][0], xb); + + glm_vec_scale(m[1], box[0][1], ya); + glm_vec_scale(m[1], box[1][1], yb); + + glm_vec_scale(m[2], box[0][2], za); + glm_vec_scale(m[2], box[1][2], zb); + + /* min(xa, xb) + min(ya, yb) + min(za, zb) + translation */ + glm_vec_minv(xa, xb, v[0]); + glm_vec_minv(ya, yb, tmp); + glm_vec_add(v[0], tmp, v[0]); + glm_vec_minv(za, zb, tmp); + glm_vec_add(v[0], tmp, v[0]); + glm_vec_add(v[0], m[3], v[0]); + + /* max(xa, xb) + max(ya, yb) + max(za, zb) + translation */ + glm_vec_maxv(xa, xb, v[1]); + glm_vec_maxv(ya, yb, tmp); + glm_vec_add(v[1], tmp, v[1]); + glm_vec_maxv(za, zb, tmp); + glm_vec_add(v[1], tmp, v[1]); + glm_vec_add(v[1], m[3], v[1]); + + glm_vec_copy(v[0], dest[0]); + glm_vec_copy(v[1], dest[1]); +} + +/*! + * @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 +glm_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2]) { + dest[0][0] = glm_min(box1[0][0], box2[0][0]); + dest[0][1] = glm_min(box1[0][1], box2[0][1]); + dest[0][2] = glm_min(box1[0][2], box2[0][2]); + + dest[1][0] = glm_max(box1[1][0], box2[1][0]); + dest[1][1] = glm_max(box1[1][1], box2[1][1]); + dest[1][2] = glm_max(box1[1][2], box2[1][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 +glm_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2]) { + dest[0][0] = glm_max(box[0][0], cropBox[0][0]); + dest[0][1] = glm_max(box[0][1], cropBox[0][1]); + dest[0][2] = glm_max(box[0][2], cropBox[0][2]); + + dest[1][0] = glm_min(box[1][0], cropBox[1][0]); + dest[1][1] = glm_min(box[1][1], cropBox[1][1]); + dest[1][2] = glm_min(box[1][2], cropBox[1][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 +glm_aabb_crop_until(vec3 box[2], + vec3 cropBox[2], + vec3 clampBox[2], + vec3 dest[2]) { + glm_aabb_crop(box, cropBox, dest); + glm_aabb_merge(clampBox, dest, dest); +} + +#endif /* cglm_box_h */ diff --git a/include/cglm/call.h b/include/cglm/call.h index 00eb13c..3f7bf14 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -22,6 +22,7 @@ extern "C" { #include "call/euler.h" #include "call/plane.h" #include "call/frustum.h" +#include "call/box.h" #include "call/io.h" #ifdef __cplusplus diff --git a/include/cglm/call/box.h b/include/cglm/call/box.h new file mode 100644 index 0000000..505732e --- /dev/null +++ b/include/cglm/call/box.h @@ -0,0 +1,39 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_box_h +#define cglmc_box_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" + +CGLM_EXPORT +void +glmc_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2]); + +CGLM_EXPORT +void +glmc_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2]); + +CGLM_EXPORT +void +glmc_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2]); + +CGLM_EXPORT +void +glmc_aabb_crop_until(vec3 box[2], + vec3 cropBox[2], + vec3 clampBox[2], + vec3 dest[2]); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_box_h */ + diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index e9fa774..3b0611c 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -19,6 +19,7 @@ #include "quat.h" #include "euler.h" #include "plane.h" +#include "box.h" #include "util.h" #include "io.h" diff --git a/makefile.am b/makefile.am index 5cfbd6f..4226f4b 100644 --- a/makefile.am +++ b/makefile.am @@ -52,7 +52,8 @@ cglm_HEADERS = include/cglm/version.h \ include/cglm/quat.h \ include/cglm/affine-mat.h \ include/cglm/plane.h \ - include/cglm/frustum.h + include/cglm/frustum.h \ + include/cglm/box.h cglm_calldir=$(includedir)/cglm/call cglm_call_HEADERS = include/cglm/call/mat4.h \ @@ -65,7 +66,8 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \ include/cglm/call/quat.h \ include/cglm/call/euler.h \ include/cglm/call/plane.h \ - include/cglm/call/frustum.h + include/cglm/call/frustum.h \ + include/cglm/call/box.h cglm_simddir=$(includedir)/cglm/simd cglm_simd_HEADERS = include/cglm/simd/intrin.h @@ -94,7 +96,8 @@ libcglm_la_SOURCES=\ src/mat3.c \ src/mat4.c \ src/plane.c \ - src/frustum.c + src/frustum.c \ + src/box.c test_tests_SOURCES=\ test/src/test_common.c \ diff --git a/src/box.c b/src/box.c new file mode 100644 index 0000000..2311f4b --- /dev/null +++ b/src/box.c @@ -0,0 +1,36 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "../include/cglm/cglm.h" +#include "../include/cglm/call.h" + +CGLM_EXPORT +void +glmc_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2]) { + glm_aabb_transform(box, m, dest); +} + +CGLM_EXPORT +void +glmc_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2]) { + glm_aabb_merge(box1, box2, dest); +} + +CGLM_EXPORT +void +glmc_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2]) { + glm_aabb_crop(box, cropBox, dest); +} + +CGLM_EXPORT +void +glmc_aabb_crop_until(vec3 box[2], + vec3 cropBox[2], + vec3 clampBox[2], + vec3 dest[2]) { + glm_aabb_crop_until(box, cropBox, clampBox, dest); +} diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index 93d9e9b..36000c0 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -20,6 +20,7 @@ + @@ -35,8 +36,10 @@ + + diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index 5ea5810..559f2f7 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -72,6 +72,9 @@ src + + src + @@ -194,5 +197,11 @@ include\cglm + + include\cglm\call + + + include\cglm + \ No newline at end of file