Singularity/Library/PackageCache/com.unity.2d.animation@7.0.10/Editor/SkinningModule/SkinningCache/MeshCache.cs
2024-05-06 11:45:45 -07:00

124 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using UnityEditor.U2D.Sprites;
using UnityEngine;
namespace UnityEditor.U2D.Animation
{
[Serializable]
internal class MeshCache : BaseSpriteMeshData
{
[SerializeField]
List<BoneCache> m_Bones = new List<BoneCache>();
[SerializeField]
SpriteCache m_Sprite;
public override string spriteName => sprite.name;
public override int boneCount => m_Bones.Count;
public override Rect frame => sprite.textureRect;
public ITextureDataProvider textureDataProvider { get; set; }
public SpriteCache sprite
{
get => m_Sprite;
set => m_Sprite = value;
}
public BoneCache[] bones
{
get => m_Bones.ToArray();
set => SetBones(value);
}
public override SpriteBoneData GetBoneData(int index)
{
var worldToLocalMatrix = sprite.worldToLocalMatrix;
//We expect m_Bones to contain character's bones references if character exists. Sprite's skeleton bones otherwise.
if (sprite.skinningCache.hasCharacter)
worldToLocalMatrix = sprite.GetCharacterPart().worldToLocalMatrix;
SpriteBoneData spriteBoneData;
var bone = m_Bones[index];
if (bone == null)
spriteBoneData = new SpriteBoneData();
else
{
spriteBoneData = new SpriteBoneData()
{
parentId = bone.parentBone == null ? -1 : m_Bones.IndexOf(bone.parentBone),
localPosition = bone.localPosition,
localRotation = bone.localRotation,
position = worldToLocalMatrix.MultiplyPoint3x4(bone.position),
endPosition = worldToLocalMatrix.MultiplyPoint3x4(bone.endPosition),
depth = bone.depth,
length = bone.localLength
};
}
return spriteBoneData;
}
public override float GetBoneDepth(int index)
{
return m_Bones[index].depth;
}
public bool ContainsBone(BoneCache bone)
{
return m_Bones.Contains(bone);
}
public void SetCompatibleBoneSet(BoneCache[] boneCache)
{
m_Bones = new List<BoneCache>(boneCache);
}
void SetBones(BoneCache[] boneCache)
{
FixWeights(boneCache);
SetCompatibleBoneSet(boneCache);
}
void FixWeights(BoneCache[] newBones)
{
var newBonesList = new List<BoneCache>(newBones);
var indexMap = new Dictionary<int, int>();
for (var i = 0; i < m_Bones.Count; ++i)
{
var bone = m_Bones[i];
var newIndex = newBonesList.IndexOf(bone);
if (newIndex != -1)
indexMap.Add(i, newIndex);
}
for (var i = 0; i < vertexWeights.Length; ++i)
{
var boneWeight = vertexWeights[i];
for (var m = 0; m < boneWeight.Count; ++m)
{
var boneRemoved = indexMap.TryGetValue(boneWeight[m].boneIndex, out var newIndex) == false;
if (boneRemoved)
{
boneWeight[m].weight = 0f;
boneWeight[m].enabled = false;
}
boneWeight[m].boneIndex = newIndex;
if (boneRemoved)
boneWeight.CompensateOtherChannels(m);
}
boneWeight.UnifyChannelsWithSameBoneIndex();
vertexWeights[i] = boneWeight;
}
}
}
}