Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/FIMSpace/FTail/FTail_SkinningVertexData.cs
2026-03-04 10:03:45 +08:00

181 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace FIMSpace.FTail
{
[Serializable]
public class FTail_SkinningVertexData
{
public Vector3 position;
public int[] bonesIndexes;
public int allMeshBonesCount;
public float[] weights;
public float[] debugDists;
public float[] debugDistWeights;
public float[] debugWeights;
public FTail_SkinningVertexData(Vector3 pos)
{
position = pos;
}
public float DistanceToLine(Vector3 pos, Vector3 lineStart, Vector3 lineEnd)
{
Vector3 rhs = pos - lineStart;
Vector3 normalized = (lineEnd - lineStart).normalized;
float num = Vector3.Distance(lineStart, lineEnd);
float num2 = Vector3.Dot(normalized, rhs);
if (num2 <= 0f)
{
return Vector3.Distance(pos, lineStart);
}
if (num2 >= num)
{
return Vector3.Distance(pos, lineEnd);
}
Vector3 vector = normalized * num2;
Vector3 b = lineStart + vector;
return Vector3.Distance(pos, b);
}
public void CalculateVertexParameters(Vector3[] bonesPos, Quaternion[] bonesRot, Vector3[] boneAreas, int maxWeightedBones, float spread, Vector3 spreadOffset, float spreadPower = 1f)
{
allMeshBonesCount = bonesPos.Length;
List<Vector2> list = new List<Vector2>();
for (int i = 0; i < bonesPos.Length; i++)
{
Vector3 lineEnd = ((i == bonesPos.Length - 1) ? Vector3.Lerp(bonesPos[i], bonesPos[i] + (bonesPos[i] - bonesPos[i - 1]), 0.9f) : Vector3.Lerp(bonesPos[i], bonesPos[i + 1], 0.9f));
lineEnd += bonesRot[i] * spreadOffset;
float y = DistanceToLine(position, bonesPos[i], lineEnd);
list.Add(new Vector2(i, y));
}
list.Sort((Vector2 a, Vector2 b) => a.y.CompareTo(b.y));
int num = Mathf.Min(maxWeightedBones, bonesPos.Length);
bonesIndexes = new int[num];
float[] array = new float[num];
for (int num2 = 0; num2 < num; num2++)
{
bonesIndexes[num2] = (int)list[num2].x;
array[num2] = list[num2].y;
}
float[] array2 = new float[num];
AutoSetBoneWeights(array2, array, spread, spreadPower, boneAreas);
float num3 = 1f;
weights = new float[num];
for (int num4 = 0; num4 < num && (spread != 0f || num4 <= 0); num4++)
{
if (num3 <= 0f)
{
weights[num4] = 0f;
continue;
}
float num5 = array2[num4];
num3 -= num5;
if (num3 <= 0f)
{
num5 += num3;
}
else if (num4 == num - 1)
{
num5 += num3;
}
weights[num4] = num5;
}
}
public void AutoSetBoneWeights(float[] weightForBone, float[] distToBone, float spread, float spreadPower, Vector3[] boneAreas)
{
int num = weightForBone.Length;
float[] array = new float[num];
for (int i = 0; i < array.Length; i++)
{
array[i] = boneAreas[i].magnitude;
}
float[] array2 = new float[num];
for (int j = 0; j < weightForBone.Length; j++)
{
weightForBone[j] = 0f;
}
float num2 = 0f;
for (int k = 0; k < num; k++)
{
num2 += distToBone[k];
}
for (int l = 0; l < num; l++)
{
array2[l] = 1f - distToBone[l] / num2;
}
debugDists = distToBone;
if (num == 1 || spread == 0f)
{
weightForBone[0] = 1f;
return;
}
if (num == 2)
{
float num3 = 1f;
weightForBone[0] = 1f;
float num4 = Mathf.InverseLerp(distToBone[0] + array[0] / 1.25f * spread, distToBone[0], distToBone[1]);
debugDists[0] = num4;
num3 += (weightForBone[1] = DistributionIn(Mathf.Lerp(0f, 1f, num4), Mathf.Lerp(1.5f, 16f, spreadPower)));
debugDistWeights = new float[weightForBone.Length];
weightForBone.CopyTo(debugDistWeights, 0);
for (int m = 0; m < num; m++)
{
weightForBone[m] /= num3;
}
debugWeights = weightForBone;
return;
}
float num5 = array[0] / 10f;
float num6 = array[0] / 2f;
float num7 = 0f;
for (int n = 0; n < num; n++)
{
float t = Mathf.InverseLerp(0f, num5 + num6 * spread, distToBone[n]);
float num8 = Mathf.Lerp(1f, 0f, t);
if (n == 0 && num8 == 0f)
{
num8 = 1f;
}
weightForBone[n] = num8;
num7 += num8;
}
debugDistWeights = new float[weightForBone.Length];
weightForBone.CopyTo(debugDistWeights, 0);
for (int num9 = 0; num9 < num; num9++)
{
weightForBone[num9] /= num7;
}
debugWeights = weightForBone;
}
public static float DistributionIn(float k, float power)
{
return Mathf.Pow(k, power + 1f);
}
public static Color GetBoneIndicatorColor(int boneIndex, int bonesCount, float s = 0.9f, float v = 0.9f)
{
return Color.HSVToRGB(((float)boneIndex * 1.125f / (float)bonesCount + 0.125f * (float)boneIndex + 0.3f) % 1f, s, v);
}
public Color GetWeightColor()
{
Color color = GetBoneIndicatorColor(bonesIndexes[0], allMeshBonesCount, 1f, 1f);
for (int i = 1; i < bonesIndexes.Length; i++)
{
color = Color.Lerp(color, GetBoneIndicatorColor(bonesIndexes[i], allMeshBonesCount, 1f, 1f), weights[i]);
}
return color;
}
}
}