修改水
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using Unity.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -25,11 +24,11 @@ namespace Obi
|
||||
|
||||
public int Compare(Oni.Contact x, Oni.Contact y)
|
||||
{
|
||||
return CompareByRef(x, y, solver);
|
||||
return CompareByRef(ref x, ref y, solver);
|
||||
}
|
||||
}
|
||||
|
||||
private static int CompareByRef(Oni.Contact a, Oni.Contact b, ObiSolver solver)
|
||||
private static int CompareByRef(ref Oni.Contact a, ref Oni.Contact b, ObiSolver solver)
|
||||
{
|
||||
if (a.bodyB == b.bodyB)
|
||||
{
|
||||
@@ -65,7 +64,7 @@ namespace Obi
|
||||
solver.OnCollision -= Solver_OnCollision;
|
||||
}
|
||||
|
||||
private int FilterOutDistantContacts(ObiNativeContactList data, int count)
|
||||
private int FilterOutDistantContacts(Oni.Contact[] data, int count)
|
||||
{
|
||||
int filteredCount = count;
|
||||
|
||||
@@ -73,12 +72,12 @@ namespace Obi
|
||||
// moving the ones above the threshold to the end of the array:
|
||||
for (int i = count - 1; i >= 0; --i)
|
||||
if (data[i].distance > distanceThreshold)
|
||||
data.Swap(i, --filteredCount);
|
||||
ObiUtils.Swap(ref data[i], ref data[--filteredCount]);
|
||||
|
||||
return filteredCount;
|
||||
}
|
||||
|
||||
private int RemoveDuplicates(ObiNativeContactList data, int count)
|
||||
private int RemoveDuplicates(Oni.Contact[] data, int count)
|
||||
{
|
||||
if (count == 0)
|
||||
return 0;
|
||||
@@ -87,13 +86,13 @@ namespace Obi
|
||||
// replacing duplicates by the first contact that's different:
|
||||
int i = 0, r = 0;
|
||||
while (++i != count)
|
||||
if (CompareByRef(data[i], data[r], solver) != 0 && ++r != i)
|
||||
if (CompareByRef(ref data[i], ref data[r], solver) != 0 && ++r != i)
|
||||
data[r] = data[i];
|
||||
|
||||
return ++r;
|
||||
}
|
||||
|
||||
private void InvokeCallbacks(ObiNativeContactList data, int count)
|
||||
private void InvokeCallbacks(Oni.Contact[] data, int count)
|
||||
{
|
||||
int a = 0, b = 0;
|
||||
int lengthA = count, lengthB = prevCount;
|
||||
@@ -102,7 +101,7 @@ namespace Obi
|
||||
while (a < lengthA && b < lengthB)
|
||||
{
|
||||
// compare both contacts:
|
||||
int compare = CompareByRef(data[a], prevData[b], solver);
|
||||
int compare = CompareByRef(ref data[a], ref prevData[b], solver);
|
||||
|
||||
// call the appropiate event depending on the comparison result:
|
||||
if (compare < 0)
|
||||
@@ -123,26 +122,30 @@ namespace Obi
|
||||
onContactExit.Invoke(solver, prevData[b++]);
|
||||
}
|
||||
|
||||
void Solver_OnCollision(object sender, ObiNativeContactList contacts)
|
||||
void Solver_OnCollision(object sender, ObiSolver.ObiCollisionEventArgs args)
|
||||
{
|
||||
// here we access the internal backing array (Data) directly,
|
||||
// instead of using the accessor property. This slightly improves performance.
|
||||
// note: the backing array length is the lists' capacity, so we
|
||||
// need to use args.contacts.Count to get the actual number of contacts.
|
||||
|
||||
// skip all contacts above the distance threshold by moving them to the end of the array:
|
||||
int filteredCount = FilterOutDistantContacts(contacts, contacts.count);
|
||||
int filteredCount = FilterOutDistantContacts(args.contacts.Data, args.contacts.Count);
|
||||
|
||||
// sort the remaining contacts by collider, then by actor:
|
||||
contacts.AsNativeArray().Slice(0,filteredCount).Sort(comparer);
|
||||
Array.Sort(args.contacts.Data, 0, filteredCount, comparer);
|
||||
|
||||
// remove duplicates:
|
||||
filteredCount = RemoveDuplicates(contacts, filteredCount);
|
||||
filteredCount = RemoveDuplicates(args.contacts.Data, filteredCount);
|
||||
|
||||
// zip trough the current and previous contact lists once, invoking events when appropiate.
|
||||
InvokeCallbacks(contacts, filteredCount);
|
||||
InvokeCallbacks(args.contacts.Data, filteredCount);
|
||||
|
||||
// store current contact list/count for next frame.
|
||||
// could get better performance by double buffering instead of copying:
|
||||
if (filteredCount > prevData.Length)
|
||||
Array.Resize(ref prevData, filteredCount);
|
||||
|
||||
contacts.CopyTo(prevData, 0, filteredCount);
|
||||
Array.Copy(args.contacts.Data, prevData, filteredCount);
|
||||
|
||||
prevCount = filteredCount;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user