static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; var bone = skeleton.Bones[timeline.BoneIndex]; AnimationCurve curve = new AnimationCurve(); float endTime = timeline.Frames[(timeline.FrameCount * 2) - 2]; float currentTime = timeline.Frames[0]; List<Keyframe> keys = new List<Keyframe>(); float rotation = timeline.Frames[1] + boneData.Rotation; keys.Add(new Keyframe(timeline.Frames[0], rotation, 0, 0)); int listIndex = 1; int frameIndex = 1; int f = 2; float[] frames = timeline.Frames; skeleton.SetToSetupPose(); float lastTime = 0; float angle = rotation; while (currentTime < endTime) { int pIndex = listIndex - 1; float curveType = timeline.GetCurveType(frameIndex - 1); if (curveType == 0) { //linear Keyframe pk = keys[pIndex]; float time = frames[f]; rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; float rOut = (r - pk.value) / (time - pk.time); pk.outTangent = rOut; keys.Add(new Keyframe(time, r, rOut, 0)); keys[pIndex] = pk; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 1) { //stepped Keyframe pk = keys[pIndex]; float time = frames[f]; rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; float rOut = float.PositiveInfinity; pk.outTangent = rOut; keys.Add(new Keyframe(time, r, rOut, 0)); keys[pIndex] = pk; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 2) { //bezier Keyframe pk = keys[pIndex]; float time = frames[f]; timeline.Apply(skeleton, lastTime, currentTime, null, 1); skeleton.UpdateWorldTransform(); rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; int steps = Mathf.FloorToInt((time - pk.time) / bakeIncrement); for (int i = 1; i <= steps; i++) { currentTime += bakeIncrement; if (i == steps) currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); skeleton.UpdateWorldTransform(); pk = keys[listIndex - 1]; rotation = bone.Rotation; angle += Mathf.DeltaAngle(angle, rotation); r = angle; float rOut = (r - pk.value) / (currentTime - pk.time); pk.outTangent = rOut; keys.Add(new Keyframe(currentTime, r, rOut, 0)); keys[listIndex - 1] = pk; listIndex++; lastTime = currentTime; } } frameIndex++; f += 2; } curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); string path = GetPath(boneData); string propertyName = "localEulerAnglesBaked"; EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); EditorCurveBinding yBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".y"); AnimationUtility.SetEditorCurve(clip, yBind, new AnimationCurve()); EditorCurveBinding zBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".z"); AnimationUtility.SetEditorCurve(clip, zBind, curve); }
public bool Apply(Skeleton skeleton) { if (skeleton == null) { throw new ArgumentNullException("skeleton", "skeleton cannot be null."); } if (this.animationsChanged) { this.AnimationsChanged(); } ExposedList <Spine.Event> events = this.events; bool flag = false; TrackEntry[] items = this.tracks.Items; int index = 0; int count = this.tracks.Count; while (index < count) { TrackEntry to = items[index]; if ((to != null) && (to.delay <= 0f)) { flag = true; MixPose currentPose = (index != 0) ? MixPose.CurrentLayered : MixPose.Current; float alpha = to.alpha; if (to.mixingFrom != null) { alpha *= this.ApplyMixingFrom(to, skeleton, currentPose); } else if ((to.trackTime >= to.trackEnd) && (to.next == null)) { alpha = 0f; } float animationLast = to.animationLast; float animationTime = to.AnimationTime; int num6 = to.animation.timelines.Count; ExposedList <Timeline> timelines = to.animation.timelines; Timeline[] timelineArray = timelines.Items; if (alpha == 1f) { for (int i = 0; i < num6; i++) { timelineArray[i].Apply(skeleton, animationLast, animationTime, events, 1f, MixPose.Setup, MixDirection.In); } } else { int[] numArray = to.timelineData.Items; bool firstFrame = to.timelinesRotation.Count == 0; if (firstFrame) { to.timelinesRotation.EnsureCapacity(timelines.Count << 1); } float[] timelinesRotation = to.timelinesRotation.Items; for (int i = 0; i < num6; i++) { Timeline timeline = timelineArray[i]; MixPose pose = (numArray[i] < 1) ? currentPose : MixPose.Setup; RotateTimeline rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame); } else { timeline.Apply(skeleton, animationLast, animationTime, events, alpha, pose, MixDirection.In); } } } this.QueueEvents(to, animationTime); events.Clear(false); to.nextAnimationLast = animationTime; to.nextTrackLast = to.trackTime; } index++; } this.queue.Drain(); return(flag); }
void ReadBoneAnimation(ref ExposedList <Timeline> timelines, SkeletonDataStream input, ref float duration, float scale) { // Bone timelines. for (int i = 0, n = SkeletonDataStream.sp_readVarint(input.ptr, 1); i < n; i++) { int boneIndex = SkeletonDataStream.sp_readVarint(input.ptr, 1); for (int ii = 0, nn = SkeletonDataStream.sp_readVarint(input.ptr, 1); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = SkeletonDataStream.sp_readVarint(input.ptr, 1); switch (timelineType) { case BONE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr)); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { timeline = new ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { timeline = new ShearTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr) * timelineScale, SkeletonDataStream.sp_readFloat(input.ptr) * timelineScale); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]); break; } } } } }
private void readAnimation(String name, Dictionary<String, Object> map, SkeletonData skeletonData) { var timelines = new List<Timeline>(); float duration = 0; var bonesMap = (Dictionary<String, Object>)map["bones"]; foreach (KeyValuePair<String, Object> entry in bonesMap) { String boneName = entry.Key; int boneIndex = skeletonData.FindBoneIndex(boneName); if (boneIndex == -1) throw new Exception("Bone not found: " + boneName); Dictionary<String, Object> timelineMap = (Dictionary<String, Object>)entry.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { List<Object> values = (List<Object>)timelineEntry.Value; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_ROTATE)) { RotateTimeline 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.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) { TranslateTimeline timeline; float timelineScale = 1; if (timelineName.Equals(TIMELINE_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("slots")) { Dictionary<String, Object> slotsMap = (Dictionary<String, Object>)map["slots"]; foreach (KeyValuePair<String, Object> entry in slotsMap) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); Dictionary<String, Object> timelineMap = (Dictionary<String, Object>)entry.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { List<Object> values = (List<Object>)timelineEntry.Value; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_COLOR)) { ColorTimeline 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.Equals(TIMELINE_ATTACHMENT)) { AttachmentTimeline 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 + ")"); } } } timelines.TrimExcess(); skeletonData.AddAnimation(new Animation(name, timelines, duration)); }
private void ReadAnimation(Dictionary <String, Object> map, String name, SkeletonData skeletonData) { var scale = this.Scale; var timelines = new ExposedList <Timeline>(); float duration = 0; // Slot timelines. 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 = (valueMap.ContainsKey("color"))? (String)valueMap["color"] : "FFFFFFFF"; timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3)); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1] * ColorTimeline.ENTRIES); } 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 + ")"); } } } } // Bone timelines. 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) { timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * RotateTimeline.ENTRIES]); } else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") { timeline = new ScaleTimeline(values.Count); } else if (timelineName == "shear") { timeline = new ShearTimeline(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 = GetFloat(valueMap, "x", 0); float y = GetFloat(valueMap, "y", 0); timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TranslateTimeline.ENTRIES]); } else { throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); } } } } // IK constraint timelines. if (map.ContainsKey("ik")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["ik"]) { IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key); var values = (List <Object>)constraintMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = GetFloat(valueMap, "mix", 1); bool bendPositive = GetBoolean(valueMap, "bendPositive", true); timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * IkConstraintTimeline.ENTRIES]); } } // Transform constraint timelines. if (map.ContainsKey("transform")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["transform"]) { TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key); var values = (List <Object>)constraintMap.Value; var timeline = new TransformConstraintTimeline(values.Count); timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float rotateMix = GetFloat(valueMap, "rotateMix", 1); float translateMix = GetFloat(valueMap, "translateMix", 1); float scaleMix = GetFloat(valueMap, "scaleMix", 1); float shearMix = GetFloat(valueMap, "shearMix", 1); timeline.SetFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TransformConstraintTimeline.ENTRIES]); } } // Path constraint timelines. if (map.ContainsKey("paths")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["paths"]) { int index = skeletonData.FindPathConstraintIndex(constraintMap.Key); if (index == -1) { throw new Exception("Path constraint not found: " + constraintMap.Key); } PathConstraintData data = skeletonData.pathConstraints.Items[index]; var timelineMap = (Dictionary <String, Object>)constraintMap.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "position" || timelineName == "spacing") { PathConstraintPositionTimeline timeline; float timelineScale = 1; if (timelineName == "spacing") { timeline = new PathConstraintSpacingTimeline(values.Count); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) { timelineScale = scale; } } else { timeline = new PathConstraintPositionTimeline(values.Count); if (data.positionMode == PositionMode.Fixed) { timelineScale = scale; } } timeline.pathConstraintIndex = index; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); } else if (timelineName == "mix") { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count); timeline.pathConstraintIndex = index; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1)); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintMixTimeline.ENTRIES]); } } } } // Deform timelines. if (map.ContainsKey("deform")) { foreach (KeyValuePair <String, Object> deformMap in (Dictionary <String, Object>)map["deform"]) { Skin skin = skeletonData.FindSkin(deformMap.Key); foreach (KeyValuePair <String, Object> slotMap in (Dictionary <String, Object>)deformMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); if (slotIndex == -1) { throw new Exception("Slot not found: " + slotMap.Key); } foreach (KeyValuePair <String, Object> timelineMap in (Dictionary <String, Object>)slotMap.Value) { var values = (List <Object>)timelineMap.Value; VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key); if (attachment == null) { throw new Exception("Deform attachment not found: " + timelineMap.Key); } bool weighted = attachment.bones != null; float[] vertices = attachment.vertices; int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; var timeline = new DeformTimeline(values.Count); timeline.slotIndex = slotIndex; timeline.attachment = attachment; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float[] deform; if (!valueMap.ContainsKey("vertices")) { deform = weighted ? new float[deformLength] : vertices; } else { deform = new float[deformLength]; int start = GetInt(valueMap, "offset", 0); float[] verticesValue = GetFloatArray(valueMap, "vertices", 1); Array.Copy(verticesValue, 0, deform, start, verticesValue.Length); if (scale != 1) { for (int i = start, n = i + verticesValue.Length; i < n; i++) { deform[i] *= scale; } } if (!weighted) { for (int i = 0; i < deformLength; i++) { deform[i] += vertices[i]; } } } timeline.SetFrame(frameIndex, (float)valueMap["time"], deform); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } } } } // Draw order timeline. 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]); } // Event timeline. 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((float)eventMap["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++, 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; 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; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_ROTATE)) { RotateTimeline 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.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) { TranslateTimeline timeline; float timelineScale = 1; if (timelineName.Equals(TIMELINE_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("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; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_COLOR)) { ColorTimeline 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.Equals(TIMELINE_ATTACHMENT)) { AttachmentTimeline 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("events")) { var eventsMap = (List<Object>)map["events"]; EventTimeline 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"]); Event 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]); } if (map.ContainsKey("draworder")) { var values = (List<Object>)map["draworder"]; DrawOrderTimeline 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; List<Object> 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. drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = 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]); } timelines.TrimExcess(); skeletonData.AddAnimation(new Animation(name, timelines, duration)); }
private void ReadAnimation(String name, Dictionary <String, Object> map, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float duration = 0; var scale = this.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" || timelineName == "shear") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") { timeline = new ScaleTimeline(values.Count); } else if (timelineName == "shear") { timeline = new ShearTimeline(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 = GetFloat(valueMap, "x", 0); float y = GetFloat(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 + ")"); } } } } // IK timelines. if (map.ContainsKey("ik")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["ik"]) { IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key); var values = (List <Object>)constraintMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = GetFloat(valueMap, "mix", 1); bool bendPositive = GetBoolean(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]); } } // Transform constraint timelines. if (map.ContainsKey("transform")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["transform"]) { TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key); var values = (List <Object>)constraintMap.Value; var timeline = new TransformConstraintTimeline(values.Count); timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float rotateMix = GetFloat(valueMap, "rotateMix", 1); float translateMix = GetFloat(valueMap, "translateMix", 1); float scaleMix = GetFloat(valueMap, "scaleMix", 1); float shearMix = GetFloat(valueMap, "shearMix", 1); timeline.SetFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]); } } // FFD timelines. 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"]); } var e = new Event((float)eventMap["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++, 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) { ExposedList <Timeline> exposedList = new ExposedList <Timeline>(); float scale = Scale; float num = 0f; int i = 0; for (int num2 = ReadVarint(input, optimizePositive: true); i < num2; i++) { int slotIndex = ReadVarint(input, optimizePositive: true); int j = 0; for (int num3 = ReadVarint(input, optimizePositive: true); j < num3; j++) { int num4 = input.ReadByte(); int num5 = ReadVarint(input, optimizePositive: true); switch (num4) { case 0: { AttachmentTimeline attachmentTimeline = new AttachmentTimeline(num5); attachmentTimeline.slotIndex = slotIndex; for (int m = 0; m < num5; m++) { attachmentTimeline.SetFrame(m, ReadFloat(input), ReadString(input)); } exposedList.Add(attachmentTimeline); num = Math.Max(num, attachmentTimeline.frames[num5 - 1]); break; } case 1: { ColorTimeline colorTimeline = new ColorTimeline(num5); colorTimeline.slotIndex = slotIndex; for (int l = 0; l < num5; l++) { float time2 = ReadFloat(input); int num8 = ReadInt(input); float r3 = (float)((num8 & 4278190080u) >> 24) / 255f; float g3 = (float)((num8 & 0xFF0000) >> 16) / 255f; float b3 = (float)((num8 & 0xFF00) >> 8) / 255f; float a2 = (float)(num8 & 0xFF) / 255f; colorTimeline.SetFrame(l, time2, r3, g3, b3, a2); if (l < num5 - 1) { ReadCurve(input, l, colorTimeline); } } exposedList.Add(colorTimeline); num = Math.Max(num, colorTimeline.frames[(colorTimeline.FrameCount - 1) * 5]); break; } case 2: { TwoColorTimeline twoColorTimeline = new TwoColorTimeline(num5); twoColorTimeline.slotIndex = slotIndex; for (int k = 0; k < num5; k++) { float time = ReadFloat(input); int num6 = ReadInt(input); float r = (float)((num6 & 4278190080u) >> 24) / 255f; float g = (float)((num6 & 0xFF0000) >> 16) / 255f; float b = (float)((num6 & 0xFF00) >> 8) / 255f; float a = (float)(num6 & 0xFF) / 255f; int num7 = ReadInt(input); float r2 = (float)((num7 & 0xFF0000) >> 16) / 255f; float g2 = (float)((num7 & 0xFF00) >> 8) / 255f; float b2 = (float)(num7 & 0xFF) / 255f; twoColorTimeline.SetFrame(k, time, r, g, b, a, r2, g2, b2); if (k < num5 - 1) { ReadCurve(input, k, twoColorTimeline); } } exposedList.Add(twoColorTimeline); num = Math.Max(num, twoColorTimeline.frames[(twoColorTimeline.FrameCount - 1) * 8]); break; } } } } int n = 0; for (int num9 = ReadVarint(input, optimizePositive: true); n < num9; n++) { int boneIndex = ReadVarint(input, optimizePositive: true); int num10 = 0; for (int num11 = ReadVarint(input, optimizePositive: true); num10 < num11; num10++) { int num12 = input.ReadByte(); int num13 = ReadVarint(input, optimizePositive: true); switch (num12) { case 0: { RotateTimeline rotateTimeline = new RotateTimeline(num13); rotateTimeline.boneIndex = boneIndex; for (int num16 = 0; num16 < num13; num16++) { rotateTimeline.SetFrame(num16, ReadFloat(input), ReadFloat(input)); if (num16 < num13 - 1) { ReadCurve(input, num16, rotateTimeline); } } exposedList.Add(rotateTimeline); num = Math.Max(num, rotateTimeline.frames[(num13 - 1) * 2]); break; } case 1: case 2: case 3: { float num14 = 1f; TranslateTimeline translateTimeline; switch (num12) { case 2: translateTimeline = new ScaleTimeline(num13); break; case 3: translateTimeline = new ShearTimeline(num13); break; default: translateTimeline = new TranslateTimeline(num13); num14 = scale; break; } translateTimeline.boneIndex = boneIndex; for (int num15 = 0; num15 < num13; num15++) { translateTimeline.SetFrame(num15, ReadFloat(input), ReadFloat(input) * num14, ReadFloat(input) * num14); if (num15 < num13 - 1) { ReadCurve(input, num15, translateTimeline); } } exposedList.Add(translateTimeline); num = Math.Max(num, translateTimeline.frames[(num13 - 1) * 3]); break; } } } } int num17 = 0; for (int num18 = ReadVarint(input, optimizePositive: true); num17 < num18; num17++) { int ikConstraintIndex = ReadVarint(input, optimizePositive: true); int num19 = ReadVarint(input, optimizePositive: true); IkConstraintTimeline ikConstraintTimeline = new IkConstraintTimeline(num19); ikConstraintTimeline.ikConstraintIndex = ikConstraintIndex; for (int num20 = 0; num20 < num19; num20++) { ikConstraintTimeline.SetFrame(num20, ReadFloat(input), ReadFloat(input), ReadSByte(input)); if (num20 < num19 - 1) { ReadCurve(input, num20, ikConstraintTimeline); } } exposedList.Add(ikConstraintTimeline); num = Math.Max(num, ikConstraintTimeline.frames[(num19 - 1) * 3]); } int num21 = 0; for (int num22 = ReadVarint(input, optimizePositive: true); num21 < num22; num21++) { int transformConstraintIndex = ReadVarint(input, optimizePositive: true); int num23 = ReadVarint(input, optimizePositive: true); TransformConstraintTimeline transformConstraintTimeline = new TransformConstraintTimeline(num23); transformConstraintTimeline.transformConstraintIndex = transformConstraintIndex; for (int num24 = 0; num24 < num23; num24++) { transformConstraintTimeline.SetFrame(num24, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (num24 < num23 - 1) { ReadCurve(input, num24, transformConstraintTimeline); } } exposedList.Add(transformConstraintTimeline); num = Math.Max(num, transformConstraintTimeline.frames[(num23 - 1) * 5]); } int num25 = 0; for (int num26 = ReadVarint(input, optimizePositive: true); num25 < num26; num25++) { int num27 = ReadVarint(input, optimizePositive: true); PathConstraintData pathConstraintData = skeletonData.pathConstraints.Items[num27]; int num28 = 0; for (int num29 = ReadVarint(input, optimizePositive: true); num28 < num29; num28++) { int num30 = ReadSByte(input); int num31 = ReadVarint(input, optimizePositive: true); switch (num30) { case 0: case 1: { float num33 = 1f; PathConstraintPositionTimeline pathConstraintPositionTimeline; if (num30 == 1) { pathConstraintPositionTimeline = new PathConstraintSpacingTimeline(num31); if (pathConstraintData.spacingMode == SpacingMode.Length || pathConstraintData.spacingMode == SpacingMode.Fixed) { num33 = scale; } } else { pathConstraintPositionTimeline = new PathConstraintPositionTimeline(num31); if (pathConstraintData.positionMode == PositionMode.Fixed) { num33 = scale; } } pathConstraintPositionTimeline.pathConstraintIndex = num27; for (int num34 = 0; num34 < num31; num34++) { pathConstraintPositionTimeline.SetFrame(num34, ReadFloat(input), ReadFloat(input) * num33); if (num34 < num31 - 1) { ReadCurve(input, num34, pathConstraintPositionTimeline); } } exposedList.Add(pathConstraintPositionTimeline); num = Math.Max(num, pathConstraintPositionTimeline.frames[(num31 - 1) * 2]); break; } case 2: { PathConstraintMixTimeline pathConstraintMixTimeline = new PathConstraintMixTimeline(num31); pathConstraintMixTimeline.pathConstraintIndex = num27; for (int num32 = 0; num32 < num31; num32++) { pathConstraintMixTimeline.SetFrame(num32, ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (num32 < num31 - 1) { ReadCurve(input, num32, pathConstraintMixTimeline); } } exposedList.Add(pathConstraintMixTimeline); num = Math.Max(num, pathConstraintMixTimeline.frames[(num31 - 1) * 3]); break; } } } } int num35 = 0; for (int num36 = ReadVarint(input, optimizePositive: true); num35 < num36; num35++) { Skin skin = skeletonData.skins.Items[ReadVarint(input, optimizePositive: true)]; int num37 = 0; for (int num38 = ReadVarint(input, optimizePositive: true); num37 < num38; num37++) { int slotIndex2 = ReadVarint(input, optimizePositive: true); int num39 = 0; for (int num40 = ReadVarint(input, optimizePositive: true); num39 < num40; num39++) { VertexAttachment vertexAttachment = (VertexAttachment)skin.GetAttachment(slotIndex2, ReadString(input)); bool flag = vertexAttachment.bones != null; float[] vertices = vertexAttachment.vertices; int num41 = (!flag) ? vertices.Length : (vertices.Length / 3 * 2); int num42 = ReadVarint(input, optimizePositive: true); DeformTimeline deformTimeline = new DeformTimeline(num42); deformTimeline.slotIndex = slotIndex2; deformTimeline.attachment = vertexAttachment; for (int num43 = 0; num43 < num42; num43++) { float time3 = ReadFloat(input); int num44 = ReadVarint(input, optimizePositive: true); float[] array; if (num44 == 0) { array = ((!flag) ? vertices : new float[num41]); } else { array = new float[num41]; int num45 = ReadVarint(input, optimizePositive: true); num44 += num45; if (scale == 1f) { for (int num46 = num45; num46 < num44; num46++) { array[num46] = ReadFloat(input); } } else { for (int num47 = num45; num47 < num44; num47++) { array[num47] = ReadFloat(input) * scale; } } if (!flag) { int num48 = 0; for (int num49 = array.Length; num48 < num49; num48++) { array[num48] += vertices[num48]; } } } deformTimeline.SetFrame(num43, time3, array); if (num43 < num42 - 1) { ReadCurve(input, num43, deformTimeline); } } exposedList.Add(deformTimeline); num = Math.Max(num, deformTimeline.frames[num42 - 1]); } } } int num50 = ReadVarint(input, optimizePositive: true); if (num50 > 0) { DrawOrderTimeline drawOrderTimeline = new DrawOrderTimeline(num50); int count = skeletonData.slots.Count; for (int num51 = 0; num51 < num50; num51++) { float time4 = ReadFloat(input); int num52 = ReadVarint(input, optimizePositive: true); int[] array2 = new int[count]; for (int num53 = count - 1; num53 >= 0; num53--) { array2[num53] = -1; } int[] array3 = new int[count - num52]; int num54 = 0; int num55 = 0; for (int num56 = 0; num56 < num52; num56++) { int num57 = ReadVarint(input, optimizePositive: true); while (num54 != num57) { array3[num55++] = num54++; } array2[num54 + ReadVarint(input, optimizePositive: true)] = num54++; } while (num54 < count) { array3[num55++] = num54++; } for (int num63 = count - 1; num63 >= 0; num63--) { if (array2[num63] == -1) { array2[num63] = array3[--num55]; } } drawOrderTimeline.SetFrame(num51, time4, array2); } exposedList.Add(drawOrderTimeline); num = Math.Max(num, drawOrderTimeline.frames[num50 - 1]); } int num64 = ReadVarint(input, optimizePositive: true); if (num64 > 0) { EventTimeline eventTimeline = new EventTimeline(num64); for (int num65 = 0; num65 < num64; num65++) { float time5 = ReadFloat(input); EventData eventData = skeletonData.events.Items[ReadVarint(input, optimizePositive: true)]; Event @event = new Event(time5, eventData); @event.Int = ReadVarint(input, optimizePositive: false); @event.Float = ReadFloat(input); @event.String = ((!ReadBoolean(input)) ? eventData.String : ReadString(input)); eventTimeline.SetFrame(num65, @event); } exposedList.Add(eventTimeline); num = Math.Max(num, eventTimeline.frames[num64 - 1]); } exposedList.TrimExcess(); skeletonData.animations.Add(new Animation(name, exposedList, num)); }
static private void ApplyRotateTimeline(RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, bool setupPose, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) { timelinesRotation[i] = 0; } if (alpha == 1) { rotateTimeline.Apply(skeleton, 0, time, null, 1, setupPose, false); return; } Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; float[] frames = rotateTimeline.frames; if (time < frames[0]) { if (setupPose) { bone.rotation = bone.data.rotation; } return; } float r2; if (time >= frames[frames.Length - RotateTimeline.ENTRIES]) // Time is after last frame. { r2 = bone.data.rotation + frames[frames.Length + RotateTimeline.PREV_ROTATION]; } else { // Interpolate between the previous frame and the current frame. int frame = Animation.BinarySearch(frames, time, RotateTimeline.ENTRIES); float prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; float frameTime = frames[frame]; float percent = rotateTimeline.GetCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation; r2 -= (16384 - (int)(16384.499999999996 - r2 / 360)) * 360; r2 = prevRotation + r2 * percent + bone.data.rotation; r2 -= (16384 - (int)(16384.499999999996 - r2 / 360)) * 360; } // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. float r1 = setupPose ? bone.data.rotation : bone.rotation; float total, diff = r2 - r1; if (diff == 0) { total = timelinesRotation[i]; } else { diff -= (16384 - (int)(16384.499999999996 - diff / 360)) * 360; float lastTotal, lastDiff; if (firstFrame) { lastTotal = 0; lastDiff = diff; } else { lastTotal = timelinesRotation[i]; // Angle and direction of mix, including loops. lastDiff = timelinesRotation[i + 1]; // Difference between bones. } bool current = diff > 0, dir = lastTotal >= 0; // Detect cross at 0 (not 180). if (Math.Sign(lastDiff) != Math.Sign(diff) && Math.Abs(lastDiff) <= 90) { // A cross after a 360 rotation is a loop. if (Math.Abs(lastTotal) > 180) { lastTotal += 360 * Math.Sign(lastTotal); } dir = current; } total = diff + lastTotal - lastTotal % 360; // Store loops as part of lastTotal. if (dir != current) { total += 360 * Math.Sign(lastTotal); } timelinesRotation[i] = total; } timelinesRotation[i + 1] = diff; r1 += total * alpha; bone.rotation = r1 - (16384 - (int)(16384.499999999996 - r1 / 360)) * 360; }
private float ApplyMixingFrom(TrackEntry to, Skeleton skeleton, MixPose currentPose) { TrackEntry mixingFrom = to.mixingFrom; if (mixingFrom.mixingFrom != null) { ApplyMixingFrom(mixingFrom, skeleton, currentPose); } float num; if (to.mixDuration == 0f) { num = 1f; } else { num = to.mixTime / to.mixDuration; if (num > 1f) { num = 1f; } } ExposedList <Event> exposedList = (!(num < mixingFrom.eventThreshold)) ? null : events; bool flag = num < mixingFrom.attachmentThreshold; bool flag2 = num < mixingFrom.drawOrderThreshold; float animationLast = mixingFrom.animationLast; float animationTime = mixingFrom.AnimationTime; ExposedList <Timeline> timelines = mixingFrom.animation.timelines; int count = timelines.Count; Timeline[] items = timelines.Items; int[] items2 = mixingFrom.timelineData.Items; TrackEntry[] items3 = mixingFrom.timelineDipMix.Items; bool flag3 = mixingFrom.timelinesRotation.Count == 0; if (flag3) { mixingFrom.timelinesRotation.Resize(timelines.Count << 1); } float[] items4 = mixingFrom.timelinesRotation.Items; float num2 = mixingFrom.alpha * to.interruptAlpha; float num3 = num2 * (1f - num); mixingFrom.totalAlpha = 0f; for (int i = 0; i < count; i++) { Timeline timeline = items[i]; MixPose pose; float num4; switch (items2[i]) { case 0: if ((!flag && timeline is AttachmentTimeline) || (!flag2 && timeline is DrawOrderTimeline)) { continue; } pose = currentPose; num4 = num3; break; case 1: pose = MixPose.Setup; num4 = num3; break; case 2: pose = MixPose.Setup; num4 = num2; break; default: { pose = MixPose.Setup; num4 = num2; TrackEntry trackEntry = items3[i]; num4 *= Math.Max(0f, 1f - trackEntry.mixTime / trackEntry.mixDuration); break; } } mixingFrom.totalAlpha += num4; RotateTimeline rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, num4, pose, items4, i << 1, flag3); } else { timeline.Apply(skeleton, animationLast, animationTime, exposedList, num4, pose, MixDirection.Out); } } if (to.mixDuration > 0f) { QueueEvents(mixingFrom, animationTime); } events.Clear(clearArray: false); mixingFrom.nextAnimationLast = animationTime; mixingFrom.nextTrackLast = mixingFrom.trackTime; return(num); }
private static void ApplyRotateTimeline(RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, MixPose pose, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) { timelinesRotation[i] = 0f; } if (alpha == 1f) { rotateTimeline.Apply(skeleton, 0f, time, null, 1f, pose, MixDirection.In); return; } Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; float[] frames = rotateTimeline.frames; if (time < frames[0]) { if (pose == MixPose.Setup) { bone.rotation = bone.data.rotation; } return; } float num; if (time >= frames[frames.Length - 2]) { num = bone.data.rotation + frames[frames.Length + -1]; } else { int num2 = Animation.BinarySearch(frames, time, 2); float num3 = frames[num2 + -1]; float num4 = frames[num2]; float curvePercent = rotateTimeline.GetCurvePercent((num2 >> 1) - 1, 1f - (time - num4) / (frames[num2 + -2] - num4)); num = frames[num2 + 1] - num3; num -= (float)((16384 - (int)(16384.499999999996 - (double)(num / 360f))) * 360); num = num3 + num * curvePercent + bone.data.rotation; num -= (float)((16384 - (int)(16384.499999999996 - (double)(num / 360f))) * 360); } float num5 = (pose != 0) ? bone.rotation : bone.data.rotation; float num6 = num - num5; float num7; if (num6 == 0f) { num7 = timelinesRotation[i]; } else { num6 -= (float)((16384 - (int)(16384.499999999996 - (double)(num6 / 360f))) * 360); float num8; float value; if (firstFrame) { num8 = 0f; value = num6; } else { num8 = timelinesRotation[i]; value = timelinesRotation[i + 1]; } bool flag = num6 > 0f; bool flag2 = num8 >= 0f; if (Math.Sign(value) != Math.Sign(num6) && Math.Abs(value) <= 90f) { if (Math.Abs(num8) > 180f) { num8 += (float)(360 * Math.Sign(num8)); } flag2 = flag; } num7 = num6 + num8 - num8 % 360f; if (flag2 != flag) { num7 += (float)(360 * Math.Sign(num8)); } timelinesRotation[i] = num7; } timelinesRotation[i + 1] = num6; num5 += num7 * alpha; bone.rotation = num5 - (float)((16384 - (int)(16384.499999999996 - (double)(num5 / 360f))) * 360); }
public bool Apply(Skeleton skeleton) { if (skeleton == null) { throw new ArgumentNullException("skeleton", "skeleton cannot be null."); } if (animationsChanged) { AnimationsChanged(); } ExposedList <Event> exposedList = events; bool result = false; TrackEntry[] items = tracks.Items; int i = 0; for (int count = tracks.Count; i < count; i++) { TrackEntry trackEntry = items[i]; if (trackEntry == null || trackEntry.delay > 0f) { continue; } result = true; MixPose mixPose = (i == 0) ? MixPose.Current : MixPose.CurrentLayered; float num = trackEntry.alpha; if (trackEntry.mixingFrom != null) { num *= ApplyMixingFrom(trackEntry, skeleton, mixPose); } else if (trackEntry.trackTime >= trackEntry.trackEnd && trackEntry.next == null) { num = 0f; } float animationLast = trackEntry.animationLast; float animationTime = trackEntry.AnimationTime; int count2 = trackEntry.animation.timelines.Count; ExposedList <Timeline> timelines = trackEntry.animation.timelines; Timeline[] items2 = timelines.Items; if (num == 1f) { for (int j = 0; j < count2; j++) { items2[j].Apply(skeleton, animationLast, animationTime, exposedList, 1f, MixPose.Setup, MixDirection.In); } } else { int[] items3 = trackEntry.timelineData.Items; bool flag = trackEntry.timelinesRotation.Count == 0; if (flag) { trackEntry.timelinesRotation.EnsureCapacity(timelines.Count << 1); } float[] items4 = trackEntry.timelinesRotation.Items; for (int k = 0; k < count2; k++) { Timeline timeline = items2[k]; MixPose pose = (items3[k] < 1) ? mixPose : MixPose.Setup; RotateTimeline rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, num, pose, items4, k << 1, flag); } else { timeline.Apply(skeleton, animationLast, animationTime, exposedList, num, pose, MixDirection.In); } } } QueueEvents(trackEntry, animationTime); exposedList.Clear(clearArray: false); trackEntry.nextAnimationLast = animationTime; trackEntry.nextTrackLast = trackEntry.trackTime; } queue.Drain(); return(result); }
private static void ApplyRotateTimeline(RotateTimeline rotateTimeline, Skeleton skeleton, float time, float alpha, MixPose pose, float[] timelinesRotation, int i, bool firstFrame) { if (firstFrame) { timelinesRotation[i] = 0f; } if (alpha == 1f) { rotateTimeline.Apply(skeleton, 0f, time, null, 1f, pose, MixDirection.In); } else { Bone bone = skeleton.bones.Items[rotateTimeline.boneIndex]; float[] frames = rotateTimeline.frames; if (time < frames[0]) { if (pose == MixPose.Setup) { bone.rotation = bone.data.rotation; } } else { float num; float num7; if (time >= frames[frames.Length - 2]) { num = bone.data.rotation + frames[frames.Length + -1]; } else { int index = Animation.BinarySearch(frames, time, 2); float num3 = frames[index + -1]; float num4 = frames[index]; float curvePercent = rotateTimeline.GetCurvePercent((index >> 1) - 1, 1f - ((time - num4) / (frames[index + -2] - num4))); num = frames[index + 1] - num3; num -= (0x4000 - ((int)(16384.499999999996 - (num / 360f)))) * 360; num = (num3 + (num * curvePercent)) + bone.data.rotation; num -= (0x4000 - ((int)(16384.499999999996 - (num / 360f)))) * 360; } float num6 = (pose != MixPose.Setup) ? bone.rotation : bone.data.rotation; float num8 = num - num6; if (num8 == 0f) { num7 = timelinesRotation[i]; } else { float num9; float num10; num8 -= (0x4000 - ((int)(16384.499999999996 - (num8 / 360f)))) * 360; if (firstFrame) { num9 = 0f; num10 = num8; } else { num9 = timelinesRotation[i]; num10 = timelinesRotation[i + 1]; } bool flag = num8 > 0f; bool flag2 = num9 >= 0f; if ((Math.Sign(num10) != Math.Sign(num8)) && (Math.Abs(num10) <= 90f)) { if (Math.Abs(num9) > 180f) { num9 += 360 * Math.Sign(num9); } flag2 = flag; } num7 = (num8 + num9) - (num9 % 360f); if (flag2 != flag) { num7 += 360 * Math.Sign(num9); } timelinesRotation[i] = num7; } timelinesRotation[i + 1] = num8; num6 += num7 * alpha; bone.rotation = num6 - ((0x4000 - ((int)(16384.499999999996 - (num6 / 360f)))) * 360); } } }
private float ApplyMixingFrom(TrackEntry to, Skeleton skeleton, MixPose currentPose) { float num; TrackEntry mixingFrom = to.mixingFrom; if (mixingFrom.mixingFrom != null) { this.ApplyMixingFrom(mixingFrom, skeleton, currentPose); } if (to.mixDuration == 0f) { num = 1f; currentPose = MixPose.Setup; } else { num = to.mixTime / to.mixDuration; if (num > 1f) { num = 1f; } } ExposedList <Spine.Event> events = (num >= mixingFrom.eventThreshold) ? null : this.events; bool flag = num < mixingFrom.attachmentThreshold; bool flag2 = num < mixingFrom.drawOrderThreshold; float animationLast = mixingFrom.animationLast; float animationTime = mixingFrom.AnimationTime; ExposedList <Timeline> timelines = mixingFrom.animation.timelines; int count = timelines.Count; Timeline[] items = timelines.Items; int[] numArray = mixingFrom.timelineData.Items; TrackEntry[] entryArray = mixingFrom.timelineDipMix.Items; bool firstFrame = mixingFrom.timelinesRotation.Count == 0; if (firstFrame) { mixingFrom.timelinesRotation.Resize(timelines.Count << 1); } float[] timelinesRotation = mixingFrom.timelinesRotation.Items; float num5 = mixingFrom.alpha * to.interruptAlpha; float num6 = num5 * (1f - num); mixingFrom.totalAlpha = 0f; for (int i = 0; i < count; i++) { MixPose setup; float num7; Timeline timeline = items[i]; switch (numArray[i]) { case 0: { if (flag || !(timeline is AttachmentTimeline)) { break; } continue; } case 1: setup = MixPose.Setup; num7 = num6; goto Label_01E3; case 2: setup = MixPose.Setup; num7 = num5; goto Label_01E3; default: { setup = MixPose.Setup; TrackEntry entry2 = entryArray[i]; num7 = num5 * Math.Max((float)0f, (float)(1f - (entry2.mixTime / entry2.mixDuration))); goto Label_01E3; } } if (!flag2 && (timeline is DrawOrderTimeline)) { continue; } setup = currentPose; num7 = num6; Label_01E3: mixingFrom.totalAlpha += num7; RotateTimeline rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, num7, setup, timelinesRotation, i << 1, firstFrame); } else { timeline.Apply(skeleton, animationLast, animationTime, events, num7, setup, MixDirection.Out); } } if (to.mixDuration > 0f) { this.QueueEvents(mixingFrom, animationTime); } this.events.Clear(false); mixingFrom.nextAnimationLast = animationTime; mixingFrom.nextTrackLast = mixingFrom.trackTime; return(num); }
private void ReadAnimation(String name, Dictionary <String, Object> map, SkeletonData skeletonData) { var timelines = new List <Timeline>(); float duration = 0; if (map.ContainsKey("bones")) { var bonesMap = (Dictionary <String, Object>)map["bones"]; foreach (KeyValuePair <String, Object> entry in bonesMap) { 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; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_ROTATE)) { RotateTimeline 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.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) { TranslateTimeline timeline; float timelineScale = 1; if (timelineName.Equals(TIMELINE_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("slots")) { var slotsMap = (Dictionary <String, Object>)map["slots"]; foreach (KeyValuePair <String, Object> entry in slotsMap) { 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; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_COLOR)) { ColorTimeline 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.Equals(TIMELINE_ATTACHMENT)) { AttachmentTimeline 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 + ")"); } } } } timelines.TrimExcess(); skeletonData.AddAnimation(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)); }
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, Stream input, SkeletonData skeletonData) { var timelines = new ExposedList<Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int slotIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case SLOT_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[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); break; } case SLOT_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 = ReadVarint(input, true); i < n; i++) { int boneIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case BONE_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 - 1) * RotateTimeline.ENTRIES]); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) timeline = new ScaleTimeline(frameCount); else if (timelineType == BONE_SHEAR) timeline = new ShearTimeline(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 - 1) * TranslateTimeline.ENTRIES]); break; } } } } // IK timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = index; 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 - 1) * IkConstraintTimeline.ENTRIES]); } // Transform constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); timeline.transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); } // Path constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); PathConstraintData data = skeletonData.pathConstraints.Items[index]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = ReadSByte(input); int frameCount = ReadVarint(input, true); switch(timelineType) { case PATH_POSITION: case PATH_SPACING: { PathConstraintPositionTimeline timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { timeline = new PathConstraintSpacingTimeline(frameCount); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale; } else { timeline = new PathConstraintPositionTimeline(frameCount); if (data.positionMode == PositionMode.Fixed) timelineScale = scale; } timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); break; } case PATH_MIX: { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); break; } } } } // Deform timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadVarint(input, true)]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int slotIndex = ReadVarint(input, true); for (int iii = 0, nnn = ReadVarint(input, true); iii < nnn; iii++) { VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, ReadString(input)); bool weighted = attachment.bones != null; float[] vertices = attachment.vertices; int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; int frameCount = ReadVarint(input, true); DeformTimeline timeline = new DeformTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] deform; int end = ReadVarint(input, true); if (end == 0) deform = weighted ? new float[deformLength] : vertices; else { deform = new float[deformLength]; int start = ReadVarint(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) deform[v] = ReadFloat(input); } else { for (int v = start; v < end; v++) deform[v] = ReadFloat(input) * scale; } if (!weighted) { for (int v = 0, vn = deform.Length; v < vn; v++) deform[v] += vertices[v]; } } timeline.SetFrame(frameIndex, time, deform); if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadVarint(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { float time = ReadFloat(input); int offsetCount = ReadVarint(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 = ReadVarint(input, true); // Collect unchanged items. while (originalIndex != slotIndex) unchanged[unchangedIndex++] = originalIndex++; // Set changed items. drawOrder[originalIndex + ReadVarint(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, time, drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadVarint(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[ReadVarint(input, true)]; Event e = new Event(time, eventData); e.Int = ReadVarint(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, 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, NewStream input, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int slotIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case SLOT_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[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); break; } case SLOT_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 = ReadVarint(input, true); i < n; i++) { int boneIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case BONE_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 - 1) * RotateTimeline.ENTRIES]); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { timeline = new ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { timeline = new ShearTimeline(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 - 1) * TranslateTimeline.ENTRIES]); break; } } } } // IK timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = index; 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 - 1) * IkConstraintTimeline.ENTRIES]); } // Transform constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); timeline.transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); } // Path constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); PathConstraintData data = skeletonData.pathConstraints.Items[index]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = ReadSByte(input); int frameCount = ReadVarint(input, true); switch (timelineType) { case PATH_POSITION: case PATH_SPACING: { PathConstraintPositionTimeline timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { timeline = new PathConstraintSpacingTimeline(frameCount); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) { timelineScale = scale; } } else { timeline = new PathConstraintPositionTimeline(frameCount); if (data.positionMode == PositionMode.Fixed) { timelineScale = scale; } } timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); break; } case PATH_MIX: { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); break; } } } } // Deform timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadVarint(input, true)]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int slotIndex = ReadVarint(input, true); for (int iii = 0, nnn = ReadVarint(input, true); iii < nnn; iii++) { VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, ReadString(input)); bool weighted = attachment.bones != null; float[] vertices = attachment.vertices; int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; int frameCount = ReadVarint(input, true); DeformTimeline timeline = new DeformTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] deform; int end = ReadVarint(input, true); if (end == 0) { deform = weighted ? new float[deformLength] : vertices; } else { deform = new float[deformLength]; int start = ReadVarint(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) { deform[v] = ReadFloat(input); } } else { for (int v = start; v < end; v++) { deform[v] = ReadFloat(input) * scale; } } if (!weighted) { for (int v = 0, vn = deform.Length; v < vn; v++) { deform[v] += vertices[v]; } } } timeline.SetFrame(frameIndex, time, deform); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadVarint(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { float time = ReadFloat(input); int offsetCount = ReadVarint(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 = ReadVarint(input, true); // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. drawOrder[originalIndex + ReadVarint(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, time, drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadVarint(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[ReadVarint(input, true)]; Event e = new Event(time, eventData); e.Int = ReadVarint(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, 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 List <Timeline>(); float duration = 0; 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; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_ROTATE)) { RotateTimeline 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.Equals(TIMELINE_TRANSLATE) || timelineName.Equals(TIMELINE_SCALE)) { TranslateTimeline timeline; float timelineScale = 1; if (timelineName.Equals(TIMELINE_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("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; String timelineName = (String)timelineEntry.Key; if (timelineName.Equals(TIMELINE_COLOR)) { ColorTimeline 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.Equals(TIMELINE_ATTACHMENT)) { AttachmentTimeline 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("events")) { var eventsMap = (List <Object>)map["events"]; EventTimeline 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"]); } Event 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]); } if (map.ContainsKey("draworder")) { var values = (List <Object>)map["draworder"]; DrawOrderTimeline 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; } List <Object> 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. drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = 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]); } timelines.TrimExcess(); skeletonData.AddAnimation(new Animation(name, timelines, duration)); }
private void ReadAnimation (Dictionary<String, Object> map, String name, SkeletonData skeletonData) { var scale = this.Scale; var timelines = new ExposedList<Timeline>(); float duration = 0; // Slot timelines. 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(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); } 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 + ")"); } } } // Bone timelines. 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) { timeline.SetFrame(frameIndex, (float)valueMap["time"], (float)valueMap["angle"]); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * RotateTimeline.ENTRIES]); } else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") timeline = new ScaleTimeline(values.Count); else if (timelineName == "shear") timeline = new ShearTimeline(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 = GetFloat(valueMap, "x", 0); float y = GetFloat(valueMap, "y", 0); timeline.SetFrame(frameIndex, time, x * timelineScale, y * timelineScale); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TranslateTimeline.ENTRIES]); } else throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); } } } // IK constraint timelines. if (map.ContainsKey("ik")) { foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["ik"]) { IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key); var values = (List<Object>)constraintMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = GetFloat(valueMap, "mix", 1); bool bendPositive = GetBoolean(valueMap, "bendPositive", true); timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * IkConstraintTimeline.ENTRIES]); } } // Transform constraint timelines. if (map.ContainsKey("transform")) { foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["transform"]) { TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key); var values = (List<Object>)constraintMap.Value; var timeline = new TransformConstraintTimeline(values.Count); timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; float rotateMix = GetFloat(valueMap, "rotateMix", 1); float translateMix = GetFloat(valueMap, "translateMix", 1); float scaleMix = GetFloat(valueMap, "scaleMix", 1); float shearMix = GetFloat(valueMap, "shearMix", 1); timeline.SetFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * TransformConstraintTimeline.ENTRIES]); } } // Path constraint timelines. if (map.ContainsKey("paths")) { foreach (KeyValuePair<String, Object> constraintMap in (Dictionary<String, Object>)map["paths"]) { int index = skeletonData.FindPathConstraintIndex(constraintMap.Key); if (index == -1) throw new Exception("Path constraint not found: " + constraintMap.Key); PathConstraintData data = skeletonData.pathConstraints.Items[index]; var timelineMap = (Dictionary<String, Object>)constraintMap.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { var values = (List<Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "position" || timelineName == "spacing") { PathConstraintPositionTimeline timeline; float timelineScale = 1; if (timelineName == "spacing") { timeline = new PathConstraintSpacingTimeline(values.Count); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) timelineScale = scale; } else { timeline = new PathConstraintPositionTimeline(values.Count); if (data.positionMode == PositionMode.Fixed) timelineScale = scale; } timeline.pathConstraintIndex = index; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, timelineName, 0) * timelineScale); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); } else if (timelineName == "mix") { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(values.Count); timeline.pathConstraintIndex = index; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { timeline.SetFrame(frameIndex, (float)valueMap["time"], GetFloat(valueMap, "rotateMix", 1), GetFloat(valueMap, "translateMix", 1)); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * PathConstraintMixTimeline.ENTRIES]); } } } } // Deform timelines. if (map.ContainsKey("deform")) { foreach (KeyValuePair<String, Object> deformMap in (Dictionary<String, Object>)map["deform"]) { Skin skin = skeletonData.FindSkin(deformMap.Key); foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)deformMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); if (slotIndex == -1) throw new Exception("Slot not found: " + slotMap.Key); foreach (KeyValuePair<String, Object> timelineMap in (Dictionary<String, Object>)slotMap.Value) { var values = (List<Object>)timelineMap.Value; VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, timelineMap.Key); if (attachment == null) throw new Exception("Deform attachment not found: " + timelineMap.Key); bool weighted = attachment.bones != null; float[] vertices = attachment.vertices; int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; var timeline = new DeformTimeline(values.Count); timeline.slotIndex = slotIndex; timeline.attachment = attachment; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float[] deform; if (!valueMap.ContainsKey("vertices")) { deform = weighted ? new float[deformLength] : vertices; } else { deform = new float[deformLength]; int start = GetInt(valueMap, "offset", 0); float[] verticesValue = GetFloatArray(valueMap, "vertices", 1); Array.Copy(verticesValue, 0, deform, start, verticesValue.Length); if (scale != 1) { for (int i = start, n = i + verticesValue.Length; i < n; i++) deform[i] *= scale; } if (!weighted) { for (int i = 0; i < deformLength; i++) deform[i] += vertices[i]; } } timeline.SetFrame(frameIndex, (float)valueMap["time"], deform); ReadCurve(valueMap, timeline, frameIndex); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } } } } // Draw order timeline. 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]); } // Event timeline. 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((float)eventMap["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++, 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 (var entry in (Dictionary <String, Object>)map["slots"]) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); var timelineMap = (Dictionary <String, Object>)entry.Value; foreach (var timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; string timelineName = timelineEntry.Key; if (timelineName.Equals("color")) { var timeline = new ColorTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { var time = (float)valueMap["time"]; var 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.Equals("attachment")) { var timeline = new AttachmentTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { var 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 (var 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 (var timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; string timelineName = timelineEntry.Key; if (timelineName.Equals("rotate")) { var timeline = new RotateTimeline(values.Count); timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { var 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.Equals("translate") || timelineName.Equals("scale")) { TranslateTimeline timeline; float timelineScale = 1; if (timelineName.Equals("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) { var 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, x * timelineScale, 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("ffd")) { foreach (var ffdMap in (Dictionary <String, Object>)map["ffd"]) { Skin skin = skeletonData.FindSkin(ffdMap.Key); foreach (var slotMap in (Dictionary <String, Object>)ffdMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); foreach (var 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")) { var values = (List <Object>)map["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"]; var 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. drawOrder[originalIndex + (int)(float)offsetMap["offset"]] = 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.AddAnimation(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, Stream input, SkeletonData skeletonData) { ExposedList <Timeline> exposedList = new ExposedList <Timeline>(); float scale = this.Scale; float num = 0f; int i = 0; int num2 = SkeletonBinary.ReadVarint(input, true); while (i < num2) { int slotIndex = SkeletonBinary.ReadVarint(input, true); int j = 0; int num3 = SkeletonBinary.ReadVarint(input, true); while (j < num3) { int num4 = input.ReadByte(); int num5 = SkeletonBinary.ReadVarint(input, true); if (num4 != 1) { if (num4 == 0) { AttachmentTimeline attachmentTimeline = new AttachmentTimeline(num5); attachmentTimeline.slotIndex = slotIndex; for (int k = 0; k < num5; k++) { attachmentTimeline.SetFrame(k, this.ReadFloat(input), this.ReadString(input)); } exposedList.Add(attachmentTimeline); num = Math.Max(num, attachmentTimeline.frames[num5 - 1]); } } else { ColorTimeline colorTimeline = new ColorTimeline(num5); colorTimeline.slotIndex = slotIndex; for (int l = 0; l < num5; l++) { float time = this.ReadFloat(input); int num6 = SkeletonBinary.ReadInt(input); float r = (float)((num6 & 4278190080u) >> 24) / 255f; float g = (float)((num6 & 16711680) >> 16) / 255f; float b = (float)((num6 & 65280) >> 8) / 255f; float a = (float)(num6 & 255) / 255f; colorTimeline.SetFrame(l, time, r, g, b, a); if (l < num5 - 1) { this.ReadCurve(input, l, colorTimeline); } } exposedList.Add(colorTimeline); num = Math.Max(num, colorTimeline.frames[(colorTimeline.FrameCount - 1) * 5]); } j++; } i++; } int m = 0; int num7 = SkeletonBinary.ReadVarint(input, true); while (m < num7) { int boneIndex = SkeletonBinary.ReadVarint(input, true); int n = 0; int num8 = SkeletonBinary.ReadVarint(input, true); while (n < num8) { int num9 = input.ReadByte(); int num10 = SkeletonBinary.ReadVarint(input, true); switch (num9) { case 0: { RotateTimeline rotateTimeline = new RotateTimeline(num10); rotateTimeline.boneIndex = boneIndex; for (int num11 = 0; num11 < num10; num11++) { rotateTimeline.SetFrame(num11, this.ReadFloat(input), this.ReadFloat(input)); if (num11 < num10 - 1) { this.ReadCurve(input, num11, rotateTimeline); } } exposedList.Add(rotateTimeline); num = Math.Max(num, rotateTimeline.frames[(num10 - 1) * 2]); break; } case 1: case 2: case 3: { float num12 = 1f; TranslateTimeline translateTimeline; if (num9 == 2) { translateTimeline = new ScaleTimeline(num10); } else if (num9 == 3) { translateTimeline = new ShearTimeline(num10); } else { translateTimeline = new TranslateTimeline(num10); num12 = scale; } translateTimeline.boneIndex = boneIndex; for (int num13 = 0; num13 < num10; num13++) { translateTimeline.SetFrame(num13, this.ReadFloat(input), this.ReadFloat(input) * num12, this.ReadFloat(input) * num12); if (num13 < num10 - 1) { this.ReadCurve(input, num13, translateTimeline); } } exposedList.Add(translateTimeline); num = Math.Max(num, translateTimeline.frames[(num10 - 1) * 3]); break; } } n++; } m++; } int num14 = 0; int num15 = SkeletonBinary.ReadVarint(input, true); while (num14 < num15) { int ikConstraintIndex = SkeletonBinary.ReadVarint(input, true); int num16 = SkeletonBinary.ReadVarint(input, true); IkConstraintTimeline ikConstraintTimeline = new IkConstraintTimeline(num16); ikConstraintTimeline.ikConstraintIndex = ikConstraintIndex; for (int num17 = 0; num17 < num16; num17++) { ikConstraintTimeline.SetFrame(num17, this.ReadFloat(input), this.ReadFloat(input), (int)SkeletonBinary.ReadSByte(input)); if (num17 < num16 - 1) { this.ReadCurve(input, num17, ikConstraintTimeline); } } exposedList.Add(ikConstraintTimeline); num = Math.Max(num, ikConstraintTimeline.frames[(num16 - 1) * 3]); num14++; } int num18 = 0; int num19 = SkeletonBinary.ReadVarint(input, true); while (num18 < num19) { int transformConstraintIndex = SkeletonBinary.ReadVarint(input, true); int num20 = SkeletonBinary.ReadVarint(input, true); TransformConstraintTimeline transformConstraintTimeline = new TransformConstraintTimeline(num20); transformConstraintTimeline.transformConstraintIndex = transformConstraintIndex; for (int num21 = 0; num21 < num20; num21++) { transformConstraintTimeline.SetFrame(num21, this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input)); if (num21 < num20 - 1) { this.ReadCurve(input, num21, transformConstraintTimeline); } } exposedList.Add(transformConstraintTimeline); num = Math.Max(num, transformConstraintTimeline.frames[(num20 - 1) * 5]); num18++; } int num22 = 0; int num23 = SkeletonBinary.ReadVarint(input, true); while (num22 < num23) { int num24 = SkeletonBinary.ReadVarint(input, true); PathConstraintData pathConstraintData = skeletonData.pathConstraints.Items[num24]; int num25 = 0; int num26 = SkeletonBinary.ReadVarint(input, true); while (num25 < num26) { int num27 = (int)SkeletonBinary.ReadSByte(input); int num28 = SkeletonBinary.ReadVarint(input, true); if (num27 != 0 && num27 != 1) { if (num27 == 2) { PathConstraintMixTimeline pathConstraintMixTimeline = new PathConstraintMixTimeline(num28); pathConstraintMixTimeline.pathConstraintIndex = num24; for (int num29 = 0; num29 < num28; num29++) { pathConstraintMixTimeline.SetFrame(num29, this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input)); if (num29 < num28 - 1) { this.ReadCurve(input, num29, pathConstraintMixTimeline); } } exposedList.Add(pathConstraintMixTimeline); num = Math.Max(num, pathConstraintMixTimeline.frames[(num28 - 1) * 3]); } } else { float num30 = 1f; PathConstraintPositionTimeline pathConstraintPositionTimeline; if (num27 == 1) { pathConstraintPositionTimeline = new PathConstraintSpacingTimeline(num28); if (pathConstraintData.spacingMode == SpacingMode.Length || pathConstraintData.spacingMode == SpacingMode.Fixed) { num30 = scale; } } else { pathConstraintPositionTimeline = new PathConstraintPositionTimeline(num28); if (pathConstraintData.positionMode == PositionMode.Fixed) { num30 = scale; } } pathConstraintPositionTimeline.pathConstraintIndex = num24; for (int num31 = 0; num31 < num28; num31++) { pathConstraintPositionTimeline.SetFrame(num31, this.ReadFloat(input), this.ReadFloat(input) * num30); if (num31 < num28 - 1) { this.ReadCurve(input, num31, pathConstraintPositionTimeline); } } exposedList.Add(pathConstraintPositionTimeline); num = Math.Max(num, pathConstraintPositionTimeline.frames[(num28 - 1) * 2]); } num25++; } num22++; } int num32 = 0; int num33 = SkeletonBinary.ReadVarint(input, true); while (num32 < num33) { Skin skin = skeletonData.skins.Items[SkeletonBinary.ReadVarint(input, true)]; int num34 = 0; int num35 = SkeletonBinary.ReadVarint(input, true); while (num34 < num35) { int slotIndex2 = SkeletonBinary.ReadVarint(input, true); int num36 = 0; int num37 = SkeletonBinary.ReadVarint(input, true); while (num36 < num37) { VertexAttachment vertexAttachment = (VertexAttachment)skin.GetAttachment(slotIndex2, this.ReadString(input)); bool flag = vertexAttachment.bones != null; float[] vertices = vertexAttachment.vertices; int num38 = (!flag) ? vertices.Length : (vertices.Length / 3 * 2); int num39 = SkeletonBinary.ReadVarint(input, true); DeformTimeline deformTimeline = new DeformTimeline(num39); deformTimeline.slotIndex = slotIndex2; deformTimeline.attachment = vertexAttachment; for (int num40 = 0; num40 < num39; num40++) { float time2 = this.ReadFloat(input); int num41 = SkeletonBinary.ReadVarint(input, true); float[] array; if (num41 == 0) { array = ((!flag) ? vertices : new float[num38]); } else { array = new float[num38]; int num42 = SkeletonBinary.ReadVarint(input, true); num41 += num42; if (scale == 1f) { for (int num43 = num42; num43 < num41; num43++) { array[num43] = this.ReadFloat(input); } } else { for (int num44 = num42; num44 < num41; num44++) { array[num44] = this.ReadFloat(input) * scale; } } if (!flag) { int num45 = 0; int num46 = array.Length; while (num45 < num46) { array[num45] += vertices[num45]; num45++; } } } deformTimeline.SetFrame(num40, time2, array); if (num40 < num39 - 1) { this.ReadCurve(input, num40, deformTimeline); } } exposedList.Add(deformTimeline); num = Math.Max(num, deformTimeline.frames[num39 - 1]); num36++; } num34++; } num32++; } int num47 = SkeletonBinary.ReadVarint(input, true); if (num47 > 0) { DrawOrderTimeline drawOrderTimeline = new DrawOrderTimeline(num47); int count = skeletonData.slots.Count; for (int num48 = 0; num48 < num47; num48++) { float time3 = this.ReadFloat(input); int num49 = SkeletonBinary.ReadVarint(input, true); int[] array2 = new int[count]; for (int num50 = count - 1; num50 >= 0; num50--) { array2[num50] = -1; } int[] array3 = new int[count - num49]; int num51 = 0; int num52 = 0; for (int num53 = 0; num53 < num49; num53++) { int num54 = SkeletonBinary.ReadVarint(input, true); while (num51 != num54) { array3[num52++] = num51++; } array2[num51 + SkeletonBinary.ReadVarint(input, true)] = num51++; } while (num51 < count) { array3[num52++] = num51++; } for (int num55 = count - 1; num55 >= 0; num55--) { if (array2[num55] == -1) { array2[num55] = array3[--num52]; } } drawOrderTimeline.SetFrame(num48, time3, array2); } exposedList.Add(drawOrderTimeline); num = Math.Max(num, drawOrderTimeline.frames[num47 - 1]); } int num56 = SkeletonBinary.ReadVarint(input, true); if (num56 > 0) { EventTimeline eventTimeline = new EventTimeline(num56); for (int num57 = 0; num57 < num56; num57++) { float time4 = this.ReadFloat(input); EventData eventData = skeletonData.events.Items[SkeletonBinary.ReadVarint(input, true)]; eventTimeline.SetFrame(num57, new Event(time4, eventData) { Int = SkeletonBinary.ReadVarint(input, false), Float = this.ReadFloat(input), String = ((!SkeletonBinary.ReadBoolean(input)) ? eventData.String : this.ReadString(input)) }); } exposedList.Add(eventTimeline); num = Math.Max(num, eventTimeline.frames[num56 - 1]); } exposedList.TrimExcess(); skeletonData.animations.Add(new Animation(name, exposedList, num)); }
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(Dictionary <string, object> map, string name, SkeletonData skeletonData) { float scale = Scale; ExposedList <Timeline> exposedList = new ExposedList <Timeline>(); float num = 0f; if (map.ContainsKey("slots")) { foreach (KeyValuePair <string, object> item3 in (Dictionary <string, object>)map["slots"]) { string key = item3.Key; int slotIndex = skeletonData.FindSlotIndex(key); Dictionary <string, object> dictionary = (Dictionary <string, object>)item3.Value; foreach (KeyValuePair <string, object> item4 in dictionary) { List <object> list = (List <object>)item4.Value; string key2 = item4.Key; if (key2 == "attachment") { AttachmentTimeline attachmentTimeline = new AttachmentTimeline(list.Count); attachmentTimeline.slotIndex = slotIndex; int num2 = 0; foreach (Dictionary <string, object> item5 in list) { float time = (float)item5["time"]; attachmentTimeline.SetFrame(num2++, time, (string)item5["name"]); } exposedList.Add(attachmentTimeline); num = Math.Max(num, attachmentTimeline.frames[attachmentTimeline.FrameCount - 1]); } else if (key2 == "color") { ColorTimeline colorTimeline = new ColorTimeline(list.Count); colorTimeline.slotIndex = slotIndex; int num4 = 0; foreach (Dictionary <string, object> item6 in list) { float time2 = (float)item6["time"]; string hexString = (string)item6["color"]; colorTimeline.SetFrame(num4, time2, ToColor(hexString, 0), ToColor(hexString, 1), ToColor(hexString, 2), ToColor(hexString, 3)); ReadCurve(item6, colorTimeline, num4); num4++; } exposedList.Add(colorTimeline); num = Math.Max(num, colorTimeline.frames[(colorTimeline.FrameCount - 1) * 5]); } else { if (!(key2 == "twoColor")) { throw new Exception("Invalid timeline type for a slot: " + key2 + " (" + key + ")"); } TwoColorTimeline twoColorTimeline = new TwoColorTimeline(list.Count); twoColorTimeline.slotIndex = slotIndex; int num5 = 0; foreach (Dictionary <string, object> item7 in list) { float time3 = (float)item7["time"]; string hexString2 = (string)item7["light"]; string hexString3 = (string)item7["dark"]; twoColorTimeline.SetFrame(num5, time3, ToColor(hexString2, 0), ToColor(hexString2, 1), ToColor(hexString2, 2), ToColor(hexString2, 3), ToColor(hexString3, 0, 6), ToColor(hexString3, 1, 6), ToColor(hexString3, 2, 6)); ReadCurve(item7, twoColorTimeline, num5); num5++; } exposedList.Add(twoColorTimeline); num = Math.Max(num, twoColorTimeline.frames[(twoColorTimeline.FrameCount - 1) * 8]); } } } } if (map.ContainsKey("bones")) { foreach (KeyValuePair <string, object> item8 in (Dictionary <string, object>)map["bones"]) { string key3 = item8.Key; int num6 = skeletonData.FindBoneIndex(key3); if (num6 == -1) { throw new Exception("Bone not found: " + key3); } Dictionary <string, object> dictionary5 = (Dictionary <string, object>)item8.Value; foreach (KeyValuePair <string, object> item9 in dictionary5) { List <object> list2 = (List <object>)item9.Value; string key4 = item9.Key; if (key4 == "rotate") { RotateTimeline rotateTimeline = new RotateTimeline(list2.Count); rotateTimeline.boneIndex = num6; int num7 = 0; foreach (Dictionary <string, object> item10 in list2) { rotateTimeline.SetFrame(num7, (float)item10["time"], (float)item10["angle"]); ReadCurve(item10, rotateTimeline, num7); num7++; } exposedList.Add(rotateTimeline); num = Math.Max(num, rotateTimeline.frames[(rotateTimeline.FrameCount - 1) * 2]); } else { if (!(key4 == "translate") && !(key4 == "scale") && !(key4 == "shear")) { throw new Exception("Invalid timeline type for a bone: " + key4 + " (" + key3 + ")"); } float num8 = 1f; TranslateTimeline translateTimeline; if (key4 == "scale") { translateTimeline = new ScaleTimeline(list2.Count); } else if (key4 == "shear") { translateTimeline = new ShearTimeline(list2.Count); } else { translateTimeline = new TranslateTimeline(list2.Count); num8 = scale; } translateTimeline.boneIndex = num6; int num9 = 0; foreach (Dictionary <string, object> item11 in list2) { float time4 = (float)item11["time"]; float @float = GetFloat(item11, "x", 0f); float float2 = GetFloat(item11, "y", 0f); translateTimeline.SetFrame(num9, time4, @float * num8, float2 * num8); ReadCurve(item11, translateTimeline, num9); num9++; } exposedList.Add(translateTimeline); num = Math.Max(num, translateTimeline.frames[(translateTimeline.FrameCount - 1) * 3]); } } } } if (map.ContainsKey("ik")) { foreach (KeyValuePair <string, object> item12 in (Dictionary <string, object>)map["ik"]) { IkConstraintData item = skeletonData.FindIkConstraint(item12.Key); List <object> list3 = (List <object>)item12.Value; IkConstraintTimeline ikConstraintTimeline = new IkConstraintTimeline(list3.Count); ikConstraintTimeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(item); int num10 = 0; foreach (Dictionary <string, object> item13 in list3) { float time5 = (float)item13["time"]; float float3 = GetFloat(item13, "mix", 1f); bool boolean = GetBoolean(item13, "bendPositive", defaultValue: true); ikConstraintTimeline.SetFrame(num10, time5, float3, boolean ? 1 : (-1)); ReadCurve(item13, ikConstraintTimeline, num10); num10++; } exposedList.Add(ikConstraintTimeline); num = Math.Max(num, ikConstraintTimeline.frames[(ikConstraintTimeline.FrameCount - 1) * 3]); } } if (map.ContainsKey("transform")) { foreach (KeyValuePair <string, object> item14 in (Dictionary <string, object>)map["transform"]) { TransformConstraintData item2 = skeletonData.FindTransformConstraint(item14.Key); List <object> list4 = (List <object>)item14.Value; TransformConstraintTimeline transformConstraintTimeline = new TransformConstraintTimeline(list4.Count); transformConstraintTimeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(item2); int num11 = 0; foreach (Dictionary <string, object> item15 in list4) { float time6 = (float)item15["time"]; float float4 = GetFloat(item15, "rotateMix", 1f); float float5 = GetFloat(item15, "translateMix", 1f); float float6 = GetFloat(item15, "scaleMix", 1f); float float7 = GetFloat(item15, "shearMix", 1f); transformConstraintTimeline.SetFrame(num11, time6, float4, float5, float6, float7); ReadCurve(item15, transformConstraintTimeline, num11); num11++; } exposedList.Add(transformConstraintTimeline); num = Math.Max(num, transformConstraintTimeline.frames[(transformConstraintTimeline.FrameCount - 1) * 5]); } } if (map.ContainsKey("paths")) { foreach (KeyValuePair <string, object> item16 in (Dictionary <string, object>)map["paths"]) { int num12 = skeletonData.FindPathConstraintIndex(item16.Key); if (num12 == -1) { throw new Exception("Path constraint not found: " + item16.Key); } PathConstraintData pathConstraintData = skeletonData.pathConstraints.Items[num12]; Dictionary <string, object> dictionary10 = (Dictionary <string, object>)item16.Value; foreach (KeyValuePair <string, object> item17 in dictionary10) { List <object> list5 = (List <object>)item17.Value; string key5 = item17.Key; switch (key5) { case "position": case "spacing": { float num14 = 1f; PathConstraintPositionTimeline pathConstraintPositionTimeline; if (key5 == "spacing") { pathConstraintPositionTimeline = new PathConstraintSpacingTimeline(list5.Count); if (pathConstraintData.spacingMode == SpacingMode.Length || pathConstraintData.spacingMode == SpacingMode.Fixed) { num14 = scale; } } else { pathConstraintPositionTimeline = new PathConstraintPositionTimeline(list5.Count); if (pathConstraintData.positionMode == PositionMode.Fixed) { num14 = scale; } } pathConstraintPositionTimeline.pathConstraintIndex = num12; int num15 = 0; foreach (Dictionary <string, object> item18 in list5) { pathConstraintPositionTimeline.SetFrame(num15, (float)item18["time"], GetFloat(item18, key5, 0f) * num14); ReadCurve(item18, pathConstraintPositionTimeline, num15); num15++; } exposedList.Add(pathConstraintPositionTimeline); num = Math.Max(num, pathConstraintPositionTimeline.frames[(pathConstraintPositionTimeline.FrameCount - 1) * 2]); break; } case "mix": { PathConstraintMixTimeline pathConstraintMixTimeline = new PathConstraintMixTimeline(list5.Count); pathConstraintMixTimeline.pathConstraintIndex = num12; int num13 = 0; foreach (Dictionary <string, object> item19 in list5) { pathConstraintMixTimeline.SetFrame(num13, (float)item19["time"], GetFloat(item19, "rotateMix", 1f), GetFloat(item19, "translateMix", 1f)); ReadCurve(item19, pathConstraintMixTimeline, num13); num13++; } exposedList.Add(pathConstraintMixTimeline); num = Math.Max(num, pathConstraintMixTimeline.frames[(pathConstraintMixTimeline.FrameCount - 1) * 3]); break; } } } } } if (map.ContainsKey("deform")) { foreach (KeyValuePair <string, object> item20 in (Dictionary <string, object>)map["deform"]) { Skin skin = skeletonData.FindSkin(item20.Key); foreach (KeyValuePair <string, object> item21 in (Dictionary <string, object>)item20.Value) { int num16 = skeletonData.FindSlotIndex(item21.Key); if (num16 == -1) { throw new Exception("Slot not found: " + item21.Key); } foreach (KeyValuePair <string, object> item22 in (Dictionary <string, object>)item21.Value) { List <object> list6 = (List <object>)item22.Value; VertexAttachment vertexAttachment = (VertexAttachment)skin.GetAttachment(num16, item22.Key); if (vertexAttachment == null) { throw new Exception("Deform attachment not found: " + item22.Key); } bool flag = vertexAttachment.bones != null; float[] vertices = vertexAttachment.vertices; int num17 = (!flag) ? vertices.Length : (vertices.Length / 3 * 2); DeformTimeline deformTimeline = new DeformTimeline(list6.Count); deformTimeline.slotIndex = num16; deformTimeline.attachment = vertexAttachment; int num18 = 0; foreach (Dictionary <string, object> item23 in list6) { float[] array; if (!item23.ContainsKey("vertices")) { array = ((!flag) ? vertices : new float[num17]); } else { array = new float[num17]; int @int = GetInt(item23, "offset", 0); float[] floatArray = GetFloatArray(item23, "vertices", 1f); Array.Copy(floatArray, 0, array, @int, floatArray.Length); if (scale != 1f) { int i = @int; for (int num19 = i + floatArray.Length; i < num19; i++) { array[i] *= scale; } } if (!flag) { for (int j = 0; j < num17; j++) { array[j] += vertices[j]; } } } deformTimeline.SetFrame(num18, (float)item23["time"], array); ReadCurve(item23, deformTimeline, num18); num18++; } exposedList.Add(deformTimeline); num = Math.Max(num, deformTimeline.frames[deformTimeline.FrameCount - 1]); } } } } if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { List <object> list7 = (List <object>)map[(!map.ContainsKey("drawOrder")) ? "draworder" : "drawOrder"]; DrawOrderTimeline drawOrderTimeline = new DrawOrderTimeline(list7.Count); int count = skeletonData.slots.Count; int num20 = 0; foreach (Dictionary <string, object> item24 in list7) { int[] array2 = null; if (item24.ContainsKey("offsets")) { array2 = new int[count]; for (int num21 = count - 1; num21 >= 0; num21--) { array2[num21] = -1; } List <object> list8 = (List <object>)item24["offsets"]; int[] array3 = new int[count - list8.Count]; int num22 = 0; int num23 = 0; foreach (Dictionary <string, object> item25 in list8) { int num24 = skeletonData.FindSlotIndex((string)item25["slot"]); if (num24 == -1) { throw new Exception("Slot not found: " + item25["slot"]); } while (num22 != num24) { array3[num23++] = num22++; } int num27 = num22 + (int)(float)item25["offset"]; array2[num27] = num22++; } while (num22 < count) { array3[num23++] = num22++; } for (int num31 = count - 1; num31 >= 0; num31--) { if (array2[num31] == -1) { array2[num31] = array3[--num23]; } } } drawOrderTimeline.SetFrame(num20++, (float)item24["time"], array2); } exposedList.Add(drawOrderTimeline); num = Math.Max(num, drawOrderTimeline.frames[drawOrderTimeline.FrameCount - 1]); } if (map.ContainsKey("events")) { List <object> list9 = (List <object>)map["events"]; EventTimeline eventTimeline = new EventTimeline(list9.Count); int num33 = 0; foreach (Dictionary <string, object> item26 in list9) { EventData eventData = skeletonData.FindEvent((string)item26["name"]); if (eventData == null) { throw new Exception("Event not found: " + item26["name"]); } Event @event = new Event((float)item26["time"], eventData); @event.Int = GetInt(item26, "int", eventData.Int); @event.Float = GetFloat(item26, "float", eventData.Float); @event.String = GetString(item26, "string", eventData.String); eventTimeline.SetFrame(num33++, @event); } exposedList.Add(eventTimeline); num = Math.Max(num, eventTimeline.frames[eventTimeline.FrameCount - 1]); } exposedList.TrimExcess(); skeletonData.animations.Add(new Animation(name, exposedList, num)); }