三国卡牌客户端基础资源仓库
hch
5 天以前 b0cdc211c9232ab09192ea6ac6ed57e64b31fd60
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/******************************************************************************
 * Spine Runtimes License Agreement
 * Last updated July 28, 2023. Replaces all prior versions.
 *
 * Copyright (c) 2013-2023, Esoteric Software LLC
 *
 * Integration of the Spine Runtimes into software or otherwise creating
 * derivative works of the Spine Runtimes is permitted under the terms and
 * conditions of Section 2 of the Spine Editor License Agreement:
 * http://esotericsoftware.com/spine-editor-license
 *
 * Otherwise, it is permitted to integrate the Spine Runtimes into software or
 * otherwise create derivative works of the Spine Runtimes (collectively,
 * "Products"), provided that each user of the Products must obtain their own
 * Spine Editor license and redistribution of the Products in any form must
 * include this license and copyright notice.
 *
 * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
 * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE
 * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *****************************************************************************/
 
using Spine;
using Spine.Unity;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
namespace Spine.Unity.Examples {
 
    //[CreateAssetMenu(menuName = "Spine/SkeletonData Modifiers/Animation Match", order = 200)]
    public class AnimationMatchModifierAsset : SkeletonDataModifierAsset {
 
        public bool matchAllAnimations = true;
 
        public override void Apply (SkeletonData skeletonData) {
            if (matchAllAnimations)
                AnimationTools.MatchAnimationTimelines(skeletonData.Animations, skeletonData);
        }
 
        public static class AnimationTools {
 
            #region Filler Timelines
            /// <summary>
            /// Matches the animation timelines across the given set of animations.
            /// This allows unkeyed properties to assume setup pose when animations are naively mixed using Animation.Apply.
            /// </summary>
            /// <param name="animations">An enumerable collection animations whose timelines will be matched.</param>
            /// <param name="skeletonData">The SkeletonData where the animations belong.</param>
            public static void MatchAnimationTimelines (IEnumerable<Spine.Animation> animations, SkeletonData skeletonData) {
                if (animations == null) return;
                if (skeletonData == null) throw new System.ArgumentNullException("skeletonData", "Timelines can't be matched without a SkeletonData source.");
 
                // Build a reference collection of timelines to match
                // and a collection of dummy timelines that can be used to fill-in missing items.
                Dictionary<string, Timeline> timelineDictionary = new Dictionary<string, Spine.Timeline>();
                foreach (Animation animation in animations) {
                    foreach (Timeline timeline in animation.Timelines) {
                        if (timeline is EventTimeline) continue;
 
                        foreach (string propertyId in timeline.PropertyIds) {
                            if (!timelineDictionary.ContainsKey(propertyId)) {
                                timelineDictionary.Add(propertyId, GetFillerTimeline(timeline, skeletonData));
                            }
                        }
                    }
                }
                List<string> idsToMatch = new List<string>(timelineDictionary.Keys);
 
                // For each animation in the list, check for and add missing timelines.
                HashSet<string> currentAnimationIDs = new HashSet<string>();
                foreach (Animation animation in animations) {
                    currentAnimationIDs.Clear();
                    foreach (Timeline timeline in animation.Timelines) {
                        if (timeline is EventTimeline) continue;
                        foreach (string propertyId in timeline.PropertyIds) {
                            currentAnimationIDs.Add(propertyId);
                        }
                    }
 
                    ExposedList<Timeline> animationTimelines = animation.Timelines;
                    foreach (string propertyId in idsToMatch) {
                        if (!currentAnimationIDs.Contains(propertyId))
                            animationTimelines.Add(timelineDictionary[propertyId]);
                    }
                }
 
                // These are locals, but sometimes Unity's GC does weird stuff. So let's clean up.
                timelineDictionary.Clear();
                timelineDictionary = null;
                idsToMatch.Clear();
                idsToMatch = null;
                currentAnimationIDs.Clear();
                currentAnimationIDs = null;
            }
 
            static Timeline GetFillerTimeline (Timeline timeline, SkeletonData skeletonData) {
                if (timeline is RotateTimeline)
                    return GetFillerTimeline((RotateTimeline)timeline, skeletonData);
                if (timeline is TranslateTimeline)
                    return GetFillerTimeline((TranslateTimeline)timeline, skeletonData);
                if (timeline is ScaleTimeline)
                    return GetFillerTimeline((ScaleTimeline)timeline, skeletonData);
                if (timeline is ShearTimeline)
                    return GetFillerTimeline((ShearTimeline)timeline, skeletonData);
                if (timeline is AttachmentTimeline)
                    return GetFillerTimeline((AttachmentTimeline)timeline, skeletonData);
                if (timeline is RGBATimeline)
                    return GetFillerTimeline((RGBATimeline)timeline, skeletonData);
                if (timeline is RGBA2Timeline)
                    return GetFillerTimeline((RGBA2Timeline)timeline, skeletonData);
                if (timeline is DeformTimeline)
                    return GetFillerTimeline((DeformTimeline)timeline, skeletonData);
                if (timeline is DrawOrderTimeline)
                    return GetFillerTimeline((DrawOrderTimeline)timeline, skeletonData);
                if (timeline is IkConstraintTimeline)
                    return GetFillerTimeline((IkConstraintTimeline)timeline, skeletonData);
                if (timeline is TransformConstraintTimeline)
                    return GetFillerTimeline((TransformConstraintTimeline)timeline, skeletonData);
                if (timeline is PathConstraintPositionTimeline)
                    return GetFillerTimeline((PathConstraintPositionTimeline)timeline, skeletonData);
                if (timeline is PathConstraintSpacingTimeline)
                    return GetFillerTimeline((PathConstraintSpacingTimeline)timeline, skeletonData);
                if (timeline is PathConstraintMixTimeline)
                    return GetFillerTimeline((PathConstraintMixTimeline)timeline, skeletonData);
                return null;
            }
 
            static RotateTimeline GetFillerTimeline (RotateTimeline timeline, SkeletonData skeletonData) {
                RotateTimeline t = new RotateTimeline(1, 0, timeline.BoneIndex);
                t.SetFrame(0, 0, 0);
                return t;
            }
 
            static TranslateTimeline GetFillerTimeline (TranslateTimeline timeline, SkeletonData skeletonData) {
                TranslateTimeline t = new TranslateTimeline(1, 0, timeline.BoneIndex);
                t.SetFrame(0, 0, 0, 0);
                return t;
            }
 
            static ScaleTimeline GetFillerTimeline (ScaleTimeline timeline, SkeletonData skeletonData) {
                ScaleTimeline t = new ScaleTimeline(1, 0, timeline.BoneIndex);
                t.SetFrame(0, 0, 0, 0);
                return t;
            }
 
            static ShearTimeline GetFillerTimeline (ShearTimeline timeline, SkeletonData skeletonData) {
                ShearTimeline t = new ShearTimeline(1, 0, timeline.BoneIndex);
                t.SetFrame(0, 0, 0, 0);
                return t;
            }
 
            static AttachmentTimeline GetFillerTimeline (AttachmentTimeline timeline, SkeletonData skeletonData) {
                AttachmentTimeline t = new AttachmentTimeline(1, timeline.SlotIndex);
                SlotData slotData = skeletonData.Slots.Items[t.SlotIndex];
                t.SetFrame(0, 0, slotData.AttachmentName);
                return t;
            }
 
            static RGBATimeline GetFillerTimeline (RGBATimeline timeline, SkeletonData skeletonData) {
                RGBATimeline t = new RGBATimeline(1, 0, timeline.SlotIndex);
                SlotData slotData = skeletonData.Slots.Items[t.SlotIndex];
                t.SetFrame(0, 0, slotData.R, slotData.G, slotData.B, slotData.A);
                return t;
            }
 
            static RGBA2Timeline GetFillerTimeline (RGBA2Timeline timeline, SkeletonData skeletonData) {
                RGBA2Timeline t = new RGBA2Timeline(1, 0, timeline.SlotIndex);
                SlotData slotData = skeletonData.Slots.Items[t.SlotIndex];
                t.SetFrame(0, 0, slotData.R, slotData.G, slotData.B, slotData.A, slotData.R2, slotData.G2, slotData.B2);
                return t;
            }
 
            static DeformTimeline GetFillerTimeline (DeformTimeline timeline, SkeletonData skeletonData) {
                DeformTimeline t = new DeformTimeline(1, 0, timeline.SlotIndex, timeline.Attachment);
                if (t.Attachment.IsWeighted()) {
                    t.SetFrame(0, 0, new float[t.Attachment.Vertices.Length]);
                } else {
                    t.SetFrame(0, 0, t.Attachment.Vertices.Clone() as float[]);
                }
 
                return t;
            }
 
            static DrawOrderTimeline GetFillerTimeline (DrawOrderTimeline timeline, SkeletonData skeletonData) {
                DrawOrderTimeline t = new DrawOrderTimeline(1);
                t.SetFrame(0, 0, null); // null means use setup pose in DrawOrderTimeline.Apply.
                return t;
            }
 
            static IkConstraintTimeline GetFillerTimeline (IkConstraintTimeline timeline, SkeletonData skeletonData) {
                IkConstraintTimeline t = new IkConstraintTimeline(1, 0, timeline.IkConstraintIndex);
                IkConstraintData ikConstraintData = skeletonData.IkConstraints.Items[timeline.IkConstraintIndex];
                t.SetFrame(0, 0, ikConstraintData.Mix, ikConstraintData.Softness, ikConstraintData.BendDirection, ikConstraintData.Compress, ikConstraintData.Stretch);
                return t;
            }
 
            static TransformConstraintTimeline GetFillerTimeline (TransformConstraintTimeline timeline, SkeletonData skeletonData) {
                TransformConstraintTimeline t = new TransformConstraintTimeline(1, 0, timeline.TransformConstraintIndex);
                TransformConstraintData data = skeletonData.TransformConstraints.Items[timeline.TransformConstraintIndex];
                t.SetFrame(0, 0, data.MixRotate, data.MixX, data.MixY, data.MixScaleX, data.MixScaleY, data.MixShearY);
                return t;
            }
 
            static PathConstraintPositionTimeline GetFillerTimeline (PathConstraintPositionTimeline timeline, SkeletonData skeletonData) {
                PathConstraintPositionTimeline t = new PathConstraintPositionTimeline(1, 0, timeline.PathConstraintIndex);
                PathConstraintData data = skeletonData.PathConstraints.Items[timeline.PathConstraintIndex];
                t.SetFrame(0, 0, data.Position);
                return t;
            }
 
            static PathConstraintSpacingTimeline GetFillerTimeline (PathConstraintSpacingTimeline timeline, SkeletonData skeletonData) {
                PathConstraintSpacingTimeline t = new PathConstraintSpacingTimeline(1, 0, timeline.PathConstraintIndex);
                PathConstraintData data = skeletonData.PathConstraints.Items[timeline.PathConstraintIndex];
                t.SetFrame(0, 0, data.Spacing);
                return t;
            }
 
            static PathConstraintMixTimeline GetFillerTimeline (PathConstraintMixTimeline timeline, SkeletonData skeletonData) {
                PathConstraintMixTimeline t = new PathConstraintMixTimeline(1, 0, timeline.PathConstraintIndex);
                PathConstraintData data = skeletonData.PathConstraints.Items[timeline.PathConstraintIndex];
                t.SetFrame(0, 0, data.RotateMix, data.MixX, data.MixY);
                return t;
            }
            #endregion
        }
 
    }
 
}