123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using Unity.Mathematics;
- using UnityEngine;
- using UnityEditor.U2D.Layout;
- using UnityEditor.U2D.Sprites;
- using UnityEngine.U2D.Common;
- using Debug = UnityEngine.Debug;
- using UnityEngine.UIElements;
-
- namespace UnityEditor.U2D.Animation
- {
- internal class SkinningObject : CacheObject
- {
- public SkinningCache skinningCache => owner as SkinningCache;
- }
-
- internal class SkinningCache : Cache
- {
- [Serializable]
- class SpriteMap : SerializableDictionary<string, SpriteCache> {}
- [Serializable]
- class MeshMap : SerializableDictionary<SpriteCache, MeshCache> {}
- [Serializable]
- class SkeletonMap : SerializableDictionary<SpriteCache, SkeletonCache> {}
- [Serializable]
- class ToolMap : SerializableDictionary<Tools, BaseTool> {}
- [Serializable]
- class MeshPreviewMap : SerializableDictionary<SpriteCache, MeshPreviewCache> {}
- [Serializable]
- class CharacterPartMap : SerializableDictionary<SpriteCache, CharacterPartCache> {}
-
- [SerializeField]
- SkinningEvents m_Events = new SkinningEvents();
- [SerializeField]
- List<BaseTool> m_Tools = new List<BaseTool>();
- [SerializeField]
- SpriteMap m_SpriteMap = new SpriteMap();
- [SerializeField]
- MeshMap m_MeshMap = new MeshMap();
- [SerializeField]
- MeshPreviewMap m_MeshPreviewMap = new MeshPreviewMap();
- [SerializeField]
- SkeletonMap m_SkeletonMap = new SkeletonMap();
- [SerializeField]
- CharacterPartMap m_CharacterPartMap = new CharacterPartMap();
- [SerializeField]
- ToolMap m_ToolMap = new ToolMap();
- [SerializeField]
- SelectionTool m_SelectionTool;
- [SerializeField]
- CharacterCache m_Character;
- [SerializeField]
- bool m_BonesReadOnly;
- [SerializeField]
- SkinningMode m_Mode = SkinningMode.SpriteSheet;
- [SerializeField]
- BaseTool m_SelectedTool;
- [SerializeField]
- SpriteCache m_SelectedSprite;
- [SerializeField]
- SkeletonSelection m_SkeletonSelection = new SkeletonSelection();
- [SerializeField]
- ISkinningCachePersistentState m_State;
-
- StringBuilder m_StringBuilder = new StringBuilder();
-
- public BaseTool selectedTool
- {
- get => m_SelectedTool;
- set
- {
- m_SelectedTool = value;
- try
- {
- m_State.lastUsedTool = m_ToolMap[value];
- }
- catch (KeyNotFoundException)
- {
- m_State.lastUsedTool = Tools.EditPose;
- }
- }
- }
-
- public virtual SkinningMode mode
- {
- get => m_Mode;
- set
- {
- m_Mode = CheckModeConsistency(value);
- m_State.lastMode = m_Mode;
- }
- }
-
- public SpriteCache selectedSprite
- {
- get => m_SelectedSprite;
- set
- {
- m_SelectedSprite = value;
- m_State.lastSpriteId = m_SelectedSprite ? m_SelectedSprite.id : String.Empty;
- }
- }
-
- public float brushSize
- {
- get => m_State.lastBrushSize;
- set => m_State.lastBrushSize = value;
- }
-
- public float brushHardness
- {
- get => m_State.lastBrushHardness;
- set => m_State.lastBrushHardness = value;
- }
-
- public float brushStep
- {
- get => m_State.lastBrushStep;
- set => m_State.lastBrushStep = value;
- }
-
- public int visibilityToolIndex
- {
- get => m_State.lastVisibilityToolIndex;
- set => m_State.lastVisibilityToolIndex = value;
- }
-
- public SkeletonSelection skeletonSelection => m_SkeletonSelection;
-
- public IndexedSelection vertexSelection => m_State.lastVertexSelection;
-
- public SkinningEvents events => m_Events;
-
- public SelectionTool selectionTool => m_SelectionTool;
-
- public SpriteCache[] GetSprites()
- {
- return m_SpriteMap.Values.ToArray();
- }
-
- public virtual CharacterCache character => m_Character;
-
- public bool hasCharacter => character != null;
-
- public bool bonesReadOnly => m_BonesReadOnly;
-
- public bool applyingChanges
- {
- get;
- set;
- }
-
- SkinningMode CheckModeConsistency(SkinningMode skinningMode)
- {
- if (skinningMode == SkinningMode.Character && hasCharacter == false)
- skinningMode = SkinningMode.SpriteSheet;
-
- return skinningMode;
- }
-
- public void Create(ISpriteEditorDataProvider spriteEditor, ISkinningCachePersistentState state)
- {
- Clear();
-
- var dataProvider = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>();
- var boneProvider = spriteEditor.GetDataProvider<ISpriteBoneDataProvider>();
- var meshProvider = spriteEditor.GetDataProvider<ISpriteMeshDataProvider>();
- var spriteRects = dataProvider.GetSpriteRects();
- var textureProvider = spriteEditor.GetDataProvider<ITextureDataProvider>();
-
- m_State = state;
- m_State.lastTexture = textureProvider.texture;
-
- for (var i = 0; i < spriteRects.Length; i++)
- {
- var spriteRect = spriteRects[i];
- var sprite = CreateSpriteCache(spriteRect);
- CreateSkeletonCache(sprite, boneProvider);
- CreateMeshCache(sprite, meshProvider, textureProvider);
- CreateMeshPreviewCache(sprite);
- }
-
- CreateCharacter(spriteEditor);
- }
-
- public void CreateToolCache(ISpriteEditor spriteEditor, LayoutOverlay layoutOverlay)
- {
- var spriteEditorDataProvider = spriteEditor.GetDataProvider<ISpriteEditorDataProvider>();
- var skeletonTool = CreateCache<SkeletonTool>();
- var meshTool = CreateCache<MeshTool>();
-
- skeletonTool.Initialize(layoutOverlay);
- meshTool.Initialize(layoutOverlay);
-
- m_ToolMap.Add(Tools.EditPose, CreateSkeletonTool<SkeletonToolWrapper>(skeletonTool, SkeletonMode.EditPose, false, layoutOverlay));
- m_ToolMap.Add(Tools.EditJoints, CreateSkeletonTool<SkeletonToolWrapper>(skeletonTool, SkeletonMode.EditJoints, true, layoutOverlay));
- m_ToolMap.Add(Tools.CreateBone, CreateSkeletonTool<SkeletonToolWrapper>(skeletonTool, SkeletonMode.CreateBone, true, layoutOverlay));
- m_ToolMap.Add(Tools.SplitBone, CreateSkeletonTool<SkeletonToolWrapper>(skeletonTool, SkeletonMode.SplitBone, true, layoutOverlay));
- m_ToolMap.Add(Tools.ReparentBone, CreateSkeletonTool<BoneReparentTool>(skeletonTool, SkeletonMode.EditPose, false, layoutOverlay));
- m_ToolMap.Add(Tools.CharacterPivotTool, CreateSkeletonTool<PivotTool>(skeletonTool, SkeletonMode.Disabled, false, layoutOverlay));
-
- m_ToolMap.Add(Tools.EditGeometry, CreateMeshTool<MeshToolWrapper>(skeletonTool, meshTool, SpriteMeshViewMode.EditGeometry, SkeletonMode.Disabled, layoutOverlay));
- m_ToolMap.Add(Tools.CreateVertex, CreateMeshTool<MeshToolWrapper>(skeletonTool, meshTool, SpriteMeshViewMode.CreateVertex, SkeletonMode.Disabled, layoutOverlay));
- m_ToolMap.Add(Tools.CreateEdge, CreateMeshTool<MeshToolWrapper>(skeletonTool, meshTool, SpriteMeshViewMode.CreateEdge, SkeletonMode.Disabled, layoutOverlay));
- m_ToolMap.Add(Tools.SplitEdge, CreateMeshTool<MeshToolWrapper>(skeletonTool, meshTool, SpriteMeshViewMode.SplitEdge, SkeletonMode.Disabled, layoutOverlay));
- m_ToolMap.Add(Tools.GenerateGeometry, CreateMeshTool<GenerateGeometryTool>(skeletonTool, meshTool, SpriteMeshViewMode.EditGeometry, SkeletonMode.EditPose, layoutOverlay));
- var copyTool = CreateTool<CopyTool>();
- copyTool.Initialize(layoutOverlay);
- copyTool.pixelsPerUnit = spriteEditorDataProvider.pixelsPerUnit;
- copyTool.skeletonTool = skeletonTool;
- copyTool.meshTool = meshTool;
- m_ToolMap.Add(Tools.CopyPaste, copyTool);
-
- CreateWeightTools(skeletonTool, meshTool, layoutOverlay);
-
- m_SelectionTool = CreateTool<SelectionTool>();
- m_SelectionTool.spriteEditor = spriteEditor;
- m_SelectionTool.Initialize(layoutOverlay);
- m_SelectionTool.Activate();
-
- var visibilityTool = CreateTool<VisibilityTool>();
- visibilityTool.Initialize(layoutOverlay);
- visibilityTool.skeletonTool = skeletonTool;
- m_ToolMap.Add(Tools.Visibility, visibilityTool);
-
- var switchModeTool = CreateTool<SwitchModeTool>();
- m_ToolMap.Add(Tools.SwitchMode, switchModeTool);
- }
-
- public void RestoreFromPersistentState()
- {
- mode = m_State.lastMode;
- events.skinningModeChanged.Invoke(mode);
-
- var hasLastSprite = m_SpriteMap.TryGetValue(m_State.lastSpriteId, out var lastSprite);
- if (hasLastSprite)
- {
- selectedSprite = lastSprite;
- }
- else
- {
- vertexSelection.Clear();
- }
-
- if (m_ToolMap.TryGetValue(m_State.lastUsedTool, out var baseTool))
- {
- selectedTool = baseTool;
- }
- else if (m_ToolMap.TryGetValue(Tools.EditPose, out baseTool))
- {
- selectedTool = baseTool;
- }
-
- var visibilityTool = m_ToolMap[Tools.Visibility];
- if (m_State.lastVisibilityToolActive)
- {
- visibilityTool.Activate();
- }
- }
-
- public void RestoreToolStateFromPersistentState()
- {
- events.boneSelectionChanged.RemoveListener(BoneSelectionChanged);
- events.skeletonPreviewPoseChanged.RemoveListener(SkeletonPreviewPoseChanged);
- events.toolChanged.RemoveListener(ToolChanged);
-
- SkeletonCache skeleton = null;
- if (hasCharacter)
- skeleton = character.skeleton;
- else if (selectedSprite != null)
- skeleton = selectedSprite.GetSkeleton();
-
- skeletonSelection.Clear();
- if (skeleton != null && m_State.lastBoneSelectionIds.Count > 0)
- {
- bool selectionChanged = false;
- foreach (var bone in skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone);
- if (m_State.lastBoneSelectionIds.Contains(id))
- {
- skeletonSelection.Select(bone, true);
- selectionChanged = true;
- }
- }
- if (selectionChanged)
- events.boneSelectionChanged.Invoke();
- }
-
- if (m_State.lastPreviewPose.Count > 0)
- {
- if (hasCharacter)
- {
- UpdatePoseFromPersistentState(character.skeleton, null);
- }
- foreach (var sprite in m_SkeletonMap.Keys)
- {
- UpdatePoseFromPersistentState(m_SkeletonMap[sprite], sprite);
- }
- }
-
- if (m_State.lastBoneVisibility.Count > 0)
- {
- if (hasCharacter)
- {
- UpdateVisibilityFromPersistentState(character.skeleton, null);
- }
-
- foreach (var sprite in m_SkeletonMap.Keys)
- {
- UpdateVisibilityFromPersistentState(m_SkeletonMap[sprite], sprite);
- }
- }
-
- if (m_State.lastSpriteVisibility.Count > 0 && hasCharacter)
- {
- foreach (var characterPart in character.parts)
- {
- if (m_State.lastSpriteVisibility.TryGetValue(characterPart.sprite.id, out var visibility))
- {
- characterPart.isVisible = visibility;
- }
- }
-
- foreach (var characterGroup in character.groups)
- {
- var groupHash = GetCharacterGroupHash(m_StringBuilder, characterGroup, character);
- if (m_State.lastGroupVisibility.TryGetValue(groupHash, out var visibility))
- {
- characterGroup.isVisible = visibility;
- }
- }
- }
-
- events.boneSelectionChanged.AddListener(BoneSelectionChanged);
- events.skeletonPreviewPoseChanged.AddListener(SkeletonPreviewPoseChanged);
- events.toolChanged.AddListener(ToolChanged);
- }
-
- void UpdatePoseFromPersistentState(SkeletonCache skeleton, SpriteCache sprite)
- {
- var poseChanged = false;
- foreach (var bone in skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, sprite);
- if (m_State.lastPreviewPose.TryGetValue(id, out var pose))
- {
- bone.localPose = pose;
- poseChanged = true;
- }
- }
- if (poseChanged)
- {
- skeleton.SetPosePreview();
- events.skeletonPreviewPoseChanged.Invoke(skeleton);
- }
- }
-
- void UpdateVisibilityFromPersistentState(SkeletonCache skeleton, SpriteCache sprite)
- {
- foreach (var bone in skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, sprite);
- if (m_State.lastBoneVisibility.TryGetValue(id, out var visibility))
- {
- bone.isVisible = visibility;
- }
- }
- }
-
- const string k_NameSeparator = "/";
-
- int GetBoneNameHash(StringBuilder sb, BoneCache bone, SpriteCache sprite = null)
- {
- sb.Clear();
- BuildBoneName(sb, bone);
- sb.Append(k_NameSeparator);
- if (sprite != null)
- {
- sb.Append(sprite.id);
- }
- else
- {
- sb.Append(0);
- }
- return Animator.StringToHash(sb.ToString());
- }
-
- static void BuildBoneName(StringBuilder sb, BoneCache bone)
- {
- if (bone.parentBone != null)
- {
- BuildBoneName(sb, bone.parentBone);
- sb.Append(k_NameSeparator);
- }
- sb.Append(bone.name);
- }
-
- static int GetCharacterGroupHash(StringBuilder sb, CharacterGroupCache characterGroup, CharacterCache characterCache)
- {
- sb.Clear();
- BuildGroupName(sb, characterGroup, characterCache);
- return Animator.StringToHash(sb.ToString());
- }
-
- static void BuildGroupName(StringBuilder sb, CharacterGroupCache group, CharacterCache characterCache)
- {
- if (group.parentGroup >= 0 && group.parentGroup < characterCache.groups.Length)
- {
- BuildGroupName(sb, characterCache.groups[group.parentGroup], characterCache);
- sb.Append(k_NameSeparator);
- }
- sb.Append(group.order);
- }
-
- void BoneSelectionChanged()
- {
- m_State.lastBoneSelectionIds.Clear();
- m_State.lastBoneSelectionIds.Capacity = skeletonSelection.elements.Length;
- for (var i = 0; i < skeletonSelection.elements.Length; ++i)
- {
- var bone = skeletonSelection.elements[i];
- m_State.lastBoneSelectionIds.Add(GetBoneNameHash(m_StringBuilder, bone));
- }
- }
-
- void SkeletonPreviewPoseChanged(SkeletonCache sc)
- {
- if (applyingChanges)
- return;
-
- m_State.lastPreviewPose.Clear();
- if (hasCharacter)
- {
- StorePersistentStatePoseForSkeleton(character.skeleton, null);
- }
- foreach (var sprite in m_SkeletonMap.Keys)
- {
- StorePersistentStatePoseForSkeleton(m_SkeletonMap[sprite], sprite);
- }
- }
-
- void StorePersistentStatePoseForSkeleton(SkeletonCache skeleton, SpriteCache sprite)
- {
- foreach (var bone in skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, sprite);
- if (bone.NotInDefaultPose())
- {
- m_State.lastPreviewPose[id] = bone.localPose;
- }
- }
- }
-
- internal void Revert()
- {
- m_State.lastVertexSelection.Clear();
- }
-
- internal void BoneVisibilityChanged()
- {
- if (applyingChanges)
- return;
-
- m_State.lastBoneVisibility.Clear();
- if (hasCharacter)
- {
- StorePersistentStateVisibilityForSkeleton(character.skeleton, null);
- }
- foreach (var sprite in m_SkeletonMap.Keys)
- {
- StorePersistentStateVisibilityForSkeleton(m_SkeletonMap[sprite], sprite);
- }
- }
-
- void StorePersistentStateVisibilityForSkeleton(SkeletonCache skeleton, SpriteCache sprite)
- {
- foreach (var bone in skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, sprite);
- m_State.lastBoneVisibility[id] = bone.isVisible;
- }
- }
-
- internal void BoneExpansionChanged(BoneCache[] boneCaches)
- {
- if (applyingChanges)
- return;
-
- m_State.lastBoneExpansion.Clear();
- if (hasCharacter)
- {
- foreach (var bone in boneCaches)
- {
- if (character.skeleton.bones.Contains(bone))
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, null);
- m_State.lastBoneExpansion[id] = true;
- }
- }
- }
-
- foreach (var sprite in m_SkeletonMap.Keys)
- {
- var skeleton = m_SkeletonMap[sprite];
- foreach (var bone in boneCaches)
- {
- if (skeleton.bones.Contains(bone))
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, sprite);
- m_State.lastBoneExpansion[id] = true;
- }
- }
- }
- }
-
- internal BoneCache[] GetExpandedBones()
- {
- var expandedBones = new HashSet<BoneCache>();
- if (m_State.lastBoneExpansion.Count > 0)
- {
- if (hasCharacter)
- {
- foreach (var bone in character.skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, null);
- if (m_State.lastBoneExpansion.TryGetValue(id, out var expanded))
- {
- expandedBones.Add(bone);
- }
- }
- }
- foreach (var sprite in m_SkeletonMap.Keys)
- {
- var skeleton = m_SkeletonMap[sprite];
- foreach (var bone in skeleton.bones)
- {
- var id = GetBoneNameHash(m_StringBuilder, bone, sprite);
- if (m_State.lastBoneExpansion.TryGetValue(id, out var expanded))
- {
- expandedBones.Add(bone);
- }
- }
- }
- }
- return expandedBones.ToArray();
- }
-
- internal void SpriteVisibilityChanged(CharacterPartCache cc)
- {
- m_State.lastSpriteVisibility[cc.sprite.id] = cc.isVisible;
- }
-
- internal void GroupVisibilityChanged(CharacterGroupCache gc)
- {
- if (!hasCharacter)
- return;
-
- var groupHash = GetCharacterGroupHash(m_StringBuilder, gc, character);
- m_State.lastGroupVisibility[groupHash] = gc.isVisible;
- }
-
- void Clear()
- {
- Destroy();
- m_Tools.Clear();
- m_SpriteMap.Clear();
- m_MeshMap.Clear();
- m_MeshPreviewMap.Clear();
- m_SkeletonMap.Clear();
- m_ToolMap.Clear();
- m_CharacterPartMap.Clear();
- }
-
- public SpriteCache GetSprite(string id)
- {
- if (string.IsNullOrEmpty(id))
- return null;
-
- m_SpriteMap.TryGetValue(id, out var sprite);
- return sprite;
- }
-
- public virtual MeshCache GetMesh(SpriteCache sprite)
- {
- if (sprite == null)
- return null;
-
- m_MeshMap.TryGetValue(sprite, out var mesh);
- return mesh;
- }
-
- public virtual MeshPreviewCache GetMeshPreview(SpriteCache sprite)
- {
- if (sprite == null)
- return null;
-
- m_MeshPreviewMap.TryGetValue(sprite, out var meshPreview);
- return meshPreview;
- }
-
- public SkeletonCache GetSkeleton(SpriteCache sprite)
- {
- if (sprite == null)
- return null;
-
- m_SkeletonMap.TryGetValue(sprite, out var skeleton);
- return skeleton;
- }
-
- public virtual CharacterPartCache GetCharacterPart(SpriteCache sprite)
- {
- if (sprite == null)
- return null;
-
- m_CharacterPartMap.TryGetValue(sprite, out var part);
- return part;
- }
-
- public SkeletonCache GetEffectiveSkeleton(SpriteCache sprite)
- {
- if (mode == SkinningMode.SpriteSheet)
- return GetSkeleton(sprite);
-
- if (hasCharacter)
- return character.skeleton;
-
- return null;
- }
-
- public BaseTool GetTool(Tools tool)
- {
- m_ToolMap.TryGetValue(tool, out var t);
- return t;
- }
-
- public override void BeginUndoOperation(string operationName)
- {
- if (isUndoOperationSet == false)
- {
- base.BeginUndoOperation(operationName);
- undo.RegisterCompleteObjectUndo(m_State, operationName);
- }
- }
-
- public UndoScope UndoScope(string operationName, bool incrementGroup = false)
- {
- return new UndoScope(this, operationName, incrementGroup);
- }
-
- public DisableUndoScope DisableUndoScope()
- {
- return new DisableUndoScope(this);
- }
-
- public T CreateTool<T>() where T : BaseTool
- {
- var tool = CreateCache<T>();
- m_Tools.Add(tool);
- return tool;
- }
-
- void UpdateCharacterPart(CharacterPartCache characterPart)
- {
- var sprite = characterPart.sprite;
- var characterPartBones = characterPart.bones;
- var newBones = new List<BoneCache>(characterPartBones);
- newBones.RemoveAll(b => b == null || IsRemoved(b) || b.skeleton != character.skeleton);
- var removedBonesCount = characterPartBones.Length - newBones.Count;
-
- characterPartBones = newBones.ToArray();
- characterPart.bones = characterPartBones;
- sprite.UpdateMesh(characterPartBones);
-
- if (removedBonesCount > 0)
- sprite.SmoothFill();
- }
-
- public void CreateSpriteSheetSkeletons()
- {
- Debug.Assert(character != null);
-
- using (new DefaultPoseScope(character.skeleton))
- {
- var characterParts = character.parts;
-
- foreach (var characterPart in characterParts)
- CreateSpriteSheetSkeleton(characterPart);
- }
-
- SyncSpriteSheetSkeletons();
- }
-
- public void SyncSpriteSheetSkeletons()
- {
- Debug.Assert(character != null);
-
- var characterParts = character.parts;
-
- foreach (var characterPart in characterParts)
- characterPart.SyncSpriteSheetSkeleton();
- }
-
- public void CreateSpriteSheetSkeleton(CharacterPartCache characterPart)
- {
- UpdateCharacterPart(characterPart);
-
- Debug.Assert(character != null);
- Debug.Assert(character.skeleton != null);
- Debug.Assert(character.skeleton.isPosePreview == false);
-
- var sprite = characterPart.sprite;
- var characterPartBones = characterPart.bones;
- var skeleton = sprite.GetSkeleton();
-
- Debug.Assert(skeleton != null);
-
- var spriteBones = characterPartBones.ToSpriteBone(characterPart.localToWorldMatrix);
- skeleton.SetBones(CreateBoneCacheFromSpriteBones(spriteBones, 1.0f), false);
-
- events.skeletonTopologyChanged.Invoke(skeleton);
- }
-
- SpriteCache CreateSpriteCache(SpriteRect spriteRect)
- {
- var sprite = CreateCache<SpriteCache>();
- sprite.name = spriteRect.name;
- sprite.id = spriteRect.spriteID.ToString();
- sprite.textureRect = spriteRect.rect;
- sprite.position = spriteRect.rect.position;
- m_SpriteMap[sprite.id] = sprite;
- return sprite;
- }
-
- void CreateSkeletonCache(SpriteCache sprite, ISpriteBoneDataProvider boneProvider)
- {
- var guid = new GUID(sprite.id);
- var skeleton = CreateCache<SkeletonCache>();
-
- skeleton.position = sprite.textureRect.position;
- skeleton.SetBones(CreateBoneCacheFromSpriteBones(boneProvider.GetBones(guid).ToArray(), 1.0f), false);
-
- m_SkeletonMap[sprite] = skeleton;
- }
-
- void CreateMeshCache(SpriteCache sprite, ISpriteMeshDataProvider meshProvider, ITextureDataProvider textureDataProvider)
- {
- Debug.Assert(m_SkeletonMap.ContainsKey(sprite));
-
- var guid = new GUID(sprite.id);
- var mesh = new MeshCache();
- var skeleton = m_SkeletonMap[sprite] as SkeletonCache;
-
- mesh.sprite = sprite;
- mesh.SetCompatibleBoneSet(skeleton.bones);
-
- var metaVertices = meshProvider.GetVertices(guid);
- if (metaVertices.Length > 0)
- {
- var vertices = new Vector2[metaVertices.Length];
- var weights = new EditableBoneWeight[metaVertices.Length];
- for (var i = 0; i < metaVertices.Length; ++i)
- {
- vertices[i] = metaVertices[i].position;
- weights[i] = EditableBoneWeightUtility.CreateFromBoneWeight(metaVertices[i].boneWeight);
- }
-
- mesh.SetVertices(vertices, weights);
- mesh.SetIndices(meshProvider.GetIndices(guid));
- mesh.SetEdges(EditorUtilities.ToInt2(meshProvider.GetEdges(guid)));
- }
- else
- {
- GenerateOutline(sprite, textureDataProvider, out var vertices, out var indices, out var edges);
-
- var vertexWeights = new EditableBoneWeight[vertices.Length];
- for (var i = 0; i < vertexWeights.Length; ++i)
- vertexWeights[i] = new EditableBoneWeight();
-
- mesh.SetVertices(vertices, vertexWeights);
- mesh.SetIndices(indices);
- mesh.SetEdges(edges);
- }
-
- mesh.textureDataProvider = textureDataProvider;
-
- m_MeshMap[sprite] = mesh;
- }
-
- static void GenerateOutline(SpriteCache sprite, ITextureDataProvider textureDataProvider,
- out Vector2[] vertices, out int[] indices, out int2[] edges)
- {
- if (textureDataProvider == null ||
- textureDataProvider.texture == null)
- {
- vertices = new Vector2[0];
- indices = new int[0];
- edges = new int2[0];
- return;
- }
-
- const float detail = 0.05f;
- const byte alphaTolerance = 200;
-
- var smd = new SpriteMeshData();
- smd.SetFrame(sprite.textureRect);
-
- var meshDataController = new SpriteMeshDataController
- {
- spriteMeshData = smd
- };
-
- meshDataController.OutlineFromAlpha(new OutlineGenerator(), textureDataProvider, detail, alphaTolerance);
- meshDataController.Triangulate(new Triangulator());
-
- vertices = smd.vertices;
- indices = smd.indices;
- edges = smd.edges;
- }
-
- void CreateMeshPreviewCache(SpriteCache sprite)
- {
- Debug.Assert(sprite != null);
- Debug.Assert(m_MeshPreviewMap.ContainsKey(sprite) == false);
-
- var meshPreview = CreateCache<MeshPreviewCache>();
-
- meshPreview.sprite = sprite;
- meshPreview.SetMeshDirty();
-
- m_MeshPreviewMap.Add(sprite, meshPreview);
- }
-
- void CreateCharacter(ISpriteEditorDataProvider spriteEditor)
- {
- var characterProvider = spriteEditor.GetDataProvider<ICharacterDataProvider>();
-
- if (characterProvider != null)
- {
- var characterData = characterProvider.GetCharacterData();
- var characterParts = new List<CharacterPartCache>();
-
- m_Character = CreateCache<CharacterCache>();
- m_BonesReadOnly = spriteEditor.GetDataProvider<IMainSkeletonDataProvider>() != null;
-
- var skeleton = CreateCache<SkeletonCache>();
-
- var characterBones = characterData.bones;
-
- skeleton.SetBones(CreateBoneCacheFromSpriteBones(characterBones, 1.0f));
- skeleton.position = Vector3.zero;
-
- var bones = skeleton.bones;
- foreach (var p in characterData.parts)
- {
- var spriteBones = p.bones != null ? p.bones.ToList() : new List<int>();
- var characterPartBones = spriteBones.ConvertAll(i => bones.ElementAtOrDefault(i)).ToArray();
- var characterPart = CreateCache<CharacterPartCache>();
-
- var positionInt = p.spritePosition.position;
- characterPart.position = new Vector2(positionInt.x, positionInt.y);
- characterPart.sprite = GetSprite(p.spriteId);
- characterPart.bones = characterPartBones;
- characterPart.parentGroup = p.parentGroup;
- characterPart.order = p.order;
-
- var mesh = characterPart.sprite.GetMesh();
- if (mesh != null)
- mesh.SetCompatibleBoneSet(characterPartBones);
-
- characterParts.Add(characterPart);
-
- m_CharacterPartMap.Add(characterPart.sprite, characterPart);
- }
- if (characterData.characterGroups != null)
- {
- m_Character.groups = characterData.characterGroups.Select(x =>
- {
- var group = CreateCache<CharacterGroupCache>();
- group.name = x.name;
- group.parentGroup = x.parentGroup;
- group.order = x.order;
- return group;
- }).ToArray();
- }
- else
- {
- m_Character.groups = new CharacterGroupCache[0];
- }
-
- m_Character.parts = characterParts.ToArray();
- m_Character.skeleton = skeleton;
- m_Character.dimension = characterData.dimension;
- m_Character.pivot = characterData.pivot;
- CreateSpriteSheetSkeletons();
- }
- }
-
- T CreateSkeletonTool<T>(SkeletonTool skeletonTool, SkeletonMode skeletonMode, bool editBindPose, LayoutOverlay layoutOverlay) where T : SkeletonToolWrapper
- {
- var tool = CreateTool<T>();
- tool.skeletonTool = skeletonTool;
- tool.mode = skeletonMode;
- tool.editBindPose = editBindPose;
- tool.Initialize(layoutOverlay);
- return tool;
- }
-
- void CreateWeightTools(SkeletonTool skeletonTool, MeshTool meshTool, LayoutOverlay layoutOverlay)
- {
- var weightPainterTool = CreateCache<WeightPainterTool>();
- weightPainterTool.Initialize(layoutOverlay);
- weightPainterTool.skeletonTool = skeletonTool;
- weightPainterTool.meshTool = meshTool;
-
- {
- var tool = CreateTool<SpriteBoneInfluenceTool>();
- tool.Initialize(layoutOverlay);
- tool.skeletonTool = skeletonTool;
- m_ToolMap.Add(Tools.BoneInfluence, tool);
- }
-
- {
- var tool = CreateTool<BoneSpriteInfluenceTool>();
- tool.Initialize(layoutOverlay);
- tool.skeletonTool = skeletonTool;
- m_ToolMap.Add(Tools.SpriteInfluence, tool);
- }
-
- {
- var tool = CreateTool<WeightPainterToolWrapper>();
-
- tool.weightPainterTool = weightPainterTool;
- tool.paintMode = WeightPainterMode.Slider;
- tool.title = TextContent.weightSlider;
- tool.Initialize(layoutOverlay);
- m_ToolMap.Add(Tools.WeightSlider, tool);
- }
-
- {
- var tool = CreateTool<WeightPainterToolWrapper>();
-
- tool.weightPainterTool = weightPainterTool;
- tool.paintMode = WeightPainterMode.Brush;
- tool.title = TextContent.weightBrush;
- tool.Initialize(layoutOverlay);
- m_ToolMap.Add(Tools.WeightBrush, tool);
- }
-
- {
- var tool = CreateTool<GenerateWeightsTool>();
- tool.Initialize(layoutOverlay);
- tool.meshTool = meshTool;
- tool.skeletonTool = skeletonTool;
- m_ToolMap.Add(Tools.GenerateWeights, tool);
- }
- }
-
- T CreateMeshTool<T>(SkeletonTool skeletonTool, MeshTool meshTool, SpriteMeshViewMode meshViewMode, SkeletonMode skeletonMode, LayoutOverlay layoutOverlay) where T : MeshToolWrapper
- {
- var tool = CreateTool<T>();
- tool.skeletonTool = skeletonTool;
- tool.meshTool = meshTool;
- tool.meshMode = meshViewMode;
- tool.skeletonMode = skeletonMode;
- tool.Initialize(layoutOverlay);
- return tool;
- }
-
- public void RestoreBindPose()
- {
- var sprites = GetSprites();
-
- foreach (var sprite in sprites)
- sprite.RestoreBindPose();
-
- if (character != null)
- character.skeleton.RestoreDefaultPose();
- }
-
- public void UndoRedoPerformed()
- {
- foreach (var tool in m_Tools)
- {
- if (tool == null)
- continue;
-
- if (!tool.isActive)
- tool.Deactivate();
- }
-
- foreach (var tool in m_Tools)
- {
- if (tool == null)
- continue;
-
- if (tool.isActive)
- tool.Activate();
- }
- }
-
- public BoneCache[] CreateBoneCacheFromSpriteBones(UnityEngine.U2D.SpriteBone[] spriteBones, float scale)
- {
- var bones = Array.ConvertAll(spriteBones, b => CreateCache<BoneCache>());
-
- for (var i = 0; i < spriteBones.Length; ++i)
- {
- var spriteBone = spriteBones[i];
- var bone = bones[i];
-
- if (spriteBone.parentId >= 0)
- bone.SetParent(bones[spriteBone.parentId]);
-
- bone.name = spriteBone.name;
- bone.guid = spriteBone.guid?.Length == 0 ? GUID.Generate().ToString() : spriteBone.guid;
- bone.localLength = spriteBone.length * scale;
- bone.depth = spriteBone.position.z;
- bone.localPosition = (Vector2)spriteBone.position * scale;
- bone.localRotation = spriteBone.rotation;
- if (spriteBone.color.a == 0)
- bone.bindPoseColor = ModuleUtility.CalculateNiceColor(i, 6);
- else
- bone.bindPoseColor = spriteBone.color;
- }
-
- foreach (var bone in bones)
- {
- if (bone.parentBone != null && bone.parentBone.localLength > 0f && (bone.position - bone.parentBone.endPosition).sqrMagnitude < 0.005f)
- bone.parentBone.chainedChild = bone;
- }
-
- return bones;
- }
-
- public bool IsOnVisualElement()
- {
- if (selectedTool == null || selectedTool.layoutOverlay == null)
- return false;
-
- var overlay = selectedTool.layoutOverlay;
- var point = InternalEngineBridge.GUIUnclip(Event.current.mousePosition);
- point = overlay.parent.parent.LocalToWorld(point);
-
- var selectedElement = selectedTool.layoutOverlay.panel.Pick(point);
- return selectedElement != null
- && selectedElement.pickingMode != PickingMode.Ignore
- && selectedElement.FindCommonAncestor(overlay) == overlay;
- }
-
- void ToolChanged(ITool tool)
- {
- var visibilityTool = GetTool(Tools.Visibility);
- if ((ITool) visibilityTool == tool)
- {
- m_State.lastVisibilityToolActive = visibilityTool.isActive;
- }
- }
- }
- }
|