NativeCapsuleCollider.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. using System;
  2. using System.IO;
  3. using kt.Utility;
  4. using UnityEngine;
  5. namespace kt.Physics
  6. {
  7. public class NativeCapsuleCollider : ANativeColliderBase
  8. {
  9. public virtual NativeCapsuleColliderStatus capsuleStatus
  10. {
  11. get
  12. {
  13. return this.CapsuleStatus;
  14. }
  15. }
  16. public override NativeColliderStatus status
  17. {
  18. get
  19. {
  20. return this.CapsuleStatus;
  21. }
  22. protected set
  23. {
  24. this.CapsuleStatus = (value as NativeCapsuleColliderStatus);
  25. }
  26. }
  27. public Vector3 localDirection
  28. {
  29. get
  30. {
  31. Vector3 vector = MathUtility.GetPrimitiveVector(this.capsuleStatus.direction);
  32. if (this.capsuleStatus.isDirectionInverse)
  33. {
  34. vector = -vector;
  35. }
  36. return vector;
  37. }
  38. }
  39. public Vector3 worldDirection
  40. {
  41. get
  42. {
  43. return base.transform.TransformDirection(this.localDirection);
  44. }
  45. }
  46. public Vector3 startPos
  47. {
  48. get
  49. {
  50. return this.worldCenter - this.worldDirection * this.capsuleStatus.height / 2f;
  51. }
  52. }
  53. public Vector3 endPos
  54. {
  55. get
  56. {
  57. return this.worldCenter + this.worldDirection * this.capsuleStatus.height / 2f;
  58. }
  59. }
  60. public virtual float startRadius
  61. {
  62. get
  63. {
  64. return this.capsuleStatus.startRadius * base.GetLossyScale();
  65. }
  66. }
  67. public virtual float endRadius
  68. {
  69. get
  70. {
  71. return this.capsuleStatus.endRadius * base.GetLossyScale();
  72. }
  73. }
  74. public override bool Collide(ref Vector3 position, float radius)
  75. {
  76. Vector3 lhs = position - this.startPos;
  77. float num = Vector3.Dot(lhs, this.worldDirection);
  78. Vector3 a = Vector3.zero;
  79. Vector3 vector = Vector3.zero;
  80. float num2;
  81. if (num < 0f || num * num > (this.endPos - this.startPos).sqrMagnitude)
  82. {
  83. vector = ((num >= 0f) ? this.endPos : this.startPos);
  84. a = position - vector;
  85. num2 = ((num >= 0f) ? this.endRadius : this.startRadius);
  86. }
  87. else
  88. {
  89. vector = this.startPos + this.worldDirection * num;
  90. a = position - vector;
  91. if (this.capsuleStatus.height > 0f)
  92. {
  93. num2 = Mathf.Lerp(this.startRadius, this.endRadius, Mathf.Clamp01(num / this.capsuleStatus.height));
  94. }
  95. else
  96. {
  97. num2 = Mathf.Max(this.startRadius, this.endRadius);
  98. }
  99. }
  100. if (this.status.bound == NativeColliderStatus.Bound.Outside)
  101. {
  102. float num3 = num2 + radius;
  103. if (a.sqrMagnitude > num3 * num3)
  104. {
  105. return false;
  106. }
  107. float magnitude = a.magnitude;
  108. if (magnitude > 0f)
  109. {
  110. position = vector + a / magnitude * num3;
  111. }
  112. }
  113. else
  114. {
  115. float num4 = Mathf.Max(num2 - radius, 0f);
  116. if (a.sqrMagnitude < num4 * num4)
  117. {
  118. return false;
  119. }
  120. float magnitude2 = a.magnitude;
  121. if (magnitude2 > 0f)
  122. {
  123. position = vector + a / magnitude2 * num4;
  124. }
  125. }
  126. return true;
  127. }
  128. protected override bool CollideCapsule(NativeCapsuleCollider capsule, ref Vector3 normal)
  129. {
  130. Vector3 zero = Vector3.zero;
  131. float radius = 0f;
  132. bool flag;
  133. if (!this.IsIntersectProjection(capsule, ref zero, ref radius))
  134. {
  135. Vector3 b = zero;
  136. flag = this.Collide(ref zero, radius);
  137. if (flag)
  138. {
  139. normal = zero - b;
  140. }
  141. if (MathUtility.IsVector3NaN(normal))
  142. {
  143. flag = false;
  144. normal = Vector3.zero;
  145. }
  146. return flag;
  147. }
  148. if (!capsule.IsIntersectProjection(this, ref zero, ref radius))
  149. {
  150. Vector3 b2 = zero;
  151. flag = capsule.Collide(ref zero, radius);
  152. if (flag)
  153. {
  154. normal = -(zero - b2);
  155. }
  156. if (MathUtility.IsVector3NaN(normal))
  157. {
  158. flag = false;
  159. normal = Vector3.zero;
  160. }
  161. return flag;
  162. }
  163. Vector3 vector = Vector3.Cross(this.worldDirection, capsule.worldDirection).normalized;
  164. float num = Vector3.Dot(capsule.startPos - this.startPos, vector);
  165. if (num < 0f)
  166. {
  167. vector = -vector;
  168. num = Mathf.Abs(num);
  169. }
  170. float num2 = Mathf.Max(this.startRadius, this.endRadius);
  171. num2 += Mathf.Max(capsule.startRadius, capsule.endRadius);
  172. if (num > num2)
  173. {
  174. return false;
  175. }
  176. flag = true;
  177. Vector3 vector2 = capsule.startPos - vector * num;
  178. Vector3 vector3 = capsule.endPos - vector * num;
  179. float d = Vector3.Dot(this.startPos - vector2, capsule.worldDirection);
  180. float num3 = Vector3.Distance(this.startPos, vector2 + capsule.worldDirection * d);
  181. float d2 = Vector3.Dot(this.endPos - vector2, capsule.worldDirection);
  182. float num4 = Vector3.Distance(this.endPos, vector2 + capsule.worldDirection * d2);
  183. float num5 = num3 / (num3 + num4);
  184. Vector3 a = this.startPos + this.worldDirection * this.capsuleStatus.height * num5;
  185. float num6 = (capsule.capsuleStatus.height <= 0f) ? 0f : (Vector3.Dot(a - capsule.startPos, capsule.worldDirection) / capsule.capsuleStatus.height);
  186. Vector3 vector4 = capsule.startPos + capsule.worldDirection * capsule.capsuleStatus.height * num6;
  187. float num7 = Mathf.Lerp(this.startRadius, this.endRadius, num5);
  188. num7 += Mathf.Lerp(capsule.startRadius, capsule.endRadius, num6);
  189. if (num > num7)
  190. {
  191. return false;
  192. }
  193. normal = vector * (num7 - num);
  194. if (MathUtility.IsVector3NaN(normal))
  195. {
  196. flag = false;
  197. normal = Vector3.zero;
  198. }
  199. return flag;
  200. }
  201. private bool IsIntersectProjection(NativeCapsuleCollider capsule, ref Vector3 near_point, ref float near_radius)
  202. {
  203. Vector3 worldDirection = this.worldDirection;
  204. Vector3 lhs = Vector3.Cross(worldDirection, capsule.startPos - this.startPos);
  205. Vector3 rhs = Vector3.Cross(worldDirection, capsule.endPos - this.startPos);
  206. near_radius = ((lhs.sqrMagnitude > rhs.sqrMagnitude) ? capsule.endRadius : capsule.startRadius);
  207. near_point = ((lhs.sqrMagnitude > rhs.sqrMagnitude) ? capsule.endPos : capsule.startPos);
  208. return Vector3.Dot(lhs, rhs) < 0f;
  209. }
  210. public override void Save(StreamWriter writer)
  211. {
  212. base.Save<NativeCapsuleColliderStatus>(writer);
  213. }
  214. public override void Load(StreamReader reader, Transform parent_search_root)
  215. {
  216. base.Load<NativeCapsuleColliderStatus>(reader, parent_search_root);
  217. }
  218. [SerializeField]
  219. private NativeCapsuleColliderStatus CapsuleStatus = new NativeCapsuleColliderStatus();
  220. }
  221. }