| 1 | /* | 
|---|
| 2 | Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/ | 
|---|
| 3 |  | 
|---|
| 4 | This software is provided 'as-is', without any express or implied warranty. | 
|---|
| 5 | In no event will the authors be held liable for any damages arising from the use of this software. | 
|---|
| 6 | Permission is granted to anyone to use this software for any purpose,  | 
|---|
| 7 | including commercial applications, and to alter it and redistribute it freely,  | 
|---|
| 8 | subject to the following restrictions: | 
|---|
| 9 |  | 
|---|
| 10 | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. | 
|---|
| 11 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 
|---|
| 12 | 3. This notice may not be removed or altered from any source distribution. | 
|---|
| 13 | */ | 
|---|
| 14 |  | 
|---|
| 15 |  | 
|---|
| 16 |  | 
|---|
| 17 | #include "btGeometryUtil.h" | 
|---|
| 18 |  | 
|---|
| 19 |  | 
|---|
| 20 | /* | 
|---|
| 21 |   Make sure this dummy function never changes so that it | 
|---|
| 22 |   can be used by probes that are checking whether the | 
|---|
| 23 |   library is actually installed. | 
|---|
| 24 | */ | 
|---|
| 25 | extern "C" | 
|---|
| 26 | {        | 
|---|
| 27 |         void btBulletMathProbe (); | 
|---|
| 28 |  | 
|---|
| 29 |         void btBulletMathProbe () {} | 
|---|
| 30 | } | 
|---|
| 31 |  | 
|---|
| 32 |  | 
|---|
| 33 | bool    btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar     margin) | 
|---|
| 34 | { | 
|---|
| 35 |         int numbrushes = planeEquations.size(); | 
|---|
| 36 |         for (int i=0;i<numbrushes;i++) | 
|---|
| 37 |         { | 
|---|
| 38 |                 const btVector3& N1 = planeEquations[i]; | 
|---|
| 39 |                 btScalar dist = btScalar(N1.dot(point))+btScalar(N1[3])-margin; | 
|---|
| 40 |                 if (dist>btScalar(0.)) | 
|---|
| 41 |                 { | 
|---|
| 42 |                         return false; | 
|---|
| 43 |                 } | 
|---|
| 44 |         } | 
|---|
| 45 |         return true; | 
|---|
| 46 |                  | 
|---|
| 47 | } | 
|---|
| 48 |  | 
|---|
| 49 |  | 
|---|
| 50 | bool    btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar  margin) | 
|---|
| 51 | { | 
|---|
| 52 |         int numvertices = vertices.size(); | 
|---|
| 53 |         for (int i=0;i<numvertices;i++) | 
|---|
| 54 |         { | 
|---|
| 55 |                 const btVector3& N1 = vertices[i]; | 
|---|
| 56 |                 btScalar dist = btScalar(planeNormal.dot(N1))+btScalar(planeNormal[3])-margin; | 
|---|
| 57 |                 if (dist>btScalar(0.)) | 
|---|
| 58 |                 { | 
|---|
| 59 |                         return false; | 
|---|
| 60 |                 } | 
|---|
| 61 |         } | 
|---|
| 62 |         return true; | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations); | 
|---|
| 66 |  | 
|---|
| 67 | bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations) | 
|---|
| 68 | { | 
|---|
| 69 |         int numbrushes = planeEquations.size(); | 
|---|
| 70 |         for (int i=0;i<numbrushes;i++) | 
|---|
| 71 |         { | 
|---|
| 72 |                 const btVector3& N1 = planeEquations[i]; | 
|---|
| 73 |                 if (planeEquation.dot(N1) > btScalar(0.999)) | 
|---|
| 74 |                 { | 
|---|
| 75 |                         return false; | 
|---|
| 76 |                 }  | 
|---|
| 77 |         } | 
|---|
| 78 |         return true; | 
|---|
| 79 | } | 
|---|
| 80 |  | 
|---|
| 81 | void    btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut ) | 
|---|
| 82 | { | 
|---|
| 83 |                 const int numvertices = vertices.size(); | 
|---|
| 84 |         // brute force: | 
|---|
| 85 |         for (int i=0;i<numvertices;i++) | 
|---|
| 86 |         { | 
|---|
| 87 |                 const btVector3& N1 = vertices[i]; | 
|---|
| 88 |                  | 
|---|
| 89 |  | 
|---|
| 90 |                 for (int j=i+1;j<numvertices;j++) | 
|---|
| 91 |                 { | 
|---|
| 92 |                         const btVector3& N2 = vertices[j]; | 
|---|
| 93 |                                  | 
|---|
| 94 |                         for (int k=j+1;k<numvertices;k++) | 
|---|
| 95 |                         { | 
|---|
| 96 |  | 
|---|
| 97 |                                 const btVector3& N3 = vertices[k]; | 
|---|
| 98 |  | 
|---|
| 99 |                                 btVector3 planeEquation,edge0,edge1; | 
|---|
| 100 |                                 edge0 = N2-N1; | 
|---|
| 101 |                                 edge1 = N3-N1; | 
|---|
| 102 |                                 btScalar normalSign = btScalar(1.); | 
|---|
| 103 |                                 for (int ww=0;ww<2;ww++) | 
|---|
| 104 |                                 { | 
|---|
| 105 |                                         planeEquation = normalSign * edge0.cross(edge1); | 
|---|
| 106 |                                         if (planeEquation.length2() > btScalar(0.0001)) | 
|---|
| 107 |                                         { | 
|---|
| 108 |                                                 planeEquation.normalize(); | 
|---|
| 109 |                                                 if (notExist(planeEquation,planeEquationsOut)) | 
|---|
| 110 |                                                 { | 
|---|
| 111 |                                                         planeEquation[3] = -planeEquation.dot(N1); | 
|---|
| 112 |                                                          | 
|---|
| 113 |                                                                 //check if inside, and replace supportingVertexOut if needed | 
|---|
| 114 |                                                                 if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01))) | 
|---|
| 115 |                                                                 { | 
|---|
| 116 |                                                                         planeEquationsOut.push_back(planeEquation); | 
|---|
| 117 |                                                                 } | 
|---|
| 118 |                                                 } | 
|---|
| 119 |                                         } | 
|---|
| 120 |                                         normalSign = btScalar(-1.); | 
|---|
| 121 |                                 } | 
|---|
| 122 |                          | 
|---|
| 123 |                         } | 
|---|
| 124 |                 } | 
|---|
| 125 |         } | 
|---|
| 126 |  | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | void    btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut ) | 
|---|
| 130 | { | 
|---|
| 131 |         const int numbrushes = planeEquations.size(); | 
|---|
| 132 |         // brute force: | 
|---|
| 133 |         for (int i=0;i<numbrushes;i++) | 
|---|
| 134 |         { | 
|---|
| 135 |                 const btVector3& N1 = planeEquations[i]; | 
|---|
| 136 |                  | 
|---|
| 137 |  | 
|---|
| 138 |                 for (int j=i+1;j<numbrushes;j++) | 
|---|
| 139 |                 { | 
|---|
| 140 |                         const btVector3& N2 = planeEquations[j]; | 
|---|
| 141 |                                  | 
|---|
| 142 |                         for (int k=j+1;k<numbrushes;k++) | 
|---|
| 143 |                         { | 
|---|
| 144 |  | 
|---|
| 145 |                                 const btVector3& N3 = planeEquations[k]; | 
|---|
| 146 |  | 
|---|
| 147 |                                 btVector3 n2n3; n2n3 = N2.cross(N3); | 
|---|
| 148 |                                 btVector3 n3n1; n3n1 = N3.cross(N1); | 
|---|
| 149 |                                 btVector3 n1n2; n1n2 = N1.cross(N2); | 
|---|
| 150 |                                  | 
|---|
| 151 |                                 if ( ( n2n3.length2() > btScalar(0.0001) ) && | 
|---|
| 152 |                                          ( n3n1.length2() > btScalar(0.0001) ) && | 
|---|
| 153 |                                          ( n1n2.length2() > btScalar(0.0001) ) ) | 
|---|
| 154 |                                 { | 
|---|
| 155 |                                         //point P out of 3 plane equations: | 
|---|
| 156 |  | 
|---|
| 157 |                                         //      d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )   | 
|---|
| 158 |                                         //P =  -------------------------------------------------------------------------   | 
|---|
| 159 |                                         //   N1 . ( N2 * N3 )   | 
|---|
| 160 |  | 
|---|
| 161 |  | 
|---|
| 162 |                                         btScalar quotient = (N1.dot(n2n3)); | 
|---|
| 163 |                                         if (btFabs(quotient) > btScalar(0.000001)) | 
|---|
| 164 |                                         { | 
|---|
| 165 |                                                 quotient = btScalar(-1.) / quotient; | 
|---|
| 166 |                                                 n2n3 *= N1[3]; | 
|---|
| 167 |                                                 n3n1 *= N2[3]; | 
|---|
| 168 |                                                 n1n2 *= N3[3]; | 
|---|
| 169 |                                                 btVector3 potentialVertex = n2n3; | 
|---|
| 170 |                                                 potentialVertex += n3n1; | 
|---|
| 171 |                                                 potentialVertex += n1n2; | 
|---|
| 172 |                                                 potentialVertex *= quotient; | 
|---|
| 173 |  | 
|---|
| 174 |                                                 //check if inside, and replace supportingVertexOut if needed | 
|---|
| 175 |                                                 if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01))) | 
|---|
| 176 |                                                 { | 
|---|
| 177 |                                                         verticesOut.push_back(potentialVertex); | 
|---|
| 178 |                                                 } | 
|---|
| 179 |                                         } | 
|---|
| 180 |                                 } | 
|---|
| 181 |                         } | 
|---|
| 182 |                 } | 
|---|
| 183 |         } | 
|---|
| 184 | } | 
|---|
| 185 |  | 
|---|