2 Physics Effects Copyright(C) 2010 Sony Computer Entertainment Inc.
\r
5 Physics Effects is open software; you can redistribute it and/or
\r
6 modify it under the terms of the BSD License.
\r
8 Physics Effects is distributed in the hope that it will be useful,
\r
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
\r
11 See the BSD License for more details.
\r
13 A copy of the BSD License is distributed with
\r
14 Physics Effects under the filename: physics_effects_license.txt
\r
17 #ifndef _SCE_PFX_GJK_SOLVER_H
\r
18 #define _SCE_PFX_GJK_SOLVER_H
\r
20 #include "../../../include/physics_effects/base_level/base/pfx_common.h"
\r
21 #include "../../../include/physics_effects/base_level/base/pfx_vec_utils.h"
\r
22 #include "pfx_simplex_solver.h"
\r
25 namespace PhysicsEffects {
\r
27 #define SCE_PFX_GJK_EPSILON 1e-04f
\r
28 #define SCE_PFX_GJK_MARGIN 0.025f
\r
29 #define SCE_PFX_GJK_ITERATION_MAX 10
\r
30 #define SCE_PFX_EPA_ITERATION_MAX 10
\r
32 ///////////////////////////////////////////////////////////////////////////////
\r
35 typedef void (*PfxGetSupportVertexFunc)(void *shape,const PfxVector3 &seperatingAxis,PfxVector3 &supportVertex);
\r
37 ///////////////////////////////////////////////////////////////////////////////
\r
39 class PfxSimplexSolver;
\r
44 static const PfxUInt32 MAX_VERTS = 128;
\r
45 static const PfxUInt32 MAX_EDGES = 128;
\r
46 static const PfxUInt32 MAX_FACETS = 64;
\r
48 PfxSimplexSolver m_simplex;
\r
51 struct PfxGjkFacet {
\r
52 PfxVector3 normal; // 面の法線
\r
53 PfxVector3 closest; // 原点からの最短ベクトル
\r
54 PfxUInt32 obsolete; // 廃棄面判定
\r
55 PfxFloat distSqr; // 原点からの距離
\r
56 PfxInt32 v[3]; // 頂点
\r
57 PfxInt32 j[3]; // 隣接面から見たIndex
\r
58 PfxGjkFacet *adj[3]; // 隣接面
\r
59 SCE_PFX_PADDING(1,4)
\r
67 PfxGjkEdge(PfxGjkFacet *f_,PfxInt32 i_)
\r
74 PfxVector3 g_vertsP[MAX_VERTS];
\r
75 PfxVector3 g_vertsQ[MAX_VERTS];
\r
76 PfxVector3 g_vertsW[MAX_VERTS];
\r
77 PfxGjkFacet g_facets[MAX_FACETS];
\r
78 PfxGjkFacet *g_facetsHead[MAX_FACETS];
\r
79 PfxGjkEdge g_edges[MAX_EDGES];
\r
81 PfxVector3 SCE_PFX_ALIGNED(16) *vertsP;
\r
82 SCE_PFX_PADDING(1,12)
\r
83 PfxVector3 SCE_PFX_ALIGNED(16) *vertsQ;
\r
84 SCE_PFX_PADDING(2,12)
\r
85 PfxVector3 SCE_PFX_ALIGNED(16) *vertsW;
\r
86 SCE_PFX_PADDING(3,12)
\r
87 PfxGjkFacet SCE_PFX_ALIGNED(16) *facets;
\r
88 SCE_PFX_PADDING(4,12)
\r
89 PfxGjkFacet SCE_PFX_ALIGNED(16) **facetsHead;
\r
90 SCE_PFX_PADDING(5,12)
\r
91 PfxGjkEdge SCE_PFX_ALIGNED(16) *edges;
\r
97 SCE_PFX_PADDING(6,12)
\r
99 inline PfxGjkFacet *addFacet(int v1,int v2,int v3);
\r
101 inline void linkFacets(PfxGjkFacet *f1,int e1,PfxGjkFacet *f2,int e2);
\r
102 void silhouette(PfxGjkFacet *facet,int i,PfxVector3 &w);
\r
104 inline bool originInTetrahedron(const PfxVector3& p0,const PfxVector3& p1,const PfxVector3& p2,const PfxVector3& p3);
\r
106 PfxFloat detectPenetrationDepth(
\r
107 const PfxTransform3 &transformA,const PfxTransform3 &transformB,
\r
108 PfxVector3 &pA,PfxVector3 &pB,PfxVector3 &normal);
\r
112 PfxGetSupportVertexFunc getSupportVertexShapeA;
\r
113 PfxGetSupportVertexFunc getSupportVertexShapeB;
\r
119 void setup(void *sA,void *sB,PfxGetSupportVertexFunc fA,PfxGetSupportVertexFunc fB);
\r
121 PfxFloat collide( PfxVector3& normal, PfxPoint3 &pointA, PfxPoint3 &pointB,
\r
122 const PfxTransform3 & transformA,
\r
123 const PfxTransform3 & transformB,
\r
124 PfxFloat distanceThreshold = SCE_PFX_FLT_MAX);
\r
128 PfxGjkSolver::PfxGjkFacet *PfxGjkSolver::addFacet(int v1,int v2,int v3)
\r
130 if(SCE_PFX_UNLIKELY(numFacets == (int)MAX_FACETS))
\r
133 PfxGjkFacet &facet = facets[numFacets];
\r
135 PfxVector3 V1 = vertsW[v1];
\r
136 PfxVector3 V2 = vertsW[v2];
\r
137 PfxVector3 V3 = vertsW[v3];
\r
138 facet.obsolete = 0;
\r
143 PfxVector3 normal = cross(V3-V1,V2-V1);
\r
145 PfxFloat l = lengthSqr(normal);
\r
147 if(l < SCE_PFX_GJK_EPSILON * SCE_PFX_GJK_EPSILON) {
\r
151 normal /= sqrtf(l);
\r
152 facet.closest = dot(V1,normal)*normal;
\r
153 facet.normal =normal;
\r
155 facet.distSqr = lengthSqr(facet.closest);
\r
157 facetsHead[numFacetsHead++] = &facet;
\r
164 void PfxGjkSolver::linkFacets(PfxGjkFacet *f1,int e1,PfxGjkFacet *f2,int e2)
\r
173 bool PfxGjkSolver::originInTetrahedron(const PfxVector3& p0,const PfxVector3& p1,const PfxVector3& p2,const PfxVector3& p3)
\r
175 PfxVector3 n0 = cross((p1-p0),(p2-p0));
\r
176 PfxVector3 n1 = cross((p2-p1),(p3-p1));
\r
177 PfxVector3 n2 = cross((p3-p2),(p0-p2));
\r
178 PfxVector3 n3 = cross((p0-p3),(p1-p3));
\r
181 dot(n0,p0) * dot(n0,p3-p0) <= 0.0f &&
\r
182 dot(n1,p1) * dot(n1,p0-p1) <= 0.0f &&
\r
183 dot(n2,p2) * dot(n2,p1-p2) <= 0.0f &&
\r
184 dot(n3,p3) * dot(n3,p2-p3) <= 0.0f;
\r
187 } //namespace PhysicsEffects
\r
190 #endif // _SCE_PFX_GJK_SOLVER_H
\r