1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include "[GJK.h]"19 #include "../Geometry/LineSegment.h"20 #include "../Geometry/Triangle.h"21 #include "../Geometry/Plane.h"22 23 [MATH_BEGIN_NAMESPACE]24 25 26 27 28 29 30 31 32 vec [UpdateSimplex](vec *s, int &n)33 {34 if (n == 2)35 {36 37 38 39 40 41 42 43 #ifdef MATH_ASSERT_CORRECTNESS44 45 46 float d0 = s[0].[DistanceSq]([vec::zero]);47 float d1 = s[1].DistanceSq([vec::zero]);48 float d2 = [LineSegment](s[0], s[1]).[DistanceSq]([vec::zero]);49 [assert2](d2 <= d0, d2, d0);50 [assert2](d2 <= d1, d2, d1);51 52 [assert]([Dot](s[1]-s[0], -s[0]) >= 0.f);53 54 [assert]([Dot](s[1]-s[0], -s[1]) <= 0.f);55 #endif56 57 vec d01 = s[1] - s[0];58 vec newSearchDir = [Cross](d01, [Cross](d01, s[1]));59 if (newSearchDir.LengthSq() > 1[e]-7f)60 return newSearchDir; 61 else62 {63 64 n = 0;65 return [vec::zero];66 }67 }68 else if (n == 3)69 {70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 #ifdef MATH_ASSERT_CORRECTNESS86 87 88 float [d][7];89 d[0] = s[0].[DistanceSq]([vec::zero]);90 d[1] = s[1].DistanceSq([vec::zero]);91 d[2] = s[2].DistanceSq([vec::zero]);92 d[3] = [LineSegment](s[0], s[1]).[DistanceSq]([vec::zero]);93 d[4] = [LineSegment](s[1], s[2]).[DistanceSq]([vec::zero]);94 d[5] = [LineSegment](s[2], s[0]).[DistanceSq]([vec::zero]);95 d[6] = [Triangle](s[0], s[1], s[2]).[DistanceSq]([vec::zero]);96 97 bool isContainedInTriangle = (d[6] <= 1[e]-3f); 98 float dist = [FLOAT_INF];99 int minDistIndex = -1;100 for(int i = 4; i < 7; ++i)101 if (d[i] < dist)102 {103 dist = d[i];104 minDistIndex = i;105 }106 107 [assert4](isContainedInTriangle || dist <= d[0] + 1[e]-4f, d[0], dist, isContainedInTriangle, minDistIndex);108 [assert4](isContainedInTriangle || dist <= d[1] + 1[e]-4f, d[1], dist, isContainedInTriangle, minDistIndex);109 [assert4](isContainedInTriangle || dist <= d[2] + 1[e]-4f, d[2], dist, isContainedInTriangle, minDistIndex);110 [assert4](isContainedInTriangle || dist <= d[3] + 1[e]-4f, d[3], dist, isContainedInTriangle, minDistIndex);111 #endif112 vec d12 = s[2]-s[1];113 vec d02 = s[2]-s[0];114 vec triNormal = [Cross](d02, d12);115 116 vec e12 = [Cross](d12, triNormal);117 float t12 = [Dot](s[1], e12);118 if (t12 < 0.f)119 {120 121 #ifdef MATH_ASSERT_CORRECTNESS122 [assert4](d[4] <= dist + 1[e]-3f * [Max](1.f, d[4], dist), d[4], dist, isContainedInTriangle, minDistIndex);123 #endif124 vec newDir = [Cross](d12, [Cross](d12, s[1]));125 s[0] = s[1];126 s[1] = s[2];127 n = 2;128 return newDir;129 }130 vec e02 = [Cross](triNormal, d02);131 float t02 = [Dot](s[0], e02);132 if (t02 < 0.f)133 {134 135 #ifdef MATH_ASSERT_CORRECTNESS136 [assert4](d[5] <= dist + 1[e]-3f * [Max](1.f, d[5], dist), d[5], dist, isContainedInTriangle, minDistIndex);137 #endif138 vec newDir = [Cross](d02, [Cross](d02, s[0]));139 s[1] = s[2];140 n = 2;141 return newDir;142 }143 144 #ifdef MATH_ASSERT_CORRECTNESS145 [assert4](d[6] <= dist + 1[e]-3f * [Max](1.f, d[6], dist), d[6], dist, isContainedInTriangle, minDistIndex);146 #endif147 float scaledSignedDistToTriangle = triNormal.Dot(s[2]);148 float distSq = scaledSignedDistToTriangle*scaledSignedDistToTriangle;149 float scaledEpsilonSq = 1[e]-6f*triNormal.LengthSq();150 151 if (distSq > scaledEpsilonSq)152 {153 154 if (scaledSignedDistToTriangle <= 0.f)155 return triNormal; 156 else157 {158 159 std::swap(s[0], s[1]);160 return -triNormal;161 }162 }163 else164 {165 166 n = 0;167 return [vec::zero];168 }169 }170 else 171 {172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 #ifdef MATH_ASSERT_CORRECTNESS196 197 198 float d[14];199 d[0] = s[0].DistanceSq([vec::zero]);200 d[1] = s[1].DistanceSq([vec::zero]);201 d[2] = s[2].DistanceSq([vec::zero]);202 d[3] = s[3].DistanceSq([vec::zero]);203 d[4] = [LineSegment](s[0], s[1]).[DistanceSq]([vec::zero]);204 d[5] = [LineSegment](s[0], s[2]).[DistanceSq]([vec::zero]);205 d[6] = [LineSegment](s[0], s[3]).[DistanceSq]([vec::zero]);206 d[7] = [LineSegment](s[1], s[2]).[DistanceSq]([vec::zero]);207 d[8] = [LineSegment](s[1], s[3]).[DistanceSq]([vec::zero]);208 d[9] = [LineSegment](s[2], s[3]).[DistanceSq]([vec::zero]);209 d[10] = [Triangle](s[0], s[1], s[2]).[DistanceSq]([vec::zero]);210 d[11] = [Triangle](s[0], s[1], s[3]).[DistanceSq]([vec::zero]);211 d[12] = [Triangle](s[0], s[2], s[3]).[DistanceSq]([vec::zero]);212 d[13] = [Triangle](s[1], s[2], s[3]).[DistanceSq]([vec::zero]);213 214 vec Tri013Normal = [Cross](s[1]-s[0], s[3]-s[0]);215 vec Tri023Normal = [Cross](s[3]-s[0], s[2]-s[0]);216 vec Tri123Normal = [Cross](s[2]-s[1], s[3]-s[1]);217 vec Tri012Normal = [Cross](s[2] - s[0], s[1] - s[0]);218 [assert]([Dot](Tri012Normal, s[3] - s[0]) <= 0.f);219 float InTri012 = [Dot](-s[0], Tri012Normal);220 float InTri013 = [Dot](-s[3], Tri013Normal);221 float InTri023 = [Dot](-s[3], Tri023Normal);222 float InTri123 = [Dot](-s[3], Tri123Normal);223 bool insideSimplex = InTri012 <= 0.f && InTri013 <= 0.f && InTri023 <= 0.f && InTri123 <= 0.f;224 225 float dist = [FLOAT_INF];226 int minDistIndex = -1;227 for(int i = 6; i < 14; ++i)228 if (i == 6 || i == 8 || i == 9 || i == 11 || i == 12 || i == 13)229 if (d[i] < dist)230 {231 dist = d[i];232 minDistIndex = i;233 }234 [assert4](insideSimplex || dist <= d[0] + 1[e]-4f * [Max](1.f, d[0], dist), d[0], dist, insideSimplex, minDistIndex);235 [assert4](insideSimplex || dist <= d[1] + 1[e]-4f * [Max](1.f, d[1], dist), d[1], dist, insideSimplex, minDistIndex);236 [assert4](insideSimplex || dist <= d[2] + 1[e]-4f * [Max](1.f, d[2], dist), d[2], dist, insideSimplex, minDistIndex);237 [assert4](insideSimplex || dist <= d[4] + 1[e]-4f * [Max](1.f, d[4], dist), d[4], dist, insideSimplex, minDistIndex);238 [assert4](insideSimplex || dist <= d[5] + 1[e]-4f * [Max](1.f, d[5], dist), d[5], dist, insideSimplex, minDistIndex);239 [assert4](insideSimplex || dist <= d[7] + 1[e]-4f * [Max](1.f, d[7], dist), d[7], dist, insideSimplex, minDistIndex);240 [assert4](insideSimplex || dist <= d[10] + 1[e]-4f * [Max](1.f, d[10], dist), d[10], dist, insideSimplex, minDistIndex);241 #endif242 243 vec d01 = s[1] - s[0];244 vec d02 = s[2] - s[0];245 vec d03 = s[3] - s[0];246 vec tri013Normal = [Cross](d01, d03); 247 vec tri023Normal = [Cross](d03, d02); 248 [assert]([Dot](tri013Normal, d02) <= 0.f);249 [assert]([Dot](tri023Normal, d01) <= 0.f);250 251 vec e03_1 = [Cross](tri013Normal, d03); 252 vec e03_2 = [Cross](d03, tri023Normal); 253 float inE03_1 = [Dot](e03_1, s[3]);254 float inE03_2 = [Dot](e03_2, s[3]);255 if (inE03_1 <= 0.f && inE03_2 <= 0.f)256 {257 258 #ifdef MATH_ASSERT_CORRECTNESS259 [assert4](!insideSimplex && d[6] <= dist + 1[e]-3f * [Max](1.f, d[6], dist), d[6], dist, insideSimplex, minDistIndex);260 #endif261 vec newDir = [Cross](d03, [Cross](d03, s[3]));262 s[1] = s[3];263 n = 2;264 return newDir;265 }266 267 vec d12 = s[2] - s[1];268 vec d13 = s[3] - s[1];269 vec tri123Normal = [Cross](d12, d13);270 [assert]([Dot](tri123Normal, -d02) <= 0.f);271 vec e13_0 = [Cross](d13, tri013Normal);272 vec e13_2 = [Cross](tri123Normal, d13);273 float inE13_0 = [Dot](e13_0, s[3]);274 float inE13_2 = [Dot](e13_2, s[3]);275 if (inE13_0 <= 0.f && inE13_2 <= 0.f)276 {277 278 #ifdef MATH_ASSERT_CORRECTNESS279 [assert4](!insideSimplex && d[8] <= dist + 1[e]-3f * [Max](1.f, d[8], dist), d[8], dist, insideSimplex, minDistIndex);280 #endif281 vec newDir = [Cross](d13, [Cross](d13, s[3]));282 s[0] = s[1];283 s[1] = s[3];284 n = 2;285 return newDir;286 }287 288 vec d23 = s[3] - s[2];289 vec e23_0 = [Cross](tri023Normal, d23);290 vec e23_1 = [Cross](d23, tri123Normal);291 float inE23_0 = [Dot](e23_0, s[3]);292 float inE23_1 = [Dot](e23_1, s[3]);293 if (inE23_0 <= 0.f && inE23_1 <= 0.f)294 {295 296 #ifdef MATH_ASSERT_CORRECTNESS297 [assert4](!insideSimplex && d[9] <= dist + 1[e]-3f * [Max](1.f, d[9], dist), d[9], dist, insideSimplex, minDistIndex);298 #endif299 vec newDir = [Cross](d23, [Cross](d23, s[3]));300 s[0] = s[2];301 s[1] = s[3];302 n = 2;303 return newDir;304 }305 306 float inTri013 = [Dot](s[3], tri013Normal);307 if (inTri013 < 0.f && inE13_0 >= 0.f && inE03_1 >= 0.f)308 {309 310 #ifdef MATH_ASSERT_CORRECTNESS311 [assert4](!insideSimplex && d[11] <= dist + 1[e]-3f * [Max](1.f, d[11], dist), d[11], dist, insideSimplex, minDistIndex);312 #endif313 s[2] = s[3];314 n = 3;315 return tri013Normal;316 }317 float inTri023 = [Dot](s[3], tri023Normal);318 if (inTri023 < 0.f && inE23_0 >= 0.f && inE03_2 >= 0.f)319 {320 321 #ifdef MATH_ASSERT_CORRECTNESS322 [assert4](!insideSimplex && d[12] <= dist + 1[e]-3f * [Max](1.f, d[12], dist), d[12], dist, insideSimplex, minDistIndex);323 #endif324 s[1] = s[0];325 s[0] = s[2];326 s[2] = s[3];327 n = 3;328 return tri023Normal;329 }330 float inTri123 = [Dot](s[3], tri123Normal);331 if (inTri123 < 0.f && inE13_2 >= 0.f && inE23_1 >= 0.f)332 {333 334 #ifdef MATH_ASSERT_CORRECTNESS335 [assert4](!insideSimplex && d[13] <= dist + 1[e]-3f * [Max](1.f, d[13], dist), d[13], dist, insideSimplex, minDistIndex);336 #endif337 s[0] = s[1];338 s[1] = s[2];339 s[2] = s[3];340 n = 3;341 return tri123Normal;342 }343 344 345 n = 0;346 return [vec::zero];347 }348 }349 350 [MATH_END_NAMESPACE] Go back to previous page