private void ReadAnimation(String name, Stream input, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { int slotIndex = ReadInt(input, true); for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadInt(input, true); switch (timelineType) { case TIMELINE_COLOR: { ColorTimeline timeline = new ColorTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); int color = ReadInt(input); float r = ((color & 0xff000000) >> 24) / 255f; float g = ((color & 0x00ff0000) >> 16) / 255f; float b = ((color & 0x0000ff00) >> 8) / 255f; float a = ((color & 0x000000ff)) / 255f; timeline.SetFrame(frameIndex, time, r, g, b, a); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 5 - 5]); break; } case TIMELINE_ATTACHMENT: { AttachmentTimeline timeline = new AttachmentTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input)); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); break; } } } } // Bone timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { int boneIndex = ReadInt(input, true); for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadInt(input, true); switch (timelineType) { case TIMELINE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]); break; } case TIMELINE_TRANSLATE: case TIMELINE_SCALE: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == TIMELINE_SCALE) { timeline = new ScaleTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]); break; } case TIMELINE_FLIPX: case TIMELINE_FLIPY: { FlipXTimeline timeline = timelineType == TIMELINE_FLIPX ? new FlipXTimeline(frameCount) : new FlipYTimeline( frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadBoolean(input)); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]); break; } } } } // IK timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { IkConstraintData ikConstraint = skeletonData.ikConstraints.Items[ReadInt(input, true)]; int frameCount = ReadInt(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint); for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]); } // FFD timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadInt(input, true)]; for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int slotIndex = ReadInt(input, true); for (int iii = 0, nnn = ReadInt(input, true); iii < nnn; iii++) { Attachment attachment = skin.GetAttachment(slotIndex, ReadString(input)); int frameCount = ReadInt(input, true); FFDTimeline timeline = new FFDTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] vertices; int vertexCount; if (attachment is MeshAttachment) { vertexCount = ((MeshAttachment)attachment).vertices.Length; } else { vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2; } int end = ReadInt(input, true); if (end == 0) { if (attachment is MeshAttachment) { vertices = ((MeshAttachment)attachment).vertices; } else { vertices = new float[vertexCount]; } } else { vertices = new float[vertexCount]; int start = ReadInt(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) { vertices[v] = ReadFloat(input); } } else { for (int v = start; v < end; v++) { vertices[v] = ReadFloat(input) * scale; } } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int v = 0, vn = vertices.Length; v < vn; v++) { vertices[v] += meshVertices[v]; } } } timeline.SetFrame(frameIndex, time, vertices); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadInt(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { int offsetCount = ReadInt(input, true); int[] drawOrder = new int[slotCount]; for (int ii = slotCount - 1; ii >= 0; ii--) { drawOrder[ii] = -1; } int[] unchanged = new int[slotCount - offsetCount]; int originalIndex = 0, unchangedIndex = 0; for (int ii = 0; ii < offsetCount; ii++) { int slotIndex = ReadInt(input, true); // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. drawOrder[originalIndex + ReadInt(input, true)] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int ii = slotCount - 1; ii >= 0; ii--) { if (drawOrder[ii] == -1) { drawOrder[ii] = unchanged[--unchangedIndex]; } } timeline.SetFrame(i, ReadFloat(input), drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadInt(input, true); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = ReadFloat(input); EventData eventData = skeletonData.events.Items[ReadInt(input, true)]; Event e = new Event(eventData); e.Int = ReadInt(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, time, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[eventCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) { var timelines = new ExposedList<Timeline>(); float duration = 0; float scale = Scale; if (map.ContainsKey("slots")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); var timelineMap = (Dictionary<String, Object>)entry.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { var values = (List<Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "color") { var timeline = new ColorTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; String c = (String)valueMap["color"]; timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3)); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]); } else if (timelineName == "attachment") { var timeline = new AttachmentTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } else throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); } } } if (map.ContainsKey("bones")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) { String boneName = entry.Key; int boneIndex = skeletonData.FindBoneIndex(boneName); if (boneIndex == -1) throw new Exception("Bone not found: " + boneName); var timelineMap = (Dictionary<String, Object>)entry.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { var values = (List<Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "rotate") { var timeline = new RotateTimeline(values.Count); timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]); } else if (timelineName == "translate" || timelineName == "scale") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") timeline = new ScaleTimeline(values.Count); else { timeline = new TranslateTimeline(values.Count); timelineScale = scale; } timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0; float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0; timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } else throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); } } } if (map.ContainsKey("ik")) { foreach (KeyValuePair<String, Object> ikMap in (Dictionary<String, Object>)map["ik"]) { IkConstraintData ikConstraint = skeletonData.FindIkConstraint(ikMap.Key); var values = (List<Object>)ikMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint); int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = valueMap.ContainsKey("mix") ? (float)valueMap["mix"] : 1; bool bendPositive = valueMap.ContainsKey("bendPositive") ? (bool)valueMap["bendPositive"] : true; timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } } if (map.ContainsKey("ffd")) { foreach (KeyValuePair<String, Object> ffdMap in (Dictionary<String, Object>)map["ffd"]) { Skin skin = skeletonData.FindSkin(ffdMap.Key); foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)ffdMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); foreach (KeyValuePair<String, Object> meshMap in (Dictionary<String, Object>)slotMap.Value) { var values = (List<Object>)meshMap.Value; var timeline = new FFDTimeline(values.Count); Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key); if (attachment == null) throw new Exception("FFD attachment not found: " + meshMap.Key); timeline.slotIndex = slotIndex; timeline.attachment = attachment; int vertexCount; if (attachment is MeshAttachment) vertexCount = ((MeshAttachment)attachment).vertices.Length; else vertexCount = ((WeightedMeshAttachment)attachment).Weights.Length / 3 * 2; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float[] vertices; if (!valueMap.ContainsKey("vertices")) { if (attachment is MeshAttachment) vertices = ((MeshAttachment)attachment).vertices; else vertices = new float[vertexCount]; } else { var verticesValue = (List<Object>)valueMap["vertices"]; vertices = new float[vertexCount]; int start = GetInt(valueMap, "offset", 0); if (scale == 1) { for (int i = 0, n = verticesValue.Count; i < n; i++) vertices[i + start] = (float)verticesValue[i]; } else { for (int i = 0, n = verticesValue.Count; i < n; i++) vertices[i + start] = (float)verticesValue[i] * scale; } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int i = 0; i < vertexCount; i++) vertices[i] += meshVertices[i]; } } timeline.SetFrame(frameIndex, (float)valueMap["time"], vertices); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } } } } if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { var values = (List<Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"]; var timeline = new DrawOrderTimeline(values.Count); int slotCount = skeletonData.slots.Count; int frameIndex = 0; foreach (Dictionary<String, Object> drawOrderMap in values) { int[] drawOrder = null; if (drawOrderMap.ContainsKey("offsets")) { drawOrder = new int[slotCount]; for (int i = slotCount - 1; i >= 0; i--) drawOrder[i] = -1; var offsets = (List<Object>)drawOrderMap["offsets"]; int[] unchanged = new int[slotCount - offsets.Count]; int originalIndex = 0, unchangedIndex = 0; foreach (Dictionary<String, Object> offsetMap in offsets) { int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]); if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]); // Collect unchanged items. while (originalIndex != slotIndex) unchanged[unchangedIndex++] = originalIndex++; // Set changed items. int index = originalIndex + (int)(float)offsetMap["offset"]; drawOrder[index] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) unchanged[unchangedIndex++] = originalIndex++; // Fill in unchanged items. for (int i = slotCount - 1; i >= 0; i--) if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; } timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } if (map.ContainsKey("events")) { var eventsMap = (List<Object>)map["events"]; var timeline = new EventTimeline(eventsMap.Count); int frameIndex = 0; foreach (Dictionary<String, Object> eventMap in eventsMap) { EventData eventData = skeletonData.FindEvent((String)eventMap["name"]); if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]); float time = (float)eventMap["time"]; var e = new Event(time, eventData); e.Int = GetInt(eventMap, "int", eventData.Int); e.Float = GetFloat(eventMap, "float", eventData.Float); e.String = GetString(eventMap, "string", eventData.String); timeline.SetFrame(frameIndex++, time, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
private void ReadAnimation(String name, Dictionary <String, Object> map, SkeletonData skeletonData) { var timelines = new List <Timeline>(); float duration = 0; float scale = Scale; if (map.ContainsKey("slots")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)map["slots"]) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); var timelineMap = (Dictionary <String, Object>)entry.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "color") { var timeline = new ColorTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; String c = (String)valueMap["color"]; timeline.setFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3)); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]); } else if (timelineName == "attachment") { var timeline = new AttachmentTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.setFrame(frameIndex++, time, (String)valueMap["name"]); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } else { throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); } } } } if (map.ContainsKey("bones")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)map["bones"]) { String boneName = entry.Key; int boneIndex = skeletonData.FindBoneIndex(boneName); if (boneIndex == -1) { throw new Exception("Bone not found: " + boneName); } var timelineMap = (Dictionary <String, Object>)entry.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "rotate") { var timeline = new RotateTimeline(values.Count); timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]); } else if (timelineName == "translate" || timelineName == "scale") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") { timeline = new ScaleTimeline(values.Count); } else { timeline = new TranslateTimeline(values.Count); timelineScale = scale; } timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0; float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0; timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } else if (timelineName == "flipX" || timelineName == "flipY") { bool x = timelineName == "flipX"; var timeline = x ? new FlipXTimeline(values.Count) : new FlipYTimeline(values.Count); timeline.boneIndex = boneIndex; String field = x ? "x" : "y"; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex, time, valueMap.ContainsKey(field) ? (bool)valueMap[field] : false); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]); } else { throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); } } } } if (map.ContainsKey("ik")) { foreach (KeyValuePair <String, Object> ikMap in (Dictionary <String, Object>)map["ik"]) { IkConstraintData ikConstraint = skeletonData.FindIkConstraint(ikMap.Key); var values = (List <Object>)ikMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = valueMap.ContainsKey("mix") ? (float)valueMap["mix"] : 1; bool bendPositive = valueMap.ContainsKey("bendPositive") ? (bool)valueMap["bendPositive"] : true; timeline.setFrame(frameIndex, time, mix, bendPositive ? 1 : -1); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } } if (map.ContainsKey("ffd")) { foreach (KeyValuePair <String, Object> ffdMap in (Dictionary <String, Object>)map["ffd"]) { Skin skin = skeletonData.FindSkin(ffdMap.Key); foreach (KeyValuePair <String, Object> slotMap in (Dictionary <String, Object>)ffdMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); foreach (KeyValuePair <String, Object> meshMap in (Dictionary <String, Object>)slotMap.Value) { var values = (List <Object>)meshMap.Value; var timeline = new FFDTimeline(values.Count); Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key); if (attachment == null) { throw new Exception("FFD attachment not found: " + meshMap.Key); } timeline.slotIndex = slotIndex; timeline.attachment = attachment; int vertexCount; if (attachment is MeshAttachment) { vertexCount = ((MeshAttachment)attachment).vertices.Length; } else { vertexCount = ((SkinnedMeshAttachment)attachment).Weights.Length / 3 * 2; } int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float[] vertices; if (!valueMap.ContainsKey("vertices")) { if (attachment is MeshAttachment) { vertices = ((MeshAttachment)attachment).vertices; } else { vertices = new float[vertexCount]; } } else { var verticesValue = (List <Object>)valueMap["vertices"]; vertices = new float[vertexCount]; int start = GetInt(valueMap, "offset", 0); if (scale == 1) { for (int i = 0, n = verticesValue.Count; i < n; i++) { vertices[i + start] = (float)verticesValue[i]; } } else { for (int i = 0, n = verticesValue.Count; i < n; i++) { vertices[i + start] = (float)verticesValue[i] * scale; } } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int i = 0; i < vertexCount; i++) { vertices[i] += meshVertices[i]; } } } timeline.setFrame(frameIndex, (float)valueMap["time"], vertices); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } } } } if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { var values = (List <Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"]; var timeline = new DrawOrderTimeline(values.Count); int slotCount = skeletonData.slots.Count; int frameIndex = 0; foreach (Dictionary <String, Object> drawOrderMap in values) { int[] drawOrder = null; if (drawOrderMap.ContainsKey("offsets")) { drawOrder = new int[slotCount]; for (int i = slotCount - 1; i >= 0; i--) { drawOrder[i] = -1; } var offsets = (List <Object>)drawOrderMap["offsets"]; int[] unchanged = new int[slotCount - offsets.Count]; int originalIndex = 0, unchangedIndex = 0; foreach (Dictionary <String, Object> offsetMap in offsets) { int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]); if (slotIndex == -1) { throw new Exception("Slot not found: " + offsetMap["slot"]); } // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. int index = originalIndex + (int)(float)offsetMap["offset"]; drawOrder[index] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int i = slotCount - 1; i >= 0; i--) { if (drawOrder[i] == -1) { drawOrder[i] = unchanged[--unchangedIndex]; } } } timeline.setFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } if (map.ContainsKey("events")) { var eventsMap = (List <Object>)map["events"]; var timeline = new EventTimeline(eventsMap.Count); int frameIndex = 0; foreach (Dictionary <String, Object> eventMap in eventsMap) { EventData eventData = skeletonData.FindEvent((String)eventMap["name"]); if (eventData == null) { throw new Exception("Event not found: " + eventMap["name"]); } var e = new Event(eventData); e.Int = GetInt(eventMap, "int", eventData.Int); e.Float = GetFloat(eventMap, "float", eventData.Float); e.String = GetString(eventMap, "string", eventData.String); timeline.setFrame(frameIndex++, (float)eventMap["time"], e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
private void ReadAnimation (String name, Stream input, SkeletonData skeletonData) { var timelines = new ExposedList<Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { int slotIndex = ReadInt(input, true); for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadInt(input, true); switch (timelineType) { case TIMELINE_COLOR: { ColorTimeline timeline = new ColorTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); int color = ReadInt(input); float r = ((color & 0xff000000) >> 24) / 255f; float g = ((color & 0x00ff0000) >> 16) / 255f; float b = ((color & 0x0000ff00) >> 8) / 255f; float a = ((color & 0x000000ff)) / 255f; timeline.SetFrame(frameIndex, time, r, g, b, a); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 5 - 5]); break; } case TIMELINE_ATTACHMENT: { AttachmentTimeline timeline = new AttachmentTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input)); timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); break; } } } } // Bone timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { int boneIndex = ReadInt(input, true); for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadInt(input, true); switch (timelineType) { case TIMELINE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]); break; } case TIMELINE_TRANSLATE: case TIMELINE_SCALE: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == TIMELINE_SCALE) timeline = new ScaleTimeline(frameCount); else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]); break; } case TIMELINE_FLIPX: case TIMELINE_FLIPY: { FlipXTimeline timeline = timelineType == TIMELINE_FLIPX ? new FlipXTimeline(frameCount) : new FlipYTimeline( frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) timeline.SetFrame(frameIndex, ReadFloat(input), ReadBoolean(input)); timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]); break; } } } } // IK timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { IkConstraintData ikConstraint = skeletonData.ikConstraints.Items[ReadInt(input, true)]; int frameCount = ReadInt(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint); for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input)); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]); } // FFD timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadInt(input, true)]; for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int slotIndex = ReadInt(input, true); for (int iii = 0, nnn = ReadInt(input, true); iii < nnn; iii++) { Attachment attachment = skin.GetAttachment(slotIndex, ReadString(input)); int frameCount = ReadInt(input, true); FFDTimeline timeline = new FFDTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] vertices; int vertexCount; if (attachment is MeshAttachment) vertexCount = ((MeshAttachment)attachment).vertices.Length; else vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2; int end = ReadInt(input, true); if (end == 0) { if (attachment is MeshAttachment) vertices = ((MeshAttachment)attachment).vertices; else vertices = new float[vertexCount]; } else { vertices = new float[vertexCount]; int start = ReadInt(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) vertices[v] = ReadFloat(input); } else { for (int v = start; v < end; v++) vertices[v] = ReadFloat(input) * scale; } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int v = 0, vn = vertices.Length; v < vn; v++) vertices[v] += meshVertices[v]; } } timeline.SetFrame(frameIndex, time, vertices); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadInt(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { int offsetCount = ReadInt(input, true); int[] drawOrder = new int[slotCount]; for (int ii = slotCount - 1; ii >= 0; ii--) drawOrder[ii] = -1; int[] unchanged = new int[slotCount - offsetCount]; int originalIndex = 0, unchangedIndex = 0; for (int ii = 0; ii < offsetCount; ii++) { int slotIndex = ReadInt(input, true); // Collect unchanged items. while (originalIndex != slotIndex) unchanged[unchangedIndex++] = originalIndex++; // Set changed items. drawOrder[originalIndex + ReadInt(input, true)] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) unchanged[unchangedIndex++] = originalIndex++; // Fill in unchanged items. for (int ii = slotCount - 1; ii >= 0; ii--) if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; timeline.SetFrame(i, ReadFloat(input), drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadInt(input, true); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = ReadFloat(input); EventData eventData = skeletonData.events.Items[ReadInt(input, true)]; Event e = new Event(eventData); e.Int = ReadInt(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, time, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[eventCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
private void ReadAnimation(string name, Dictionary <string, object> map, SkeletonData skeletonData) { ExposedList <Timeline> exposedList = new ExposedList <Timeline>(); float num = 0f; float scale = this.Scale; if (map.ContainsKey("slots")) { using (Dictionary <string, object> .Enumerator enumerator = ((Dictionary <string, object>)map.get_Item("slots")).GetEnumerator()) { while (enumerator.MoveNext()) { KeyValuePair <string, object> current = enumerator.get_Current(); string key = current.get_Key(); int slotIndex = skeletonData.FindSlotIndex(key); Dictionary <string, object> dictionary = (Dictionary <string, object>)current.get_Value(); using (Dictionary <string, object> .Enumerator enumerator2 = dictionary.GetEnumerator()) { while (enumerator2.MoveNext()) { KeyValuePair <string, object> current2 = enumerator2.get_Current(); List <object> list = (List <object>)current2.get_Value(); string key2 = current2.get_Key(); if (key2 == "color") { ColorTimeline colorTimeline = new ColorTimeline(list.get_Count()); colorTimeline.slotIndex = slotIndex; int num2 = 0; for (int i = 0; i < list.get_Count(); i++) { Dictionary <string, object> dictionary2 = (Dictionary <string, object>)list.get_Item(i); float time = (float)dictionary2.get_Item("time"); string hexString = (string)dictionary2.get_Item("color"); colorTimeline.SetFrame(num2, time, this.ToColor(hexString, 0), this.ToColor(hexString, 1), this.ToColor(hexString, 2), this.ToColor(hexString, 3)); this.ReadCurve(colorTimeline, num2, dictionary2); num2++; } exposedList.Add(colorTimeline); num = Math.Max(num, colorTimeline.frames[colorTimeline.FrameCount * 5 - 5]); } else if (key2 == "attachment") { AttachmentTimeline attachmentTimeline = new AttachmentTimeline(list.get_Count()); attachmentTimeline.slotIndex = slotIndex; int num3 = 0; for (int j = 0; j < list.get_Count(); j++) { Dictionary <string, object> dictionary3 = (Dictionary <string, object>)list.get_Item(j); float time2 = (float)dictionary3.get_Item("time"); attachmentTimeline.SetFrame(num3++, time2, (string)dictionary3.get_Item("name")); } exposedList.Add(attachmentTimeline); num = Math.Max(num, attachmentTimeline.frames[attachmentTimeline.FrameCount - 1]); } } } } } } if (map.ContainsKey("bones")) { using (Dictionary <string, object> .Enumerator enumerator3 = ((Dictionary <string, object>)map.get_Item("bones")).GetEnumerator()) { while (enumerator3.MoveNext()) { KeyValuePair <string, object> current3 = enumerator3.get_Current(); string key3 = current3.get_Key(); int num4 = skeletonData.FindBoneIndex(key3); if (num4 == -1) { throw new Exception("Bone not found: " + key3); } Dictionary <string, object> dictionary4 = (Dictionary <string, object>)current3.get_Value(); using (Dictionary <string, object> .Enumerator enumerator4 = dictionary4.GetEnumerator()) { while (enumerator4.MoveNext()) { KeyValuePair <string, object> current4 = enumerator4.get_Current(); List <object> list2 = (List <object>)current4.get_Value(); string key4 = current4.get_Key(); if (key4 == "rotate") { RotateTimeline rotateTimeline = new RotateTimeline(list2.get_Count()); rotateTimeline.boneIndex = num4; int num5 = 0; for (int k = 0; k < list2.get_Count(); k++) { Dictionary <string, object> dictionary5 = (Dictionary <string, object>)list2.get_Item(k); float time3 = (float)dictionary5.get_Item("time"); rotateTimeline.SetFrame(num5, time3, (float)dictionary5.get_Item("angle")); this.ReadCurve(rotateTimeline, num5, dictionary5); num5++; } exposedList.Add(rotateTimeline); num = Math.Max(num, rotateTimeline.frames[rotateTimeline.FrameCount * 2 - 2]); } else if (key4 == "translate" || key4 == "scale") { float num6 = 1f; TranslateTimeline translateTimeline; if (key4 == "scale") { translateTimeline = new ScaleTimeline(list2.get_Count()); } else { translateTimeline = new TranslateTimeline(list2.get_Count()); num6 = scale; } translateTimeline.boneIndex = num4; int num7 = 0; for (int l = 0; l < list2.get_Count(); l++) { Dictionary <string, object> dictionary6 = (Dictionary <string, object>)list2.get_Item(l); float time4 = (float)dictionary6.get_Item("time"); float num8 = (!dictionary6.ContainsKey("x")) ? 0f : ((float)dictionary6.get_Item("x")); float num9 = (!dictionary6.ContainsKey("y")) ? 0f : ((float)dictionary6.get_Item("y")); translateTimeline.SetFrame(num7, time4, num8 * num6, num9 * num6); this.ReadCurve(translateTimeline, num7, dictionary6); num7++; } exposedList.Add(translateTimeline); num = Math.Max(num, translateTimeline.frames[translateTimeline.FrameCount * 3 - 3]); } else if (key4 == "flipX" || key4 == "flipY") { bool flag = key4 == "flipX"; FlipXTimeline flipXTimeline = (!flag) ? new FlipYTimeline(list2.get_Count()) : new FlipXTimeline(list2.get_Count()); flipXTimeline.boneIndex = num4; string text = (!flag) ? "y" : "x"; int num10 = 0; for (int m = 0; m < list2.get_Count(); m++) { Dictionary <string, object> dictionary7 = (Dictionary <string, object>)list2.get_Item(m); float time5 = (float)dictionary7.get_Item("time"); flipXTimeline.SetFrame(num10, time5, dictionary7.ContainsKey(text) && (bool)dictionary7.get_Item(text)); num10++; } exposedList.Add(flipXTimeline); num = Math.Max(num, flipXTimeline.frames[flipXTimeline.FrameCount * 2 - 2]); } } } } } } if (map.ContainsKey("ik")) { using (Dictionary <string, object> .Enumerator enumerator5 = ((Dictionary <string, object>)map.get_Item("ik")).GetEnumerator()) { while (enumerator5.MoveNext()) { KeyValuePair <string, object> current5 = enumerator5.get_Current(); IkConstraintData item = skeletonData.FindIkConstraint(current5.get_Key()); List <object> list3 = (List <object>)current5.get_Value(); IkConstraintTimeline ikConstraintTimeline = new IkConstraintTimeline(list3.get_Count()); ikConstraintTimeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(item); int num11 = 0; for (int n = 0; n < list3.get_Count(); n++) { Dictionary <string, object> dictionary8 = (Dictionary <string, object>)list3.get_Item(n); float time6 = (float)dictionary8.get_Item("time"); float mix = (!dictionary8.ContainsKey("mix")) ? 1f : ((float)dictionary8.get_Item("mix")); bool flag2 = !dictionary8.ContainsKey("bendPositive") || (bool)dictionary8.get_Item("bendPositive"); ikConstraintTimeline.SetFrame(num11, time6, mix, (!flag2) ? -1 : 1); this.ReadCurve(ikConstraintTimeline, num11, dictionary8); num11++; } exposedList.Add(ikConstraintTimeline); num = Math.Max(num, ikConstraintTimeline.frames[ikConstraintTimeline.FrameCount * 3 - 3]); } } } if (map.ContainsKey("ffd")) { using (Dictionary <string, object> .Enumerator enumerator6 = ((Dictionary <string, object>)map.get_Item("ffd")).GetEnumerator()) { while (enumerator6.MoveNext()) { KeyValuePair <string, object> current6 = enumerator6.get_Current(); Skin skin = skeletonData.FindSkin(current6.get_Key()); using (Dictionary <string, object> .Enumerator enumerator7 = ((Dictionary <string, object>)current6.get_Value()).GetEnumerator()) { while (enumerator7.MoveNext()) { KeyValuePair <string, object> current7 = enumerator7.get_Current(); int slotIndex2 = skeletonData.FindSlotIndex(current7.get_Key()); using (Dictionary <string, object> .Enumerator enumerator8 = ((Dictionary <string, object>)current7.get_Value()).GetEnumerator()) { while (enumerator8.MoveNext()) { KeyValuePair <string, object> current8 = enumerator8.get_Current(); List <object> list4 = (List <object>)current8.get_Value(); FFDTimeline fFDTimeline = new FFDTimeline(list4.get_Count()); Attachment attachment = skin.GetAttachment(slotIndex2, current8.get_Key()); if (attachment == null) { throw new Exception("FFD attachment not found: " + current8.get_Key()); } fFDTimeline.slotIndex = slotIndex2; fFDTimeline.attachment = attachment; int num12; if (attachment is MeshAttachment) { num12 = ((MeshAttachment)attachment).vertices.Length; } else { num12 = ((SkinnedMeshAttachment)attachment).Weights.Length / 3 * 2; } int num13 = 0; for (int num14 = 0; num14 < list4.get_Count(); num14++) { Dictionary <string, object> dictionary9 = (Dictionary <string, object>)list4.get_Item(num14); float[] array; if (!dictionary9.ContainsKey("vertices")) { if (attachment is MeshAttachment) { array = ((MeshAttachment)attachment).vertices; } else { array = new float[num12]; } } else { List <object> list5 = (List <object>)dictionary9.get_Item("vertices"); array = new float[num12]; int @int = this.GetInt(dictionary9, "offset", 0); if (scale == 1f) { int num15 = 0; int count = list5.get_Count(); while (num15 < count) { array[num15 + @int] = (float)list5.get_Item(num15); num15++; } } else { int num16 = 0; int count2 = list5.get_Count(); while (num16 < count2) { array[num16 + @int] = (float)list5.get_Item(num16) * scale; num16++; } } if (attachment is MeshAttachment) { float[] vertices = ((MeshAttachment)attachment).vertices; for (int num17 = 0; num17 < num12; num17++) { array[num17] += vertices[num17]; } } } fFDTimeline.SetFrame(num13, (float)dictionary9.get_Item("time"), array); this.ReadCurve(fFDTimeline, num13, dictionary9); num13++; } exposedList.Add(fFDTimeline); num = Math.Max(num, fFDTimeline.frames[fFDTimeline.FrameCount - 1]); } } } } } } } if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { List <object> list6 = (List <object>)map.get_Item((!map.ContainsKey("drawOrder")) ? "draworder" : "drawOrder"); DrawOrderTimeline drawOrderTimeline = new DrawOrderTimeline(list6.get_Count()); int count3 = skeletonData.slots.Count; int num18 = 0; for (int num19 = 0; num19 < list6.get_Count(); num19++) { Dictionary <string, object> dictionary10 = (Dictionary <string, object>)list6.get_Item(num19); int[] array2 = null; if (dictionary10.ContainsKey("offsets")) { array2 = new int[count3]; for (int num20 = count3 - 1; num20 >= 0; num20--) { array2[num20] = -1; } List <object> list7 = (List <object>)dictionary10.get_Item("offsets"); int[] array3 = new int[count3 - list7.get_Count()]; int num21 = 0; int num22 = 0; for (int num23 = 0; num23 < list7.get_Count(); num23++) { Dictionary <string, object> dictionary11 = (Dictionary <string, object>)list7.get_Item(num23); int num24 = skeletonData.FindSlotIndex((string)dictionary11.get_Item("slot")); if (num24 == -1) { throw new Exception("Slot not found: " + dictionary11.get_Item("slot")); } while (num21 != num24) { array3[num22++] = num21++; } int num25 = num21 + (int)((float)dictionary11.get_Item("offset")); array2[num25] = num21++; } while (num21 < count3) { array3[num22++] = num21++; } for (int num26 = count3 - 1; num26 >= 0; num26--) { if (array2[num26] == -1) { array2[num26] = array3[--num22]; } } } drawOrderTimeline.SetFrame(num18++, (float)dictionary10.get_Item("time"), array2); } exposedList.Add(drawOrderTimeline); num = Math.Max(num, drawOrderTimeline.frames[drawOrderTimeline.FrameCount - 1]); } if (map.ContainsKey("events")) { List <object> list8 = (List <object>)map.get_Item("events"); EventTimeline eventTimeline = new EventTimeline(list8.get_Count()); int num27 = 0; for (int num28 = 0; num28 < list8.get_Count(); num28++) { Dictionary <string, object> dictionary12 = (Dictionary <string, object>)list8.get_Item(num28); EventData eventData = skeletonData.FindEvent((string)dictionary12.get_Item("name")); if (eventData == null) { throw new Exception("Event not found: " + dictionary12.get_Item("name")); } Event @event = new Event(eventData); @event.Int = this.GetInt(dictionary12, "int", eventData.Int); @event.Float = this.GetFloat(dictionary12, "float", eventData.Float); @event.String = this.GetString(dictionary12, "string", eventData.String); eventTimeline.SetFrame(num27++, (float)dictionary12.get_Item("time"), @event); } exposedList.Add(eventTimeline); num = Math.Max(num, eventTimeline.frames[eventTimeline.FrameCount - 1]); } exposedList.TrimExcess(); skeletonData.animations.Add(new Animation(name, exposedList, num)); }