From 8d2ce679de7b1e6f1702a7fd633bdf99c89154a1 Mon Sep 17 00:00:00 2001 From: Sebastian Eibl <sebastian.eibl@fau.de> Date: Tue, 12 Jun 2018 13:59:47 +0200 Subject: [PATCH] removed external dependency libccd --- src/pe/CMakeLists.txt | 23 - src/pe/collision/GJKEPAHelper.cpp | 79 -- src/pe/collision/GJKEPAHelper.h | 87 -- src/pe/extern/libccd/.gitignore | 5 - src/pe/extern/libccd/BSD-LICENSE | 44 - src/pe/extern/libccd/alloc.h | 50 - src/pe/extern/libccd/ccd.c | 1001 -------------------- src/pe/extern/libccd/ccd/ccd.h | 154 --- src/pe/extern/libccd/ccd/compiler.h | 83 -- src/pe/extern/libccd/ccd/config.h.cmake.in | 7 - src/pe/extern/libccd/ccd/config.h.m4 | 7 - src/pe/extern/libccd/ccd/quat.h | 239 ----- src/pe/extern/libccd/ccd/vec3.h | 339 ------- src/pe/extern/libccd/dbg.h | 65 -- src/pe/extern/libccd/list.h | 155 --- src/pe/extern/libccd/mpr.c | 547 ----------- src/pe/extern/libccd/polytope.c | 298 ------ src/pe/extern/libccd/polytope.h | 322 ------- src/pe/extern/libccd/simplex.h | 104 -- src/pe/extern/libccd/support.c | 34 - src/pe/extern/libccd/support.h | 55 -- src/pe/extern/libccd/vec3.c | 211 ----- tests/pe/Collision.cpp | 38 - 23 files changed, 3947 deletions(-) delete mode 100644 src/pe/collision/GJKEPAHelper.cpp delete mode 100644 src/pe/collision/GJKEPAHelper.h delete mode 100644 src/pe/extern/libccd/.gitignore delete mode 100644 src/pe/extern/libccd/BSD-LICENSE delete mode 100644 src/pe/extern/libccd/alloc.h delete mode 100644 src/pe/extern/libccd/ccd.c delete mode 100644 src/pe/extern/libccd/ccd/ccd.h delete mode 100644 src/pe/extern/libccd/ccd/compiler.h delete mode 100644 src/pe/extern/libccd/ccd/config.h.cmake.in delete mode 100644 src/pe/extern/libccd/ccd/config.h.m4 delete mode 100644 src/pe/extern/libccd/ccd/quat.h delete mode 100644 src/pe/extern/libccd/ccd/vec3.h delete mode 100644 src/pe/extern/libccd/dbg.h delete mode 100644 src/pe/extern/libccd/list.h delete mode 100644 src/pe/extern/libccd/mpr.c delete mode 100644 src/pe/extern/libccd/polytope.c delete mode 100644 src/pe/extern/libccd/polytope.h delete mode 100644 src/pe/extern/libccd/simplex.h delete mode 100644 src/pe/extern/libccd/support.c delete mode 100644 src/pe/extern/libccd/support.h delete mode 100644 src/pe/extern/libccd/vec3.c diff --git a/src/pe/CMakeLists.txt b/src/pe/CMakeLists.txt index 1dd7edd80..dadbb9186 100644 --- a/src/pe/CMakeLists.txt +++ b/src/pe/CMakeLists.txt @@ -5,27 +5,4 @@ # ################################################################################################### -if(WALBERLA_DOUBLE_ACCURACY) - set(CCD_DOUBLE ON) - set(CCD_SINGLE OFF) -else() - set(CCD_DOUBLE OFF) - set(CCD_SINGLE ON) -endif() - -configure_file(extern/libccd/ccd/config.h.cmake.in extern/libccd/ccd/config.h) - -include_directories(extern/libccd) -include_directories("${CMAKE_CURRENT_BINARY_DIR}/extern/libccd") - waLBerla_add_module( DEPENDS core blockforest domain_decomposition geometry stencil vtk ) - -if( WALBERLA_CXX_COMPILER_IS_MSVC ) - SET_SOURCE_FILES_PROPERTIES( extern/libccd/ccd.c - extern/libccd/mpr.c - extern/libccd/polytope.c - extern/libccd/support.c - extern/libccd/vec3.c - PROPERTIES LANGUAGE CXX ) -endif() - diff --git a/src/pe/collision/GJKEPAHelper.cpp b/src/pe/collision/GJKEPAHelper.cpp deleted file mode 100644 index d8316cd6d..000000000 --- a/src/pe/collision/GJKEPAHelper.cpp +++ /dev/null @@ -1,79 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file GJKHelper.cpp -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include "GJKEPAHelper.h" - -#include "pe/rigidbody/GeomPrimitive.h" - -extern "C" { - #include "pe/extern/libccd/ccd/ccd.h" - #include "pe/extern/libccd/ccd/quat.h" -} - -#include "core/logging/Logging.h" - -namespace walberla { -namespace pe { - -Vec3 convertVec3(const ccd_vec3_t& vec) { return Vec3(real_c(vec.v[0]), real_c(vec.v[1]), real_c(vec.v[2])); } -ccd_vec3_t convertVec3(const Vec3& vec) { ccd_vec3_t ret; ret.v[0] = vec[0]; ret.v[1] = vec[1]; ret.v[2] = vec[2]; return ret; } - -void support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec) -{ - ConstGeomID bd = reinterpret_cast<ConstGeomID> (obj); - Vec3 d = convertVec3(*dir); - Vec3 sup = bd->support( d ); - *vec = convertVec3(sup); -} - -bool collideGJK( ConstGeomID bd1, - ConstGeomID bd2, - Vec3& contactPoint, - Vec3& contactNormal, - real_t& penetrationDepth, - const unsigned long numIterations, - const real_t epaTol ) -{ - ccd_t ccd; - CCD_INIT(&ccd); // initialize ccd_t struct - - // set up ccd_t struct - ccd.support1 = support; // support function for first object - ccd.support2 = support; // support function for second object - ccd.max_iterations = numIterations; // maximal number of iterations - ccd.epa_tolerance = epaTol; - - ccd_vec3_t dir, pos; - ccd_real_t penetrationDepthCCD; - int intersect = ccdGJKPenetration(reinterpret_cast<const void*> (bd1), reinterpret_cast<const void*> (bd2), &ccd, &penetrationDepthCCD, &dir, &pos); - penetrationDepth = real_c(penetrationDepthCCD); - contactPoint = convertVec3(pos); - contactNormal = -convertVec3(dir); - penetrationDepth *= -1; - - return (intersect == 0); -} - -} // namespace pe -} // namespace walberla diff --git a/src/pe/collision/GJKEPAHelper.h b/src/pe/collision/GJKEPAHelper.h deleted file mode 100644 index b1d73b1a1..000000000 --- a/src/pe/collision/GJKEPAHelper.h +++ /dev/null @@ -1,87 +0,0 @@ -//====================================================================================================================== -// -// This file is part of waLBerla. waLBerla is free software: you can -// redistribute it and/or modify it under the terms of the GNU General Public -// License as published by the Free Software Foundation, either version 3 of -// the License, or (at your option) any later version. -// -// waLBerla is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file GJKHelper.h -//! \author Sebastian Eibl <sebastian.eibl@fau.de> -// -//====================================================================================================================== - -#pragma once - -//************************************************************************************************* -// Includes -//************************************************************************************************* - -#include "pe/contact/Contact.h" -#include "pe/Types.h" - -#include "core/math/Vector3.h" - -namespace walberla { -namespace pe { - -static unsigned long maxGJKIterations = 100ul; -static real_t epaTolerance = real_t(0.000001); - -inline -void setMaxGJKIterations(const unsigned long& iter) -{ - maxGJKIterations = iter; -} -inline -unsigned long getMaxGJKIterations() -{ - return maxGJKIterations; -} - -inline -void setEPATolerance(const real_t& tol) -{ - epaTolerance = tol; -} -inline -real_t getEPATolerance() -{ - return epaTolerance; -} - -bool collideGJK( ConstGeomID bd1, - ConstGeomID bd2, - Vec3& contactPoint, - Vec3& contactNormal, - real_t& penetrationDepth, - const unsigned long numIterations = maxGJKIterations, - const real_t epaTol = epaTolerance ); - -template <typename Container> -bool collideGJK( GeomID bd1, - GeomID bd2, - Container& container, - const unsigned long numIterations = maxGJKIterations, - const real_t epaTol = epaTolerance ) -{ - real_t penetrationDepth; - Vec3 contactPoint; - Vec3 contactNormal; - bool retVal = collideGJK(bd1, bd2, contactPoint, contactNormal, penetrationDepth, numIterations, epaTol); - if (retVal) - { - container.push_back( Contact(bd1, bd2, contactPoint, contactNormal, penetrationDepth) ); - } - return retVal; -} - -} // namespace pe -} // namespace walberla diff --git a/src/pe/extern/libccd/.gitignore b/src/pe/extern/libccd/.gitignore deleted file mode 100644 index e3fa61345..000000000 --- a/src/pe/extern/libccd/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.o -*.a -ccd/config.h -ccd/config.h.in - diff --git a/src/pe/extern/libccd/BSD-LICENSE b/src/pe/extern/libccd/BSD-LICENSE deleted file mode 100644 index 1cb2dc53d..000000000 --- a/src/pe/extern/libccd/BSD-LICENSE +++ /dev/null @@ -1,44 +0,0 @@ -libccd -------- - -Copyright (c)2010-2012 Daniel Fiser <danfis@danfis.cz>, -Intelligent and Mobile Robotics Group, Department of Cybernetics, -Faculty of Electrical Engineering, Czech Technical University in Prague. -All rights reserved. - - -This work was supported by SYMBRION and REPLICATOR projects. -The SYMBRION project is funded by European Commission within the work -"Future and Emergent Technologies Proactive" under grant agreement no. -216342. -The REPLICATOR project is funded within the work programme "Cognitive -Systems, Interaction, Robotics" under grant agreement no. 216240. -http://www.symbrion.eu/ -http://www.replicators.eu/ - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/src/pe/extern/libccd/alloc.h b/src/pe/extern/libccd/alloc.h deleted file mode 100644 index 7cba3a4d7..000000000 --- a/src/pe/extern/libccd/alloc.h +++ /dev/null @@ -1,50 +0,0 @@ -/*** - * 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 *)realloc((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)) - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __CCD_ALLOC_H__ */ diff --git a/src/pe/extern/libccd/ccd.c b/src/pe/extern/libccd/ccd.c deleted file mode 100644 index 79b2f42c9..000000000 --- a/src/pe/extern/libccd/ccd.c +++ /dev/null @@ -1,1001 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2012 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. - */ - -#include <stdio.h> -#include <float.h> -#include <ccd/ccd.h> -#include <ccd/vec3.h> -#include "simplex.h" -#include "polytope.h" -#include "alloc.h" -#include "dbg.h" - - -/** Performs GJK algorithm. Returns 0 if intersection was found and simplex - * is filled with resulting polytope. */ -static int __ccdGJK(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *simplex); - -/** Performs GJK+EPA algorithm. Returns 0 if intersection was found and - * pt is filled with resulting polytope and nearest with pointer to - * nearest element (vertex, edge, face) of polytope to origin. */ -static int __ccdGJKEPA(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - - -/** Returns true if simplex contains origin. - * This function also alteres simplex and dir according to further - * processing of GJK algorithm. */ -static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir); -static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir); -static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir); -static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir); - -/** d = a x b x c */ -_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b, - const ccd_vec3_t *c, ccd_vec3_t *d); - - -/** Transforms simplex to polytope. It is assumed that simplex has 4 - * vertices. */ -static int simplexToPolytope4(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - -/** Transforms simplex to polytope, three vertices required */ -static int simplexToPolytope3(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - -/** Transforms simplex to polytope, two vertices required */ -static int simplexToPolytope2(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest); - -/** Expands polytope using new vertex v. - * Return 0 on success, -2 on memory allocation failure.*/ -static int expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el, - const ccd_support_t *newv); - -/** Finds next support point (at stores it in out argument). - * Returns 0 on success, -1 otherwise */ -static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_pt_el_t *el, - ccd_support_t *out); - - - -void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir) -{ - (void)(o1); - (void)(o2); - - ccdVec3Set(dir, CCD_ONE, CCD_ZERO, CCD_ZERO); -} - -int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd) -{ - ccd_simplex_t simplex; - return __ccdGJK(obj1, obj2, ccd, &simplex) == 0; -} - -int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_vec3_t *sep) -{ - ccd_pt_t polytope; - ccd_pt_el_t *nearest; - int ret; - - ccdPtInit(&polytope); - - ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest); - - // set separation vector - if (nearest) - ccdVec3Copy(sep, &nearest->witness); - - ccdPtDestroy(&polytope); - - return ret; -} - - -static int penEPAPosCmp(const void *a, const void *b) -{ - ccd_pt_vertex_t *v1, *v2; - v1 = *(ccd_pt_vertex_t **)a; - v2 = *(ccd_pt_vertex_t **)b; - - if (ccdEq(v1->dist, v2->dist)){ - return 0; - }else if (v1->dist < v2->dist){ - return -1; - }else{ - return 1; - } -} - -static int penEPAPos(const ccd_pt_t *pt, const ccd_pt_el_t * nearest, - ccd_vec3_t *pos) -{ - (void)(nearest); - - ccd_pt_vertex_t *v; - ccd_pt_vertex_t **vs; - size_t i, len; - ccd_real_t scale; - - // compute median - len = 0; - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - len++; - } - - vs = CCD_ALLOC_ARR(ccd_pt_vertex_t *, len); - if (vs == NULL) - return -1; - - i = 0; - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - vs[i++] = v; - } - - qsort(vs, len, sizeof(ccd_pt_vertex_t *), penEPAPosCmp); - - ccdVec3Set(pos, CCD_ZERO, CCD_ZERO, CCD_ZERO); - scale = CCD_ZERO; - if (len % 2 == 1) - len++; - - for (i = 0; i < len / 2; i++){ - ccdVec3Add(pos, &vs[i]->v.v1); - ccdVec3Add(pos, &vs[i]->v.v2); - scale += CCD_REAL(2.); - } - ccdVec3Scale(pos, CCD_ONE / scale); - - free(vs); - - return 0; -} - -int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - ccd_pt_t polytope; - ccd_pt_el_t *nearest; - int ret; - - ccdPtInit(&polytope); - - ret = __ccdGJKEPA(obj1, obj2, ccd, &polytope, &nearest); - - // set separation vector - if (ret == 0 && nearest){ - // compute depth of penetration - *depth = CCD_SQRT(nearest->dist); - - // store normalized direction vector - ccdVec3Copy(dir, &nearest->witness); - ccdVec3Normalize(dir); - - // compute position - if (penEPAPos(&polytope, nearest, pos) != 0){ - ccdPtDestroy(&polytope); - return -2; - } - } - - ccdPtDestroy(&polytope); - - return ret; -} - - -static int __ccdGJK(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *simplex) -{ - unsigned long iterations; - ccd_vec3_t dir; // direction vector - ccd_support_t last; // last support point - int do_simplex_res; - - // initialize simplex struct - ccdSimplexInit(simplex); - - // get first direction - ccd->first_dir(obj1, obj2, &dir); - // get first support point - __ccdSupport(obj1, obj2, &dir, ccd, &last); - // and add this point to simplex as last one - ccdSimplexAdd(simplex, &last); - - // set up direction vector to as (O - last) which is exactly -last - ccdVec3Copy(&dir, &last.v); - ccdVec3Scale(&dir, -CCD_ONE); - - // start iterations - for (iterations = 0UL; iterations < ccd->max_iterations; ++iterations) { - // obtain support point - __ccdSupport(obj1, obj2, &dir, ccd, &last); - - // check if farthest point in Minkowski difference in direction dir - // isn't somewhere before origin (the test on negative dot product) - // - because if it is, objects are not intersecting at all. - if (ccdVec3Dot(&last.v, &dir) < CCD_ZERO){ - return -1; // intersection not found - } - - // add last support vector to simplex - ccdSimplexAdd(simplex, &last); - - // if doSimplex returns 1 if objects intersect, -1 if objects don't - // intersect and 0 if algorithm should continue - do_simplex_res = doSimplex(simplex, &dir); - if (do_simplex_res == 1){ - return 0; // intersection found - }else if (do_simplex_res == -1){ - return -1; // intersection not found - } - - if (ccdIsZero(ccdVec3Len2(&dir))){ - return -1; // intersection not found - } - } - - // intersection wasn't found - return -1; -} - -static int __ccdGJKEPA(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_pt_t *polytope, ccd_pt_el_t **nearest) -{ - ccd_simplex_t simplex; - ccd_support_t supp; // support point - int ret, size; - - *nearest = NULL; - - // run GJK and obtain terminal simplex - ret = __ccdGJK(obj1, obj2, ccd, &simplex); - if (ret != 0) - return -1; - - // transform simplex to polytope - simplex won't be used anymore - size = ccdSimplexSize(&simplex); - if (size == 4){ - ret = simplexToPolytope4(obj1, obj2, ccd, &simplex, polytope, nearest); - }else if (size == 3){ - ret = simplexToPolytope3(obj1, obj2, ccd, &simplex, polytope, nearest); - }else{ // size == 2 - ret = simplexToPolytope2(obj1, obj2, ccd, &simplex, polytope, nearest); - } - - if (ret == -1){ - // touching contact - return 0; - }else if (ret == -2){ - // failed memory allocation - return -2; - } - - - while (1){ - // get triangle nearest to origin - *nearest = ccdPtNearest(polytope); - - // get next support point - if (nextSupport(obj1, obj2, ccd, *nearest, &supp) != 0) - break; - - // expand nearest triangle using new point - supp - if (expandPolytope(polytope, *nearest, &supp) != 0) - return -2; - } - - return 0; -} - - - -static int doSimplex2(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - const ccd_support_t *A, *B; - ccd_vec3_t AB, AO, tmp; - ccd_real_t dot; - - // get last added as A - A = ccdSimplexLast(simplex); - // get the other point - B = ccdSimplexPoint(simplex, 0); - // compute AB oriented segment - ccdVec3Sub2(&AB, &B->v, &A->v); - // compute AO vector - ccdVec3Copy(&AO, &A->v); - ccdVec3Scale(&AO, -CCD_ONE); - - // dot product AB . AO - dot = ccdVec3Dot(&AB, &AO); - - // check if origin doesn't lie on AB segment - ccdVec3Cross(&tmp, &AB, &AO); - if (ccdIsZero(ccdVec3Len2(&tmp)) && dot > CCD_ZERO){ - return 1; - } - - // check if origin is in area where AB segment is - if (ccdIsZero(dot) || dot < CCD_ZERO){ - // origin is in outside are of A - ccdSimplexSet(simplex, 0, A); - ccdSimplexSetSize(simplex, 1); - ccdVec3Copy(dir, &AO); - }else{ - // origin is in area where AB segment is - - // keep simplex untouched and set direction to - // AB x AO x AB - tripleCross(&AB, &AO, &AB, dir); - } - - return 0; -} - -static int doSimplex3(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - const ccd_support_t *A, *B, *C; - ccd_vec3_t AO, AB, AC, ABC, tmp; - ccd_real_t dot, dist; - - // get last added as A - A = ccdSimplexLast(simplex); - // get the other points - B = ccdSimplexPoint(simplex, 1); - C = ccdSimplexPoint(simplex, 0); - - // check touching contact - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL); - if (ccdIsZero(dist)){ - return 1; - } - - // check if triangle is really triangle (has area > 0) - // if not simplex can't be expanded and thus no itersection is found - if (ccdVec3Eq(&A->v, &B->v) || ccdVec3Eq(&A->v, &C->v)){ - return -1; - } - - // compute AO vector - ccdVec3Copy(&AO, &A->v); - ccdVec3Scale(&AO, -CCD_ONE); - - // compute AB and AC segments and ABC vector (perpendircular to triangle) - ccdVec3Sub2(&AB, &B->v, &A->v); - ccdVec3Sub2(&AC, &C->v, &A->v); - ccdVec3Cross(&ABC, &AB, &AC); - - ccdVec3Cross(&tmp, &ABC, &AC); - dot = ccdVec3Dot(&tmp, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - dot = ccdVec3Dot(&AC, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - // C is already in place - ccdSimplexSet(simplex, 1, A); - ccdSimplexSetSize(simplex, 2); - tripleCross(&AC, &AO, &AC, dir); - }else{ -ccd_do_simplex3_45: - dot = ccdVec3Dot(&AB, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - ccdSimplexSet(simplex, 0, B); - ccdSimplexSet(simplex, 1, A); - ccdSimplexSetSize(simplex, 2); - tripleCross(&AB, &AO, &AB, dir); - }else{ - ccdSimplexSet(simplex, 0, A); - ccdSimplexSetSize(simplex, 1); - ccdVec3Copy(dir, &AO); - } - } - }else{ - ccdVec3Cross(&tmp, &AB, &ABC); - dot = ccdVec3Dot(&tmp, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - goto ccd_do_simplex3_45; - }else{ - dot = ccdVec3Dot(&ABC, &AO); - if (ccdIsZero(dot) || dot > CCD_ZERO){ - ccdVec3Copy(dir, &ABC); - }else{ - ccd_support_t Ctmp; - ccdSupportCopy(&Ctmp, C); - ccdSimplexSet(simplex, 0, B); - ccdSimplexSet(simplex, 1, &Ctmp); - - ccdVec3Copy(dir, &ABC); - ccdVec3Scale(dir, -CCD_ONE); - } - } - } - - return 0; -} - -static int doSimplex4(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - const ccd_support_t *A, *B, *C, *D; - ccd_vec3_t AO, AB, AC, AD, ABC, ACD, ADB; - int B_on_ACD, C_on_ADB, D_on_ABC; - int AB_O, AC_O, AD_O; - ccd_real_t dist; - - // get last added as A - A = ccdSimplexLast(simplex); - // get the other points - B = ccdSimplexPoint(simplex, 2); - C = ccdSimplexPoint(simplex, 1); - D = ccdSimplexPoint(simplex, 0); - - // check if tetrahedron is really tetrahedron (has volume > 0) - // if it is not simplex can't be expanded and thus no intersection is - // found - dist = ccdVec3PointTriDist2(&A->v, &B->v, &C->v, &D->v, NULL); - if (ccdIsZero(dist)){ - return -1; - } - - // check if origin lies on some of tetrahedron's face - if so objects - // intersect - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &C->v, NULL); - if (ccdIsZero(dist)) - return 1; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &C->v, &D->v, NULL); - if (ccdIsZero(dist)) - return 1; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &A->v, &B->v, &D->v, NULL); - if (ccdIsZero(dist)) - return 1; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &B->v, &C->v, &D->v, NULL); - if (ccdIsZero(dist)) - return 1; - - // compute AO, AB, AC, AD segments and ABC, ACD, ADB normal vectors - ccdVec3Copy(&AO, &A->v); - ccdVec3Scale(&AO, -CCD_ONE); - ccdVec3Sub2(&AB, &B->v, &A->v); - ccdVec3Sub2(&AC, &C->v, &A->v); - ccdVec3Sub2(&AD, &D->v, &A->v); - ccdVec3Cross(&ABC, &AB, &AC); - ccdVec3Cross(&ACD, &AC, &AD); - ccdVec3Cross(&ADB, &AD, &AB); - - // side (positive or negative) of B, C, D relative to planes ACD, ADB - // and ABC respectively - B_on_ACD = ccdSign(ccdVec3Dot(&ACD, &AB)); - C_on_ADB = ccdSign(ccdVec3Dot(&ADB, &AC)); - D_on_ABC = ccdSign(ccdVec3Dot(&ABC, &AD)); - - // whether origin is on same side of ACD, ADB, ABC as B, C, D - // respectively - AB_O = ccdSign(ccdVec3Dot(&ACD, &AO)) == B_on_ACD; - AC_O = ccdSign(ccdVec3Dot(&ADB, &AO)) == C_on_ADB; - AD_O = ccdSign(ccdVec3Dot(&ABC, &AO)) == D_on_ABC; - - if (AB_O && AC_O && AD_O){ - // origin is in tetrahedron - return 1; - - // rearrange simplex to triangle and call doSimplex3() - }else if (!AB_O){ - // B is farthest from the origin among all of the tetrahedron's - // points, so remove it from the list and go on with the triangle - // case - - // D and C are in place - ccdSimplexSet(simplex, 2, A); - ccdSimplexSetSize(simplex, 3); - }else if (!AC_O){ - // C is farthest - ccdSimplexSet(simplex, 1, D); - ccdSimplexSet(simplex, 0, B); - ccdSimplexSet(simplex, 2, A); - ccdSimplexSetSize(simplex, 3); - }else{ // (!AD_O) - ccdSimplexSet(simplex, 0, C); - ccdSimplexSet(simplex, 1, B); - ccdSimplexSet(simplex, 2, A); - ccdSimplexSetSize(simplex, 3); - } - - return doSimplex3(simplex, dir); -} - -static int doSimplex(ccd_simplex_t *simplex, ccd_vec3_t *dir) -{ - if (ccdSimplexSize(simplex) == 2){ - // simplex contains segment only one segment - return doSimplex2(simplex, dir); - }else if (ccdSimplexSize(simplex) == 3){ - // simplex contains triangle - return doSimplex3(simplex, dir); - }else{ // ccdSimplexSize(simplex) == 4 - // tetrahedron - this is the only shape which can encapsule origin - // so doSimplex4() also contains test on it - return doSimplex4(simplex, dir); - } -} - - -_ccd_inline void tripleCross(const ccd_vec3_t *a, const ccd_vec3_t *b, - const ccd_vec3_t *c, ccd_vec3_t *d) -{ - ccd_vec3_t e; - ccdVec3Cross(&e, a, b); - ccdVec3Cross(d, &e, c); -} - - - -/** Transforms simplex to polytope. It is assumed that simplex has 4 - * vertices! */ -static int simplexToPolytope4(const void *obj1, const void *obj2, - const ccd_t *ccd, - ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest) -{ - const ccd_support_t *a, *b, *c, *d; - int use_polytope3; - ccd_real_t dist; - ccd_pt_vertex_t *v[4]; - ccd_pt_edge_t *e[6]; - size_t i; - - a = ccdSimplexPoint(simplex, 0); - b = ccdSimplexPoint(simplex, 1); - c = ccdSimplexPoint(simplex, 2); - d = ccdSimplexPoint(simplex, 3); - - // check if origin lies on some of tetrahedron's face - if so use - // simplexToPolytope3() - use_polytope3 = 0; - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &c->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - } - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &c->v, &d->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - ccdSimplexSet(simplex, 1, c); - ccdSimplexSet(simplex, 2, d); - } - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &a->v, &b->v, &d->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - ccdSimplexSet(simplex, 2, d); - } - dist = ccdVec3PointTriDist2(ccd_vec3_origin, &b->v, &c->v, &d->v, NULL); - if (ccdIsZero(dist)){ - use_polytope3 = 1; - ccdSimplexSet(simplex, 0, b); - ccdSimplexSet(simplex, 1, c); - ccdSimplexSet(simplex, 2, d); - } - - if (use_polytope3){ - ccdSimplexSetSize(simplex, 3); - return simplexToPolytope3(obj1, obj2, ccd, simplex, pt, nearest); - } - - // no touching contact - simply create tetrahedron - for (i = 0; i < 4; i++){ - v[i] = ccdPtAddVertex(pt, ccdSimplexPoint(simplex, (int)i)); - } - - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[0]); - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - e[4] = ccdPtAddEdge(pt, v[3], v[1]); - e[5] = ccdPtAddEdge(pt, v[3], v[2]); - - // ccdPtAdd*() functions return NULL either if the memory allocation - // failed of if any of the input pointers are NULL, so the bad - // allocation can be checked by the last calls of ccdPtAddFace() - // because the rest of the bad allocations eventually "bubble up" here - if (ccdPtAddFace(pt, e[0], e[1], e[2]) == NULL - || ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL - || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL - || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL){ - return -2; - } - - return 0; -} - -/** Transforms simplex to polytope, three vertices required */ -static int simplexToPolytope3(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest) -{ - const ccd_support_t *a, *b, *c; - ccd_support_t d, d2; - ccd_vec3_t ab, ac, dir; - ccd_pt_vertex_t *v[5]; - ccd_pt_edge_t *e[9]; - ccd_real_t dist, dist2; - - *nearest = NULL; - - a = ccdSimplexPoint(simplex, 0); - b = ccdSimplexPoint(simplex, 1); - c = ccdSimplexPoint(simplex, 2); - - // If only one triangle left from previous GJK run origin lies on this - // triangle. So it is necessary to expand triangle into two - // tetrahedrons connected with base (which is exactly abc triangle). - - // get next support point in direction of normal of triangle - ccdVec3Sub2(&ab, &b->v, &a->v); - ccdVec3Sub2(&ac, &c->v, &a->v); - ccdVec3Cross(&dir, &ab, &ac); - __ccdSupport(obj1, obj2, &dir, ccd, &d); - dist = ccdVec3PointTriDist2(&d.v, &a->v, &b->v, &c->v, NULL); - - // and second one take in opposite direction - ccdVec3Scale(&dir, -CCD_ONE); - __ccdSupport(obj1, obj2, &dir, ccd, &d2); - dist2 = ccdVec3PointTriDist2(&d2.v, &a->v, &b->v, &c->v, NULL); - - // check if face isn't already on edge of minkowski sum and thus we - // have touching contact - if (ccdIsZero(dist) || ccdIsZero(dist2)){ - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, b); - v[2] = ccdPtAddVertex(pt, c); - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[0]); - *nearest = (ccd_pt_el_t *)ccdPtAddFace(pt, e[0], e[1], e[2]); - if (*nearest == NULL) - return -2; - - return -1; - } - - // form polyhedron - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, b); - v[2] = ccdPtAddVertex(pt, c); - v[3] = ccdPtAddVertex(pt, &d); - v[4] = ccdPtAddVertex(pt, &d2); - - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[0]); - - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - e[4] = ccdPtAddEdge(pt, v[3], v[1]); - e[5] = ccdPtAddEdge(pt, v[3], v[2]); - - e[6] = ccdPtAddEdge(pt, v[4], v[0]); - e[7] = ccdPtAddEdge(pt, v[4], v[1]); - e[8] = ccdPtAddEdge(pt, v[4], v[2]); - - if (ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL - || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL - || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL - - || ccdPtAddFace(pt, e[6], e[7], e[0]) == NULL - || ccdPtAddFace(pt, e[7], e[8], e[1]) == NULL - || ccdPtAddFace(pt, e[8], e[6], e[2]) == NULL){ - return -2; - } - - return 0; -} - -/** Transforms simplex to polytope, two vertices required */ -static int simplexToPolytope2(const void *obj1, const void *obj2, - const ccd_t *ccd, - const ccd_simplex_t *simplex, - ccd_pt_t *pt, ccd_pt_el_t **nearest) -{ - const ccd_support_t *a, *b; - ccd_vec3_t ab, ac, dir; - ccd_support_t supp[4]; - ccd_pt_vertex_t *v[6]; - ccd_pt_edge_t *e[12]; - size_t i; - int found; - - a = ccdSimplexPoint(simplex, 0); - b = ccdSimplexPoint(simplex, 1); - - // This situation is a bit tricky. If only one segment comes from - // previous run of GJK - it means that either this segment is on - // minkowski edge (and thus we have touch contact) or it it isn't and - // therefore segment is somewhere *inside* minkowski sum and it *must* - // be possible to fully enclose this segment with polyhedron formed by - // at least 8 triangle faces. - - // get first support point (any) - found = 0; - for (i = 0; i < ccd_points_on_sphere_len; i++){ - __ccdSupport(obj1, obj2, &ccd_points_on_sphere[i], ccd, &supp[0]); - if (!ccdVec3Eq(&a->v, &supp[0].v) && !ccdVec3Eq(&b->v, &supp[0].v)){ - found = 1; - break; - } - } - if (!found) - goto simplexToPolytope2_touching_contact; - - // get second support point in opposite direction than supp[0] - ccdVec3Copy(&dir, &supp[0].v); - ccdVec3Scale(&dir, -CCD_ONE); - __ccdSupport(obj1, obj2, &dir, ccd, &supp[1]); - if (ccdVec3Eq(&a->v, &supp[1].v) || ccdVec3Eq(&b->v, &supp[1].v)) - goto simplexToPolytope2_touching_contact; - - // next will be in direction of normal of triangle a,supp[0],supp[1] - ccdVec3Sub2(&ab, &supp[0].v, &a->v); - ccdVec3Sub2(&ac, &supp[1].v, &a->v); - ccdVec3Cross(&dir, &ab, &ac); - __ccdSupport(obj1, obj2, &dir, ccd, &supp[2]); - if (ccdVec3Eq(&a->v, &supp[2].v) || ccdVec3Eq(&b->v, &supp[2].v)) - goto simplexToPolytope2_touching_contact; - - // and last one will be in opposite direction - ccdVec3Scale(&dir, -CCD_ONE); - __ccdSupport(obj1, obj2, &dir, ccd, &supp[3]); - if (ccdVec3Eq(&a->v, &supp[3].v) || ccdVec3Eq(&b->v, &supp[3].v)) - goto simplexToPolytope2_touching_contact; - - goto simplexToPolytope2_not_touching_contact; -simplexToPolytope2_touching_contact: - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, b); - *nearest = (ccd_pt_el_t *)ccdPtAddEdge(pt, v[0], v[1]); - if (*nearest == NULL) - return -2; - - return -1; - -simplexToPolytope2_not_touching_contact: - // form polyhedron - v[0] = ccdPtAddVertex(pt, a); - v[1] = ccdPtAddVertex(pt, &supp[0]); - v[2] = ccdPtAddVertex(pt, b); - v[3] = ccdPtAddVertex(pt, &supp[1]); - v[4] = ccdPtAddVertex(pt, &supp[2]); - v[5] = ccdPtAddVertex(pt, &supp[3]); - - e[0] = ccdPtAddEdge(pt, v[0], v[1]); - e[1] = ccdPtAddEdge(pt, v[1], v[2]); - e[2] = ccdPtAddEdge(pt, v[2], v[3]); - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - - e[4] = ccdPtAddEdge(pt, v[4], v[0]); - e[5] = ccdPtAddEdge(pt, v[4], v[1]); - e[6] = ccdPtAddEdge(pt, v[4], v[2]); - e[7] = ccdPtAddEdge(pt, v[4], v[3]); - - e[8] = ccdPtAddEdge(pt, v[5], v[0]); - e[9] = ccdPtAddEdge(pt, v[5], v[1]); - e[10] = ccdPtAddEdge(pt, v[5], v[2]); - e[11] = ccdPtAddEdge(pt, v[5], v[3]); - - if (ccdPtAddFace(pt, e[4], e[5], e[0]) == NULL - || ccdPtAddFace(pt, e[5], e[6], e[1]) == NULL - || ccdPtAddFace(pt, e[6], e[7], e[2]) == NULL - || ccdPtAddFace(pt, e[7], e[4], e[3]) == NULL - - || ccdPtAddFace(pt, e[8], e[9], e[0]) == NULL - || ccdPtAddFace(pt, e[9], e[10], e[1]) == NULL - || ccdPtAddFace(pt, e[10], e[11], e[2]) == NULL - || ccdPtAddFace(pt, e[11], e[8], e[3]) == NULL){ - return -2; - } - - return 0; -} - -/** Expands polytope's tri by new vertex v. Triangle tri is replaced by - * three triangles each with one vertex in v. */ -static int expandPolytope(ccd_pt_t *pt, ccd_pt_el_t *el, - const ccd_support_t *newv) -{ - ccd_pt_vertex_t *v[5]; - ccd_pt_edge_t *e[8]; - ccd_pt_face_t *f[2]; - - - // element can be either segment or triangle - if (el->type == CCD_PT_EDGE){ - // In this case, segment should be replaced by new point. - // Simpliest case is when segment stands alone and in this case - // this segment is replaced by two other segments both connected to - // newv. - // Segment can be also connected to max two faces and in that case - // each face must be replaced by two other faces. To do this - // correctly it is necessary to have correctly ordered edges and - // vertices which is exactly what is done in following code. - // - - ccdPtEdgeVertices((const ccd_pt_edge_t *)el, &v[0], &v[2]); - - ccdPtEdgeFaces((ccd_pt_edge_t *)el, &f[0], &f[1]); - - if (f[0]){ - ccdPtFaceEdges(f[0], &e[0], &e[1], &e[2]); - if (e[0] == (ccd_pt_edge_t *)el){ - e[0] = e[2]; - }else if (e[1] == (ccd_pt_edge_t *)el){ - e[1] = e[2]; - } - ccdPtEdgeVertices(e[0], &v[1], &v[3]); - if (v[1] != v[0] && v[3] != v[0]){ - e[2] = e[0]; - e[0] = e[1]; - e[1] = e[2]; - if (v[1] == v[2]) - v[1] = v[3]; - }else{ - if (v[1] == v[0]) - v[1] = v[3]; - } - - if (f[1]){ - ccdPtFaceEdges(f[1], &e[2], &e[3], &e[4]); - if (e[2] == (ccd_pt_edge_t *)el){ - e[2] = e[4]; - }else if (e[3] == (ccd_pt_edge_t *)el){ - e[3] = e[4]; - } - ccdPtEdgeVertices(e[2], &v[3], &v[4]); - if (v[3] != v[2] && v[4] != v[2]){ - e[4] = e[2]; - e[2] = e[3]; - e[3] = e[4]; - if (v[3] == v[0]) - v[3] = v[4]; - }else{ - if (v[3] == v[2]) - v[3] = v[4]; - } - } - - - v[4] = ccdPtAddVertex(pt, newv); - - ccdPtDelFace(pt, f[0]); - if (f[1]){ - ccdPtDelFace(pt, f[1]); - ccdPtDelEdge(pt, (ccd_pt_edge_t *)el); - } - - e[4] = ccdPtAddEdge(pt, v[4], v[2]); - e[5] = ccdPtAddEdge(pt, v[4], v[0]); - e[6] = ccdPtAddEdge(pt, v[4], v[1]); - if (f[1]) - e[7] = ccdPtAddEdge(pt, v[4], v[3]); - - - if (ccdPtAddFace(pt, e[1], e[4], e[6]) == NULL - || ccdPtAddFace(pt, e[0], e[6], e[5]) == NULL){ - return -2; - } - - if (f[1]){ - if (ccdPtAddFace(pt, e[3], e[5], e[7]) == NULL - || ccdPtAddFace(pt, e[4], e[7], e[2]) == NULL){ - return -2; - } - }else{ - if (ccdPtAddFace(pt, e[4], e[5], (ccd_pt_edge_t *)el) == NULL) - return -2; - } - } - }else{ // el->type == CCD_PT_FACE - // replace triangle by tetrahedron without base (base would be the - // triangle that will be removed) - - // get triplet of surrounding edges and vertices of triangle face - ccdPtFaceEdges((const ccd_pt_face_t *)el, &e[0], &e[1], &e[2]); - ccdPtEdgeVertices(e[0], &v[0], &v[1]); - ccdPtEdgeVertices(e[1], &v[2], &v[3]); - - // following code sorts edges to have e[0] between vertices 0-1, - // e[1] between 1-2 and e[2] between 2-0 - if (v[2] != v[1] && v[3] != v[1]){ - // swap e[1] and e[2] - e[3] = e[1]; - e[1] = e[2]; - e[2] = e[3]; - } - if (v[3] != v[0] && v[3] != v[1]) - v[2] = v[3]; - - // remove triangle face - ccdPtDelFace(pt, (ccd_pt_face_t *)el); - - // expand triangle to tetrahedron - v[3] = ccdPtAddVertex(pt, newv); - e[3] = ccdPtAddEdge(pt, v[3], v[0]); - e[4] = ccdPtAddEdge(pt, v[3], v[1]); - e[5] = ccdPtAddEdge(pt, v[3], v[2]); - - if (ccdPtAddFace(pt, e[3], e[4], e[0]) == NULL - || ccdPtAddFace(pt, e[4], e[5], e[1]) == NULL - || ccdPtAddFace(pt, e[5], e[3], e[2]) == NULL){ - return -2; - } - } - - return 0; -} - -/** Finds next support point (and stores it in out argument). - * Returns 0 on success, -1 otherwise */ -static int nextSupport(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_pt_el_t *el, - ccd_support_t *out) -{ - ccd_vec3_t *a, *b, *c; - ccd_real_t dist; - - if (el->type == CCD_PT_VERTEX) - return -1; - - // touch contact - if (ccdIsZero(el->dist)) - return -1; - - __ccdSupport(obj1, obj2, &el->witness, ccd, out); - - // Compute dist of support point along element witness point direction - // so we can determine whether we expanded a polytope surrounding the - // origin a bit. - dist = ccdVec3Dot(&out->v, &el->witness); - - if (dist - el->dist < ccd->epa_tolerance) - return -1; - - if (el->type == CCD_PT_EDGE){ - // fetch end points of edge - ccdPtEdgeVec3((ccd_pt_edge_t *)el, &a, &b); - - // get distance from segment - dist = ccdVec3PointSegmentDist2(&out->v, a, b, NULL); - }else{ // el->type == CCD_PT_FACE - // fetch vertices of triangle face - ccdPtFaceVec3((ccd_pt_face_t *)el, &a, &b, &c); - - // check if new point can significantly expand polytope - dist = ccdVec3PointTriDist2(&out->v, a, b, c, NULL); - } - - if (dist < ccd->epa_tolerance) - return -1; - - return 0; -} diff --git a/src/pe/extern/libccd/ccd/ccd.h b/src/pe/extern/libccd/ccd/ccd.h deleted file mode 100644 index fb8df75a0..000000000 --- a/src/pe/extern/libccd/ccd/ccd.h +++ /dev/null @@ -1,154 +0,0 @@ -/*** - * 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/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 - ccd_real_t dist_tolerance; -}; -typedef struct _ccd_t ccd_t; - -/** - * Default first direction. - */ -_ccd_export 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); \ - (ccd)->dist_tolerance = CCD_REAL(1E-6); \ - } while(0) - - -/** - * Returns true if two given objects interest. - */ -_ccd_export 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. - * If memory allocation fails -2 is returned. - */ -_ccd_export 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. - * If memory allocation fails -2 is returned. - */ -_ccd_export 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. - */ -_ccd_export 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. - */ -_ccd_export 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/src/pe/extern/libccd/ccd/compiler.h b/src/pe/extern/libccd/ccd/compiler.h deleted file mode 100644 index b022e26e4..000000000 --- a/src/pe/extern/libccd/ccd/compiler.h +++ /dev/null @@ -1,83 +0,0 @@ -/*** - * 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 exported function. - */ -//#ifdef _WIN32 -//# ifdef libccd_EXPORTS -//# define _ccd_export __declspec(dllexport) -//# else /* libccd_EXPORTS */ -//# define _ccd_export __declspec(dllimport) -//# endif /* libccd_EXPORTS */ -//#else /* _WIN32 */ -//# define _ccd_export -//#endif /* _WIN32 */ - -#define _ccd_export - - -/** - * Marks inline function. - */ -#ifdef __GNUC__ -# define _ccd_inline static inline __attribute__((always_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 */ - -#ifdef _MSC_VER -// disable unsafe function warning -# ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -# endif -#endif /* _MSC_VER */ - -#endif /* __CCD_COMPILER_H__ */ - diff --git a/src/pe/extern/libccd/ccd/config.h.cmake.in b/src/pe/extern/libccd/ccd/config.h.cmake.in deleted file mode 100644 index 051500916..000000000 --- a/src/pe/extern/libccd/ccd/config.h.cmake.in +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CCD_CONFIG_H__ -#define __CCD_CONFIG_H__ - -#cmakedefine CCD_SINGLE -#cmakedefine CCD_DOUBLE - -#endif /* __CCD_CONFIG_H__ */ diff --git a/src/pe/extern/libccd/ccd/config.h.m4 b/src/pe/extern/libccd/ccd/config.h.m4 deleted file mode 100644 index 4c11fbab0..000000000 --- a/src/pe/extern/libccd/ccd/config.h.m4 +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CCD_CONFIG_H__ -#define __CCD_CONFIG_H__ - -ifdef(`USE_SINGLE', `#define CCD_SINGLE') -ifdef(`USE_DOUBLE', `#define CCD_DOUBLE') - -#endif /* __CCD_CONFIG_H__ */ diff --git a/src/pe/extern/libccd/ccd/quat.h b/src/pe/extern/libccd/ccd/quat.h deleted file mode 100644 index fc6753210..000000000 --- a/src/pe/extern/libccd/ccd/quat.h +++ /dev/null @@ -1,239 +0,0 @@ -/*** - * 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{ -#ifdef CCD_DOUBLE - s = sin(a)/n; -#else - s = sinf(a)/n; -#endif - -#ifdef CCD_DOUBLE - q->q[3] = cos(a); -#else - q->q[3] = cosf(a); -#endif - 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/src/pe/extern/libccd/ccd/vec3.h b/src/pe/extern/libccd/ccd/vec3.h deleted file mode 100644 index b0c1b338f..000000000 --- a/src/pe/extern/libccd/ccd/vec3.h +++ /dev/null @@ -1,339 +0,0 @@ -/*** - * libccd - * --------------------------------- - * Copyright (c)2010-2013 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/compiler.h> -#include <ccd/config.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 */ - -#ifdef WIN32 -# define CCD_FMIN(x, y) ((x) < (y) ? (x) : (y)) -#endif /* WIN32 */ - -#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 */ - -# ifndef CCD_FMIN -# define CCD_FMIN(x, y) (fminf((x), (y))) /*!< minimum of two floats */ -# endif /* CCD_FMIN */ - -#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 */ - -# ifndef CCD_FMIN -# define CCD_FMIN(x, y) (fmin((x), (y))) /*!< minimum of two floats */ -# endif /* CCD_FMIN */ - -#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); - -/** - * Substracts 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 distance^2 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_export ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P, - const ccd_vec3_t *a, - const ccd_vec3_t *b, - ccd_vec3_t *witness); - -/** - * Returns distance^2 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_export 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__ */ diff --git a/src/pe/extern/libccd/dbg.h b/src/pe/extern/libccd/dbg.h deleted file mode 100644 index f4852c1a0..000000000 --- a/src/pe/extern/libccd/dbg.h +++ /dev/null @@ -1,65 +0,0 @@ -/*** - * 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/src/pe/extern/libccd/list.h b/src/pe/extern/libccd/list.h deleted file mode 100644 index 40ea6328f..000000000 --- a/src/pe/extern/libccd/list.h +++ /dev/null @@ -1,155 +0,0 @@ -/*** - * 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 *new_element) -{ - new_element->prev = l->prev; - new_element->next = l; - l->prev->next = new_element; - l->prev = new_element; -} - -_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/src/pe/extern/libccd/mpr.c b/src/pe/extern/libccd/mpr.c deleted file mode 100644 index 5f5533a5b..000000000 --- a/src/pe/extern/libccd/mpr.c +++ /dev/null @@ -1,547 +0,0 @@ -/*** - * 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. - */ - -#include <stdlib.h> -#include <ccd/ccd.h> -#include "simplex.h" -#include "dbg.h" - -/** Finds origin (center) of Minkowski difference (actually it can be any - * interior point of Minkowski difference. */ -_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_support_t *center); - -/** Discovers initial portal - that is tetrahedron that intersects with - * origin ray (ray from center of Minkowski diff to (0,0,0). - * - * Returns -1 if already recognized that origin is outside Minkowski - * portal. - * Returns 1 if origin lies on v1 of simplex (only v0 and v1 are present - * in simplex). - * Returns 2 if origin lies on v0-v1 segment. - * Returns 0 if portal was built. - */ -static int discoverPortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal); - - -/** Expands portal towards origin and determine if objects intersect. - * Already established portal must be given as argument. - * If intersection is found 0 is returned, -1 otherwise */ -static int refinePortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal); - -/** Finds penetration info by expanding provided portal. */ -static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** Finds penetration info if origin lies on portal's v1 */ -static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** Find penetration info if origin lies on portal's segment v0-v1 */ -static void findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos); - -/** Finds position vector from fully established portal */ -static void findPos(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_simplex_t *portal, ccd_vec3_t *pos); - -/** Extends portal with new support point. - * Portal must have face v1-v2-v3 arranged to face outside portal. */ -_ccd_inline void expandPortal(ccd_simplex_t *portal, - const ccd_support_t *v4); - -/** Fill dir with direction outside portal. Portal's v1-v2-v3 face must be - * arranged in correct order! */ -_ccd_inline void portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir); - -/** Returns true if portal encapsules origin (0,0,0), dir is direction of - * v1-v2-v3 face. */ -_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal, - const ccd_vec3_t *dir); - -/** Returns true if portal with new point v4 would reach specified - * tolerance (i.e. returns true if portal can _not_ significantly expand - * within Minkowski difference). - * - * v4 is candidate for new point in portal, dir is direction in which v4 - * was obtained. */ -_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir, - const ccd_t *ccd); - -/** Returns true if portal expanded by new point v4 could possibly contain - * origin, dir is direction in which v4 was obtained. */ -_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir); - - -int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd) -{ - ccd_simplex_t portal; - int res; - - // Phase 1: Portal discovery - find portal that intersects with origin - // ray (ray from center of Minkowski diff to origin of coordinates) - res = discoverPortal(obj1, obj2, ccd, &portal); - if (res < 0) - return 0; - if (res > 0) - return 1; - - // Phase 2: Portal refinement - res = refinePortal(obj1, obj2, ccd, &portal); - return (res == 0 ? 1 : 0); -} - -int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - ccd_simplex_t portal; - int res; - - // Phase 1: Portal discovery - res = discoverPortal(obj1, obj2, ccd, &portal); - if (res < 0){ - // Origin isn't inside portal - no collision. - return -1; - - }else if (res == 1){ - // Touching contact on portal's v1. - findPenetrTouch(obj1, obj2, ccd, &portal, depth, dir, pos); - - }else if (res == 2){ - // Origin lies on v0-v1 segment. - findPenetrSegment(obj1, obj2, ccd, &portal, depth, dir, pos); - - }else if (res == 0){ - // Phase 2: Portal refinement - res = refinePortal(obj1, obj2, ccd, &portal); - if (res < 0) - return -1; - - // Phase 3. Penetration info - findPenetr(obj1, obj2, ccd, &portal, depth, dir, pos); - } - - return 0; -} - - - -_ccd_inline void findOrigin(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_support_t *center) -{ - ccd->center1(obj1, ¢er->v1); - ccd->center2(obj2, ¢er->v2); - ccdVec3Sub2(¢er->v, ¢er->v1, ¢er->v2); -} - -static int discoverPortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal) -{ - ccd_vec3_t dir, va, vb; - ccd_real_t dot; - int cont; - - // vertex 0 is center of portal - findOrigin(obj1, obj2, ccd, ccdSimplexPointW(portal, 0)); - ccdSimplexSetSize(portal, 1); - - if (ccdVec3Eq(&ccdSimplexPoint(portal, 0)->v, ccd_vec3_origin)){ - // Portal's center lies on origin (0,0,0) => we know that objects - // intersect but we would need to know penetration info. - // So move center little bit... - ccdVec3Set(&va, CCD_EPS * CCD_REAL(10.), CCD_ZERO, CCD_ZERO); - ccdVec3Add(&ccdSimplexPointW(portal, 0)->v, &va); - } - - - // vertex 1 = support in direction of origin - ccdVec3Copy(&dir, &ccdSimplexPoint(portal, 0)->v); - ccdVec3Scale(&dir, CCD_REAL(-1.)); - ccdVec3Normalize(&dir); - __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 1)); - ccdSimplexSetSize(portal, 2); - - // test if origin isn't outside of v1 - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &dir); - if (ccdIsZero(dot) || dot < CCD_ZERO) - return -1; - - - // vertex 2 - ccdVec3Cross(&dir, &ccdSimplexPoint(portal, 0)->v, - &ccdSimplexPoint(portal, 1)->v); - if (ccdIsZero(ccdVec3Len2(&dir))){ - if (ccdVec3Eq(&ccdSimplexPoint(portal, 1)->v, ccd_vec3_origin)){ - // origin lies on v1 - return 1; - }else{ - // origin lies on v0-v1 segment - return 2; - } - } - - ccdVec3Normalize(&dir); - __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 2)); - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &dir); - if (ccdIsZero(dot) || dot < CCD_ZERO) - return -1; - - ccdSimplexSetSize(portal, 3); - - // vertex 3 direction - ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Cross(&dir, &va, &vb); - ccdVec3Normalize(&dir); - - // it is better to form portal faces to be oriented "outside" origin - dot = ccdVec3Dot(&dir, &ccdSimplexPoint(portal, 0)->v); - if (dot > CCD_ZERO){ - ccdSimplexSwap(portal, 1, 2); - ccdVec3Scale(&dir, CCD_REAL(-1.)); - } - - while (ccdSimplexSize(portal) < 4){ - __ccdSupport(obj1, obj2, &dir, ccd, ccdSimplexPointW(portal, 3)); - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &dir); - if (ccdIsZero(dot) || dot < CCD_ZERO) - return -1; - - cont = 0; - - // test if origin is outside (v1, v0, v3) - set v2 as v3 and - // continue - ccdVec3Cross(&va, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 3)->v); - dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v); - if (dot < CCD_ZERO && !ccdIsZero(dot)){ - ccdSimplexSet(portal, 2, ccdSimplexPoint(portal, 3)); - cont = 1; - } - - if (!cont){ - // test if origin is outside (v3, v0, v2) - set v1 as v3 and - // continue - ccdVec3Cross(&va, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 2)->v); - dot = ccdVec3Dot(&va, &ccdSimplexPoint(portal, 0)->v); - if (dot < CCD_ZERO && !ccdIsZero(dot)){ - ccdSimplexSet(portal, 1, ccdSimplexPoint(portal, 3)); - cont = 1; - } - } - - if (cont){ - ccdVec3Sub2(&va, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Sub2(&vb, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 0)->v); - ccdVec3Cross(&dir, &va, &vb); - ccdVec3Normalize(&dir); - }else{ - ccdSimplexSetSize(portal, 4); - } - } - - return 0; -} - -static int refinePortal(const void *obj1, const void *obj2, - const ccd_t *ccd, ccd_simplex_t *portal) -{ - ccd_vec3_t dir; - ccd_support_t v4; - - while (1){ - // compute direction outside the portal (from v0 throught v1,v2,v3 - // face) - portalDir(portal, &dir); - - // test if origin is inside the portal - if (portalEncapsulesOrigin(portal, &dir)) - return 0; - - // get next support point - __ccdSupport(obj1, obj2, &dir, ccd, &v4); - - // test if v4 can expand portal to contain origin and if portal - // expanding doesn't reach given tolerance - if (!portalCanEncapsuleOrigin(portal, &v4, &dir) - || portalReachTolerance(portal, &v4, &dir, ccd)){ - return -1; - } - - // v1-v2-v3 triangle must be rearranged to face outside Minkowski - // difference (direction from v0). - expandPortal(portal, &v4); - } - - return -1; -} - - -static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *pdir, ccd_vec3_t *pos) -{ - ccd_vec3_t dir; - ccd_support_t v4; - unsigned long iterations; - - iterations = 0UL; - while (1){ - // compute portal direction and obtain next support point - portalDir(portal, &dir); - __ccdSupport(obj1, obj2, &dir, ccd, &v4); - - // reached tolerance -> find penetration info - if (portalReachTolerance(portal, &v4, &dir, ccd) - || iterations > ccd->max_iterations){ - *depth = ccdVec3PointTriDist2(ccd_vec3_origin, - &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 3)->v, - pdir); - *depth = CCD_SQRT(*depth); - ccdVec3Normalize(pdir); - - // barycentric coordinates: - findPos(obj1, obj2, ccd, portal, pos); - - return; - } - - expandPortal(portal, &v4); - - iterations++; - } -} - -static void findPenetrTouch(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - (void)(obj1); - (void)(obj2); - (void)(ccd); - // Touching contact on portal's v1 - so depth is zero and direction - // is unimportant and pos can be guessed - *depth = CCD_REAL(0.); - ccdVec3Copy(dir, ccd_vec3_origin); - - ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1); - ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2); - ccdVec3Scale(pos, 0.5); -} - -static void findPenetrSegment(const void *obj1, const void *obj2, const ccd_t *ccd, - ccd_simplex_t *portal, - ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos) -{ - (void)(obj1); - (void)(obj2); - (void)(ccd); - - /* - ccd_vec3_t vec; - ccd_real_t k; - */ - - // Origin lies on v0-v1 segment. - // Depth is distance to v1, direction also and position must be - // computed - - ccdVec3Copy(pos, &ccdSimplexPoint(portal, 1)->v1); - ccdVec3Add(pos, &ccdSimplexPoint(portal, 1)->v2); - ccdVec3Scale(pos, CCD_REAL(0.5)); - - /* - ccdVec3Sub2(&vec, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 0)->v); - k = CCD_SQRT(ccdVec3Len2(&ccdSimplexPoint(portal, 0)->v)); - k /= CCD_SQRT(ccdVec3Len2(&vec)); - ccdVec3Scale(&vec, -k); - ccdVec3Add(pos, &vec); - */ - - ccdVec3Copy(dir, &ccdSimplexPoint(portal, 1)->v); - *depth = CCD_SQRT(ccdVec3Len2(dir)); - ccdVec3Normalize(dir); -} - - -static void findPos(const void *obj1, const void *obj2, const ccd_t *ccd, - const ccd_simplex_t *portal, ccd_vec3_t *pos) -{ - (void)(obj1); - (void)(obj2); - (void)(ccd); - - ccd_vec3_t dir; - size_t i; - ccd_real_t b[4], sum, inv; - ccd_vec3_t vec, p1, p2; - - portalDir(portal, &dir); - - // use barycentric coordinates of tetrahedron to find origin - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 2)->v); - b[0] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 2)->v); - b[1] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 0)->v, - &ccdSimplexPoint(portal, 1)->v); - b[2] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 3)->v); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 1)->v); - b[3] = ccdVec3Dot(&vec, &ccdSimplexPoint(portal, 0)->v); - - sum = b[0] + b[1] + b[2] + b[3]; - - if (ccdIsZero(sum) || sum < CCD_ZERO){ - b[0] = CCD_REAL(0.); - - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 3)->v); - b[1] = ccdVec3Dot(&vec, &dir); - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 1)->v); - b[2] = ccdVec3Dot(&vec, &dir); - ccdVec3Cross(&vec, &ccdSimplexPoint(portal, 1)->v, - &ccdSimplexPoint(portal, 2)->v); - b[3] = ccdVec3Dot(&vec, &dir); - - sum = b[1] + b[2] + b[3]; - } - - inv = CCD_REAL(1.) / sum; - - ccdVec3Copy(&p1, ccd_vec3_origin); - ccdVec3Copy(&p2, ccd_vec3_origin); - for (i = 0; i < 4; i++){ - ccdVec3Copy(&vec, &ccdSimplexPoint(portal, (int)i)->v1); - ccdVec3Scale(&vec, b[i]); - ccdVec3Add(&p1, &vec); - - ccdVec3Copy(&vec, &ccdSimplexPoint(portal, (int)i)->v2); - ccdVec3Scale(&vec, b[i]); - ccdVec3Add(&p2, &vec); - } - ccdVec3Scale(&p1, inv); - ccdVec3Scale(&p2, inv); - - ccdVec3Copy(pos, &p1); - ccdVec3Add(pos, &p2); - ccdVec3Scale(pos, 0.5); -} - -_ccd_inline void expandPortal(ccd_simplex_t *portal, - const ccd_support_t *v4) -{ - ccd_real_t dot; - ccd_vec3_t v4v0; - - ccdVec3Cross(&v4v0, &v4->v, &ccdSimplexPoint(portal, 0)->v); - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, &v4v0); - if (dot > CCD_ZERO){ - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, &v4v0); - if (dot > CCD_ZERO){ - ccdSimplexSet(portal, 1, v4); - }else{ - ccdSimplexSet(portal, 3, v4); - } - }else{ - dot = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, &v4v0); - if (dot > CCD_ZERO){ - ccdSimplexSet(portal, 2, v4); - }else{ - ccdSimplexSet(portal, 1, v4); - } - } -} - -_ccd_inline void portalDir(const ccd_simplex_t *portal, ccd_vec3_t *dir) -{ - ccd_vec3_t v2v1, v3v1; - - ccdVec3Sub2(&v2v1, &ccdSimplexPoint(portal, 2)->v, - &ccdSimplexPoint(portal, 1)->v); - ccdVec3Sub2(&v3v1, &ccdSimplexPoint(portal, 3)->v, - &ccdSimplexPoint(portal, 1)->v); - ccdVec3Cross(dir, &v2v1, &v3v1); - ccdVec3Normalize(dir); -} - -_ccd_inline int portalEncapsulesOrigin(const ccd_simplex_t *portal, - const ccd_vec3_t *dir) -{ - ccd_real_t dot; - dot = ccdVec3Dot(dir, &ccdSimplexPoint(portal, 1)->v); - return ccdIsZero(dot) || dot > CCD_ZERO; -} - -_ccd_inline int portalReachTolerance(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir, - const ccd_t *ccd) -{ - ccd_real_t dv1, dv2, dv3, dv4; - ccd_real_t dot1, dot2, dot3; - - // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} - - dv1 = ccdVec3Dot(&ccdSimplexPoint(portal, 1)->v, dir); - dv2 = ccdVec3Dot(&ccdSimplexPoint(portal, 2)->v, dir); - dv3 = ccdVec3Dot(&ccdSimplexPoint(portal, 3)->v, dir); - dv4 = ccdVec3Dot(&v4->v, dir); - - dot1 = dv4 - dv1; - dot2 = dv4 - dv2; - dot3 = dv4 - dv3; - - dot1 = CCD_FMIN(dot1, dot2); - dot1 = CCD_FMIN(dot1, dot3); - - return ccdEq(dot1, ccd->mpr_tolerance) || dot1 < ccd->mpr_tolerance; -} - -_ccd_inline int portalCanEncapsuleOrigin(const ccd_simplex_t *portal, - const ccd_support_t *v4, - const ccd_vec3_t *dir) -{ - (void)(portal); - - ccd_real_t dot; - dot = ccdVec3Dot(&v4->v, dir); - return ccdIsZero(dot) || dot > CCD_ZERO; -} diff --git a/src/pe/extern/libccd/polytope.c b/src/pe/extern/libccd/polytope.c deleted file mode 100644 index 527016cde..000000000 --- a/src/pe/extern/libccd/polytope.c +++ /dev/null @@ -1,298 +0,0 @@ -/*** - * 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. - */ - -#include <stdio.h> -#include <float.h> -#include "polytope.h" -#include "alloc.h" - -_ccd_inline void _ccdPtNearestUpdate(ccd_pt_t *pt, ccd_pt_el_t *el) -{ - if (ccdEq(pt->nearest_dist, el->dist)){ - if (el->type < pt->nearest_type){ - pt->nearest = el; - pt->nearest_dist = el->dist; - pt->nearest_type = el->type; - } - }else if (el->dist < pt->nearest_dist){ - pt->nearest = el; - pt->nearest_dist = el->dist; - pt->nearest_type = el->type; - } -} - -static void _ccdPtNearestRenew(ccd_pt_t *pt) -{ - ccd_pt_vertex_t *v; - ccd_pt_edge_t *e; - ccd_pt_face_t *f; - - pt->nearest_dist = CCD_REAL_MAX; - pt->nearest_type = 3; - pt->nearest = NULL; - - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)v); - } - - ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)e); - } - - ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)f); - } -} - - - -void ccdPtInit(ccd_pt_t *pt) -{ - ccdListInit(&pt->vertices); - ccdListInit(&pt->edges); - ccdListInit(&pt->faces); - - pt->nearest = NULL; - pt->nearest_dist = CCD_REAL_MAX; - pt->nearest_type = 3; -} - -void ccdPtDestroy(ccd_pt_t *pt) -{ - ccd_pt_face_t *f, *f2; - ccd_pt_edge_t *e, *e2; - ccd_pt_vertex_t *v, *v2; - - // first delete all faces - ccdListForEachEntrySafe(&pt->faces, f, ccd_pt_face_t, f2, ccd_pt_face_t, list){ - ccdPtDelFace(pt, f); - } - - // delete all edges - ccdListForEachEntrySafe(&pt->edges, e, ccd_pt_edge_t, e2, ccd_pt_edge_t, list){ - ccdPtDelEdge(pt, e); - } - - // delete all vertices - ccdListForEachEntrySafe(&pt->vertices, v, ccd_pt_vertex_t, v2, ccd_pt_vertex_t, list){ - ccdPtDelVertex(pt, v); - } -} - - -ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v) -{ - ccd_pt_vertex_t *vert; - - vert = CCD_ALLOC(ccd_pt_vertex_t); - if (vert == NULL) - return NULL; - - vert->type = CCD_PT_VERTEX; - ccdSupportCopy(&vert->v, v); - - vert->dist = ccdVec3Len2(&vert->v.v); - ccdVec3Copy(&vert->witness, &vert->v.v); - - ccdListInit(&vert->edges); - - // add vertex to list - ccdListAppend(&pt->vertices, &vert->list); - - // update position in .nearest array - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)vert); - - return vert; -} - -ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1, - ccd_pt_vertex_t *v2) -{ - const ccd_vec3_t *a, *b; - ccd_pt_edge_t *edge; - - if (v1 == NULL || v2 == NULL) - return NULL; - - edge = CCD_ALLOC(ccd_pt_edge_t); - if (edge == NULL) - return NULL; - - edge->type = CCD_PT_EDGE; - edge->vertex[0] = v1; - edge->vertex[1] = v2; - edge->faces[0] = edge->faces[1] = NULL; - - a = &edge->vertex[0]->v.v; - b = &edge->vertex[1]->v.v; - edge->dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &edge->witness); - - ccdListAppend(&edge->vertex[0]->edges, &edge->vertex_list[0]); - ccdListAppend(&edge->vertex[1]->edges, &edge->vertex_list[1]); - - ccdListAppend(&pt->edges, &edge->list); - - // update position in .nearest array - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)edge); - - return edge; -} - -ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1, - ccd_pt_edge_t *e2, - ccd_pt_edge_t *e3) -{ - const ccd_vec3_t *a, *b, *c; - ccd_pt_face_t *face; - ccd_pt_edge_t *e; - size_t i; - - if (e1 == NULL || e2 == NULL || e3 == NULL) - return NULL; - - face = CCD_ALLOC(ccd_pt_face_t); - if (face == NULL) - return NULL; - - face->type = CCD_PT_FACE; - face->edge[0] = e1; - face->edge[1] = e2; - face->edge[2] = e3; - - // obtain triplet of vertices - a = &face->edge[0]->vertex[0]->v.v; - b = &face->edge[0]->vertex[1]->v.v; - e = face->edge[1]; - if (e->vertex[0] != face->edge[0]->vertex[0] - && e->vertex[0] != face->edge[0]->vertex[1]){ - c = &e->vertex[0]->v.v; - }else{ - c = &e->vertex[1]->v.v; - } - face->dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &face->witness); - - - for (i = 0; i < 3; i++){ - if (face->edge[i]->faces[0] == NULL){ - face->edge[i]->faces[0] = face; - }else{ - face->edge[i]->faces[1] = face; - } - } - - ccdListAppend(&pt->faces, &face->list); - - // update position in .nearest array - _ccdPtNearestUpdate(pt, (ccd_pt_el_t *)face); - - return face; -} - - -void ccdPtRecomputeDistances(ccd_pt_t *pt) -{ - ccd_pt_vertex_t *v; - ccd_pt_edge_t *e; - ccd_pt_face_t *f; - const ccd_vec3_t *a, *b, *c; - ccd_real_t dist; - - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - dist = ccdVec3Len2(&v->v.v); - v->dist = dist; - ccdVec3Copy(&v->witness, &v->v.v); - } - - ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ - a = &e->vertex[0]->v.v; - b = &e->vertex[1]->v.v; - dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &e->witness); - e->dist = dist; - } - - ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ - // obtain triplet of vertices - a = &f->edge[0]->vertex[0]->v.v; - b = &f->edge[0]->vertex[1]->v.v; - e = f->edge[1]; - if (e->vertex[0] != f->edge[0]->vertex[0] - && e->vertex[0] != f->edge[0]->vertex[1]){ - c = &e->vertex[0]->v.v; - }else{ - c = &e->vertex[1]->v.v; - } - - dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &f->witness); - f->dist = dist; - } -} - -ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt) -{ - if (!pt->nearest){ - _ccdPtNearestRenew(pt); - } - return pt->nearest; -} - - -void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn) -{ - FILE *fout; - - fout = fopen(fn, "a"); - if (fout == NULL) - return; - - ccdPtDumpSVT2(pt, fout); - - fclose(fout); -} - -void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *fout) -{ - ccd_pt_vertex_t *v, *a, *b, *c; - ccd_pt_edge_t *e; - ccd_pt_face_t *f; - size_t i; - - fprintf(fout, "-----\n"); - - fprintf(fout, "Points:\n"); - i = 0; - ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){ - v->id = (int)(i++); - fprintf(fout, "%lf %lf %lf\n", - ccdVec3X(&v->v.v), ccdVec3Y(&v->v.v), ccdVec3Z(&v->v.v)); - } - - fprintf(fout, "Edges:\n"); - ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){ - fprintf(fout, "%d %d\n", e->vertex[0]->id, e->vertex[1]->id); - } - - fprintf(fout, "Faces:\n"); - ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){ - a = f->edge[0]->vertex[0]; - b = f->edge[0]->vertex[1]; - c = f->edge[1]->vertex[0]; - if (c == a || c == b){ - c = f->edge[1]->vertex[1]; - } - fprintf(fout, "%d %d %d\n", a->id, b->id, c->id); - } -} diff --git a/src/pe/extern/libccd/polytope.h b/src/pe/extern/libccd/polytope.h deleted file mode 100644 index b671224eb..000000000 --- a/src/pe/extern/libccd/polytope.h +++ /dev/null @@ -1,322 +0,0 @@ -/*** - * 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 "support.h" -#include "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/src/pe/extern/libccd/simplex.h b/src/pe/extern/libccd/simplex.h deleted file mode 100644 index 8ae09c712..000000000 --- a/src/pe/extern/libccd/simplex.h +++ /dev/null @@ -1,104 +0,0 @@ -/*** - * 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/compiler.h> -#include "support.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/src/pe/extern/libccd/support.c b/src/pe/extern/libccd/support.c deleted file mode 100644 index 6c7f1cc65..000000000 --- a/src/pe/extern/libccd/support.c +++ /dev/null @@ -1,34 +0,0 @@ -/*** - * 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. - */ - -#include "support.h" - -void __ccdSupport(const void *obj1, const void *obj2, - const ccd_vec3_t *_dir, const ccd_t *ccd, - ccd_support_t *supp) -{ - ccd_vec3_t dir; - - ccdVec3Copy(&dir, _dir); - - ccd->support1(obj1, &dir, &supp->v1); - - ccdVec3Scale(&dir, -CCD_ONE); - ccd->support2(obj2, &dir, &supp->v2); - - ccdVec3Sub2(&supp->v, &supp->v1, &supp->v2); -} diff --git a/src/pe/extern/libccd/support.h b/src/pe/extern/libccd/support.h deleted file mode 100644 index 3372f5ef2..000000000 --- a/src/pe/extern/libccd/support.h +++ /dev/null @@ -1,55 +0,0 @@ -/*** - * 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/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/src/pe/extern/libccd/vec3.c b/src/pe/extern/libccd/vec3.c deleted file mode 100644 index f0a331f4f..000000000 --- a/src/pe/extern/libccd/vec3.c +++ /dev/null @@ -1,211 +0,0 @@ -/*** - * 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. - */ - -#include <stdio.h> -#include <ccd/vec3.h> -#include "dbg.h" - -static CCD_VEC3(__ccd_vec3_origin, CCD_ZERO, CCD_ZERO, CCD_ZERO); -ccd_vec3_t *ccd_vec3_origin = &__ccd_vec3_origin; - -static ccd_vec3_t points_on_sphere[] = { - CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-0.000000), CCD_REAL(-1.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL(-0.525725), CCD_REAL(-0.447219)), - CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL(-0.850649), CCD_REAL(-0.447219)), - CCD_VEC3_STATIC(CCD_REAL(-0.894426), CCD_REAL(-0.000000), CCD_REAL(-0.447216)), - CCD_VEC3_STATIC(CCD_REAL(-0.276388), CCD_REAL( 0.850649), CCD_REAL(-0.447220)), - CCD_VEC3_STATIC(CCD_REAL( 0.723608), CCD_REAL( 0.525725), CCD_REAL(-0.447219)), - CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL(-0.850649), CCD_REAL( 0.447220)), - CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL(-0.525725), CCD_REAL( 0.447219)), - CCD_VEC3_STATIC(CCD_REAL(-0.723608), CCD_REAL( 0.525725), CCD_REAL( 0.447219)), - CCD_VEC3_STATIC(CCD_REAL( 0.276388), CCD_REAL( 0.850649), CCD_REAL( 0.447219)), - CCD_VEC3_STATIC(CCD_REAL( 0.894426), CCD_REAL( 0.000000), CCD_REAL( 0.447216)), - CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 0.000000), CCD_REAL( 1.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL(-0.309011), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL(-0.499995), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL(-0.809012), CCD_REAL(-0.525738)), - CCD_VEC3_STATIC(CCD_REAL( 0.425323), CCD_REAL( 0.309011), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL( 0.850648), CCD_REAL(-0.000000), CCD_REAL(-0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.525730), CCD_REAL(-0.000000), CCD_REAL(-0.850652)), - CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL(-0.499997), CCD_REAL(-0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.162456), CCD_REAL( 0.499995), CCD_REAL(-0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.688190), CCD_REAL( 0.499997), CCD_REAL(-0.525736)), - CCD_VEC3_STATIC(CCD_REAL( 0.262869), CCD_REAL( 0.809012), CCD_REAL(-0.525738)), - CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL( 0.309013), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.951058), CCD_REAL(-0.309013), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.000000), CCD_REAL(-1.000000), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL(-0.809017), CCD_REAL( 0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL(-0.309013), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.951058), CCD_REAL( 0.309013), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL(-0.000000), CCD_REAL( 1.000000), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.587786), CCD_REAL( 0.809017), CCD_REAL(-0.000000)), - CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL(-0.499997), CCD_REAL( 0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL(-0.809012), CCD_REAL( 0.525738)), - CCD_VEC3_STATIC(CCD_REAL(-0.850648), CCD_REAL( 0.000000), CCD_REAL( 0.525736)), - CCD_VEC3_STATIC(CCD_REAL(-0.262869), CCD_REAL( 0.809012), CCD_REAL( 0.525738)), - CCD_VEC3_STATIC(CCD_REAL( 0.688190), CCD_REAL( 0.499997), CCD_REAL( 0.525736)), - CCD_VEC3_STATIC(CCD_REAL( 0.525730), CCD_REAL( 0.000000), CCD_REAL( 0.850652)), - CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL(-0.499995), CCD_REAL( 0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL(-0.309011), CCD_REAL( 0.850654)), - CCD_VEC3_STATIC(CCD_REAL(-0.425323), CCD_REAL( 0.309011), CCD_REAL( 0.850654)), - CCD_VEC3_STATIC(CCD_REAL( 0.162456), CCD_REAL( 0.499995), CCD_REAL( 0.850654)) -}; -ccd_vec3_t *ccd_points_on_sphere = points_on_sphere; -size_t ccd_points_on_sphere_len = sizeof(points_on_sphere) / sizeof(ccd_vec3_t); - - -_ccd_inline ccd_real_t __ccdVec3PointSegmentDist2(const ccd_vec3_t *P, - const ccd_vec3_t *x0, - const ccd_vec3_t *b, - ccd_vec3_t *witness) -{ - // The computation comes from solving equation of segment: - // S(t) = x0 + t.d - // where - x0 is initial point of segment - // - d is direction of segment from x0 (|d| > 0) - // - t belongs to <0, 1> interval - // - // Than, distance from a segment to some point P can be expressed: - // D(t) = |x0 + t.d - P|^2 - // which is distance from any point on segment. Minimization - // of this function brings distance from P to segment. - // Minimization of D(t) leads to simple quadratic equation that's - // solving is straightforward. - // - // Bonus of this method is witness point for free. - - ccd_real_t dist, t; - ccd_vec3_t d, a; - - // direction of segment - ccdVec3Sub2(&d, b, x0); - - // precompute vector from P to x0 - ccdVec3Sub2(&a, x0, P); - - t = -CCD_REAL(1.) * ccdVec3Dot(&a, &d); - t /= ccdVec3Len2(&d); - - if (t < CCD_ZERO || ccdIsZero(t)){ - dist = ccdVec3Dist2(x0, P); - if (witness) - ccdVec3Copy(witness, x0); - }else if (t > CCD_ONE || ccdEq(t, CCD_ONE)){ - dist = ccdVec3Dist2(b, P); - if (witness) - ccdVec3Copy(witness, b); - }else{ - if (witness){ - ccdVec3Copy(witness, &d); - ccdVec3Scale(witness, t); - ccdVec3Add(witness, x0); - dist = ccdVec3Dist2(witness, P); - }else{ - // recycling variables - ccdVec3Scale(&d, t); - ccdVec3Add(&d, &a); - dist = ccdVec3Len2(&d); - } - } - - return dist; -} - -ccd_real_t ccdVec3PointSegmentDist2(const ccd_vec3_t *P, - const ccd_vec3_t *x0, const ccd_vec3_t *b, - ccd_vec3_t *witness) -{ - return __ccdVec3PointSegmentDist2(P, x0, b, witness); -} - -ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P, - const ccd_vec3_t *x0, const ccd_vec3_t *B, - const ccd_vec3_t *C, - ccd_vec3_t *witness) -{ - // Computation comes from analytic expression for triangle (x0, B, C) - // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and - // Then equation for distance is: - // D(s, t) = | T(s, t) - P |^2 - // This leads to minimization of quadratic function of two variables. - // The solution from is taken only if s is between 0 and 1, t is - // between 0 and 1 and t + s < 1, otherwise distance from segment is - // computed. - - ccd_vec3_t d1, d2, a; - ccd_real_t u, v, w, p, q, r; - ccd_real_t s, t, dist, dist2; - ccd_vec3_t witness2; - - ccdVec3Sub2(&d1, B, x0); - ccdVec3Sub2(&d2, C, x0); - ccdVec3Sub2(&a, x0, P); - - u = ccdVec3Dot(&a, &a); - v = ccdVec3Dot(&d1, &d1); - w = ccdVec3Dot(&d2, &d2); - p = ccdVec3Dot(&a, &d1); - q = ccdVec3Dot(&a, &d2); - r = ccdVec3Dot(&d1, &d2); - - s = (q * r - w * p) / (w * v - r * r); - t = (-s * r - q) / w; - - if ((ccdIsZero(s) || s > CCD_ZERO) - && (ccdEq(s, CCD_ONE) || s < CCD_ONE) - && (ccdIsZero(t) || t > CCD_ZERO) - && (ccdEq(t, CCD_ONE) || t < CCD_ONE) - && (ccdEq(t + s, CCD_ONE) || t + s < CCD_ONE)){ - - if (witness){ - ccdVec3Scale(&d1, s); - ccdVec3Scale(&d2, t); - ccdVec3Copy(witness, x0); - ccdVec3Add(witness, &d1); - ccdVec3Add(witness, &d2); - - dist = ccdVec3Dist2(witness, P); - }else{ - dist = s * s * v; - dist += t * t * w; - dist += CCD_REAL(2.) * s * t * r; - dist += CCD_REAL(2.) * s * p; - dist += CCD_REAL(2.) * t * q; - dist += u; - } - }else{ - dist = __ccdVec3PointSegmentDist2(P, x0, B, witness); - - dist2 = __ccdVec3PointSegmentDist2(P, x0, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - ccdVec3Copy(witness, &witness2); - } - - dist2 = __ccdVec3PointSegmentDist2(P, B, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - ccdVec3Copy(witness, &witness2); - } - } - - return dist; -} diff --git a/tests/pe/Collision.cpp b/tests/pe/Collision.cpp index 54d4f1125..bd77d39c0 100644 --- a/tests/pe/Collision.cpp +++ b/tests/pe/Collision.cpp @@ -18,7 +18,6 @@ // //====================================================================================================================== -#include "pe/collision/GJKEPAHelper.h" #include "pe/fcd/AnalyticCollisionDetection.h" #include "pe/utility/BodyCast.h" @@ -126,20 +125,14 @@ void BoxTest() std::vector<Contact> contacts; fcd::AnalyticCollideFunctor< std::vector<Contact> > collideFunc(contacts); - real_t penetrationDepth = real_t(0); - Vec3 contactPoint = Vec3(); - Vec3 contactNormal = Vec3(); - // std::vector<Contact> contacts; // BOX <-> BOX WALBERLA_LOG_INFO("BOX <-> BOX"); - WALBERLA_CHECK( !collideGJK(&b1, &b3, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( !collideFunc(&b1, &b3) ); // WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); // WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); // WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth); - WALBERLA_CHECK( collideGJK(&b1, &b2, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &b2) ); // WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); // WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); @@ -147,29 +140,24 @@ void BoxTest() b4.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 0.999); - WALBERLA_CHECK( collideGJK(&b1, &b4, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &b4) ); // WALBERLA_LOG_WARNING("contactPoint : " << contacts.back().getPosition()); // WALBERLA_LOG_WARNING("contactNormal : " << contacts.back().getNormal()); // WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.back().getDistance()); b4.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.001); - WALBERLA_CHECK( !collideGJK(&b1, &b4, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( !collideFunc(&b1, &b4) ); b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 0.99); - WALBERLA_CHECK( collideGJK(&b1, &b5, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &b5) ); // WALBERLA_LOG_WARNING("contactPoint : " << contacts.back().getPosition()); // WALBERLA_LOG_WARNING("contactNormal : " << contacts.back().getNormal()); // WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.back().getDistance()); b5.setPosition( (Vec3(0,0,1) * real_t(sqrt(3)) + Vec3(0,0,1)) * 1.01); - WALBERLA_CHECK( !collideGJK(&b1, &b5, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( !collideFunc(&b1, &b5) ); Sphere s1(126, 0, Vec3(real_t(1.5), real_t(1.5), real_t(1.5)), Vec3(0,0,0), Quat(), 1, iron, false, true, false); - WALBERLA_CHECK( collideGJK(&b1, &s1, contactPoint, contactNormal, penetrationDepth) ); WALBERLA_CHECK( collideFunc(&b1, &s1) ); // WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); // WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); @@ -187,13 +175,6 @@ void CapsuleTest() // CAPSULE <-> SPHERE WALBERLA_LOG_INFO("CAPSULE <-> SPHERE"); - sp1.setPosition(real_t(2.9), 0, 0); - WALBERLA_CHECK( collideGJK(&c1, &sp1, contacts) ); -// WALBERLA_LOG_WARNING("contactPoint : " << contacts.at(0).getPosition()); -// WALBERLA_LOG_WARNING("contactNormal : " << contacts.at(0).getNormal()); -// WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.at(0).getDistance()); - sp1.setPosition(real_t(3.1), 0, 0); - WALBERLA_CHECK( !collideGJK(&c1, &sp1, contacts) ); sp1.setPosition(0, real_t(1.9), 0); WALBERLA_CHECK( collideFunc(&c1, &sp1) ); @@ -225,8 +206,6 @@ void CapsuleTest() void CapsuleTest2() { - setMaxGJKIterations(10000); - setEPATolerance(real_t(0.00000001)); const real_t static_cof ( real_t(0.1) / 2 ); // Coefficient of static friction. Roughly 0.85 with high variation depending on surface roughness for low stresses. Note: pe doubles the input coefficient of friction for material-material contacts. const real_t dynamic_cof ( static_cof ); // Coefficient of dynamic friction. Similar to static friction for low speed friction. MaterialID material = createMaterial( "granular", real_t( 1.0 ), 0, static_cof, dynamic_cof, real_t( 0.5 ), 1, 1, 0, 0 ); @@ -240,10 +219,6 @@ void CapsuleTest2() WALBERLA_LOG_DEVEL( c1 ); WALBERLA_LOG_DEVEL( sp1 ); - real_t penetrationDepth = real_t(0); - Vec3 contactPoint = Vec3(); - Vec3 contactNormal = Vec3(); - WALBERLA_LOG_INFO("CAPSULE TEST"); Vec2 distance; distance[0] = (sp1.getPosition() - c1.getPosition())[0]; @@ -251,24 +226,11 @@ void CapsuleTest2() std::cout << std::setprecision(10); WALBERLA_LOG_DEVEL("DISTANCE: " << distance.length()); - WALBERLA_LOG_DEVEL("GJK: " << getMaxGJKIterations()); - WALBERLA_LOG_DEVEL("EPA: " << getEPATolerance() ); - WALBERLA_LOG_DEVEL(" CAPSULE <-> SPHERE (GJK) "); - WALBERLA_LOG_DEVEL( collideGJK(&c1, &sp1, contactPoint, contactNormal, penetrationDepth) ); - WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); - WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); - WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth); - WALBERLA_LOG_DEVEL(" SPHERE <-> CAPSULE (GJK) "); - WALBERLA_LOG_DEVEL( collideGJK(&sp1, &c1, contactPoint, contactNormal, penetrationDepth) ); - WALBERLA_LOG_WARNING("contactPoint : " << contactPoint); - WALBERLA_LOG_WARNING("contactNormal : " << contactNormal); - WALBERLA_LOG_WARNING("penetrationDepth: " << penetrationDepth); WALBERLA_LOG_DEVEL(" SPHERE <-> CAPSULE (ANALYTICAL) "); WALBERLA_LOG_DEVEL( collide(&sp1, &c1, contacts) ); WALBERLA_LOG_WARNING("contactPoint : " << contacts.at(0).getPosition()); WALBERLA_LOG_WARNING("contactNormal : " << contacts.at(0).getNormal()); WALBERLA_LOG_WARNING("penetrationDepth: " << contacts.at(0).getDistance()); - } void UnionTest() -- GitLab