diff options
author | sanine <sanine.not@pm.me> | 2022-10-01 20:59:36 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-10-01 20:59:36 -0500 |
commit | c5fc66ee58f2c60f2d226868bb1cf5b91badaf53 (patch) | |
tree | 277dd280daf10bf77013236b8edfa5f88708c7e0 /libs/ode-0.16.1/libccd/src/ccd | |
parent | 1cf9cc3408af7008451f9133fb95af66a9697d15 (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.h | 52 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/ccd.h | 148 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/compiler.h | 61 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/dbg.h | 65 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/list.h | 155 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/polytope.h | 322 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/precision.h.in | 14 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/quat.h | 231 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/simplex.h | 104 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/support.h | 57 | ||||
-rw-r--r-- | libs/ode-0.16.1/libccd/src/ccd/vec3.h | 340 |
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__ */ |