Files
AutoMorpherDecompiled/Assets/@Eden_Tools/Eden_AutoMorpher/Script/BvhTriangleMesh.cs

702 lines
32 KiB
C#

// Decompiled with JetBrains decompiler
// Type: Eden.AutoMorpher.BvhTriangleMesh
// Assembly: EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: D39968B3-E151-4276-BDB4-E82752BBAFF0
// Assembly location: D:\dev\AutoMorpher\Assets\@Eden_Tools\Eden_AutoMorpher\Script\EdenAutoMorpherScript.dll
using System.Collections.Generic;
using UnityEngine;
namespace Eden.AutoMorpher
{
public class BvhTriangleMesh
{
private TriangleUtil triangleUtil;
private HumanBodyBones[] humanBones;
public BvhTriangle[] triangles;
public BvhNode[] nodes;
public int[] triIndices;
private const int LeafMaxTriangles = 4;
public BvhTriangleMesh()
{
// ISSUE: unable to decompile the method.
}
private HumanBodyBones[] BuildVertexMainHumanBone(
SkinnedMeshRenderer smr,
Animator animator,
HumanBodyBones[] bodyBones)
{
Mesh sharedMesh = smr.sharedMesh;
BoneWeight[] boneWeights = sharedMesh.boneWeights;
int[] boneToBodyIndex = this.BuildBoneToBodyIndexMap(smr, animator, bodyBones);
HumanBodyBones[] humanBodyBonesArray = new HumanBodyBones[sharedMesh.vertexCount];
for (int index = 0; index < sharedMesh.vertexCount; ++index)
{
BoneWeight boneWeight = boneWeights[index];
int bestBodyIdx = -1;
float bestWeight = 0.0f;
Try(((BoneWeight)ref boneWeight).boneIndex0, ((BoneWeight)ref boneWeight).weight0);
Try(((BoneWeight)ref boneWeight).boneIndex1, ((BoneWeight)ref boneWeight).weight1);
Try(((BoneWeight)ref boneWeight).boneIndex2, ((BoneWeight)ref boneWeight).weight2);
Try(((BoneWeight)ref boneWeight).boneIndex3, ((BoneWeight)ref boneWeight).weight3);
humanBodyBonesArray[index] = bestBodyIdx >= 0 ? (HumanBodyBones)(int)bodyBones[bestBodyIdx] : (HumanBodyBones)55;
void Try(int boneIdx, float w)
{
if ((double)w <= 0.0 || boneIdx < 0 || boneIdx >= boneToBodyIndex.Length)
return;
int num = boneToBodyIndex[boneIdx];
if (num < 0 || (double)w <= (double)bestWeight)
return;
bestWeight = w;
bestBodyIdx = num;
}
}
return humanBodyBonesArray;
}
public BvhTriangleMesh BuildFromSkinnedMeshes(
IReadOnlyList<SkinnedMeshRenderer> renderers,
Animator animator)
{
if (renderers == null || renderers.Count == 0)
return (BvhTriangleMesh)null;
BvhTriangleMesh bvhTriangleMesh = new BvhTriangleMesh();
int length = 0;
foreach (SkinnedMeshRenderer renderer in (IEnumerable<SkinnedMeshRenderer>)renderers)
{
if (!Object.op_Equality((Object)renderer, (Object)null) && !Object.op_Equality((Object)renderer.sharedMesh, (Object)null))
length += renderer.sharedMesh.triangles.Length / 3;
}
if (length == 0)
return (BvhTriangleMesh)null;
bvhTriangleMesh.triangles = new BvhTriangle[length];
int num1 = 0;
Mesh mesh = new Mesh();
foreach (SkinnedMeshRenderer renderer in (IEnumerable<SkinnedMeshRenderer>)renderers)
{
if (!Object.op_Equality((Object)renderer, (Object)null) && !Object.op_Equality((Object)renderer.sharedMesh, (Object)null))
{
mesh.Clear();
renderer.BakeMesh(mesh);
Vector3[] vertices = mesh.vertices;
int[] triangles = renderer.sharedMesh.triangles;
BoneWeight[] boneWeights = renderer.sharedMesh.boneWeights;
int[] bodyIndexMap = this.BuildBoneToBodyIndexMap(renderer, animator, this.humanBones);
int num2 = triangles.Length / 3;
Transform transform = ((Component)renderer).transform;
Vector3 lossyScale = transform.lossyScale;
Vector3 vector3_1;
// ISSUE: explicit constructor call
((Vector3)ref vector3_1).\u002Ector(1f / Mathf.Max(lossyScale.x, 1E-08f), 1f / Mathf.Max(lossyScale.y, 1E-08f), 1f / Mathf.Max(lossyScale.z, 1E-08f));
Matrix4x4 matrix4x4 = Matrix4x4.op_Multiply(transform.localToWorldMatrix, Matrix4x4.Scale(vector3_1));
for (int index = 0; index < num2; ++index)
{
int vi0 = triangles[index * 3];
int vi1 = triangles[index * 3 + 1];
int vi2 = triangles[index * 3 + 2];
Vector3 vector3_2 = ((Matrix4x4)ref matrix4x4).MultiplyPoint3x4(vertices[vi0]);
Vector3 vector3_3 = ((Matrix4x4)ref matrix4x4).MultiplyPoint3x4(vertices[vi1]);
Vector3 vector3_4 = ((Matrix4x4)ref matrix4x4).MultiplyPoint3x4(vertices[vi2]);
Vector3 vector3_5 = Vector3.Cross(Vector3.op_Subtraction(vector3_3, vector3_2), Vector3.op_Subtraction(vector3_4, vector3_2));
float magnitude = ((Vector3)ref vector3_5).magnitude;
Vector3 vector3_6 = (double)magnitude <= 9.99999993922529E-09 ? Vector3.up : Vector3.op_Division(vector3_5, magnitude);
int mainHumanBoneIndex = this.ComputeTriangleMainHumanBoneIndex(vi0, vi1, vi2, boneWeights, bodyIndexMap, this.humanBones.Length);
HumanBodyBones humanBodyBones = mainHumanBoneIndex >= 0 ? (HumanBodyBones)(int)this.humanBones[mainHumanBoneIndex] : (HumanBodyBones)55;
bvhTriangleMesh.triangles[num1++] = new BvhTriangle()
{
a = vector3_2,
b = vector3_3,
c = vector3_4,
normal = vector3_6,
mainHumanBone = humanBodyBones
};
mesh.Clear();
}
}
}
int count = length;
int[] triIndices = new int[count];
for (int index = 0; index < count; ++index)
triIndices[index] = index;
bvhTriangleMesh.triIndices = triIndices;
List<BvhNode> outNodes = new List<BvhNode>();
this.BuildRecursive(bvhTriangleMesh.triangles, triIndices, 0, count, outNodes);
bvhTriangleMesh.nodes = outNodes.ToArray();
return bvhTriangleMesh;
}
private int[] BuildBoneToBodyIndexMap(
SkinnedMeshRenderer smr,
Animator animator,
HumanBodyBones[] bodyBones)
{
Transform[] bones = smr.bones;
int[] bodyIndexMap = new int[bones.Length];
for (int index = 0; index < bodyIndexMap.Length; ++index)
bodyIndexMap[index] = -1;
if (Object.op_Equality((Object)animator, (Object)null) || bodyBones == null || bones == null)
return bodyIndexMap;
Dictionary<Transform, int> dictionary1 = new Dictionary<Transform, int>();
for (int index = 0; index < bones.Length; ++index)
{
if (!Object.op_Equality((Object)bones[index], (Object)null) && !dictionary1.ContainsKey(bones[index]))
dictionary1.Add(bones[index], index);
}
Dictionary<HumanBodyBones, HashSet<Transform>> dictionary2 = new MeshClassifier().MeshHumanoidBoneMatcher(animator, (IReadOnlyList<SkinnedMeshRenderer>)new SkinnedMeshRenderer[1]
{
smr
});
for (int index1 = 0; index1 < bodyBones.Length; ++index1)
{
HumanBodyBones bodyBone = (HumanBodyBones)(int)bodyBones[index1];
HashSet<Transform> transformSet;
if (dictionary2.TryGetValue(bodyBone, out transformSet) && transformSet != null)
{
foreach (Transform key in transformSet)
{
int index2;
if (!Object.op_Equality((Object)key, (Object)null) && dictionary1.TryGetValue(key, out index2))
bodyIndexMap[index2] = index1;
}
}
}
for (int index3 = 0; index3 < bones.Length; ++index3)
{
if (bodyIndexMap[index3] == -1)
{
Transform transform = bones[index3];
if (!Object.op_Equality((Object)transform, (Object)null))
{
Transform parent = transform.parent;
int index4;
if (!Object.op_Equality((Object)parent, (Object)null) && dictionary1.TryGetValue(parent, out index4))
{
int num = bodyIndexMap[index4];
if (num != -1)
bodyIndexMap[index3] = num;
}
}
}
}
return bodyIndexMap;
}
private int ComputeTriangleMainHumanBoneIndex(
int vi0,
int vi1,
int vi2,
BoneWeight[] weights,
int[] boneToBodyIndex,
int bodyBonesCount)
{
if (weights == null || weights.Length == 0 || boneToBodyIndex == null || boneToBodyIndex.Length == 0)
return -1;
float[] scores = new float[bodyBonesCount];
Accumulate(vi0);
Accumulate(vi1);
Accumulate(vi2);
int mainHumanBoneIndex = -1;
float num = 0.0f;
for (int index = 0; index < scores.Length; ++index)
{
if ((double)scores[index] > (double)num)
{
num = scores[index];
mainHumanBoneIndex = index;
}
}
return mainHumanBoneIndex;
void Accumulate(int v)
{
if (v < 0 || v >= weights.Length)
return;
BoneWeight weight = weights[v];
Add(((BoneWeight)ref weight).boneIndex0, ((BoneWeight)ref weight).weight0);
Add(((BoneWeight)ref weight).boneIndex1, ((BoneWeight)ref weight).weight1);
Add(((BoneWeight)ref weight).boneIndex2, ((BoneWeight)ref weight).weight2);
Add(((BoneWeight)ref weight).boneIndex3, ((BoneWeight)ref weight).weight3);
}
void Add(int boneIdx, float w)
{
if ((double)w <= 0.0 || boneIdx < 0 || boneIdx >= boneToBodyIndex.Length)
return;
int index = boneToBodyIndex[boneIdx];
if (index < 0)
return;
scores[index] += w;
}
}
public BvhTriangleMesh BuildFromSkinnedMeshes(IList<SkinnedMeshRenderer> renderers)
{
if (renderers == null || renderers.Count == 0)
return (BvhTriangleMesh)null;
BvhTriangleMesh bvhTriangleMesh = new BvhTriangleMesh();
int length = 0;
foreach (SkinnedMeshRenderer renderer in (IEnumerable<SkinnedMeshRenderer>)renderers)
{
if (!Object.op_Equality((Object)renderer, (Object)null) && !Object.op_Equality((Object)renderer.sharedMesh, (Object)null))
length += renderer.sharedMesh.triangles.Length / 3;
}
if (length == 0)
return (BvhTriangleMesh)null;
bvhTriangleMesh.triangles = new BvhTriangle[length];
int num1 = 0;
foreach (SkinnedMeshRenderer renderer in (IEnumerable<SkinnedMeshRenderer>)renderers)
{
if (!Object.op_Equality((Object)renderer, (Object)null) && !Object.op_Equality((Object)renderer.sharedMesh, (Object)null))
{
Mesh sharedMesh = renderer.sharedMesh;
Vector3[] vertices = sharedMesh.vertices;
int[] triangles = sharedMesh.triangles;
int num2 = triangles.Length / 3;
for (int index1 = 0; index1 < num2; ++index1)
{
int index2 = triangles[index1 * 3];
int index3 = triangles[index1 * 3 + 1];
int index4 = triangles[index1 * 3 + 2];
Vector3 vector3_1 = ((Component)renderer).transform.TransformPoint(vertices[index2]);
Vector3 vector3_2 = ((Component)renderer).transform.TransformPoint(vertices[index3]);
Vector3 vector3_3 = ((Component)renderer).transform.TransformPoint(vertices[index4]);
Vector3 vector3_4 = Vector3.Cross(Vector3.op_Subtraction(vector3_2, vector3_1), Vector3.op_Subtraction(vector3_3, vector3_1));
float magnitude = ((Vector3)ref vector3_4).magnitude;
Vector3 vector3_5 = (double)magnitude <= 9.99999993922529E-09 ? Vector3.up : Vector3.op_Division(vector3_4, magnitude);
bvhTriangleMesh.triangles[num1++] = new BvhTriangle()
{
a = vector3_1,
b = vector3_2,
c = vector3_3,
normal = vector3_5
};
}
}
}
int count = length;
int[] triIndices = new int[count];
for (int index = 0; index < count; ++index)
triIndices[index] = index;
bvhTriangleMesh.triIndices = triIndices;
List<BvhNode> outNodes = new List<BvhNode>();
this.BuildRecursive(bvhTriangleMesh.triangles, triIndices, 0, count, outNodes);
bvhTriangleMesh.nodes = outNodes.ToArray();
return bvhTriangleMesh;
}
public BvhTriangleMesh BuildFromMesh(Mesh mesh, Transform transform)
{
BvhTriangleMesh bvhTriangleMesh = new BvhTriangleMesh();
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
int count = triangles.Length / 3;
bvhTriangleMesh.triangles = new BvhTriangle[count];
for (int index1 = 0; index1 < count; ++index1)
{
int index2 = triangles[index1 * 3];
int index3 = triangles[index1 * 3 + 1];
int index4 = triangles[index1 * 3 + 2];
Vector3 vector3_1 = transform.TransformPoint(vertices[index2]);
Vector3 vector3_2 = transform.TransformPoint(vertices[index3]);
Vector3 vector3_3 = transform.TransformPoint(vertices[index4]);
Vector3 vector3_4 = Vector3.Cross(Vector3.op_Subtraction(vector3_2, vector3_1), Vector3.op_Subtraction(vector3_3, vector3_1));
float magnitude = ((Vector3)ref vector3_4).magnitude;
vector3_4 = (double)magnitude <= 9.99999993922529E-09 ? Vector3.up : Vector3.op_Division(vector3_4, magnitude);
bvhTriangleMesh.triangles[index1] = new BvhTriangle()
{
a = vector3_1,
b = vector3_2,
c = vector3_3,
normal = vector3_4
};
}
int[] triIndices = new int[count];
for (int index = 0; index < count; ++index)
triIndices[index] = index;
bvhTriangleMesh.triIndices = triIndices;
List<BvhNode> outNodes = new List<BvhNode>();
this.BuildRecursive(bvhTriangleMesh.triangles, triIndices, 0, count, outNodes);
bvhTriangleMesh.nodes = outNodes.ToArray();
return bvhTriangleMesh;
}
private int BuildRecursive(
BvhTriangle[] tris,
int[] triIndices,
int start,
int count,
List<BvhNode> outNodes)
{
int count1 = outNodes.Count;
BvhNode bvhNode = new BvhNode();
Bounds bounds = new Bounds();
bool flag = true;
for (int index = start; index < start + count; ++index)
{
BvhTriangle tri = tris[triIndices[index]];
if (flag)
{
// ISSUE: explicit constructor call
((Bounds)ref bounds).\u002Ector(tri.a, Vector3.zero);
((Bounds)ref bounds).Encapsulate(tri.b);
((Bounds)ref bounds).Encapsulate(tri.c);
flag = false;
}
else
{
((Bounds)ref bounds).Encapsulate(tri.a);
((Bounds)ref bounds).Encapsulate(tri.b);
((Bounds)ref bounds).Encapsulate(tri.c);
}
}
bvhNode.bounds = bounds;
if (count <= 4)
{
bvhNode.isLeaf = true;
bvhNode.start = start;
bvhNode.count = count;
bvhNode.leftChild = -1;
bvhNode.rightChild = -1;
outNodes.Add(bvhNode);
return count1;
}
Vector3 size = ((Bounds)ref bounds).size;
int axis = 0;
if ((double)size.y > (double)size.x && (double)size.y > (double)size.z)
axis = 1;
else if ((double)size.z > (double)size.x && (double)size.z > (double)size.y)
axis = 2;
float num1 = 0.0f;
for (int index = start; index < start + count; ++index)
{
BvhTriangle tri = tris[triIndices[index]];
Vector3 vector3 = Vector3.op_Division(Vector3.op_Addition(Vector3.op_Addition(tri.a, tri.b), tri.c), 3f);
num1 += ((Vector3)ref vector3)[axis];
}
float splitPos = num1 / (float)count;
int start1 = this.Partition(tris, triIndices, start, count, axis, splitPos);
if (start1 == start || start1 == start + count)
start1 = start + count / 2;
bvhNode.isLeaf = false;
bvhNode.start = -1;
bvhNode.count = 0;
outNodes.Add(bvhNode);
int num2 = this.BuildRecursive(tris, triIndices, start, start1 - start, outNodes);
int num3 = this.BuildRecursive(tris, triIndices, start1, start + count - start1, outNodes);
bvhNode.leftChild = num2;
bvhNode.rightChild = num3;
outNodes[count1] = bvhNode;
return count1;
}
private int Partition(
BvhTriangle[] tris,
int[] triIndices,
int start,
int count,
int axis,
float splitPos)
{
int index1 = start;
int index2 = start + count - 1;
while (index1 <= index2)
{
BvhTriangle tri1 = tris[triIndices[index1]];
BvhTriangle tri2 = tris[triIndices[index2]];
double num1 = ((double)((Vector3)ref tri1.a)[axis] + (double)((Vector3)ref tri1.b)[axis] + (double)((Vector3)ref tri1.c)[axis]) / 3.0;
double num2 = ((double)((Vector3)ref tri2.a)[axis] + (double)((Vector3)ref tri2.b)[axis] + (double)((Vector3)ref tri2.c)[axis]) / 3.0;
double num3 = (double)splitPos;
if (num1 < num3)
{
++index1;
}
else
{
int triIndex = triIndices[index1];
triIndices[index1] = triIndices[index2];
triIndices[index2] = triIndex;
--index2;
}
}
return index1;
}
public BvhTriangleMesh.ClosestHit QueryClosest(Vector3 point)
{
BvhTriangleMesh.ClosestHit best = new BvhTriangleMesh.ClosestHit()
{
triangleIndex = -1,
sqrDistance = float.MaxValue
};
if (this.nodes == null || this.nodes.Length == 0)
return best;
this.QueryClosestRecursive(0, point, ref best);
return best;
}
public BvhTriangleMesh.ClosestHit QueryClosest(
Vector3 point,
HashSet<HumanBodyBones> allowedBones)
{
BvhTriangleMesh.ClosestHit best = new BvhTriangleMesh.ClosestHit()
{
triangleIndex = -1,
sqrDistance = float.MaxValue
};
if (this.nodes == null || this.nodes.Length == 0)
return best;
if (allowedBones == null || allowedBones.Count == 0)
this.QueryClosestRecursive(0, point, ref best);
else
this.QueryClosestRecursiveFiltered(0, point, ref best, allowedBones);
return best;
}
private void QueryClosestRecursiveFiltered(
int nodeIndex,
Vector3 p,
ref BvhTriangleMesh.ClosestHit best,
HashSet<HumanBodyBones> allowedBones)
{
BvhNode node = this.nodes[nodeIndex];
if ((double)this.DistanceSqPointAABB(p, node.bounds) > (double)best.sqrDistance)
return;
if (node.isLeaf)
{
int num = node.start + node.count;
for (int start = node.start; start < num; ++start)
{
int triIndex = this.triIndices[start];
BvhTriangle triangle = this.triangles[triIndex];
if (allowedBones.Contains(triangle.mainHumanBone))
{
Vector3 vector3_1 = this.triangleUtil.ClosestPointOnTriangle(p, triangle.a, triangle.b, triangle.c);
Vector3 vector3_2 = Vector3.op_Subtraction(p, vector3_1);
float sqrMagnitude = ((Vector3)ref vector3_2).sqrMagnitude;
if ((double)sqrMagnitude < (double)best.sqrDistance)
{
best.sqrDistance = sqrMagnitude;
best.triangleIndex = triIndex;
best.closestPoint = vector3_1;
best.normal = triangle.normal;
best.mainHumanBone = triangle.mainHumanBone;
}
}
}
}
else
{
int leftChild = node.leftChild;
int rightChild = node.rightChild;
if ((double)this.DistanceSqPointAABB(p, this.nodes[leftChild].bounds) < (double)this.DistanceSqPointAABB(p, this.nodes[rightChild].bounds))
{
this.QueryClosestRecursiveFiltered(leftChild, p, ref best, allowedBones);
this.QueryClosestRecursiveFiltered(rightChild, p, ref best, allowedBones);
}
else
{
this.QueryClosestRecursiveFiltered(rightChild, p, ref best, allowedBones);
this.QueryClosestRecursiveFiltered(leftChild, p, ref best, allowedBones);
}
}
}
private void QueryClosestRecursive(int nodeIndex, Vector3 p, ref BvhTriangleMesh.ClosestHit best)
{
BvhNode node = this.nodes[nodeIndex];
if ((double)this.DistanceSqPointAABB(p, node.bounds) > (double)best.sqrDistance)
return;
if (node.isLeaf)
{
int num = node.start + node.count;
for (int start = node.start; start < num; ++start)
{
int triIndex = this.triIndices[start];
BvhTriangle triangle = this.triangles[triIndex];
Vector3 vector3_1 = this.triangleUtil.ClosestPointOnTriangle(p, triangle.a, triangle.b, triangle.c);
Vector3 vector3_2 = Vector3.op_Subtraction(p, vector3_1);
float sqrMagnitude = ((Vector3)ref vector3_2).sqrMagnitude;
if ((double)sqrMagnitude < (double)best.sqrDistance)
{
best.sqrDistance = sqrMagnitude;
best.triangleIndex = triIndex;
best.closestPoint = vector3_1;
best.normal = triangle.normal;
best.mainHumanBone = triangle.mainHumanBone;
}
}
}
else
{
int leftChild = node.leftChild;
int rightChild = node.rightChild;
if ((double)this.DistanceSqPointAABB(p, this.nodes[leftChild].bounds) < (double)this.DistanceSqPointAABB(p, this.nodes[rightChild].bounds))
{
this.QueryClosestRecursive(leftChild, p, ref best);
this.QueryClosestRecursive(rightChild, p, ref best);
}
else
{
this.QueryClosestRecursive(rightChild, p, ref best);
this.QueryClosestRecursive(leftChild, p, ref best);
}
}
}
private float DistanceSqPointAABB(Vector3 p, Bounds b)
{
float num1 = Mathf.Max(new float[3]
{
((Bounds) ref b).min.x - p.x,
0.0f,
p.x - ((Bounds) ref b).max.x
});
float num2 = Mathf.Max(new float[3]
{
((Bounds) ref b).min.y - p.y,
0.0f,
p.y - ((Bounds) ref b).max.y
});
float num3 = Mathf.Max(new float[3]
{
((Bounds) ref b).min.z - p.z,
0.0f,
p.z - ((Bounds) ref b).max.z
});
return (float)((double)num1 * (double)num1 + (double)num2 * (double)num2 + (double)num3 * (double)num3);
}
public int QueryClosestN(
Vector3 point,
int maxCount,
float maxDistance,
List<BvhTriangleMesh.ClosestHit> results)
{
results.Clear();
if (this.nodes == null || this.nodes.Length == 0 || maxCount <= 0)
return 0;
float maxDistanceSq = maxDistance * maxDistance;
float currentMaxSq = maxDistanceSq;
this.QueryClosestNRecursive(0, point, maxCount, maxDistanceSq, results, ref currentMaxSq);
return results.Count;
}
private void QueryClosestNRecursive(
int nodeIndex,
Vector3 p,
int maxCount,
float maxDistanceSq,
List<BvhTriangleMesh.ClosestHit> bestHits,
ref float currentMaxSq)
{
BvhNode node = this.nodes[nodeIndex];
if ((double)this.DistanceSqPointAABB(p, node.bounds) > (double)currentMaxSq)
return;
if (node.isLeaf)
{
int num1 = node.start + node.count;
for (int start = node.start; start < num1; ++start)
{
int triIndex = this.triIndices[start];
BvhTriangle triangle = this.triangles[triIndex];
Vector3 vector3_1 = this.triangleUtil.ClosestPointOnTriangle(p, triangle.a, triangle.b, triangle.c);
Vector3 vector3_2 = Vector3.op_Subtraction(p, vector3_1);
float sqrMagnitude = ((Vector3)ref vector3_2).sqrMagnitude;
BvhTriangleMesh.ClosestHit closestHit1;
if ((double)sqrMagnitude <= (double)maxDistanceSq)
{
if (bestHits.Count < maxCount)
{
List<BvhTriangleMesh.ClosestHit> closestHitList = bestHits;
closestHit1 = new BvhTriangleMesh.ClosestHit();
closestHit1.triangleIndex = triIndex;
closestHit1.closestPoint = vector3_1;
closestHit1.normal = triangle.normal;
closestHit1.sqrDistance = sqrMagnitude;
closestHit1.mainHumanBone = triangle.mainHumanBone;
BvhTriangleMesh.ClosestHit closestHit2 = closestHit1;
closestHitList.Add(closestHit2);
if (bestHits.Count == maxCount)
currentMaxSq = this.GetMaxSqrDistance(bestHits, maxDistanceSq);
}
else if ((double)sqrMagnitude < (double)currentMaxSq)
{
int num2 = 0;
float sqrDistance = bestHits[0].sqrDistance;
for (int index = 1; index < bestHits.Count; ++index)
{
if ((double)bestHits[index].sqrDistance > (double)sqrDistance)
{
sqrDistance = bestHits[index].sqrDistance;
num2 = index;
}
}
List<BvhTriangleMesh.ClosestHit> closestHitList = bestHits;
int index1 = num2;
closestHit1 = new BvhTriangleMesh.ClosestHit();
closestHit1.triangleIndex = triIndex;
closestHit1.closestPoint = vector3_1;
closestHit1.normal = triangle.normal;
closestHit1.sqrDistance = sqrMagnitude;
BvhTriangleMesh.ClosestHit closestHit3 = closestHit1;
closestHitList[index1] = closestHit3;
currentMaxSq = this.GetMaxSqrDistance(bestHits, maxDistanceSq);
}
}
}
}
else
{
int leftChild = node.leftChild;
int rightChild = node.rightChild;
if ((double)this.DistanceSqPointAABB(p, this.nodes[leftChild].bounds) < (double)this.DistanceSqPointAABB(p, this.nodes[rightChild].bounds))
{
this.QueryClosestNRecursive(leftChild, p, maxCount, maxDistanceSq, bestHits, ref currentMaxSq);
this.QueryClosestNRecursive(rightChild, p, maxCount, maxDistanceSq, bestHits, ref currentMaxSq);
}
else
{
this.QueryClosestNRecursive(rightChild, p, maxCount, maxDistanceSq, bestHits, ref currentMaxSq);
this.QueryClosestNRecursive(leftChild, p, maxCount, maxDistanceSq, bestHits, ref currentMaxSq);
}
}
}
private float GetMaxSqrDistance(List<BvhTriangleMesh.ClosestHit> bestHits, float maxDistanceSq)
{
if (bestHits.Count == 0)
return maxDistanceSq;
float sqrDistance = bestHits[0].sqrDistance;
for (int index = 1; index < bestHits.Count; ++index)
{
if ((double)bestHits[index].sqrDistance > (double)sqrDistance)
sqrDistance = bestHits[index].sqrDistance;
}
return Mathf.Min(sqrDistance, maxDistanceSq);
}
public Vector3 ComputeMoveVectorToSurface(Vector3 p, float targetGap = 0.0f)
{
BvhTriangleMesh.ClosestHit closestHit = this.QueryClosest(p);
if (closestHit.triangleIndex < 0)
return Vector3.zero;
Vector3 moveVectorToSurface = Vector3.op_Subtraction(closestHit.closestPoint, p);
if ((double)targetGap > 0.0)
moveVectorToSurface = Vector3.op_Addition(moveVectorToSurface, Vector3.op_Multiply(((Vector3)ref closestHit.normal).normalized, targetGap));
return moveVectorToSurface;
}
public struct ClosestHit
{
public int triangleIndex;
public Vector3 closestPoint;
public Vector3 normal;
public float sqrDistance;
public HumanBodyBones mainHumanBone;
}
}
}