diff --git a/CREDITS b/CREDITS
index 44e55a8..0488bad 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,7 +1,7 @@
This library [initially] used some [piece of] implementations
(may include codes) from these open source projects/resources:
-1. Affine Transforms
+1. Initial Affine Transforms
The original glm repo (g-truc), url: https://github.com/g-truc/glm
LICENSE[S]:
@@ -11,7 +11,7 @@ LICENSE[S]:
FULL LICENSE: https://github.com/g-truc/glm/blob/master/copying.txt
-2. Quaternions
+2. Initial Quaternions
Anton's OpenGL 4 Tutorials book source code:
LICENSE:
@@ -47,6 +47,8 @@ http://old.cescg.org/CESCG-2002/DSykoraJJelinek/
7. Quaternions
Initial mat4_quat is borrowed from Apple's simd library
-
8. Vector Rotation using Quaternion
https://gamedev.stackexchange.com/questions/28395/rotating-vector3-by-a-quaternion
+
+9. Sphere AABB intersect
+https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
diff --git a/configure.ac b/configure.ac
index 6e9c00c..af3a0d9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,7 +7,7 @@
#*****************************************************************************
AC_PREREQ([2.69])
-AC_INIT([cglm], [0.4.6], [info@recp.me])
+AC_INIT([cglm], [0.4.7], [info@recp.me])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_MACRO_DIR([m4])
diff --git a/docs/source/api.rst b/docs/source/api.rst
index c61365b..d0e4721 100644
--- a/docs/source/api.rst
+++ b/docs/source/api.rst
@@ -45,3 +45,4 @@ Follow the :doc:`build` documentation for this
util
io
call
+ sphere
diff --git a/docs/source/box.rst b/docs/source/box.rst
index 6430c64..7a388e2 100644
--- a/docs/source/box.rst
+++ b/docs/source/box.rst
@@ -29,6 +29,10 @@ Functions:
#. :c:func:`glm_aabb_size`
#. :c:func:`glm_aabb_radius`
#. :c:func:`glm_aabb_center`
+#. :c:func:`glm_aabb_aabb`
+#. :c:func:`glm_aabb_sphere`
+#. :c:func:`glm_aabb_point`
+#. :c:func:`glm_aabb_contains`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
@@ -137,6 +141,41 @@ Functions documentation
| computes center point of AABB
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **dest** center of bounding box
+
+.. c:function:: bool glm_aabb_aabb(vec3 box[2], vec3 other[2])
+
+ | check if two AABB intersects
+
Parameters:
| *[in]* **box** bounding box
- | *[out]* **box** center of bounding box
+ | *[out]* **other** other bounding box
+
+.. c:function:: bool glm_aabb_sphere(vec3 box[2], vec4 s)
+
+ | check if AABB intersects with sphere
+
+ | https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
+ | Solid Box - Solid Sphere test.
+
+ Parameters:
+ | *[in]* **box** solid bounding box
+ | *[out]* **s** solid sphere
+
+.. c:function:: bool glm_aabb_point(vec3 box[2], vec3 point)
+
+ | check if point is inside of AABB
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **point** point
+
+.. c:function:: bool glm_aabb_contains(vec3 box[2], vec3 other[2])
+
+ | check if AABB contains other AABB
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **other** other bounding box
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 995e5a2..8bfd1b1 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -62,9 +62,9 @@ author = u'Recep Aslantas'
# built documents.
#
# The short X.Y version.
-version = u'0.4.6'
+version = u'0.4.7'
# The full version, including alpha/beta/rc tags.
-release = u'0.4.6'
+release = u'0.4.7'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/source/sphere.rst b/docs/source/sphere.rst
new file mode 100644
index 0000000..db238f4
--- /dev/null
+++ b/docs/source/sphere.rst
@@ -0,0 +1,74 @@
+.. default-domain:: C
+
+Sphere
+================================================================================
+
+Header: cglm/sphere.h
+
+**Definition of sphere:**
+
+Sphere Representation in cglm is *vec4*: **[center.x, center.y, center.z, radii]**
+
+You can call any vec3 function by pasing sphere. Because first three elements
+defines center of sphere.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_sphere_radii`
+#. :c:func:`glm_sphere_transform`
+#. :c:func:`glm_sphere_merge`
+#. :c:func:`glm_sphere_sphere`
+#. :c:func:`glm_sphere_point`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: float glm_sphere_radii(vec4 s)
+
+ | helper for getting sphere radius
+
+ Parameters:
+ | *[in]* **s** sphere
+
+ Returns:
+ returns radii
+
+.. c:function:: void glm_sphere_transform(vec4 s, mat4 m, vec4 dest)
+
+ | apply transform to sphere, it is just wrapper for glm_mat4_mulv3
+
+ Parameters:
+ | *[in]* **s** sphere
+ | *[in]* **m** transform matrix
+ | *[out]* **dest** transformed sphere
+
+.. c:function:: void glm_sphere_merge(vec4 s1, vec4 s2, vec4 dest)
+
+ | merges two spheres and creates a new one
+
+ two sphere must be in same space, for instance if one in world space then
+ the other must be in world space too, not in local space.
+
+ Parameters:
+ | *[in]* **s1** sphere 1
+ | *[in]* **s2** sphere 2
+ | *[out]* **dest** merged/extended sphere
+
+.. c:function:: bool glm_sphere_sphere(vec4 s1, vec4 s2)
+
+ | check if two sphere intersects
+
+ Parameters:
+ | *[in]* **s1** sphere
+ | *[in]* **s2** other sphere
+
+.. c:function:: bool glm_sphere_point(vec4 s, vec3 point)
+
+ | check if sphere intersects with point
+
+ Parameters:
+ | *[in]* **s** sphere
+ | *[in]* **point** point
diff --git a/docs/source/vec3.rst b/docs/source/vec3.rst
index fcbfbfb..e4a2746 100644
--- a/docs/source/vec3.rst
+++ b/docs/source/vec3.rst
@@ -56,6 +56,7 @@ Functions:
#. :c:func:`glm_vec_inv_to`
#. :c:func:`glm_vec_normalize`
#. :c:func:`glm_vec_normalize_to`
+#. :c:func:`glm_vec_distance2`
#. :c:func:`glm_vec_distance`
#. :c:func:`glm_vec_angle`
#. :c:func:`glm_vec_rotate`
@@ -366,6 +367,17 @@ Functions documentation
| *[in]* **v2** vector2
| *[out]* **dest** center point
+.. c:function:: float glm_vec_distance2(vec3 v1, vec3 v2)
+
+ squared distance between two vectors
+
+ Parameters:
+ | *[in]* **mat** vector1
+ | *[in]* **row1** vector2
+
+ Returns:
+ | squared distance (distance * distance)
+
.. c:function:: float glm_vec_distance(vec3 v1, vec3 v2)
distance between two vectors
diff --git a/include/cglm/box.h b/include/cglm/box.h
index 5ed135e..3708107 100644
--- a/include/cglm/box.h
+++ b/include/cglm/box.h
@@ -212,4 +212,72 @@ glm_aabb_center(vec3 box[2], vec3 dest) {
glm_vec_center(box[0], box[1], dest);
}
+/*!
+ * @brief check if two AABB intersects
+ *
+ * @param[in] box bounding box
+ * @param[in] other other bounding box
+ */
+CGLM_INLINE
+bool
+glm_aabb_aabb(vec3 box[2], vec3 other[2]) {
+ return (box[0][0] <= other[1][0] && box[1][0] >= other[0][0])
+ && (box[0][1] <= other[1][1] && box[1][1] >= other[0][1])
+ && (box[0][2] <= other[1][2] && box[1][2] >= other[0][2]);
+}
+
+/*!
+ * @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
+glm_aabb_sphere(vec3 box[2], vec4 s) {
+ float dmin;
+ int a, b, c;
+
+ a = s[0] >= box[0][0];
+ b = s[1] >= box[0][1];
+ c = s[2] >= box[0][2];
+
+ dmin = glm_pow2(s[0] - box[a][0])
+ + glm_pow2(s[1] - box[b][1])
+ + glm_pow2(s[2] - box[c][2]);
+
+ return dmin <= glm_pow2(s[3]);
+}
+
+/*!
+ * @brief check if point is inside of AABB
+ *
+ * @param[in] box bounding box
+ * @param[in] point point
+ */
+CGLM_INLINE
+bool
+glm_aabb_point(vec3 box[2], vec3 point) {
+ return (point[0] >= box[0][0] && point[0] <= box[1][0])
+ && (point[1] >= box[0][1] && point[1] <= box[1][1])
+ && (point[2] >= box[0][2] && point[2] <= box[1][2]);
+}
+
+/*!
+ * @brief check if AABB contains other AABB
+ *
+ * @param[in] box bounding box
+ * @param[in] other other bounding box
+ */
+CGLM_INLINE
+bool
+glm_aabb_contains(vec3 box[2], vec3 other[2]) {
+ return (box[0][0] <= other[0][0] && box[1][0] >= other[1][0])
+ && (box[0][1] <= other[0][1] && box[1][1] >= other[1][1])
+ && (box[0][2] <= other[0][2] && box[1][2] >= other[1][2]);
+}
+
#endif /* cglm_box_h */
diff --git a/include/cglm/call.h b/include/cglm/call.h
index ce08b78..77148ac 100644
--- a/include/cglm/call.h
+++ b/include/cglm/call.h
@@ -25,6 +25,7 @@ extern "C" {
#include "call/box.h"
#include "call/io.h"
#include "call/project.h"
+#include "call/sphere.h"
#ifdef __cplusplus
}
diff --git a/include/cglm/call/box.h b/include/cglm/call/box.h
index bf25508..afb7558 100644
--- a/include/cglm/call/box.h
+++ b/include/cglm/call/box.h
@@ -56,6 +56,22 @@ CGLM_EXPORT
void
glmc_aabb_center(vec3 box[2], vec3 dest);
+CGLM_EXPORT
+bool
+glmc_aabb_aabb(vec3 box[2], vec3 other[2]);
+
+CGLM_EXPORT
+bool
+glmc_aabb_point(vec3 box[2], vec3 point);
+
+CGLM_EXPORT
+bool
+glmc_aabb_contains(vec3 box[2], vec3 other[2]);
+
+CGLM_EXPORT
+bool
+glmc_aabb_sphere(vec3 box[2], vec4 s);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/cglm/call/sphere.h b/include/cglm/call/sphere.h
new file mode 100644
index 0000000..02c3d55
--- /dev/null
+++ b/include/cglm/call/sphere.h
@@ -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
+ */
+
+#ifndef cglmc_sphere_h
+#define cglmc_sphere_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../cglm.h"
+
+CGLM_EXPORT
+float
+glmc_sphere_radii(vec4 s);
+
+CGLM_EXPORT
+void
+glmc_sphere_transform(vec4 s, mat4 m, vec4 dest);
+
+CGLM_EXPORT
+void
+glmc_sphere_merge(vec4 s1, vec4 s2, vec4 dest);
+
+CGLM_EXPORT
+bool
+glmc_sphere_sphere(vec4 s1, vec4 s2);
+
+CGLM_EXPORT
+bool
+glmc_sphere_point(vec4 s, vec3 point);
+
+#endif /* cglmc_sphere_h */
diff --git a/include/cglm/call/vec3.h b/include/cglm/call/vec3.h
index 50a6b22..ae21620 100644
--- a/include/cglm/call/vec3.h
+++ b/include/cglm/call/vec3.h
@@ -148,6 +148,10 @@ CGLM_EXPORT
void
glmc_vec_center(vec3 v1, vec3 v2, vec3 dest);
+CGLM_EXPORT
+float
+glmc_vec_distance2(vec3 v1, vec3 v2);
+
CGLM_EXPORT
float
glmc_vec_distance(vec3 v1, vec3 v2);
diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h
index 52c7e97..720ae08 100644
--- a/include/cglm/cglm.h
+++ b/include/cglm/cglm.h
@@ -24,5 +24,6 @@
#include "util.h"
#include "io.h"
#include "project.h"
+#include "sphere.h"
#endif /* cglm_h */
diff --git a/include/cglm/quat.h b/include/cglm/quat.h
index fd4f25f..aa303ca 100644
--- a/include/cglm/quat.h
+++ b/include/cglm/quat.h
@@ -646,15 +646,12 @@ glm_quat_slerp(versor from, versor to, float t, versor dest) {
CGLM_INLINE
void
glm_quat_look(vec3 eye, versor ori, mat4 dest) {
- CGLM_ALIGN(16) vec4 t;
-
/* orientation */
glm_quat_mat4t(ori, dest);
/* translate */
- glm_vec4(eye, 1.0f, t);
- glm_mat4_mulv(dest, t, t);
- glm_vec_flipsign_to(t, dest[3]);
+ glm_mat4_mulv3(dest, eye, 1.0f, dest[3]);
+ glm_vec_flipsign(dest[3]);
}
/*!
diff --git a/include/cglm/sphere.h b/include/cglm/sphere.h
new file mode 100644
index 0000000..a7501b9
--- /dev/null
+++ b/include/cglm/sphere.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglm_sphere_h
+#define cglm_sphere_h
+
+#include "common.h"
+#include "mat4.h"
+
+/*
+ Sphere Representation in cglm: [center.x, center.y, center.z, radii]
+
+ You could use this representation or you can convert it to vec4 before call
+ any function
+ */
+
+/*!
+ * @brief helper for getting sphere radius
+ *
+ * @param[in] s sphere
+ *
+ * @return returns radii
+ */
+CGLM_INLINE
+float
+glm_sphere_radii(vec4 s) {
+ return s[3];
+}
+
+/*!
+ * @brief apply transform to sphere, it is just wrapper for glm_mat4_mulv3
+ *
+ * @param[in] s sphere
+ * @param[in] m transform matrix
+ * @param[out] dest transformed sphere
+ */
+CGLM_INLINE
+void
+glm_sphere_transform(vec4 s, mat4 m, vec4 dest) {
+ glm_mat4_mulv3(m, s, 1.0f, dest);
+ dest[3] = s[3];
+}
+
+/*!
+ * @brief merges two spheres and creates a new one
+ *
+ * two sphere must be in same space, for instance if one in world space then
+ * the other must be in world space too, not in local space.
+ *
+ * @param[in] s1 sphere 1
+ * @param[in] s2 sphere 2
+ * @param[out] dest merged/extended sphere
+ */
+CGLM_INLINE
+void
+glm_sphere_merge(vec4 s1, vec4 s2, vec4 dest) {
+ float dist, radii;
+
+ dist = glm_vec_distance(s1, s2);
+ radii = dist + s1[3] + s2[3];
+
+ radii = glm_max(radii, s1[3]);
+ radii = glm_max(radii, s2[3]);
+
+ glm_vec_center(s1, s2, dest);
+ dest[3] = radii;
+}
+
+/*!
+ * @brief check if two sphere intersects
+ *
+ * @param[in] s1 sphere
+ * @param[in] s2 other sphere
+ */
+CGLM_INLINE
+bool
+glm_sphere_sphere(vec4 s1, vec4 s2) {
+ return glm_vec_distance2(s1, s2) <= glm_pow2(s1[3] + s2[3]);
+}
+
+/*!
+ * @brief check if sphere intersects with point
+ *
+ * @param[in] s sphere
+ * @param[in] point point
+ */
+CGLM_INLINE
+bool
+glm_sphere_point(vec4 s, vec3 point) {
+ float rr;
+ rr = s[3] * s[3];
+ return glm_vec_distance2(point, s) <= rr;
+}
+
+#endif /* cglm_sphere_h */
diff --git a/include/cglm/util.h b/include/cglm/util.h
index b272d44..af7514c 100644
--- a/include/cglm/util.h
+++ b/include/cglm/util.h
@@ -98,7 +98,6 @@ glm_make_deg(float *rad) {
CGLM_INLINE
float
glm_pow2(float x) {
-
return x * x;
}
diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h
index 34a910c..18d8a7b 100644
--- a/include/cglm/vec3.h
+++ b/include/cglm/vec3.h
@@ -633,6 +633,21 @@ glm_vec_center(vec3 v1, vec3 v2, vec3 dest) {
glm_vec_scale(dest, 0.5f, dest);
}
+/**
+ * @brief squared distance between two vectors
+ *
+ * @param[in] v1 vector1
+ * @param[in] v2 vector2
+ * @return returns squared distance (distance * distance)
+ */
+CGLM_INLINE
+float
+glm_vec_distance2(vec3 v1, vec3 v2) {
+ return glm_pow2(v2[0] - v1[0])
+ + glm_pow2(v2[1] - v1[1])
+ + glm_pow2(v2[2] - v1[2]);
+}
+
/**
* @brief distance between two vectors
*
@@ -643,9 +658,7 @@ glm_vec_center(vec3 v1, vec3 v2, vec3 dest) {
CGLM_INLINE
float
glm_vec_distance(vec3 v1, vec3 v2) {
- return sqrtf(glm_pow2(v2[0] - v1[0])
- + glm_pow2(v2[1] - v1[1])
- + glm_pow2(v2[2] - v1[2]));
+ return sqrtf(glm_vec_distance2(v1, v2));
}
/*!
diff --git a/include/cglm/version.h b/include/cglm/version.h
index 370a6a0..6eee580 100644
--- a/include/cglm/version.h
+++ b/include/cglm/version.h
@@ -10,6 +10,6 @@
#define CGLM_VERSION_MAJOR 0
#define CGLM_VERSION_MINOR 4
-#define CGLM_VERSION_PATCH 6
+#define CGLM_VERSION_PATCH 7
#endif /* cglm_version_h */
diff --git a/makefile.am b/makefile.am
index 1999b3d..7ee0904 100644
--- a/makefile.am
+++ b/makefile.am
@@ -55,7 +55,8 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/frustum.h \
include/cglm/box.h \
include/cglm/color.h \
- include/cglm/project.h
+ include/cglm/project.h \
+ include/cglm/sphere.h
cglm_calldir=$(includedir)/cglm/call
cglm_call_HEADERS = include/cglm/call/mat4.h \
@@ -70,7 +71,8 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/plane.h \
include/cglm/call/frustum.h \
include/cglm/call/box.h \
- include/cglm/call/project.h
+ include/cglm/call/project.h \
+ include/cglm/call/sphere.h
cglm_simddir=$(includedir)/cglm/simd
cglm_simd_HEADERS = include/cglm/simd/intrin.h
@@ -101,7 +103,8 @@ libcglm_la_SOURCES=\
src/plane.c \
src/frustum.c \
src/box.c \
- src/project.c
+ src/project.c \
+ src/sphere.c
test_tests_SOURCES=\
test/src/test_common.c \
diff --git a/src/box.c b/src/box.c
index 0274390..fd639ea 100644
--- a/src/box.c
+++ b/src/box.c
@@ -70,3 +70,27 @@ void
glmc_aabb_center(vec3 box[2], vec3 dest) {
glm_aabb_center(box, dest);
}
+
+CGLM_EXPORT
+bool
+glmc_aabb_aabb(vec3 box[2], vec3 other[2]) {
+ return glm_aabb_aabb(box, other);
+}
+
+CGLM_EXPORT
+bool
+glmc_aabb_point(vec3 box[2], vec3 point) {
+ return glm_aabb_point(box, point);
+}
+
+CGLM_EXPORT
+bool
+glmc_aabb_contains(vec3 box[2], vec3 other[2]) {
+ return glm_aabb_contains(box, other);
+}
+
+CGLM_EXPORT
+bool
+glmc_aabb_sphere(vec3 box[2], vec4 s) {
+ return glm_aabb_sphere(box, s);
+}
diff --git a/src/sphere.c b/src/sphere.c
new file mode 100644
index 0000000..003ef87
--- /dev/null
+++ b/src/sphere.c
@@ -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
+ */
+
+#include "../include/cglm/cglm.h"
+#include "../include/cglm/call.h"
+
+CGLM_EXPORT
+float
+glmc_sphere_radii(vec4 s) {
+ return glm_sphere_radii(s);
+}
+
+CGLM_EXPORT
+void
+glmc_sphere_transform(vec4 s, mat4 m, vec4 dest) {
+ glm_sphere_transform(s, m, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_sphere_merge(vec4 s1, vec4 s2, vec4 dest) {
+ glm_sphere_merge(s1, s2, dest);
+}
+
+CGLM_EXPORT
+bool
+glmc_sphere_sphere(vec4 s1, vec4 s2) {
+ return glm_sphere_sphere(s1, s2);
+}
+
+CGLM_EXPORT
+bool
+glmc_sphere_point(vec4 s, vec3 point) {
+ return glm_sphere_point(s, point);
+}
diff --git a/src/vec3.c b/src/vec3.c
index 401b983..a2ab499 100644
--- a/src/vec3.c
+++ b/src/vec3.c
@@ -206,6 +206,12 @@ glmc_vec_center(vec3 v1, vec3 v2, vec3 dest) {
glm_vec_center(v1, v2, dest);
}
+CGLM_EXPORT
+float
+glmc_vec_distance2(vec3 v1, vec3 v2) {
+ return glm_vec_distance2(v1, v2);
+}
+
CGLM_EXPORT
float
glmc_vec_distance(vec3 v1, vec3 v2) {
diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj
index 415a87d..556a24e 100644
--- a/win/cglm.vcxproj
+++ b/win/cglm.vcxproj
@@ -31,6 +31,7 @@
+
@@ -50,6 +51,7 @@
+
@@ -72,6 +74,7 @@
+
diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters
index 3090d72..cf7634b 100644
--- a/win/cglm.vcxproj.filters
+++ b/win/cglm.vcxproj.filters
@@ -78,6 +78,9 @@
src
+
+ src
+
@@ -215,5 +218,11 @@
include\cglm\call
+
+ include\cglm\call
+
+
+ include\cglm
+
\ No newline at end of file