EdenAutoMorpherScript dll을 디컴파일한 결과를 그대로 가져옴
This commit is contained in:
701
Assets/@Eden_Tools/Eden_AutoMorpher/Script/BvhTriangleMesh.cs
Normal file
701
Assets/@Eden_Tools/Eden_AutoMorpher/Script/BvhTriangleMesh.cs
Normal file
@@ -0,0 +1,701 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user