218 lines
4.7 KiB
C#
218 lines
4.7 KiB
C#
namespace Fusion.Addons.KCC
|
|
{
|
|
using UnityEngine;
|
|
|
|
public sealed class KCCShapeCastInfo
|
|
{
|
|
// PUBLIC MEMBERS
|
|
|
|
public Vector3 Position;
|
|
public float Radius;
|
|
public float Height;
|
|
public float Extent;
|
|
public Vector3 Direction;
|
|
public float MaxDistance;
|
|
public LayerMask LayerMask;
|
|
public QueryTriggerInteraction TriggerInteraction;
|
|
public KCCShapeCastHit[] AllHits;
|
|
public int AllHitCount;
|
|
public KCCShapeCastHit[] ColliderHits;
|
|
public int ColliderHitCount;
|
|
public KCCShapeCastHit[] TriggerHits;
|
|
public int TriggerHitCount;
|
|
|
|
// PRIVATE MEMBERS
|
|
|
|
private static readonly float[] _sortDistances = new float[KCC.CACHE_SIZE];
|
|
|
|
// CONSTRUCTORS
|
|
|
|
public KCCShapeCastInfo() : this(KCC.CACHE_SIZE)
|
|
{
|
|
}
|
|
|
|
public KCCShapeCastInfo(int maxHits)
|
|
{
|
|
AllHits = new KCCShapeCastHit[maxHits];
|
|
TriggerHits = new KCCShapeCastHit[maxHits];
|
|
ColliderHits = new KCCShapeCastHit[maxHits];
|
|
|
|
for (int i = 0; i < maxHits; ++i)
|
|
{
|
|
AllHits[i] = new KCCShapeCastHit();
|
|
}
|
|
}
|
|
|
|
// PUBLIC METHODS
|
|
|
|
public bool HasCollider(Collider collider)
|
|
{
|
|
for (int i = 0, count = AllHitCount; i < count; ++i)
|
|
{
|
|
KCCShapeCastHit hit = AllHits[i];
|
|
if (object.ReferenceEquals(hit.Collider, collider) == true)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool HasCollider(EColliderType colliderType)
|
|
{
|
|
for (int i = 0, count = AllHitCount; i < count; ++i)
|
|
{
|
|
KCCShapeCastHit hit = AllHits[i];
|
|
if (hit.Type == colliderType)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void AddHit(RaycastHit raycastHit)
|
|
{
|
|
if (AllHitCount == AllHits.Length)
|
|
return;
|
|
|
|
KCCShapeCastHit hit = AllHits[AllHitCount];
|
|
if (hit.Set(raycastHit) == true)
|
|
{
|
|
++AllHitCount;
|
|
|
|
if (hit.IsTrigger == true)
|
|
{
|
|
TriggerHits[TriggerHitCount] = hit;
|
|
++TriggerHitCount;
|
|
}
|
|
else
|
|
{
|
|
ColliderHits[ColliderHitCount] = hit;
|
|
++ColliderHitCount;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Sort()
|
|
{
|
|
int count = AllHitCount;
|
|
if (count <= 1)
|
|
return;
|
|
|
|
bool isSorted = false;
|
|
bool hasChanged = false;
|
|
KCCShapeCastHit[] allHits = AllHits;
|
|
float[] distances = _sortDistances;
|
|
int leftIndex;
|
|
int rightIndex;
|
|
float leftDistance;
|
|
float rightDistance;
|
|
KCCShapeCastHit leftHit;
|
|
KCCShapeCastHit rightHit;
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
distances[i] = allHits[i].RaycastHit.distance;
|
|
}
|
|
|
|
while (isSorted == false)
|
|
{
|
|
isSorted = true;
|
|
|
|
leftIndex = 0;
|
|
rightIndex = 1;
|
|
leftDistance = distances[leftIndex];
|
|
|
|
while (rightIndex < count)
|
|
{
|
|
rightDistance = distances[rightIndex];
|
|
|
|
if (leftDistance <= rightDistance)
|
|
{
|
|
leftDistance = rightDistance;
|
|
}
|
|
else
|
|
{
|
|
distances[leftIndex] = rightDistance;
|
|
distances[rightIndex] = leftDistance;
|
|
|
|
leftHit = allHits[leftIndex];
|
|
rightHit = allHits[rightIndex];
|
|
|
|
allHits[leftIndex] = rightHit;
|
|
allHits[rightIndex] = leftHit;
|
|
|
|
isSorted = false;
|
|
hasChanged = true;
|
|
}
|
|
|
|
++leftIndex;
|
|
++rightIndex;
|
|
}
|
|
}
|
|
|
|
if (hasChanged == true)
|
|
{
|
|
TriggerHitCount = 0;
|
|
ColliderHitCount = 0;
|
|
|
|
KCCShapeCastHit hit;
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
hit = allHits[i];
|
|
|
|
if (hit.IsTrigger == true)
|
|
{
|
|
TriggerHits[TriggerHitCount] = hit;
|
|
++TriggerHitCount;
|
|
}
|
|
else
|
|
{
|
|
ColliderHits[ColliderHitCount] = hit;
|
|
++ColliderHitCount;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Reset(bool deep)
|
|
{
|
|
Position = default;
|
|
Radius = default;
|
|
Height = default;
|
|
Extent = default;
|
|
Direction = default;
|
|
MaxDistance = default;
|
|
Radius = default;
|
|
LayerMask = default;
|
|
TriggerInteraction = QueryTriggerInteraction.Collide;
|
|
AllHitCount = default;
|
|
ColliderHitCount = default;
|
|
TriggerHitCount = default;
|
|
|
|
if (deep == true)
|
|
{
|
|
for (int i = 0, count = AllHits.Length; i < count; ++i)
|
|
{
|
|
AllHits[i].Reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DumpHits(KCC kcc)
|
|
{
|
|
if (AllHitCount <= 0)
|
|
return;
|
|
|
|
kcc.Log($"ShapeCast Hits ({AllHitCount})");
|
|
|
|
KCCShapeCastHit[] hits = AllHits;
|
|
for (int i = 0, count = AllHitCount; i < count; ++i)
|
|
{
|
|
KCCShapeCastHit hit = AllHits[i];
|
|
kcc.Log($"Collider: {hit.Collider.name}, Type: {hit.Type}, IsTrigger: {hit.IsTrigger}, Distance: {hit.RaycastHit.distance}");
|
|
}
|
|
}
|
|
}
|
|
}
|