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_SIMPLEX_SOLVER_H
\r
18 #define _SCE_PFX_SIMPLEX_SOLVER_H
\r
20 #include "../../../include/physics_effects/base_level/base/pfx_common.h"
\r
23 namespace PhysicsEffects {
\r
26 ///////////////////////////////////////////////////////////////////////////////
\r
27 // Voronoi Simplex Solver
\r
29 struct SCE_PFX_ALIGNED(16) PfxBarycentricCoords {
\r
31 PfxFloat barycentricCoords[4];
\r
32 unsigned int usedVertices;
\r
33 SCE_PFX_PADDING(1,12)
\r
37 barycentricCoords[0] = 0.0f;
\r
38 barycentricCoords[1] = 0.0f;
\r
39 barycentricCoords[2] = 0.0f;
\r
40 barycentricCoords[3] = 0.0f;
\r
46 return (barycentricCoords[0] >= 0.0f) &&
\r
47 (barycentricCoords[1] >= 0.0f) &&
\r
48 (barycentricCoords[2] >= 0.0f) &&
\r
49 (barycentricCoords[3] >= 0.0f);
\r
52 void setBarycentricCoordinates(PfxFloat a,PfxFloat b,PfxFloat c,PfxFloat d)
\r
54 barycentricCoords[0] = a;
\r
55 barycentricCoords[1] = b;
\r
56 barycentricCoords[2] = c;
\r
57 barycentricCoords[3] = d;
\r
58 if(a != 0.0f) usedVertices |= 1<<3;
\r
59 if(b != 0.0f) usedVertices |= 1<<2;
\r
60 if(c != 0.0f) usedVertices |= 1<<1;
\r
61 if(d != 0.0f) usedVertices |= 1;
\r
65 class PfxSimplexSolver {
\r
67 static const int MAX_VERTS = 4;
\r
71 SCE_PFX_PADDING(1,12)
\r
72 PfxVector3 W[MAX_VERTS];
\r
73 PfxVector3 P[MAX_VERTS];
\r
74 PfxVector3 Q[MAX_VERTS];
\r
76 PfxBarycentricCoords bc;
\r
78 inline void removeVertex(int index);
\r
79 inline void reduceVertices ();
\r
81 inline bool originOutsideOfPlane(const PfxVector3& a, const PfxVector3& b, const PfxVector3& c, const PfxVector3& d);
\r
82 bool closestPointTetrahedronFromOrigin(const PfxVector3 &a,const PfxVector3 &b,const PfxVector3 &c,const PfxVector3 &d, PfxBarycentricCoords& result);
\r
83 bool closestPointTriangleFromOrigin(const PfxVector3 &a,const PfxVector3 &b,const PfxVector3 &c,PfxBarycentricCoords& result);
\r
92 inline void addVertex(const PfxVector3& w_, const PfxVector3& p_, const PfxVector3& q_);
\r
94 bool closest(PfxVector3& v);
\r
96 bool fullSimplex() const
\r
98 return (numVertices == 4);
\r
101 bool inSimplex(const PfxVector3& w);
\r
105 void PfxSimplexSolver::removeVertex(int index)
\r
107 SCE_PFX_ASSERT(numVertices>0);
\r
109 W[index] = W[numVertices];
\r
110 P[index] = P[numVertices];
\r
111 Q[index] = Q[numVertices];
\r
115 void PfxSimplexSolver::reduceVertices ()
\r
117 if ((numVertices >= 4) && (!(bc.usedVertices&0x01)))
\r
120 if ((numVertices >= 3) && (!(bc.usedVertices&0x02)))
\r
123 if ((numVertices >= 2) && (!(bc.usedVertices&0x04)))
\r
126 if ((numVertices >= 1) && (!(bc.usedVertices&0x08)))
\r
131 void PfxSimplexSolver::addVertex(const PfxVector3& w, const PfxVector3& p, const PfxVector3& q)
\r
133 W[numVertices] = w;
\r
134 P[numVertices] = p;
\r
135 Q[numVertices] = q;
\r
140 bool PfxSimplexSolver::originOutsideOfPlane(const PfxVector3& a, const PfxVector3& b, const PfxVector3& c, const PfxVector3& d)
\r
142 PfxVector3 normal = cross((b-a),(c-a));
\r
144 PfxFloat signp = dot(-a,normal);
\r
145 PfxFloat signd = dot((d - a),normal);
\r
147 return signp * signd < 0.0f;
\r
150 } //namespace PhysicsEffects
\r
153 #endif // _SCE_PFX_SIMPLEX_SOLVER_H
\r