summaryrefslogtreecommitdiff
path: root/libs/ode-0.16.1/libccd/src/ccd
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-10-01 20:59:36 -0500
committersanine <sanine.not@pm.me>2022-10-01 20:59:36 -0500
commitc5fc66ee58f2c60f2d226868bb1cf5b91badaf53 (patch)
tree277dd280daf10bf77013236b8edfa5f88708c7e0 /libs/ode-0.16.1/libccd/src/ccd
parent1cf9cc3408af7008451f9133fb95af66a9697d15 (diff)
add ode
Diffstat (limited to 'libs/ode-0.16.1/libccd/src/ccd')
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/alloc.h52
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/ccd.h148
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/compiler.h61
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/dbg.h65
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/list.h155
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/polytope.h322
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/precision.h.in14
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/quat.h231
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/simplex.h104
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/support.h57
-rw-r--r--libs/ode-0.16.1/libccd/src/ccd/vec3.h340
11 files changed, 1549 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/libccd/src/ccd/alloc.h b/libs/ode-0.16.1/libccd/src/ccd/alloc.h
new file mode 100644
index 0000000..7b92e3e
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/alloc.h
@@ -0,0 +1,52 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_ALLOC_H__
+#define __CCD_ALLOC_H__
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Functions and macros required for memory allocation.
+ */
+
+/* Memory allocation: */
+#define __CCD_ALLOC_MEMORY(type, ptr_old, size) \
+ (type *)ccdRealloc((void *)ptr_old, (size))
+
+/** Allocate memory for one element of type. */
+#define CCD_ALLOC(type) \
+ __CCD_ALLOC_MEMORY(type, NULL, sizeof(type))
+
+/** Allocate memory for array of elements of type type. */
+#define CCD_ALLOC_ARR(type, num_elements) \
+ __CCD_ALLOC_MEMORY(type, NULL, sizeof(type) * (num_elements))
+
+#define CCD_REALLOC_ARR(ptr, type, num_elements) \
+ __CCD_ALLOC_MEMORY(type, ptr, sizeof(type) * (num_elements))
+
+void *ccdRealloc(void *ptr, size_t size);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_ALLOC_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/ccd.h b/libs/ode-0.16.1/libccd/src/ccd/ccd.h
new file mode 100644
index 0000000..3aaba8a
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/ccd.h
@@ -0,0 +1,148 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_H__
+#define __CCD_H__
+
+#include <ccd/precision.h>
+
+#include <ccd/vec3.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Type of *support* function that takes pointer to 3D object and direction
+ * and returns (via vec argument) furthest point from object in specified
+ * direction.
+ */
+typedef void (*ccd_support_fn)(const void *obj, const ccd_vec3_t *dir,
+ ccd_vec3_t *vec);
+
+/**
+ * Returns (via dir argument) first direction vector that will be used in
+ * initialization of algorithm.
+ */
+typedef void (*ccd_first_dir_fn)(const void *obj1, const void *obj2,
+ ccd_vec3_t *dir);
+
+
+/**
+ * Returns (via center argument) geometric center (some point near center)
+ * of given object.
+ */
+typedef void (*ccd_center_fn)(const void *obj1, ccd_vec3_t *center);
+
+/**
+ * Main structure of CCD algorithm.
+ */
+struct _ccd_t {
+ ccd_first_dir_fn first_dir; /*!< Returns initial direction where first
+ !< support point will be searched*/
+ ccd_support_fn support1; /*!< Function that returns support point of
+ !< first object*/
+ ccd_support_fn support2; /*!< Function that returns support point of
+ !< second object*/
+
+ ccd_center_fn center1; /*!< Function that returns geometric center of
+ !< first object*/
+ ccd_center_fn center2; /*!< Function that returns geometric center of
+ !< second object*/
+
+ unsigned long max_iterations; /*!< Maximal number of iterations*/
+ ccd_real_t epa_tolerance;
+ ccd_real_t mpr_tolerance; /*!< Boundary tolerance for MPR algorithm*/
+};
+typedef struct _ccd_t ccd_t;
+
+/**
+ * Default first direction.
+ */
+void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir);
+
+#define CCD_INIT(ccd) \
+ do { \
+ (ccd)->first_dir = ccdFirstDirDefault; \
+ (ccd)->support1 = NULL; \
+ (ccd)->support2 = NULL; \
+ (ccd)->center1 = NULL; \
+ (ccd)->center2 = NULL; \
+ \
+ (ccd)->max_iterations = (unsigned long)-1; \
+ (ccd)->epa_tolerance = CCD_REAL(0.0001); \
+ (ccd)->mpr_tolerance = CCD_REAL(0.0001); \
+ } while(0)
+
+
+/**
+ * Returns true if two given objects interest.
+ */
+int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd);
+
+/**
+ * This function computes separation vector of two objects. Separation
+ * vector is minimal translation of obj2 to get obj1 and obj2 speparated
+ * (without intersection).
+ * Returns 0 if obj1 and obj2 intersect and sep is filled with translation
+ * vector. If obj1 and obj2 don't intersect -1 is returned.
+ */
+int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd,
+ ccd_vec3_t *sep);
+
+/**
+ * Computes penetration of obj2 into obj1.
+ * Depth of penetration, direction and position is returned. It means that
+ * if obj2 is translated by distance depth in direction dir objects will
+ * have touching contact, pos should be position in global coordinates
+ * where force should take a place.
+ *
+ * CCD+EPA algorithm is used.
+ *
+ * Returns 0 if obj1 and obj2 intersect and depth, dir and pos are filled
+ * if given non-NULL pointers.
+ * If obj1 and obj2 don't intersect -1 is returned.
+ */
+int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd,
+ ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
+
+
+/**
+ * Returns true if two given objects intersect - MPR algorithm is used.
+ */
+int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd);
+
+/**
+ * Computes penetration of obj2 into obj1.
+ * Depth of penetration, direction and position is returned, i.e. if obj2
+ * is translated by computed depth in resulting direction obj1 and obj2
+ * would have touching contact. Position is point in global coordinates
+ * where force should be take a place.
+ *
+ * Minkowski Portal Refinement algorithm is used (MPR, a.k.a. XenoCollide,
+ * see Game Programming Gem 7).
+ *
+ * Returns 0 if obj1 and obj2 intersect, otherwise -1 is returned.
+ */
+int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd,
+ ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/compiler.h b/libs/ode-0.16.1/libccd/src/ccd/compiler.h
new file mode 100644
index 0000000..380878f
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/compiler.h
@@ -0,0 +1,61 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_COMPILER_H__
+#define __CCD_COMPILER_H__
+
+#include <stddef.h>
+
+#define ccd_offsetof(TYPE, MEMBER) offsetof(TYPE, MEMBER)
+
+#define ccd_container_of(ptr, type, member) \
+ (type *)( (char *)ptr - ccd_offsetof(type, member))
+
+
+/**
+ * Marks inline function.
+ */
+#ifdef __GNUC__
+/*# define _ccd_inline static inline __attribute__((always_inline))*/
+# define _ccd_inline static inline
+#else /* __GNUC__ */
+# define _ccd_inline static __inline
+#endif /* __GNUC__ */
+
+
+/**
+ * __prefetch(x) - prefetches the cacheline at "x" for read
+ * __prefetchw(x) - prefetches the cacheline at "x" for write
+ */
+#ifdef __GNUC__
+# define _ccd_prefetch(x) __builtin_prefetch(x)
+# define _ccd_prefetchw(x) __builtin_prefetch(x,1)
+#else /* __GNUC__ */
+# define _ccd_prefetch(x) ((void)0)
+# define _ccd_prefetchw(x) ((void)0)
+#endif /* __GNUC__ */
+
+
+#ifdef __ICC
+/* disable unused parameter warning */
+# pragma warning(disable:869)
+/* disable annoying "operands are evaluated in unspecified order" warning */
+# pragma warning(disable:981)
+#endif /* __ICC */
+
+#endif /* __CCD_COMPILER_H__ */
+
diff --git a/libs/ode-0.16.1/libccd/src/ccd/dbg.h b/libs/ode-0.16.1/libccd/src/ccd/dbg.h
new file mode 100644
index 0000000..f4852c1
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/dbg.h
@@ -0,0 +1,65 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_DBG_H__
+#define __CCD_DBG_H__
+
+/**
+ * Some macros which can be used for printing debug info to stderr if macro
+ * NDEBUG not defined.
+ *
+ * DBG_PROLOGUE can be specified as string and this string will be
+ * prepended to output text
+ */
+#ifndef NDEBUG
+
+#include <stdio.h>
+
+#ifndef DBG_PROLOGUE
+# define DBG_PROLOGUE
+#endif
+
+# define DBG(format, ...) do { \
+ fprintf(stderr, DBG_PROLOGUE "%s :: " format "\n", __func__, ## __VA_ARGS__); \
+ fflush(stderr); \
+ } while (0)
+
+# define DBG2(str) do { \
+ fprintf(stderr, DBG_PROLOGUE "%s :: " str "\n", __func__); \
+ fflush(stderr); \
+ } while (0)
+
+# define DBG_VEC3(vec, prefix) do {\
+ fprintf(stderr, DBG_PROLOGUE "%s :: %s[%lf %lf %lf]\n", \
+ __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \
+ fflush(stderr); \
+ } while (0)
+/*
+# define DBG_VEC3(vec, prefix) do {\
+ fprintf(stderr, DBG_PROLOGUE "%s :: %s[%.20lf %.20lf %.20lf]\n", \
+ __func__, prefix, ccdVec3X(vec), ccdVec3Y(vec), ccdVec3Z(vec)); \
+ fflush(stderr); \
+ } while (0)
+*/
+
+#else
+# define DBG(format, ...)
+# define DBG2(str)
+# define DBG_VEC3(v, prefix)
+#endif
+
+#endif /* __CCD_DBG_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/list.h b/libs/ode-0.16.1/libccd/src/ccd/list.h
new file mode 100644
index 0000000..54391ed
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/list.h
@@ -0,0 +1,155 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_LIST_H__
+#define __CCD_LIST_H__
+
+#include <string.h>
+#include <ccd/compiler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct _ccd_list_t {
+ struct _ccd_list_t *next, *prev;
+};
+typedef struct _ccd_list_t ccd_list_t;
+
+
+
+/**
+ * Get the struct for this entry.
+ * @ptr: the &ccd_list_t pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define ccdListEntry(ptr, type, member) \
+ ccd_container_of(ptr, type, member)
+
+/**
+ * Iterates over list.
+ */
+#define ccdListForEach(list, item) \
+ for (item = (list)->next; \
+ _ccd_prefetch((item)->next), item != (list); \
+ item = (item)->next)
+
+/**
+ * Iterates over list safe against remove of list entry
+ */
+#define ccdListForEachSafe(list, item, tmp) \
+ for (item = (list)->next, tmp = (item)->next; \
+ item != (list); \
+ item = tmp, tmp = (item)->next)
+
+/**
+ * Iterates over list of given type.
+ * @pos: the type * to use as a loop cursor.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define ccdListForEachEntry(head, pos, postype, member) \
+ for (pos = ccdListEntry((head)->next, postype, member); \
+ _ccd_prefetch(pos->member.next), &pos->member != (head); \
+ pos = ccdListEntry(pos->member.next, postype, member))
+
+/**
+ * Iterates over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop cursor.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define ccdListForEachEntrySafe(head, pos, postype, n, ntype, member) \
+ for (pos = ccdListEntry((head)->next, postype, member), \
+ n = ccdListEntry(pos->member.next, postype, member); \
+ &pos->member != (head); \
+ pos = n, n = ccdListEntry(n->member.next, ntype, member))
+
+
+/**
+ * Initialize list.
+ */
+_ccd_inline void ccdListInit(ccd_list_t *l);
+
+_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l);
+_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l);
+
+/**
+ * Returns true if list is empty.
+ */
+_ccd_inline int ccdListEmpty(const ccd_list_t *head);
+
+/**
+ * Appends item to end of the list l.
+ */
+_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *item);
+
+/**
+ * Removes item from list.
+ */
+_ccd_inline void ccdListDel(ccd_list_t *item);
+
+
+
+///
+/// INLINES:
+///
+
+_ccd_inline void ccdListInit(ccd_list_t *l)
+{
+ l->next = l;
+ l->prev = l;
+}
+
+_ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l)
+{
+ return l->next;
+}
+
+_ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l)
+{
+ return l->prev;
+}
+
+_ccd_inline int ccdListEmpty(const ccd_list_t *head)
+{
+ return head->next == head;
+}
+
+_ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *newccd)
+{
+ newccd->prev = l->prev;
+ newccd->next = l;
+ l->prev->next = newccd;
+ l->prev = newccd;
+}
+
+_ccd_inline void ccdListDel(ccd_list_t *item)
+{
+ item->next->prev = item->prev;
+ item->prev->next = item->next;
+ item->next = item;
+ item->prev = item;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_LIST_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/polytope.h b/libs/ode-0.16.1/libccd/src/ccd/polytope.h
new file mode 100644
index 0000000..c9ee2ab
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/polytope.h
@@ -0,0 +1,322 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_POLYTOPE_H__
+#define __CCD_POLYTOPE_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ccd/support.h>
+#include <ccd/list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define CCD_PT_VERTEX 1
+#define CCD_PT_EDGE 2
+#define CCD_PT_FACE 3
+
+
+#define __CCD_PT_EL \
+ int type; /*! type of element */ \
+ ccd_real_t dist; /*! distance from origin */ \
+ ccd_vec3_t witness; /*! witness point of projection of origin */ \
+ ccd_list_t list; /*! list of elements of same type */
+
+/**
+ * General polytope element.
+ * Could be vertex, edge or triangle.
+ */
+struct _ccd_pt_el_t {
+ __CCD_PT_EL
+};
+typedef struct _ccd_pt_el_t ccd_pt_el_t;
+
+struct _ccd_pt_edge_t;
+struct _ccd_pt_face_t;
+
+/**
+ * Polytope's vertex.
+ */
+struct _ccd_pt_vertex_t {
+ __CCD_PT_EL
+
+ int id;
+ ccd_support_t v;
+ ccd_list_t edges; //!< List of edges
+};
+typedef struct _ccd_pt_vertex_t ccd_pt_vertex_t;
+
+/**
+ * Polytope's edge.
+ */
+struct _ccd_pt_edge_t {
+ __CCD_PT_EL
+
+ ccd_pt_vertex_t *vertex[2]; //!< Reference to vertices
+ struct _ccd_pt_face_t *faces[2]; //!< Reference to faces
+
+ ccd_list_t vertex_list[2]; //!< List items in vertices' lists
+};
+typedef struct _ccd_pt_edge_t ccd_pt_edge_t;
+
+/**
+ * Polytope's triangle faces.
+ */
+struct _ccd_pt_face_t {
+ __CCD_PT_EL
+
+ ccd_pt_edge_t *edge[3]; //!< Reference to surrounding edges
+};
+typedef struct _ccd_pt_face_t ccd_pt_face_t;
+
+
+/**
+ * Struct containing polytope.
+ */
+struct _ccd_pt_t {
+ ccd_list_t vertices; //!< List of vertices
+ ccd_list_t edges; //!< List of edges
+ ccd_list_t faces; //!< List of faces
+
+ ccd_pt_el_t *nearest;
+ ccd_real_t nearest_dist;
+ int nearest_type;
+};
+typedef struct _ccd_pt_t ccd_pt_t;
+
+
+void ccdPtInit(ccd_pt_t *pt);
+void ccdPtDestroy(ccd_pt_t *pt);
+
+/**
+ * Returns vertices surrounding given triangle face.
+ */
+_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face,
+ ccd_vec3_t **a,
+ ccd_vec3_t **b,
+ ccd_vec3_t **c);
+_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face,
+ ccd_pt_vertex_t **a,
+ ccd_pt_vertex_t **b,
+ ccd_pt_vertex_t **c);
+_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f,
+ ccd_pt_edge_t **a,
+ ccd_pt_edge_t **b,
+ ccd_pt_edge_t **c);
+
+_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e,
+ ccd_vec3_t **a,
+ ccd_vec3_t **b);
+_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e,
+ ccd_pt_vertex_t **a,
+ ccd_pt_vertex_t **b);
+_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e,
+ ccd_pt_face_t **f1,
+ ccd_pt_face_t **f2);
+
+
+/**
+ * Adds vertex to polytope and returns pointer to newly created vertex.
+ */
+ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v);
+_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt,
+ ccd_real_t x, ccd_real_t y, ccd_real_t z);
+
+/**
+ * Adds edge to polytope.
+ */
+ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1,
+ ccd_pt_vertex_t *v2);
+
+/**
+ * Adds face to polytope.
+ */
+ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1,
+ ccd_pt_edge_t *e2,
+ ccd_pt_edge_t *e3);
+
+/**
+ * Deletes vertex from polytope.
+ * Returns 0 on success, -1 otherwise.
+ */
+_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *);
+_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *);
+_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *);
+
+
+/**
+ * Recompute distances from origin for all elements in pt.
+ */
+void ccdPtRecomputeDistances(ccd_pt_t *pt);
+
+/**
+ * Returns nearest element to origin.
+ */
+ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt);
+
+
+void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn);
+void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *);
+
+
+/**** INLINES ****/
+_ccd_inline ccd_pt_vertex_t *ccdPtAddVertexCoords(ccd_pt_t *pt,
+ ccd_real_t x, ccd_real_t y, ccd_real_t z)
+{
+ ccd_support_t s;
+ ccdVec3Set(&s.v, x, y, z);
+ return ccdPtAddVertex(pt, &s);
+}
+
+_ccd_inline int ccdPtDelVertex(ccd_pt_t *pt, ccd_pt_vertex_t *v)
+{
+ // test if any edge is connected to this vertex
+ if (!ccdListEmpty(&v->edges))
+ return -1;
+
+ // delete vertex from main list
+ ccdListDel(&v->list);
+
+ if ((void *)pt->nearest == (void *)v){
+ pt->nearest = NULL;
+ }
+
+ free(v);
+ return 0;
+}
+
+_ccd_inline int ccdPtDelEdge(ccd_pt_t *pt, ccd_pt_edge_t *e)
+{
+ // text if any face is connected to this edge (faces[] is always
+ // aligned to lower indices)
+ if (e->faces[0] != NULL)
+ return -1;
+
+ // disconnect edge from lists of edges in vertex struct
+ ccdListDel(&e->vertex_list[0]);
+ ccdListDel(&e->vertex_list[1]);
+
+ // disconnect edge from main list
+ ccdListDel(&e->list);
+
+ if ((void *)pt->nearest == (void *)e){
+ pt->nearest = NULL;
+ }
+
+ free(e);
+ return 0;
+}
+
+_ccd_inline int ccdPtDelFace(ccd_pt_t *pt, ccd_pt_face_t *f)
+{
+ ccd_pt_edge_t *e;
+ size_t i;
+
+ // remove face from edges' recerence lists
+ for (i = 0; i < 3; i++){
+ e = f->edge[i];
+ if (e->faces[0] == f){
+ e->faces[0] = e->faces[1];
+ }
+ e->faces[1] = NULL;
+ }
+
+ // remove face from list of all faces
+ ccdListDel(&f->list);
+
+ if ((void *)pt->nearest == (void *)f){
+ pt->nearest = NULL;
+ }
+
+ free(f);
+ return 0;
+}
+
+_ccd_inline void ccdPtFaceVec3(const ccd_pt_face_t *face,
+ ccd_vec3_t **a,
+ ccd_vec3_t **b,
+ ccd_vec3_t **c)
+{
+ *a = &face->edge[0]->vertex[0]->v.v;
+ *b = &face->edge[0]->vertex[1]->v.v;
+
+ if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0]
+ && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){
+ *c = &face->edge[1]->vertex[0]->v.v;
+ }else{
+ *c = &face->edge[1]->vertex[1]->v.v;
+ }
+}
+
+_ccd_inline void ccdPtFaceVertices(const ccd_pt_face_t *face,
+ ccd_pt_vertex_t **a,
+ ccd_pt_vertex_t **b,
+ ccd_pt_vertex_t **c)
+{
+ *a = face->edge[0]->vertex[0];
+ *b = face->edge[0]->vertex[1];
+
+ if (face->edge[1]->vertex[0] != face->edge[0]->vertex[0]
+ && face->edge[1]->vertex[0] != face->edge[0]->vertex[1]){
+ *c = face->edge[1]->vertex[0];
+ }else{
+ *c = face->edge[1]->vertex[1];
+ }
+}
+
+_ccd_inline void ccdPtFaceEdges(const ccd_pt_face_t *f,
+ ccd_pt_edge_t **a,
+ ccd_pt_edge_t **b,
+ ccd_pt_edge_t **c)
+{
+ *a = f->edge[0];
+ *b = f->edge[1];
+ *c = f->edge[2];
+}
+
+_ccd_inline void ccdPtEdgeVec3(const ccd_pt_edge_t *e,
+ ccd_vec3_t **a,
+ ccd_vec3_t **b)
+{
+ *a = &e->vertex[0]->v.v;
+ *b = &e->vertex[1]->v.v;
+}
+
+_ccd_inline void ccdPtEdgeVertices(const ccd_pt_edge_t *e,
+ ccd_pt_vertex_t **a,
+ ccd_pt_vertex_t **b)
+{
+ *a = e->vertex[0];
+ *b = e->vertex[1];
+}
+
+_ccd_inline void ccdPtEdgeFaces(const ccd_pt_edge_t *e,
+ ccd_pt_face_t **f1,
+ ccd_pt_face_t **f2)
+{
+ *f1 = e->faces[0];
+ *f2 = e->faces[1];
+}
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_POLYTOPE_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/precision.h.in b/libs/ode-0.16.1/libccd/src/ccd/precision.h.in
new file mode 100644
index 0000000..4f98509
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/precision.h.in
@@ -0,0 +1,14 @@
+#ifndef __CCD_PRECISION_H__
+#define __CCD_PRECISION_H__
+
+/* define either CCD_SINGLE or CCD_DOUBLE */
+
+#if defined(CCD_IDESINGLE)
+#define CCD_SINGLE
+#elif defined(CCD_IDEDOUBLE)
+#define CCD_DOUBLE
+#else
+#define @CCD_PRECISION@
+#endif
+
+#endif
diff --git a/libs/ode-0.16.1/libccd/src/ccd/quat.h b/libs/ode-0.16.1/libccd/src/ccd/quat.h
new file mode 100644
index 0000000..3929671
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/quat.h
@@ -0,0 +1,231 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_QUAT_H__
+#define __CCD_QUAT_H__
+
+#include <ccd/compiler.h>
+#include <ccd/vec3.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct _ccd_quat_t {
+ ccd_real_t q[4]; //!< x, y, z, w
+};
+typedef struct _ccd_quat_t ccd_quat_t;
+
+#define CCD_QUAT(name, x, y, z, w) \
+ ccd_quat_t name = { {x, y, z, w} }
+
+_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q);
+_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q);
+
+_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w);
+_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src);
+
+_ccd_inline int ccdQuatNormalize(ccd_quat_t *q);
+
+_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q,
+ ccd_real_t angle, const ccd_vec3_t *axis);
+
+_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k);
+
+/**
+ * q = q * q2
+ */
+_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2);
+
+/**
+ * q = a * b
+ */
+_ccd_inline void ccdQuatMul2(ccd_quat_t *q,
+ const ccd_quat_t *a, const ccd_quat_t *b);
+
+/**
+ * Inverts quaternion.
+ * Returns 0 on success.
+ */
+_ccd_inline int ccdQuatInvert(ccd_quat_t *q);
+_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src);
+
+
+/**
+ * Rotate vector v by quaternion q.
+ */
+_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q);
+
+
+/**** INLINES ****/
+_ccd_inline ccd_real_t ccdQuatLen2(const ccd_quat_t *q)
+{
+ ccd_real_t len;
+
+ len = q->q[0] * q->q[0];
+ len += q->q[1] * q->q[1];
+ len += q->q[2] * q->q[2];
+ len += q->q[3] * q->q[3];
+
+ return len;
+}
+
+_ccd_inline ccd_real_t ccdQuatLen(const ccd_quat_t *q)
+{
+ return CCD_SQRT(ccdQuatLen2(q));
+}
+
+_ccd_inline void ccdQuatSet(ccd_quat_t *q, ccd_real_t x, ccd_real_t y, ccd_real_t z, ccd_real_t w)
+{
+ q->q[0] = x;
+ q->q[1] = y;
+ q->q[2] = z;
+ q->q[3] = w;
+}
+
+_ccd_inline void ccdQuatCopy(ccd_quat_t *dest, const ccd_quat_t *src)
+{
+ *dest = *src;
+}
+
+
+_ccd_inline int ccdQuatNormalize(ccd_quat_t *q)
+{
+ ccd_real_t len = ccdQuatLen(q);
+ if (len < CCD_EPS)
+ return 0;
+
+ ccdQuatScale(q, CCD_ONE / len);
+ return 1;
+}
+
+_ccd_inline void ccdQuatSetAngleAxis(ccd_quat_t *q,
+ ccd_real_t angle, const ccd_vec3_t *axis)
+{
+ ccd_real_t a, x, y, z, n, s;
+
+ a = angle/2;
+ x = ccdVec3X(axis);
+ y = ccdVec3Y(axis);
+ z = ccdVec3Z(axis);
+ n = CCD_SQRT(x*x + y*y + z*z);
+
+ // axis==0? (treat this the same as angle==0 with an arbitrary axis)
+ if (n < CCD_EPS){
+ q->q[0] = q->q[1] = q->q[2] = CCD_ZERO;
+ q->q[3] = CCD_ONE;
+ }else{
+ s = sin(a)/n;
+
+ q->q[3] = cos(a);
+ q->q[0] = x*s;
+ q->q[1] = y*s;
+ q->q[2] = z*s;
+
+ ccdQuatNormalize(q);
+ }
+}
+
+
+_ccd_inline void ccdQuatScale(ccd_quat_t *q, ccd_real_t k)
+{
+ size_t i;
+ for (i = 0; i < 4; i++)
+ q->q[i] *= k;
+}
+
+_ccd_inline void ccdQuatMul(ccd_quat_t *q, const ccd_quat_t *q2)
+{
+ ccd_quat_t a;
+ ccdQuatCopy(&a, q);
+ ccdQuatMul2(q, &a, q2);
+}
+
+_ccd_inline void ccdQuatMul2(ccd_quat_t *q,
+ const ccd_quat_t *a, const ccd_quat_t *b)
+{
+ q->q[0] = a->q[3] * b->q[0]
+ + a->q[0] * b->q[3]
+ + a->q[1] * b->q[2]
+ - a->q[2] * b->q[1];
+ q->q[1] = a->q[3] * b->q[1]
+ + a->q[1] * b->q[3]
+ - a->q[0] * b->q[2]
+ + a->q[2] * b->q[0];
+ q->q[2] = a->q[3] * b->q[2]
+ + a->q[2] * b->q[3]
+ + a->q[0] * b->q[1]
+ - a->q[1] * b->q[0];
+ q->q[3] = a->q[3] * b->q[3]
+ - a->q[0] * b->q[0]
+ - a->q[1] * b->q[1]
+ - a->q[2] * b->q[2];
+}
+
+_ccd_inline int ccdQuatInvert(ccd_quat_t *q)
+{
+ ccd_real_t len2 = ccdQuatLen2(q);
+ if (len2 < CCD_EPS)
+ return -1;
+
+ len2 = CCD_ONE / len2;
+
+ q->q[0] = -q->q[0] * len2;
+ q->q[1] = -q->q[1] * len2;
+ q->q[2] = -q->q[2] * len2;
+ q->q[3] = q->q[3] * len2;
+
+ return 0;
+}
+_ccd_inline int ccdQuatInvert2(ccd_quat_t *dest, const ccd_quat_t *src)
+{
+ ccdQuatCopy(dest, src);
+ return ccdQuatInvert(dest);
+}
+
+_ccd_inline void ccdQuatRotVec(ccd_vec3_t *v, const ccd_quat_t *q)
+{
+ // original version: 31 mul + 21 add
+ // optimized version: 18 mul + 12 add
+ // formula: v = v + 2 * cross(q.xyz, cross(q.xyz, v) + q.w * v)
+ ccd_real_t cross1_x, cross1_y, cross1_z, cross2_x, cross2_y, cross2_z;
+ ccd_real_t x, y, z, w;
+ ccd_real_t vx, vy, vz;
+
+ vx = ccdVec3X(v);
+ vy = ccdVec3Y(v);
+ vz = ccdVec3Z(v);
+
+ w = q->q[3];
+ x = q->q[0];
+ y = q->q[1];
+ z = q->q[2];
+
+ cross1_x = y * vz - z * vy + w * vx;
+ cross1_y = z * vx - x * vz + w * vy;
+ cross1_z = x * vy - y * vx + w * vz;
+ cross2_x = y * cross1_z - z * cross1_y;
+ cross2_y = z * cross1_x - x * cross1_z;
+ cross2_z = x * cross1_y - y * cross1_x;
+ ccdVec3Set(v, vx + 2 * cross2_x, vy + 2 * cross2_y, vz + 2 * cross2_z);
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_QUAT_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/simplex.h b/libs/ode-0.16.1/libccd/src/ccd/simplex.h
new file mode 100644
index 0000000..1d07e39
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/simplex.h
@@ -0,0 +1,104 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_SIMPLEX_H__
+#define __CCD_SIMPLEX_H__
+
+#include <ccd/support.h>
+#include <ccd/compiler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct _ccd_simplex_t {
+ ccd_support_t ps[4];
+ int last; /*!< index of last added point*/
+};
+typedef struct _ccd_simplex_t ccd_simplex_t;
+
+
+_ccd_inline void ccdSimplexInit(ccd_simplex_t *s);
+_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s);
+_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s);
+_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx);
+_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx);
+
+_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v);
+_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a);
+_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size);
+_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2);
+
+
+/**** INLINES ****/
+
+_ccd_inline void ccdSimplexInit(ccd_simplex_t *s)
+{
+ s->last = -1;
+}
+
+_ccd_inline int ccdSimplexSize(const ccd_simplex_t *s)
+{
+ return s->last + 1;
+}
+
+_ccd_inline const ccd_support_t *ccdSimplexLast(const ccd_simplex_t *s)
+{
+ return ccdSimplexPoint(s, s->last);
+}
+
+_ccd_inline const ccd_support_t *ccdSimplexPoint(const ccd_simplex_t *s, int idx)
+{
+ /* here is no check on boundaries */
+ return &s->ps[idx];
+}
+_ccd_inline ccd_support_t *ccdSimplexPointW(ccd_simplex_t *s, int idx)
+{
+ return &s->ps[idx];
+}
+
+_ccd_inline void ccdSimplexAdd(ccd_simplex_t *s, const ccd_support_t *v)
+{
+ /* here is no check on boundaries in sake of speed */
+ ++s->last;
+ ccdSupportCopy(s->ps + s->last, v);
+}
+
+_ccd_inline void ccdSimplexSet(ccd_simplex_t *s, size_t pos, const ccd_support_t *a)
+{
+ ccdSupportCopy(s->ps + pos, a);
+}
+
+_ccd_inline void ccdSimplexSetSize(ccd_simplex_t *s, int size)
+{
+ s->last = size - 1;
+}
+
+_ccd_inline void ccdSimplexSwap(ccd_simplex_t *s, size_t pos1, size_t pos2)
+{
+ ccd_support_t supp;
+
+ ccdSupportCopy(&supp, &s->ps[pos1]);
+ ccdSupportCopy(&s->ps[pos1], &s->ps[pos2]);
+ ccdSupportCopy(&s->ps[pos2], &supp);
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_SIMPLEX_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/support.h b/libs/ode-0.16.1/libccd/src/ccd/support.h
new file mode 100644
index 0000000..0a21b3e
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/support.h
@@ -0,0 +1,57 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_SUPPORT_H__
+#define __CCD_SUPPORT_H__
+
+#include <ccd/compiler.h>
+#include <ccd/vec3.h>
+#include <ccd/ccd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct _ccd_support_t {
+ ccd_vec3_t v; /*!< Support point in minkowski sum*/
+ ccd_vec3_t v1; /*!< Support point in obj1*/
+ ccd_vec3_t v2; /*!< Support point in obj2*/
+};
+typedef struct _ccd_support_t ccd_support_t;
+
+_ccd_inline void ccdSupportCopy(ccd_support_t *, const ccd_support_t *s);
+
+/**
+ * Computes support point of obj1 and obj2 in direction dir.
+ * Support point is returned via supp.
+ */
+void __ccdSupport(const void *obj1, const void *obj2,
+ const ccd_vec3_t *dir, const ccd_t *ccd,
+ ccd_support_t *supp);
+
+
+/**** INLINES ****/
+_ccd_inline void ccdSupportCopy(ccd_support_t *d, const ccd_support_t *s)
+{
+ *d = *s;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_SUPPORT_H__ */
diff --git a/libs/ode-0.16.1/libccd/src/ccd/vec3.h b/libs/ode-0.16.1/libccd/src/ccd/vec3.h
new file mode 100644
index 0000000..d9175ed
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/ccd/vec3.h
@@ -0,0 +1,340 @@
+/***
+ * libccd
+ * ---------------------------------
+ * Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of libccd.
+ *
+ * Distributed under the OSI-approved BSD License (the "License");
+ * see accompanying file BDS-LICENSE for details or see
+ * <http://www.opensource.org/licenses/bsd-license.php>.
+ *
+ * This software is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the License for more information.
+ */
+
+#ifndef __CCD_VEC3_H__
+#define __CCD_VEC3_H__
+
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+
+#include <ccd/precision.h>
+#include <ccd/compiler.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#ifndef CCD_SINGLE
+# ifndef CCD_DOUBLE
+# error You must define CCD_SINGLE or CCD_DOUBLE
+# endif /* CCD_DOUBLE */
+#endif /* CCD_SINGLE */
+
+
+#if defined(_MSC_VER) && _MSC_VER < 1700
+/* Define fmin, fmax, fminf, fmaxf which are missing from MSVC (up to VS2005 at least) */
+static __inline double fmin(double x, double y) { return __min(x, y); }
+static __inline double fmax(double x, double y) { return __max(x, y); }
+static __inline float fminf(float x, float y) { return __min(x, y); }
+static __inline float fmaxf(float x, float y) { return __max(x, y); }
+
+#endif /* #if defined(_MSC_VER) */
+
+
+#ifdef CCD_SINGLE
+# ifdef CCD_DOUBLE
+# error You can define either CCD_SINGLE or CCD_DOUBLE, not both!
+# endif /* CCD_DOUBLE */
+
+typedef float ccd_real_t;
+
+/*# define CCD_EPS 1E-6*/
+# define CCD_EPS FLT_EPSILON
+
+# define CCD_REAL_MAX FLT_MAX
+
+# define CCD_REAL(x) (x ## f) /*!< form a constant */
+# define CCD_SQRT(x) (sqrtf(x)) /*!< square root */
+# define CCD_FABS(x) (fabsf(x)) /*!< absolute value */
+# define CCD_FMAX(x, y) (fmaxf((x), (y))) /*!< maximum of two floats */
+# define CCD_FMIN(x, y) (fminf((x), (y))) /*!< minimum of two floats */
+#endif /* CCD_SINGLE */
+
+#ifdef CCD_DOUBLE
+typedef double ccd_real_t;
+
+/*# define CCD_EPS 1E-10*/
+# define CCD_EPS DBL_EPSILON
+
+# define CCD_REAL_MAX DBL_MAX
+
+# define CCD_REAL(x) (x) /*!< form a constant */
+# define CCD_SQRT(x) (sqrt(x)) /*!< square root */
+# define CCD_FABS(x) (fabs(x)) /*!< absolute value */
+# define CCD_FMAX(x, y) (fmax((x), (y))) /*!< maximum of two floats */
+# define CCD_FMIN(x, y) (fmin((x), (y))) /*!< minimum of two floats */
+#endif /* CCD_DOUBLE */
+
+#define CCD_ONE CCD_REAL(1.)
+#define CCD_ZERO CCD_REAL(0.)
+
+struct _ccd_vec3_t {
+ ccd_real_t v[3];
+};
+typedef struct _ccd_vec3_t ccd_vec3_t;
+
+
+/**
+ * Holds origin (0,0,0) - this variable is meant to be read-only!
+ */
+extern ccd_vec3_t *ccd_vec3_origin;
+
+/**
+ * Array of points uniformly distributed on unit sphere.
+ */
+extern ccd_vec3_t *ccd_points_on_sphere;
+extern size_t ccd_points_on_sphere_len;
+
+/** Returns sign of value. */
+_ccd_inline int ccdSign(ccd_real_t val);
+/** Returns true if val is zero. **/
+_ccd_inline int ccdIsZero(ccd_real_t val);
+/** Returns true if a and b equal. **/
+_ccd_inline int ccdEq(ccd_real_t a, ccd_real_t b);
+
+
+#define CCD_VEC3_STATIC(x, y, z) \
+ { { (x), (y), (z) } }
+
+#define CCD_VEC3(name, x, y, z) \
+ ccd_vec3_t name = CCD_VEC3_STATIC((x), (y), (z))
+
+_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v);
+_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v);
+_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v);
+
+/**
+ * Returns true if a and b equal.
+ */
+_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b);
+
+/**
+ * Returns squared length of vector.
+ */
+_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v);
+
+/**
+ * Returns distance between a and b.
+ */
+_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b);
+
+
+_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z);
+
+/**
+ * v = w
+ */
+_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w);
+
+/**
+ * Subtracts coordinates of vector w from vector v. v = v - w
+ */
+_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w);
+
+/**
+ * Adds coordinates of vector w to vector v. v = v + w
+ */
+_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w);
+
+/**
+ * d = v - w
+ */
+_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w);
+
+/**
+ * d = d * k;
+ */
+_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k);
+
+
+/**
+ * Normalizes given vector to unit length.
+ */
+_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d);
+
+
+/**
+ * Dot product of two vectors.
+ */
+_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b);
+
+/**
+ * Cross product: d = a x b.
+ */
+_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b);
+
+
+/**
+ * Returns distance2 of point P to segment ab.
+ * If witness is non-NULL it is filled with coordinates of point from which
+ * was computed distance to point P.
+ */
+ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P,
+ const ccd_vec3_t *a, const ccd_vec3_t *b,
+ ccd_vec3_t *witness);
+
+/**
+ * Returns distance2 of point P from triangle formed by triplet a, b, c.
+ * If witness vector is provided it is filled with coordinates of point
+ * from which was computed distance to point P.
+ */
+ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P,
+ const ccd_vec3_t *a, const ccd_vec3_t *b,
+ const ccd_vec3_t *c,
+ ccd_vec3_t *witness);
+
+
+/**** INLINES ****/
+_ccd_inline int ccdSign(ccd_real_t val)
+{
+ if (ccdIsZero(val)){
+ return 0;
+ }else if (val < CCD_ZERO){
+ return -1;
+ }
+ return 1;
+}
+
+_ccd_inline int ccdIsZero(ccd_real_t val)
+{
+ return CCD_FABS(val) < CCD_EPS;
+}
+
+_ccd_inline int ccdEq(ccd_real_t _a, ccd_real_t _b)
+{
+ ccd_real_t ab;
+ ccd_real_t a, b;
+
+ ab = CCD_FABS(_a - _b);
+ if (CCD_FABS(ab) < CCD_EPS)
+ return 1;
+
+ a = CCD_FABS(_a);
+ b = CCD_FABS(_b);
+ if (b > a){
+ return ab < CCD_EPS * b;
+ }else{
+ return ab < CCD_EPS * a;
+ }
+}
+
+
+_ccd_inline ccd_real_t ccdVec3X(const ccd_vec3_t *v)
+{
+ return v->v[0];
+}
+
+_ccd_inline ccd_real_t ccdVec3Y(const ccd_vec3_t *v)
+{
+ return v->v[1];
+}
+
+_ccd_inline ccd_real_t ccdVec3Z(const ccd_vec3_t *v)
+{
+ return v->v[2];
+}
+
+_ccd_inline int ccdVec3Eq(const ccd_vec3_t *a, const ccd_vec3_t *b)
+{
+ return ccdEq(ccdVec3X(a), ccdVec3X(b))
+ && ccdEq(ccdVec3Y(a), ccdVec3Y(b))
+ && ccdEq(ccdVec3Z(a), ccdVec3Z(b));
+}
+
+_ccd_inline ccd_real_t ccdVec3Len2(const ccd_vec3_t *v)
+{
+ return ccdVec3Dot(v, v);
+}
+
+_ccd_inline ccd_real_t ccdVec3Dist2(const ccd_vec3_t *a, const ccd_vec3_t *b)
+{
+ ccd_vec3_t ab;
+ ccdVec3Sub2(&ab, a, b);
+ return ccdVec3Len2(&ab);
+}
+
+_ccd_inline void ccdVec3Set(ccd_vec3_t *v, ccd_real_t x, ccd_real_t y, ccd_real_t z)
+{
+ v->v[0] = x;
+ v->v[1] = y;
+ v->v[2] = z;
+}
+
+_ccd_inline void ccdVec3Copy(ccd_vec3_t *v, const ccd_vec3_t *w)
+{
+ *v = *w;
+}
+
+_ccd_inline void ccdVec3Sub(ccd_vec3_t *v, const ccd_vec3_t *w)
+{
+ v->v[0] -= w->v[0];
+ v->v[1] -= w->v[1];
+ v->v[2] -= w->v[2];
+}
+
+_ccd_inline void ccdVec3Sub2(ccd_vec3_t *d, const ccd_vec3_t *v, const ccd_vec3_t *w)
+{
+ d->v[0] = v->v[0] - w->v[0];
+ d->v[1] = v->v[1] - w->v[1];
+ d->v[2] = v->v[2] - w->v[2];
+}
+
+_ccd_inline void ccdVec3Add(ccd_vec3_t *v, const ccd_vec3_t *w)
+{
+ v->v[0] += w->v[0];
+ v->v[1] += w->v[1];
+ v->v[2] += w->v[2];
+}
+
+_ccd_inline void ccdVec3Scale(ccd_vec3_t *d, ccd_real_t k)
+{
+ d->v[0] *= k;
+ d->v[1] *= k;
+ d->v[2] *= k;
+}
+
+_ccd_inline void ccdVec3Normalize(ccd_vec3_t *d)
+{
+ ccd_real_t k = CCD_ONE / CCD_SQRT(ccdVec3Len2(d));
+ ccdVec3Scale(d, k);
+}
+
+_ccd_inline ccd_real_t ccdVec3Dot(const ccd_vec3_t *a, const ccd_vec3_t *b)
+{
+ ccd_real_t dot;
+
+ dot = a->v[0] * b->v[0];
+ dot += a->v[1] * b->v[1];
+ dot += a->v[2] * b->v[2];
+ return dot;
+}
+
+_ccd_inline void ccdVec3Cross(ccd_vec3_t *d, const ccd_vec3_t *a, const ccd_vec3_t *b)
+{
+ d->v[0] = (a->v[1] * b->v[2]) - (a->v[2] * b->v[1]);
+ d->v[1] = (a->v[2] * b->v[0]) - (a->v[0] * b->v[2]);
+ d->v[2] = (a->v[0] * b->v[1]) - (a->v[1] * b->v[0]);
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* __CCD_VEC3_H__ */