123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- using System;
- using System.IO;
- using kt.Utility;
- using UnityEngine;
- namespace kt.Physics
- {
- public class NativeCapsuleCollider : ANativeColliderBase
- {
- public virtual NativeCapsuleColliderStatus capsuleStatus
- {
- get
- {
- return this.CapsuleStatus;
- }
- }
- public override NativeColliderStatus status
- {
- get
- {
- return this.CapsuleStatus;
- }
- protected set
- {
- this.CapsuleStatus = (value as NativeCapsuleColliderStatus);
- }
- }
- public Vector3 localDirection
- {
- get
- {
- Vector3 vector = MathUtility.GetPrimitiveVector(this.capsuleStatus.direction);
- if (this.capsuleStatus.isDirectionInverse)
- {
- vector = -vector;
- }
- return vector;
- }
- }
- public Vector3 worldDirection
- {
- get
- {
- return base.transform.TransformDirection(this.localDirection);
- }
- }
- public Vector3 startPos
- {
- get
- {
- return this.worldCenter - this.worldDirection * this.capsuleStatus.height / 2f;
- }
- }
- public Vector3 endPos
- {
- get
- {
- return this.worldCenter + this.worldDirection * this.capsuleStatus.height / 2f;
- }
- }
- public virtual float startRadius
- {
- get
- {
- return this.capsuleStatus.startRadius * base.GetLossyScale();
- }
- }
- public virtual float endRadius
- {
- get
- {
- return this.capsuleStatus.endRadius * base.GetLossyScale();
- }
- }
- public override bool Collide(ref Vector3 position, float radius)
- {
- Vector3 lhs = position - this.startPos;
- float num = Vector3.Dot(lhs, this.worldDirection);
- Vector3 a = Vector3.zero;
- Vector3 vector = Vector3.zero;
- float num2;
- if (num < 0f || num * num > (this.endPos - this.startPos).sqrMagnitude)
- {
- vector = ((num >= 0f) ? this.endPos : this.startPos);
- a = position - vector;
- num2 = ((num >= 0f) ? this.endRadius : this.startRadius);
- }
- else
- {
- vector = this.startPos + this.worldDirection * num;
- a = position - vector;
- if (this.capsuleStatus.height > 0f)
- {
- num2 = Mathf.Lerp(this.startRadius, this.endRadius, Mathf.Clamp01(num / this.capsuleStatus.height));
- }
- else
- {
- num2 = Mathf.Max(this.startRadius, this.endRadius);
- }
- }
- if (this.status.bound == NativeColliderStatus.Bound.Outside)
- {
- float num3 = num2 + radius;
- if (a.sqrMagnitude > num3 * num3)
- {
- return false;
- }
- float magnitude = a.magnitude;
- if (magnitude > 0f)
- {
- position = vector + a / magnitude * num3;
- }
- }
- else
- {
- float num4 = Mathf.Max(num2 - radius, 0f);
- if (a.sqrMagnitude < num4 * num4)
- {
- return false;
- }
- float magnitude2 = a.magnitude;
- if (magnitude2 > 0f)
- {
- position = vector + a / magnitude2 * num4;
- }
- }
- return true;
- }
- protected override bool CollideCapsule(NativeCapsuleCollider capsule, ref Vector3 normal)
- {
- Vector3 zero = Vector3.zero;
- float radius = 0f;
- bool flag;
- if (!this.IsIntersectProjection(capsule, ref zero, ref radius))
- {
- Vector3 b = zero;
- flag = this.Collide(ref zero, radius);
- if (flag)
- {
- normal = zero - b;
- }
- if (MathUtility.IsVector3NaN(normal))
- {
- flag = false;
- normal = Vector3.zero;
- }
- return flag;
- }
- if (!capsule.IsIntersectProjection(this, ref zero, ref radius))
- {
- Vector3 b2 = zero;
- flag = capsule.Collide(ref zero, radius);
- if (flag)
- {
- normal = -(zero - b2);
- }
- if (MathUtility.IsVector3NaN(normal))
- {
- flag = false;
- normal = Vector3.zero;
- }
- return flag;
- }
- Vector3 vector = Vector3.Cross(this.worldDirection, capsule.worldDirection).normalized;
- float num = Vector3.Dot(capsule.startPos - this.startPos, vector);
- if (num < 0f)
- {
- vector = -vector;
- num = Mathf.Abs(num);
- }
- float num2 = Mathf.Max(this.startRadius, this.endRadius);
- num2 += Mathf.Max(capsule.startRadius, capsule.endRadius);
- if (num > num2)
- {
- return false;
- }
- flag = true;
- Vector3 vector2 = capsule.startPos - vector * num;
- Vector3 vector3 = capsule.endPos - vector * num;
- float d = Vector3.Dot(this.startPos - vector2, capsule.worldDirection);
- float num3 = Vector3.Distance(this.startPos, vector2 + capsule.worldDirection * d);
- float d2 = Vector3.Dot(this.endPos - vector2, capsule.worldDirection);
- float num4 = Vector3.Distance(this.endPos, vector2 + capsule.worldDirection * d2);
- float num5 = num3 / (num3 + num4);
- Vector3 a = this.startPos + this.worldDirection * this.capsuleStatus.height * num5;
- float num6 = (capsule.capsuleStatus.height <= 0f) ? 0f : (Vector3.Dot(a - capsule.startPos, capsule.worldDirection) / capsule.capsuleStatus.height);
- Vector3 vector4 = capsule.startPos + capsule.worldDirection * capsule.capsuleStatus.height * num6;
- float num7 = Mathf.Lerp(this.startRadius, this.endRadius, num5);
- num7 += Mathf.Lerp(capsule.startRadius, capsule.endRadius, num6);
- if (num > num7)
- {
- return false;
- }
- normal = vector * (num7 - num);
- if (MathUtility.IsVector3NaN(normal))
- {
- flag = false;
- normal = Vector3.zero;
- }
- return flag;
- }
- private bool IsIntersectProjection(NativeCapsuleCollider capsule, ref Vector3 near_point, ref float near_radius)
- {
- Vector3 worldDirection = this.worldDirection;
- Vector3 lhs = Vector3.Cross(worldDirection, capsule.startPos - this.startPos);
- Vector3 rhs = Vector3.Cross(worldDirection, capsule.endPos - this.startPos);
- near_radius = ((lhs.sqrMagnitude > rhs.sqrMagnitude) ? capsule.endRadius : capsule.startRadius);
- near_point = ((lhs.sqrMagnitude > rhs.sqrMagnitude) ? capsule.endPos : capsule.startPos);
- return Vector3.Dot(lhs, rhs) < 0f;
- }
- public override void Save(StreamWriter writer)
- {
- base.Save<NativeCapsuleColliderStatus>(writer);
- }
- public override void Load(StreamReader reader, Transform parent_search_root)
- {
- base.Load<NativeCapsuleColliderStatus>(reader, parent_search_root);
- }
- [SerializeField]
- private NativeCapsuleColliderStatus CapsuleStatus = new NativeCapsuleColliderStatus();
- }
- }
|