Advertisement
Guest User

Untitled

a guest
Aug 28th, 2016
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.16 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. static class PhysicsExtensionMethods
  6. {
  7. public static bool IsInSameDirection(this Vector3 vector, Vector3 otherVector)
  8. {
  9. return Vector3.Dot(vector, otherVector) > 0;
  10. }
  11.  
  12. public static bool IsInOppositeDirection(this Vector3 vector, Vector3 otherVector)
  13. {
  14. return Vector3.Dot(vector, otherVector) < 0;
  15. }
  16. }
  17.  
  18. public interface IConvexRegion
  19. {
  20. Vector3 GetFurthestPoint(Vector3 direction);
  21. }
  22.  
  23. class Simplex
  24. {
  25. List<Vector3> _vertices =
  26. new List<Vector3>();
  27.  
  28. public int Count
  29. {
  30. get { return _vertices.Count; }
  31. }
  32.  
  33. public Vector3 this[int i]
  34. {
  35. get { return _vertices[i]; }
  36. }
  37.  
  38. public Simplex(params Vector3[] vertices)
  39. {
  40. for (int i = 0; i < vertices.Length; i++)
  41. {
  42. _vertices.Add(vertices[i]);
  43. }
  44. }
  45.  
  46. public void Add(Vector3 vertex)
  47. {
  48. _vertices.Add(vertex);
  49. }
  50.  
  51. public void Remove(Vector3 vertex)
  52. {
  53. _vertices.Remove(vertex);
  54. }
  55. }
  56.  
  57. public class GJK
  58. {
  59. public static bool Intersects(IConvexRegion regioneOne, IConvexRegion regionTwo)
  60. {
  61. Vector3 s = Support(regioneOne, regionTwo, Vector3.one);
  62. Simplex simplex = new Simplex(s);
  63. Vector3 d = -s;
  64. int maxIterations = 50;
  65.  
  66. for (int i = 0; i < maxIterations; i++)
  67. {
  68. Vector3 a = Support(regioneOne, regionTwo, d);
  69.  
  70. if (a.IsInOppositeDirection(d))
  71. {
  72. return false;
  73. }
  74. simplex.Add(a);
  75. if (ProcessSimplex(ref simplex, ref d))
  76. {
  77. return true;
  78. }
  79. }
  80. return true;
  81. }
  82.  
  83. static bool ProcessSimplex(ref Simplex simplex, ref Vector3 direction)
  84. {
  85. if (simplex.Count == 2)
  86. {
  87. return ProcessLine(ref simplex, ref direction);
  88. }
  89. else if (simplex.Count == 3)
  90. {
  91. return ProcessTriangle(ref simplex, ref direction);
  92. }
  93. else
  94. {
  95. return ProcessTetrehedron(ref simplex, ref direction);
  96. }
  97. }
  98.  
  99. static bool ProcessLine(ref Simplex simplex, ref Vector3 direction)
  100. {
  101. Vector3 a = simplex[1];
  102. Vector3 b = simplex[0];
  103. Vector3 ab = b - a;
  104. Vector3 aO = -a;
  105.  
  106. Debug.DrawLine(a, b, Color.red);
  107.  
  108. if (ab.IsInSameDirection(aO))
  109. {
  110. float dot = Vector3.Dot(ab, aO);
  111. float angle = (float)Mathf.Acos(dot / (ab.magnitude * aO.magnitude));
  112. direction = Vector3.Cross(Vector3.Cross(ab, aO), ab);
  113. }
  114. else
  115. {
  116. simplex.Remove(b);
  117. direction = aO;
  118. }
  119. return false;
  120. }
  121.  
  122. static bool ProcessTriangle(ref Simplex simplex, ref Vector3 direction)
  123. {
  124. Vector3 a = simplex[2];
  125. Vector3 b = simplex[1];
  126. Vector3 c = simplex[0];
  127. Vector3 ab = b - a;
  128. Vector3 ac = c - a;
  129. Vector3 abc = Vector3.Cross(ab, ac);
  130. Vector3 aO = -a;
  131. Vector3 acNormal = Vector3.Cross(abc, ac);
  132. Vector3 abNormal = Vector3.Cross(ab, abc);
  133.  
  134.  
  135. Debug.DrawLine(a, b, Color.blue);
  136. Debug.DrawLine(b, c, Color.blue);
  137. Debug.DrawLine(a, c, Color.blue);
  138.  
  139. if (acNormal.IsInSameDirection(aO))
  140. {
  141. if (ac.IsInSameDirection(aO))
  142. {
  143. simplex.Remove(b);
  144. direction = Vector3.Cross(Vector3.Cross(ac, aO), ac);
  145. }
  146. else
  147. {
  148. if (ab.IsInSameDirection(aO))
  149. {
  150. simplex.Remove(c);
  151. direction = Vector3.Cross(Vector3.Cross(ab, aO), ab);
  152. }
  153. else
  154. {
  155. simplex.Remove(b);
  156. simplex.Remove(c);
  157. direction = aO;
  158. }
  159. }
  160. }
  161. else
  162. {
  163. if (abNormal.IsInSameDirection(aO))
  164. {
  165. if (ab.IsInSameDirection(aO))
  166. {
  167. simplex.Remove(c);
  168. direction = Vector3.Cross(Vector3.Cross(ab, aO), ab);
  169. }
  170. else
  171. {
  172. simplex.Remove(b);
  173. simplex.Remove(c);
  174. direction = aO;
  175. }
  176. }
  177. else
  178. {
  179. if (abc.IsInSameDirection(aO))
  180. {
  181. direction = Vector3.Cross(Vector3.Cross(abc, aO), abc);
  182. }
  183. else
  184. {
  185. direction = Vector3.Cross(Vector3.Cross(-abc, aO), -abc);
  186. }
  187. }
  188. }
  189. return false;
  190. }
  191.  
  192. static bool ProcessTetrehedron(ref Simplex simplex, ref Vector3 direction)
  193. {
  194. Vector3 a = simplex[3];
  195. Vector3 b = simplex[2];
  196. Vector3 c = simplex[1];
  197. Vector3 d = simplex[0];
  198. Vector3 ac = c - a;
  199. Vector3 ad = d - a;
  200. Vector3 ab = b - a;
  201. Vector3 bc = c - b;
  202. Vector3 bd = d - b;
  203.  
  204. Vector3 acd = Vector3.Cross(ad, ac);
  205. Vector3 abd = Vector3.Cross(ab, ad);
  206. Vector3 abc = Vector3.Cross(ac, ab);
  207.  
  208. Vector3 aO = -a;
  209.  
  210. if (abc.IsInSameDirection(aO))
  211. {
  212. if (Vector3.Cross(abc, ac).IsInSameDirection(aO))
  213. {
  214. simplex.Remove(b);
  215. simplex.Remove(d);
  216. direction = Vector3.Cross(Vector3.Cross(ac, aO), ac);
  217. }
  218. else if (Vector3.Cross(ab, abc).IsInSameDirection(aO))
  219. {
  220. simplex.Remove(c);
  221. simplex.Remove(d);
  222. direction = Vector3.Cross(Vector3.Cross(ab, aO), ab);
  223. }
  224. else
  225. {
  226. simplex.Remove(d);
  227. direction = abc;
  228. }
  229. }
  230. else if (acd.IsInSameDirection(aO))
  231. {
  232. if (Vector3.Cross(acd, ad).IsInSameDirection(aO))
  233. {
  234. simplex.Remove(b);
  235. simplex.Remove(c);
  236. direction = Vector3.Cross(Vector3.Cross(ad, aO), ad);
  237. }
  238. else if (Vector3.Cross(ac, acd).IsInSameDirection(aO))
  239. {
  240. simplex.Remove(b);
  241. simplex.Remove(d);
  242. direction = Vector3.Cross(Vector3.Cross(ac, aO), ac);
  243. }
  244. else
  245. {
  246. simplex.Remove(b);
  247. direction = acd;
  248. }
  249. }
  250. else if (abd.IsInSameDirection(aO))
  251. {
  252. if (Vector3.Cross(abd, ab).IsInSameDirection(aO))
  253. {
  254. simplex.Remove(c);
  255. simplex.Remove(d);
  256. direction = Vector3.Cross(Vector3.Cross(ab, aO), ab);
  257. }
  258. else if (Vector3.Cross(ad, abd).IsInSameDirection(aO))
  259. {
  260. simplex.Remove(b);
  261. simplex.Remove(c);
  262. direction = Vector3.Cross(Vector3.Cross(ad, aO), ad);
  263. }
  264. else
  265. {
  266. simplex.Remove(c);
  267. direction = abd;
  268. }
  269. }
  270. else
  271. {
  272. Debug.DrawLine(a, b, Color.green);
  273. Debug.DrawLine(b, c, Color.green);
  274. Debug.DrawLine(c, d, Color.green);
  275. Debug.DrawLine(d, a, Color.green);
  276. return true;
  277. }
  278.  
  279. Debug.DrawLine(a, b, Color.yellow);
  280. Debug.DrawLine(b, c, Color.yellow);
  281. Debug.DrawLine(c, d, Color.yellow);
  282. Debug.DrawLine(d, a, Color.yellow);
  283. return false;
  284. }
  285.  
  286. static Vector3 Support(
  287. IConvexRegion regionOne,
  288. IConvexRegion regionTwo,
  289. Vector3 direction)
  290. {
  291. return regionOne.GetFurthestPoint(direction) -
  292. regionTwo.GetFurthestPoint(-direction);
  293. }
  294. }
  295.  
  296.  
  297. public class Sphere : IConvexRegion
  298. {
  299. public Vector3 Center;
  300. public float Radius;
  301.  
  302. public Sphere(Vector3 center, float radius)
  303. {
  304. Center = center;
  305. Radius = radius;
  306. }
  307.  
  308. public Vector3 GetFurthestPoint(Vector3 direction)
  309. {
  310. if (direction != Vector3.zero)
  311. {
  312. direction.Normalize();
  313. }
  314. return Center + Radius * direction;
  315. }
  316. }
  317.  
  318.  
  319. public class Box : IConvexRegion
  320. {
  321. public Vector3 Center;
  322. Vector3 _halfDimensions = Vector3.one;
  323. Quaternion _orientation = Quaternion.identity;
  324.  
  325. public Vector3 Dimensions
  326. {
  327. get { return 2f * _halfDimensions; }
  328. }
  329.  
  330. public Box(Vector3 center) : this(center, 1f, 1f, 1f)
  331. {
  332. }
  333.  
  334. public Box(Vector3 center,float width,float height,float depth)
  335. : this(center, width, height, depth, Matrix4x4.identity)
  336. {
  337. }
  338.  
  339. public Box(Vector3 center,float width,float height,float depth,Matrix4x4 rotationMatrix)
  340. {
  341. Center = center;
  342. _halfDimensions = new Vector3(width / 2f,height / 2f,depth / 2f);
  343. _orientation = variables.QuaternionFromMatrix(rotationMatrix);
  344. }
  345.  
  346. public Vector3 GetFurthestPoint(Vector3 direction)
  347. {
  348. Vector3 halfHeight = _halfDimensions.y * Vector3.up;
  349. Vector3 halfWidth = _halfDimensions.x * Vector3.right;
  350. Vector3 halfDepth = _halfDimensions.z * Vector3.back;
  351.  
  352. Vector3[] vertices = new Vector3[8];
  353. vertices[0] = halfWidth + halfHeight + halfDepth;
  354. vertices[1] = -halfWidth + halfHeight + halfDepth;
  355. vertices[2] = halfWidth - halfHeight + halfDepth;
  356. vertices[3] = halfWidth + halfHeight - halfDepth;
  357. vertices[4] = -halfWidth - halfHeight + halfDepth;
  358. vertices[5] = halfWidth - halfHeight - halfDepth;
  359. vertices[6] = -halfWidth + halfHeight - halfDepth;
  360. vertices[7] = -halfWidth - halfHeight - halfDepth;
  361.  
  362. Matrix4x4 m = Matrix4x4.TRS(Center, _orientation, Vector3.one);
  363.  
  364. Vector3 furthestPoint = m.MultiplyPoint(vertices[0]);
  365. float maxDot = Vector3.Dot(furthestPoint, direction);
  366. for (int i = 1; i < 8; i++)
  367. {
  368. Vector3 vertex = m.MultiplyPoint(vertices[i]);
  369. float dot = Vector3.Dot(vertex, direction);
  370. if (dot > maxDot)
  371. {
  372. maxDot = dot;
  373. furthestPoint = vertex;
  374. }
  375. }
  376. return furthestPoint;
  377. }
  378. }
  379.  
  380. public class Capsue : IConvexRegion
  381. {
  382. public Vector3[] innerPoints = new Vector3[2];
  383. public float radius;
  384.  
  385. public Capsue(Vector3[] innerPoints) : this(innerPoints, 1f)
  386. {
  387. }
  388.  
  389. public Capsue(Vector3[] innerPoints, float radius)
  390. {
  391. this.innerPoints = innerPoints;
  392. this.radius = radius;
  393. }
  394.  
  395. public Vector3 GetFurthestPoint(Vector3 direction)
  396. {
  397. if (direction != Vector3.zero)
  398. {
  399. direction.Normalize();
  400. }
  401. return (Vector3.Dot(direction, innerPoints[1] - innerPoints[0]) >= .0f ? innerPoints[1] : innerPoints[0]) + radius * direction;
  402. }
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement