public static Spine.Attachment GetAttachment(string attachmentPath, Spine.SkeletonData skeletonData) { var hierarchy = SpineAttachment.GetHierarchy(attachmentPath); if (hierarchy.name == "") { return(null); } return(skeletonData.FindSkin(hierarchy.skin).GetAttachment(skeletonData.FindSlotIndex(hierarchy.slot), hierarchy.name)); }
static int FindSlotIndex(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Spine.SkeletonData obj = (Spine.SkeletonData)ToLua.CheckObject <Spine.SkeletonData>(L, 1); string arg0 = ToLua.CheckString(L, 2); int o = obj.FindSlotIndex(arg0); LuaDLL.lua_pushinteger(L, o); return(1); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
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)); }
public SkeletonData ReadSkeletonData (TextReader reader) { if (reader == null) throw new ArgumentNullException("reader cannot be null."); SkeletonData skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary<String, Object>; if (root == null) throw new Exception("Invalid JSON."); // Bones. foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) throw new Exception("Parent bone not found: " + boneMap["parent"]); } BoneData boneData = new BoneData((String)boneMap["name"], parent); boneData.length = GetFloat(boneMap, "length", 0) * Scale; boneData.x = GetFloat(boneMap, "x", 0) * Scale; boneData.y = GetFloat(boneMap, "y", 0) * Scale; boneData.rotation = GetFloat(boneMap, "rotation", 0); boneData.scaleX = GetFloat(boneMap, "scaleX", 1); boneData.scaleY = GetFloat(boneMap, "scaleY", 1); boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true); boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true); skeletonData.AddBone(boneData); } // Slots. if (root.ContainsKey("slots")) { foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) { String slotName = (String)slotMap["name"]; String boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) throw new Exception("Slot bone not found: " + boneName); SlotData slotData = new SlotData(slotName, boneData); if (slotMap.ContainsKey("color")) { String color = (String)slotMap["color"]; slotData.r = ToColor(color, 0); slotData.g = ToColor(color, 1); slotData.b = ToColor(color, 2); slotData.a = ToColor(color, 3); } if (slotMap.ContainsKey("attachment")) slotData.attachmentName = (String)slotMap["attachment"]; if (slotMap.ContainsKey("additive")) slotData.additiveBlending = (bool)slotMap["additive"]; skeletonData.AddSlot(slotData); } } // Skins. if (root.ContainsKey("skins")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["skins"]) { Skin skin = new Skin(entry.Key); foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)entry.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair<String, Object> attachmentEntry in ((Dictionary<String, Object>)slotEntry.Value)) { Attachment attachment = ReadAttachment(skin, attachmentEntry.Key, (Dictionary<String, Object>)attachmentEntry.Value); if (attachment != null) skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment); } } skeletonData.AddSkin(skin); if (skin.name == "default") skeletonData.defaultSkin = skin; } } // Events. if (root.ContainsKey("events")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) { var entryMap = (Dictionary<String, Object>)entry.Value; EventData eventData = new EventData(entry.Key); eventData.Int = GetInt(entryMap, "int", 0); eventData.Float = GetFloat(entryMap, "float", 0); eventData.String = GetString(entryMap, "string", null); skeletonData.AddEvent(eventData); } } // Animations. if (root.ContainsKey("animations")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"]) ReadAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData); } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.animations.TrimExcess(); return skeletonData; }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader", "reader cannot be null."); } float scale = Scale; SkeletonData skeletonData = new SkeletonData(); Dictionary <string, object> dictionary = Json.Deserialize(reader) as Dictionary <string, object>; if (dictionary == null) { throw new Exception("Invalid JSON."); } if (dictionary.ContainsKey("skeleton")) { Dictionary <string, object> dictionary2 = (Dictionary <string, object>)dictionary["skeleton"]; skeletonData.hash = (string)dictionary2["hash"]; skeletonData.version = (string)dictionary2["spine"]; skeletonData.width = GetFloat(dictionary2, "width", 0f); skeletonData.height = GetFloat(dictionary2, "height", 0f); skeletonData.fps = GetFloat(dictionary2, "fps", 0f); skeletonData.imagesPath = GetString(dictionary2, "images", null); } foreach (Dictionary <string, object> item in (List <object>)dictionary["bones"]) { BoneData boneData = null; if (item.ContainsKey("parent")) { boneData = skeletonData.FindBone((string)item["parent"]); if (boneData == null) { throw new Exception("Parent bone not found: " + item["parent"]); } } BoneData boneData2 = new BoneData(skeletonData.Bones.Count, (string)item["name"], boneData); boneData2.length = GetFloat(item, "length", 0f) * scale; boneData2.x = GetFloat(item, "x", 0f) * scale; boneData2.y = GetFloat(item, "y", 0f) * scale; boneData2.rotation = GetFloat(item, "rotation", 0f); boneData2.scaleX = GetFloat(item, "scaleX", 1f); boneData2.scaleY = GetFloat(item, "scaleY", 1f); boneData2.shearX = GetFloat(item, "shearX", 0f); boneData2.shearY = GetFloat(item, "shearY", 0f); string @string = GetString(item, "transform", TransformMode.Normal.ToString()); boneData2.transformMode = (TransformMode)Enum.Parse(typeof(TransformMode), @string, ignoreCase: true); skeletonData.bones.Add(boneData2); } if (dictionary.ContainsKey("slots")) { foreach (Dictionary <string, object> item2 in (List <object>)dictionary["slots"]) { string name = (string)item2["name"]; string text = (string)item2["bone"]; BoneData boneData3 = skeletonData.FindBone(text); if (boneData3 == null) { throw new Exception("Slot bone not found: " + text); } SlotData slotData = new SlotData(skeletonData.Slots.Count, name, boneData3); if (item2.ContainsKey("color")) { string hexString = (string)item2["color"]; slotData.r = ToColor(hexString, 0); slotData.g = ToColor(hexString, 1); slotData.b = ToColor(hexString, 2); slotData.a = ToColor(hexString, 3); } if (item2.ContainsKey("dark")) { string hexString2 = (string)item2["dark"]; slotData.r2 = ToColor(hexString2, 0, 6); slotData.g2 = ToColor(hexString2, 1, 6); slotData.b2 = ToColor(hexString2, 2, 6); slotData.hasSecondColor = true; } slotData.attachmentName = GetString(item2, "attachment", null); if (item2.ContainsKey("blend")) { slotData.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (string)item2["blend"], ignoreCase: true); } else { slotData.blendMode = BlendMode.Normal; } skeletonData.slots.Add(slotData); } } if (dictionary.ContainsKey("ik")) { foreach (Dictionary <string, object> item3 in (List <object>)dictionary["ik"]) { IkConstraintData ikConstraintData = new IkConstraintData((string)item3["name"]); ikConstraintData.order = GetInt(item3, "order", 0); foreach (string item4 in (List <object>)item3["bones"]) { BoneData boneData4 = skeletonData.FindBone(item4); if (boneData4 == null) { throw new Exception("IK constraint bone not found: " + item4); } ikConstraintData.bones.Add(boneData4); } string text3 = (string)item3["target"]; ikConstraintData.target = skeletonData.FindBone(text3); if (ikConstraintData.target == null) { throw new Exception("Target bone not found: " + text3); } ikConstraintData.bendDirection = (GetBoolean(item3, "bendPositive", defaultValue: true) ? 1 : (-1)); ikConstraintData.mix = GetFloat(item3, "mix", 1f); skeletonData.ikConstraints.Add(ikConstraintData); } } if (dictionary.ContainsKey("transform")) { foreach (Dictionary <string, object> item5 in (List <object>)dictionary["transform"]) { TransformConstraintData transformConstraintData = new TransformConstraintData((string)item5["name"]); transformConstraintData.order = GetInt(item5, "order", 0); foreach (string item6 in (List <object>)item5["bones"]) { BoneData boneData5 = skeletonData.FindBone(item6); if (boneData5 == null) { throw new Exception("Transform constraint bone not found: " + item6); } transformConstraintData.bones.Add(boneData5); } string text5 = (string)item5["target"]; transformConstraintData.target = skeletonData.FindBone(text5); if (transformConstraintData.target == null) { throw new Exception("Target bone not found: " + text5); } transformConstraintData.local = GetBoolean(item5, "local", defaultValue: false); transformConstraintData.relative = GetBoolean(item5, "relative", defaultValue: false); transformConstraintData.offsetRotation = GetFloat(item5, "rotation", 0f); transformConstraintData.offsetX = GetFloat(item5, "x", 0f) * scale; transformConstraintData.offsetY = GetFloat(item5, "y", 0f) * scale; transformConstraintData.offsetScaleX = GetFloat(item5, "scaleX", 0f); transformConstraintData.offsetScaleY = GetFloat(item5, "scaleY", 0f); transformConstraintData.offsetShearY = GetFloat(item5, "shearY", 0f); transformConstraintData.rotateMix = GetFloat(item5, "rotateMix", 1f); transformConstraintData.translateMix = GetFloat(item5, "translateMix", 1f); transformConstraintData.scaleMix = GetFloat(item5, "scaleMix", 1f); transformConstraintData.shearMix = GetFloat(item5, "shearMix", 1f); skeletonData.transformConstraints.Add(transformConstraintData); } } if (dictionary.ContainsKey("path")) { foreach (Dictionary <string, object> item7 in (List <object>)dictionary["path"]) { PathConstraintData pathConstraintData = new PathConstraintData((string)item7["name"]); pathConstraintData.order = GetInt(item7, "order", 0); foreach (string item8 in (List <object>)item7["bones"]) { BoneData boneData6 = skeletonData.FindBone(item8); if (boneData6 == null) { throw new Exception("Path bone not found: " + item8); } pathConstraintData.bones.Add(boneData6); } string text7 = (string)item7["target"]; pathConstraintData.target = skeletonData.FindSlot(text7); if (pathConstraintData.target == null) { throw new Exception("Target slot not found: " + text7); } pathConstraintData.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(item7, "positionMode", "percent"), ignoreCase: true); pathConstraintData.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(item7, "spacingMode", "length"), ignoreCase: true); pathConstraintData.rotateMode = (RotateMode)Enum.Parse(typeof(RotateMode), GetString(item7, "rotateMode", "tangent"), ignoreCase: true); pathConstraintData.offsetRotation = GetFloat(item7, "rotation", 0f); pathConstraintData.position = GetFloat(item7, "position", 0f); if (pathConstraintData.positionMode == PositionMode.Fixed) { pathConstraintData.position *= scale; } pathConstraintData.spacing = GetFloat(item7, "spacing", 0f); if (pathConstraintData.spacingMode == SpacingMode.Length || pathConstraintData.spacingMode == SpacingMode.Fixed) { pathConstraintData.spacing *= scale; } pathConstraintData.rotateMix = GetFloat(item7, "rotateMix", 1f); pathConstraintData.translateMix = GetFloat(item7, "translateMix", 1f); skeletonData.pathConstraints.Add(pathConstraintData); } } if (dictionary.ContainsKey("skins")) { foreach (KeyValuePair <string, object> item9 in (Dictionary <string, object>)dictionary["skins"]) { Skin skin = new Skin(item9.Key); foreach (KeyValuePair <string, object> item10 in (Dictionary <string, object>)item9.Value) { int slotIndex = skeletonData.FindSlotIndex(item10.Key); foreach (KeyValuePair <string, object> item11 in (Dictionary <string, object>)item10.Value) { try { Attachment attachment = ReadAttachment((Dictionary <string, object>)item11.Value, skin, slotIndex, item11.Key, skeletonData); if (attachment != null) { skin.AddAttachment(slotIndex, item11.Key, attachment); } } catch (Exception innerException) { throw new Exception("Error reading attachment: " + item11.Key + ", skin: " + skin, innerException); } } } skeletonData.skins.Add(skin); if (skin.name == "default") { skeletonData.defaultSkin = skin; } } } int i = 0; for (int count = linkedMeshes.Count; i < count; i++) { LinkedMesh linkedMesh = linkedMeshes[i]; Skin skin2 = (linkedMesh.skin != null) ? skeletonData.FindSkin(linkedMesh.skin) : skeletonData.defaultSkin; if (skin2 == null) { throw new Exception("Slot not found: " + linkedMesh.skin); } Attachment attachment2 = skin2.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); if (attachment2 == null) { throw new Exception("Parent mesh not found: " + linkedMesh.parent); } linkedMesh.mesh.ParentMesh = (MeshAttachment)attachment2; linkedMesh.mesh.UpdateUVs(); } linkedMeshes.Clear(); if (dictionary.ContainsKey("events")) { foreach (KeyValuePair <string, object> item12 in (Dictionary <string, object>)dictionary["events"]) { Dictionary <string, object> map = (Dictionary <string, object>)item12.Value; EventData eventData = new EventData(item12.Key); eventData.Int = GetInt(map, "int", 0); eventData.Float = GetFloat(map, "float", 0f); eventData.String = GetString(map, "string", string.Empty); skeletonData.events.Add(eventData); } } if (dictionary.ContainsKey("animations")) { foreach (KeyValuePair <string, object> item13 in (Dictionary <string, object>)dictionary["animations"]) { try { ReadAnimation((Dictionary <string, object>)item13.Value, item13.Key, skeletonData); } catch (Exception innerException2) { throw new Exception("Error reading animation: " + item13.Key, innerException2); } } } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.events.TrimExcess(); skeletonData.animations.TrimExcess(); skeletonData.ikConstraints.TrimExcess(); return(skeletonData); }
/// <summary><see cref="Spine.Skin.FindAttachmentsForSlot(int,List)"/></summary> public static void FindAttachmentsForSlot(this Skin skin, string slotName, SkeletonData skeletonData, List <Attachment> results) { int slotIndex = skeletonData.FindSlotIndex(slotName); skin.FindAttachmentsForSlot(slotIndex, results); }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader", "reader cannot be null."); } var scale = this.Scale; var skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary <String, Object>; if (root == null) { throw new Exception("Invalid JSON."); } // Skeleton. if (root.ContainsKey("skeleton")) { var skeletonMap = (Dictionary <String, Object>)root["skeleton"]; skeletonData.hash = (String)skeletonMap["hash"]; skeletonData.version = (String)skeletonMap["spine"]; skeletonData.width = GetFloat(skeletonMap, "width", 0); skeletonData.height = GetFloat(skeletonMap, "height", 0); } // Bones. foreach (Dictionary <String, Object> boneMap in (List <Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) { throw new Exception("Parent bone not found: " + boneMap["parent"]); } } var data = new BoneData(skeletonData.Bones.Count, (String)boneMap["name"], parent); data.length = GetFloat(boneMap, "length", 0) * scale; data.x = GetFloat(boneMap, "x", 0) * scale; data.y = GetFloat(boneMap, "y", 0) * scale; data.rotation = GetFloat(boneMap, "rotation", 0); data.scaleX = GetFloat(boneMap, "scaleX", 1); data.scaleY = GetFloat(boneMap, "scaleY", 1); data.shearX = GetFloat(boneMap, "shearX", 0); data.shearY = GetFloat(boneMap, "shearY", 0); data.inheritRotation = GetBoolean(boneMap, "inheritRotation", true); data.inheritScale = GetBoolean(boneMap, "inheritScale", true); skeletonData.bones.Add(data); } // Slots. if (root.ContainsKey("slots")) { foreach (Dictionary <String, Object> slotMap in (List <Object>)root["slots"]) { var slotName = (String)slotMap["name"]; var boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) { throw new Exception("Slot bone not found: " + boneName); } var data = new SlotData(skeletonData.Slots.Count, slotName, boneData); if (slotMap.ContainsKey("color")) { var color = (String)slotMap["color"]; data.r = ToColor(color, 0); data.g = ToColor(color, 1); data.b = ToColor(color, 2); data.a = ToColor(color, 3); } data.attachmentName = GetString(slotMap, "attachment", null); if (slotMap.ContainsKey("blend")) { data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false); } else { data.blendMode = BlendMode.normal; } skeletonData.slots.Add(data); } } // IK constraints. if (root.ContainsKey("ik")) { foreach (Dictionary <String, Object> constraintMap in (List <Object>)root["ik"]) { IkConstraintData data = new IkConstraintData((String)constraintMap["name"]); foreach (String boneName in (List <Object>)constraintMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) { throw new Exception("IK constraint bone not found: " + boneName); } data.bones.Add(bone); } String targetName = (String)constraintMap["target"]; data.target = skeletonData.FindBone(targetName); if (data.target == null) { throw new Exception("Target bone not found: " + targetName); } data.bendDirection = GetBoolean(constraintMap, "bendPositive", true) ? 1 : -1; data.mix = GetFloat(constraintMap, "mix", 1); skeletonData.ikConstraints.Add(data); } } // Transform constraints. if (root.ContainsKey("transform")) { foreach (Dictionary <String, Object> constraintMap in (List <Object>)root["transform"]) { TransformConstraintData data = new TransformConstraintData((String)constraintMap["name"]); foreach (String boneName in (List <Object>)constraintMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) { throw new Exception("Transform constraint bone not found: " + boneName); } data.bones.Add(bone); } String targetName = (String)constraintMap["target"]; data.target = skeletonData.FindBone(targetName); if (data.target == null) { throw new Exception("Target bone not found: " + targetName); } data.offsetRotation = GetFloat(constraintMap, "rotation", 0); data.offsetX = GetFloat(constraintMap, "x", 0) * scale; data.offsetY = GetFloat(constraintMap, "y", 0) * scale; data.offsetScaleX = GetFloat(constraintMap, "scaleX", 0); data.offsetScaleY = GetFloat(constraintMap, "scaleY", 0); data.offsetShearY = GetFloat(constraintMap, "shearY", 0); data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); data.translateMix = GetFloat(constraintMap, "translateMix", 1); data.scaleMix = GetFloat(constraintMap, "scaleMix", 1); data.shearMix = GetFloat(constraintMap, "shearMix", 1); skeletonData.transformConstraints.Add(data); } } // Path constraints. if (root.ContainsKey("path")) { foreach (Dictionary <String, Object> constraintMap in (List <Object>)root["path"]) { PathConstraintData data = new PathConstraintData((String)constraintMap["name"]); foreach (String boneName in (List <Object>)constraintMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) { throw new Exception("Path bone not found: " + boneName); } data.bones.Add(bone); } String targetName = (String)constraintMap["target"]; data.target = skeletonData.FindSlot(targetName); if (data.target == null) { throw new Exception("Target slot not found: " + targetName); } data.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true); data.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true); data.rotateMode = (RotateMode)Enum.Parse(typeof(RotateMode), GetString(constraintMap, "rotateMode", "tangent"), true); data.offsetRotation = GetFloat(constraintMap, "rotation", 0); data.position = GetFloat(constraintMap, "position", 0); if (data.positionMode == PositionMode.Fixed) { data.position *= scale; } data.spacing = GetFloat(constraintMap, "spacing", 0); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) { data.spacing *= scale; } data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); data.translateMix = GetFloat(constraintMap, "translateMix", 1); skeletonData.pathConstraints.Add(data); } } // Skins. if (root.ContainsKey("skins")) { foreach (KeyValuePair <String, Object> skinMap in (Dictionary <String, Object>)root["skins"]) { var skin = new Skin(skinMap.Key); foreach (KeyValuePair <String, Object> slotEntry in (Dictionary <String, Object>)skinMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair <String, Object> entry in ((Dictionary <String, Object>)slotEntry.Value)) { try { Attachment attachment = ReadAttachment((Dictionary <String, Object>)entry.Value, skin, slotIndex, entry.Key); if (attachment != null) { skin.AddAttachment(slotIndex, entry.Key, attachment); } } catch (Exception e) { throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e); } } } skeletonData.skins.Add(skin); if (skin.name == "default") { skeletonData.defaultSkin = skin; } } } // Linked meshes. for (int i = 0, n = linkedMeshes.Count; i < n; i++) { LinkedMesh linkedMesh = linkedMeshes[i]; Skin skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.FindSkin(linkedMesh.skin); if (skin == null) { throw new Exception("Slot not found: " + linkedMesh.skin); } Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); if (parent == null) { throw new Exception("Parent mesh not found: " + linkedMesh.parent); } linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; linkedMesh.mesh.UpdateUVs(); } linkedMeshes.Clear(); // Events. if (root.ContainsKey("events")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["events"]) { var entryMap = (Dictionary <String, Object>)entry.Value; var data = new EventData(entry.Key); data.Int = GetInt(entryMap, "int", 0); data.Float = GetFloat(entryMap, "float", 0); data.String = GetString(entryMap, "string", null); skeletonData.events.Add(data); } } // Animations. if (root.ContainsKey("animations")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["animations"]) { try { ReadAnimation((Dictionary <String, Object>)entry.Value, entry.Key, skeletonData); } catch (Exception e) { throw new Exception("Error reading animation: " + entry.Key, e); } } } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.events.TrimExcess(); skeletonData.animations.TrimExcess(); skeletonData.ikConstraints.TrimExcess(); return(skeletonData); }
private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) { var timelines = new ExposedList<Timeline>(); float duration = 0; float scale = Scale; if (map.ContainsKey("slots")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); var timelineMap = (Dictionary<String, Object>)entry.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { var values = (List<Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "color") { var timeline = new ColorTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; String c = (String)valueMap["color"]; timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3)); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]); } else if (timelineName == "attachment") { var timeline = new AttachmentTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } else throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); } } } if (map.ContainsKey("bones")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) { String boneName = entry.Key; int boneIndex = skeletonData.FindBoneIndex(boneName); if (boneIndex == -1) throw new Exception("Bone not found: " + boneName); var timelineMap = (Dictionary<String, Object>)entry.Value; foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) { var values = (List<Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "rotate") { var timeline = new RotateTimeline(values.Count); timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]); } else if (timelineName == "translate" || timelineName == "scale") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") timeline = new ScaleTimeline(values.Count); else { timeline = new TranslateTimeline(values.Count); timelineScale = scale; } timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0; float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0; timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } else throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); } } } if (map.ContainsKey("ik")) { foreach (KeyValuePair<String, Object> ikMap in (Dictionary<String, Object>)map["ik"]) { IkConstraintData ikConstraint = skeletonData.FindIkConstraint(ikMap.Key); var values = (List<Object>)ikMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint); int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = valueMap.ContainsKey("mix") ? (float)valueMap["mix"] : 1; bool bendPositive = valueMap.ContainsKey("bendPositive") ? (bool)valueMap["bendPositive"] : true; timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } } if (map.ContainsKey("ffd")) { foreach (KeyValuePair<String, Object> ffdMap in (Dictionary<String, Object>)map["ffd"]) { Skin skin = skeletonData.FindSkin(ffdMap.Key); foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)ffdMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); foreach (KeyValuePair<String, Object> meshMap in (Dictionary<String, Object>)slotMap.Value) { var values = (List<Object>)meshMap.Value; var timeline = new FFDTimeline(values.Count); Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key); if (attachment == null) throw new Exception("FFD attachment not found: " + meshMap.Key); timeline.slotIndex = slotIndex; timeline.attachment = attachment; int vertexCount; if (attachment is MeshAttachment) vertexCount = ((MeshAttachment)attachment).vertices.Length; else vertexCount = ((WeightedMeshAttachment)attachment).Weights.Length / 3 * 2; int frameIndex = 0; foreach (Dictionary<String, Object> valueMap in values) { float[] vertices; if (!valueMap.ContainsKey("vertices")) { if (attachment is MeshAttachment) vertices = ((MeshAttachment)attachment).vertices; else vertices = new float[vertexCount]; } else { var verticesValue = (List<Object>)valueMap["vertices"]; vertices = new float[vertexCount]; int start = GetInt(valueMap, "offset", 0); if (scale == 1) { for (int i = 0, n = verticesValue.Count; i < n; i++) vertices[i + start] = (float)verticesValue[i]; } else { for (int i = 0, n = verticesValue.Count; i < n; i++) vertices[i + start] = (float)verticesValue[i] * scale; } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int i = 0; i < vertexCount; i++) vertices[i] += meshVertices[i]; } } timeline.SetFrame(frameIndex, (float)valueMap["time"], vertices); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } } } } if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { var values = (List<Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"]; var timeline = new DrawOrderTimeline(values.Count); int slotCount = skeletonData.slots.Count; int frameIndex = 0; foreach (Dictionary<String, Object> drawOrderMap in values) { int[] drawOrder = null; if (drawOrderMap.ContainsKey("offsets")) { drawOrder = new int[slotCount]; for (int i = slotCount - 1; i >= 0; i--) drawOrder[i] = -1; var offsets = (List<Object>)drawOrderMap["offsets"]; int[] unchanged = new int[slotCount - offsets.Count]; int originalIndex = 0, unchangedIndex = 0; foreach (Dictionary<String, Object> offsetMap in offsets) { int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]); if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]); // Collect unchanged items. while (originalIndex != slotIndex) unchanged[unchangedIndex++] = originalIndex++; // Set changed items. int index = originalIndex + (int)(float)offsetMap["offset"]; drawOrder[index] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) unchanged[unchangedIndex++] = originalIndex++; // Fill in unchanged items. for (int i = slotCount - 1; i >= 0; i--) if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex]; } timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } if (map.ContainsKey("events")) { var eventsMap = (List<Object>)map["events"]; var timeline = new EventTimeline(eventsMap.Count); int frameIndex = 0; foreach (Dictionary<String, Object> eventMap in eventsMap) { EventData eventData = skeletonData.FindEvent((String)eventMap["name"]); if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]); float time = (float)eventMap["time"]; var e = new Event(time, eventData); e.Int = GetInt(eventMap, "int", eventData.Int); e.Float = GetFloat(eventMap, "float", eventData.Float); e.String = GetString(eventMap, "string", eventData.String); timeline.SetFrame(frameIndex++, time, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
private void readAnimation(String name, Dictionary<String, Object> map, SkeletonData skeletonData) { var timelines = new List<Timeline>(); float duration = 0; 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(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 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) { 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)); }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader cannot be null."); } SkeletonData skeletonData = new SkeletonData(); Dictionary <string, object> dictionary = Json.Deserialize(reader) as Dictionary <string, object>; if (dictionary == null) { throw new Exception("Invalid JSON."); } if (dictionary.ContainsKey("skeleton")) { Dictionary <string, object> dictionary2 = (Dictionary <string, object>)dictionary.get_Item("skeleton"); skeletonData.hash = (string)dictionary2.get_Item("hash"); skeletonData.version = (string)dictionary2.get_Item("spine"); skeletonData.width = this.GetFloat(dictionary2, "width", 0f); skeletonData.height = this.GetFloat(dictionary2, "height", 0f); } List <object> list = (List <object>)dictionary.get_Item("bones"); for (int i = 0; i < list.get_Count(); i++) { Dictionary <string, object> dictionary3 = (Dictionary <string, object>)list.get_Item(i); BoneData boneData = null; if (dictionary3.ContainsKey("parent")) { boneData = skeletonData.FindBone((string)dictionary3.get_Item("parent")); if (boneData == null) { throw new Exception("Parent bone not found: " + dictionary3.get_Item("parent")); } } BoneData boneData2 = new BoneData((string)dictionary3.get_Item("name"), boneData); boneData2.length = this.GetFloat(dictionary3, "length", 0f) * this.Scale; boneData2.x = this.GetFloat(dictionary3, "x", 0f) * this.Scale; boneData2.y = this.GetFloat(dictionary3, "y", 0f) * this.Scale; boneData2.rotation = this.GetFloat(dictionary3, "rotation", 0f); boneData2.scaleX = this.GetFloat(dictionary3, "scaleX", 1f); boneData2.scaleY = this.GetFloat(dictionary3, "scaleY", 1f); boneData2.flipX = this.GetBoolean(dictionary3, "flipX", false); boneData2.flipY = this.GetBoolean(dictionary3, "flipY", false); boneData2.inheritScale = this.GetBoolean(dictionary3, "inheritScale", true); boneData2.inheritRotation = this.GetBoolean(dictionary3, "inheritRotation", true); skeletonData.bones.Add(boneData2); } if (dictionary.ContainsKey("ik")) { List <object> list2 = (List <object>)dictionary.get_Item("ik"); for (int j = 0; j < list2.get_Count(); j++) { Dictionary <string, object> dictionary4 = (Dictionary <string, object>)list2.get_Item(j); IkConstraintData ikConstraintData = new IkConstraintData((string)dictionary4.get_Item("name")); List <object> list3 = (List <object>)dictionary4.get_Item("bones"); for (int k = 0; k < list3.get_Count(); k++) { string text = (string)list3.get_Item(k); BoneData boneData3 = skeletonData.FindBone(text); if (boneData3 == null) { throw new Exception("IK bone not found: " + text); } ikConstraintData.bones.Add(boneData3); } string text2 = (string)dictionary4.get_Item("target"); ikConstraintData.target = skeletonData.FindBone(text2); if (ikConstraintData.target == null) { throw new Exception("Target bone not found: " + text2); } ikConstraintData.bendDirection = ((!this.GetBoolean(dictionary4, "bendPositive", true)) ? -1 : 1); ikConstraintData.mix = this.GetFloat(dictionary4, "mix", 1f); skeletonData.ikConstraints.Add(ikConstraintData); } } if (dictionary.ContainsKey("slots")) { List <object> list4 = (List <object>)dictionary.get_Item("slots"); for (int l = 0; l < list4.get_Count(); l++) { Dictionary <string, object> dictionary5 = (Dictionary <string, object>)list4.get_Item(l); string name = (string)dictionary5.get_Item("name"); string text3 = (string)dictionary5.get_Item("bone"); BoneData boneData4 = skeletonData.FindBone(text3); if (boneData4 == null) { throw new Exception("Slot bone not found: " + text3); } SlotData slotData = new SlotData(name, boneData4); if (dictionary5.ContainsKey("color")) { string hexString = (string)dictionary5.get_Item("color"); slotData.r = this.ToColor(hexString, 0); slotData.g = this.ToColor(hexString, 1); slotData.b = this.ToColor(hexString, 2); slotData.a = this.ToColor(hexString, 3); } if (dictionary5.ContainsKey("attachment")) { slotData.attachmentName = (string)dictionary5.get_Item("attachment"); } if (dictionary5.ContainsKey("blend")) { slotData.blendMode = (BlendMode)((int)Enum.Parse(typeof(BlendMode), (string)dictionary5.get_Item("blend"), false)); } else { slotData.blendMode = BlendMode.normal; } skeletonData.slots.Add(slotData); } } if (dictionary.ContainsKey("skins")) { using (Dictionary <string, object> .Enumerator enumerator = ((Dictionary <string, object>)dictionary.get_Item("skins")).GetEnumerator()) { while (enumerator.MoveNext()) { KeyValuePair <string, object> current = enumerator.get_Current(); Skin skin = new Skin(current.get_Key()); using (Dictionary <string, object> .Enumerator enumerator2 = ((Dictionary <string, object>)current.get_Value()).GetEnumerator()) { while (enumerator2.MoveNext()) { KeyValuePair <string, object> current2 = enumerator2.get_Current(); int slotIndex = skeletonData.FindSlotIndex(current2.get_Key()); using (Dictionary <string, object> .Enumerator enumerator3 = ((Dictionary <string, object>)current2.get_Value()).GetEnumerator()) { while (enumerator3.MoveNext()) { KeyValuePair <string, object> current3 = enumerator3.get_Current(); Attachment attachment = this.ReadAttachment(skin, current3.get_Key(), (Dictionary <string, object>)current3.get_Value()); if (attachment != null) { skin.AddAttachment(slotIndex, current3.get_Key(), attachment); } } } } } skeletonData.skins.Add(skin); if (skin.name == "default") { skeletonData.defaultSkin = skin; } } } } if (dictionary.ContainsKey("events")) { using (Dictionary <string, object> .Enumerator enumerator4 = ((Dictionary <string, object>)dictionary.get_Item("events")).GetEnumerator()) { while (enumerator4.MoveNext()) { KeyValuePair <string, object> current4 = enumerator4.get_Current(); Dictionary <string, object> map = (Dictionary <string, object>)current4.get_Value(); EventData eventData = new EventData(current4.get_Key()); eventData.Int = this.GetInt(map, "int", 0); eventData.Float = this.GetFloat(map, "float", 0f); eventData.String = this.GetString(map, "string", null); skeletonData.events.Add(eventData); } } } if (dictionary.ContainsKey("animations")) { using (Dictionary <string, object> .Enumerator enumerator5 = ((Dictionary <string, object>)dictionary.get_Item("animations")).GetEnumerator()) { while (enumerator5.MoveNext()) { KeyValuePair <string, object> current5 = enumerator5.get_Current(); this.ReadAnimation(current5.get_Key(), (Dictionary <string, object>)current5.get_Value(), skeletonData); } } } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.events.TrimExcess(); skeletonData.animations.TrimExcess(); skeletonData.ikConstraints.TrimExcess(); return(skeletonData); }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader cannot be null."); } var scale = this.Scale; var skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary <String, Object>; if (root == null) { throw new Exception("Invalid JSON."); } // Skeleton. if (root.ContainsKey("skeleton")) { var skeletonMap = (Dictionary <String, Object>)root["skeleton"]; skeletonData.hash = (String)skeletonMap["hash"]; skeletonData.version = (String)skeletonMap["spine"]; skeletonData.width = GetFloat(skeletonMap, "width", 0); skeletonData.height = GetFloat(skeletonMap, "height", 0); } // Bones. foreach (Dictionary <String, Object> boneMap in (List <Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) { throw new Exception("Parent bone not found: " + boneMap["parent"]); } } var boneData = new BoneData((String)boneMap["name"], parent); boneData.length = GetFloat(boneMap, "length", 0) * scale; boneData.x = GetFloat(boneMap, "x", 0) * scale; boneData.y = GetFloat(boneMap, "y", 0) * scale; boneData.rotation = GetFloat(boneMap, "rotation", 0); boneData.scaleX = GetFloat(boneMap, "scaleX", 1); boneData.scaleY = GetFloat(boneMap, "scaleY", 1); boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true); boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true); skeletonData.bones.Add(boneData); } // IK constraints. if (root.ContainsKey("ik")) { foreach (Dictionary <String, Object> ikMap in (List <Object>)root["ik"]) { IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]); foreach (String boneName in (List <Object>)ikMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) { throw new Exception("IK bone not found: " + boneName); } ikConstraintData.bones.Add(bone); } String targetName = (String)ikMap["target"]; ikConstraintData.target = skeletonData.FindBone(targetName); if (ikConstraintData.target == null) { throw new Exception("Target bone not found: " + targetName); } ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1; ikConstraintData.mix = GetFloat(ikMap, "mix", 1); skeletonData.ikConstraints.Add(ikConstraintData); } } // Transform constraints. if (root.ContainsKey("transform")) { foreach (Dictionary <String, Object> transformMap in (List <Object>)root["transform"]) { TransformConstraintData transformConstraintData = new TransformConstraintData((String)transformMap["name"]); String boneName = (String)transformMap["bone"]; transformConstraintData.bone = skeletonData.FindBone(boneName); if (transformConstraintData.bone == null) { throw new Exception("Bone not found: " + boneName); } String targetName = (String)transformMap["target"]; transformConstraintData.target = skeletonData.FindBone(targetName); if (transformConstraintData.target == null) { throw new Exception("Target bone not found: " + targetName); } transformConstraintData.translateMix = GetFloat(transformMap, "translateMix", 1); transformConstraintData.x = GetFloat(transformMap, "x", 0) * scale; transformConstraintData.y = GetFloat(transformMap, "y", 0) * scale; skeletonData.transformConstraints.Add(transformConstraintData); } } // Slots. if (root.ContainsKey("slots")) { foreach (Dictionary <String, Object> slotMap in (List <Object>)root["slots"]) { var slotName = (String)slotMap["name"]; var boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) { throw new Exception("Slot bone not found: " + boneName); } var slotData = new SlotData(slotName, boneData); if (slotMap.ContainsKey("color")) { var color = (String)slotMap["color"]; slotData.r = ToColor(color, 0); slotData.g = ToColor(color, 1); slotData.b = ToColor(color, 2); slotData.a = ToColor(color, 3); } if (slotMap.ContainsKey("attachment")) { slotData.attachmentName = (String)slotMap["attachment"]; } if (slotMap.ContainsKey("blend")) { slotData.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false); } else { slotData.blendMode = BlendMode.normal; } skeletonData.slots.Add(slotData); } } // Skins. if (root.ContainsKey("skins")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["skins"]) { var skin = new Skin(entry.Key); foreach (KeyValuePair <String, Object> slotEntry in (Dictionary <String, Object>)entry.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair <String, Object> attachmentEntry in ((Dictionary <String, Object>)slotEntry.Value)) { Attachment attachment = ReadAttachment(skin, slotIndex, attachmentEntry.Key, (Dictionary <String, Object>)attachmentEntry.Value); if (attachment != null) { skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment); } } } skeletonData.skins.Add(skin); if (skin.name == "default") { skeletonData.defaultSkin = skin; } } } // Linked meshes. for (int i = 0, n = linkedMeshes.Count; i < n; i++) { LinkedMesh linkedMesh = linkedMeshes[i]; Skin skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.FindSkin(linkedMesh.skin); if (skin == null) { throw new Exception("Slot not found: " + linkedMesh.skin); } Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); if (parent == null) { throw new Exception("Parent mesh not found: " + linkedMesh.parent); } if (linkedMesh.mesh is MeshAttachment) { MeshAttachment mesh = (MeshAttachment)linkedMesh.mesh; mesh.ParentMesh = (MeshAttachment)parent; mesh.UpdateUVs(); } else { WeightedMeshAttachment mesh = (WeightedMeshAttachment)linkedMesh.mesh; mesh.ParentMesh = (WeightedMeshAttachment)parent; mesh.UpdateUVs(); } } linkedMeshes.Clear(); // Events. if (root.ContainsKey("events")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["events"]) { var entryMap = (Dictionary <String, Object>)entry.Value; var eventData = new EventData(entry.Key); eventData.Int = GetInt(entryMap, "int", 0); eventData.Float = GetFloat(entryMap, "float", 0); eventData.String = GetString(entryMap, "string", null); skeletonData.events.Add(eventData); } } // Animations. if (root.ContainsKey("animations")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["animations"]) { ReadAnimation(entry.Key, (Dictionary <String, Object>)entry.Value, skeletonData); } } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.events.TrimExcess(); skeletonData.animations.TrimExcess(); skeletonData.ikConstraints.TrimExcess(); return(skeletonData); }
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)); }
public SkeletonData ReadSkeletonData (TextReader reader) { if (reader == null) throw new ArgumentNullException("reader", "reader cannot be null."); var scale = this.Scale; var skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary<String, Object>; if (root == null) throw new Exception("Invalid JSON."); // Skeleton. if (root.ContainsKey("skeleton")) { var skeletonMap = (Dictionary<String, Object>)root["skeleton"]; skeletonData.hash = (String)skeletonMap["hash"]; skeletonData.version = (String)skeletonMap["spine"]; skeletonData.width = GetFloat(skeletonMap, "width", 0); skeletonData.height = GetFloat(skeletonMap, "height", 0); skeletonData.fps = GetFloat(skeletonMap, "fps", 0); skeletonData.imagesPath = GetString(skeletonMap, "images", null); } // Bones. foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) throw new Exception("Parent bone not found: " + boneMap["parent"]); } var data = new BoneData(skeletonData.Bones.Count, (String)boneMap["name"], parent); data.length = GetFloat(boneMap, "length", 0) * scale; data.x = GetFloat(boneMap, "x", 0) * scale; data.y = GetFloat(boneMap, "y", 0) * scale; data.rotation = GetFloat(boneMap, "rotation", 0); data.scaleX = GetFloat(boneMap, "scaleX", 1); data.scaleY = GetFloat(boneMap, "scaleY", 1); data.shearX = GetFloat(boneMap, "shearX", 0); data.shearY = GetFloat(boneMap, "shearY", 0); string tm = GetString(boneMap, "transform", TransformMode.Normal.ToString()); data.transformMode = (TransformMode)Enum.Parse(typeof(TransformMode), tm, true); skeletonData.bones.Add(data); } // Slots. if (root.ContainsKey("slots")) { foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) { var slotName = (String)slotMap["name"]; var boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) throw new Exception("Slot bone not found: " + boneName); var data = new SlotData(skeletonData.Slots.Count, slotName, boneData); if (slotMap.ContainsKey("color")) { var color = (String)slotMap["color"]; data.r = ToColor(color, 0); data.g = ToColor(color, 1); data.b = ToColor(color, 2); data.a = ToColor(color, 3); } data.attachmentName = GetString(slotMap, "attachment", null); if (slotMap.ContainsKey("blend")) data.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false); else data.blendMode = BlendMode.normal; skeletonData.slots.Add(data); } } // IK constraints. if (root.ContainsKey("ik")) { foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["ik"]) { IkConstraintData data = new IkConstraintData((String)constraintMap["name"]); data.order = GetInt(constraintMap, "order", 0); foreach (String boneName in (List<Object>)constraintMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) throw new Exception("IK constraint bone not found: " + boneName); data.bones.Add(bone); } String targetName = (String)constraintMap["target"]; data.target = skeletonData.FindBone(targetName); if (data.target == null) throw new Exception("Target bone not found: " + targetName); data.bendDirection = GetBoolean(constraintMap, "bendPositive", true) ? 1 : -1; data.mix = GetFloat(constraintMap, "mix", 1); skeletonData.ikConstraints.Add(data); } } // Transform constraints. if (root.ContainsKey("transform")) { foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["transform"]) { TransformConstraintData data = new TransformConstraintData((String)constraintMap["name"]); data.order = GetInt(constraintMap, "order", 0); foreach (String boneName in (List<Object>)constraintMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) throw new Exception("Transform constraint bone not found: " + boneName); data.bones.Add(bone); } String targetName = (String)constraintMap["target"]; data.target = skeletonData.FindBone(targetName); if (data.target == null) throw new Exception("Target bone not found: " + targetName); data.offsetRotation = GetFloat(constraintMap, "rotation", 0); data.offsetX = GetFloat(constraintMap, "x", 0) * scale; data.offsetY = GetFloat(constraintMap, "y", 0) * scale; data.offsetScaleX = GetFloat(constraintMap, "scaleX", 0); data.offsetScaleY = GetFloat(constraintMap, "scaleY", 0); data.offsetShearY = GetFloat(constraintMap, "shearY", 0); data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); data.translateMix = GetFloat(constraintMap, "translateMix", 1); data.scaleMix = GetFloat(constraintMap, "scaleMix", 1); data.shearMix = GetFloat(constraintMap, "shearMix", 1); skeletonData.transformConstraints.Add(data); } } // Path constraints. if(root.ContainsKey("path")) { foreach (Dictionary<String, Object> constraintMap in (List<Object>)root["path"]) { PathConstraintData data = new PathConstraintData((String)constraintMap["name"]); data.order = GetInt(constraintMap, "order", 0); foreach (String boneName in (List<Object>)constraintMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) throw new Exception("Path bone not found: " + boneName); data.bones.Add(bone); } String targetName = (String)constraintMap["target"]; data.target = skeletonData.FindSlot(targetName); if (data.target == null) throw new Exception("Target slot not found: " + targetName); data.positionMode = (PositionMode)Enum.Parse(typeof(PositionMode), GetString(constraintMap, "positionMode", "percent"), true); data.spacingMode = (SpacingMode)Enum.Parse(typeof(SpacingMode), GetString(constraintMap, "spacingMode", "length"), true); data.rotateMode = (RotateMode)Enum.Parse(typeof(RotateMode), GetString(constraintMap, "rotateMode", "tangent"), true); data.offsetRotation = GetFloat(constraintMap, "rotation", 0); data.position = GetFloat(constraintMap, "position", 0); if (data.positionMode == PositionMode.Fixed) data.position *= scale; data.spacing = GetFloat(constraintMap, "spacing", 0); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) data.spacing *= scale; data.rotateMix = GetFloat(constraintMap, "rotateMix", 1); data.translateMix = GetFloat(constraintMap, "translateMix", 1); skeletonData.pathConstraints.Add(data); } } // Skins. if (root.ContainsKey("skins")) { foreach (KeyValuePair<String, Object> skinMap in (Dictionary<String, Object>)root["skins"]) { var skin = new Skin(skinMap.Key); foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)skinMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair<String, Object> entry in ((Dictionary<String, Object>)slotEntry.Value)) { try { Attachment attachment = ReadAttachment((Dictionary<String, Object>)entry.Value, skin, slotIndex, entry.Key); if (attachment != null) skin.AddAttachment(slotIndex, entry.Key, attachment); } catch (Exception e) { throw new Exception("Error reading attachment: " + entry.Key + ", skin: " + skin, e); } } } skeletonData.skins.Add(skin); if (skin.name == "default") skeletonData.defaultSkin = skin; } } // Linked meshes. for (int i = 0, n = linkedMeshes.Count; i < n; i++) { LinkedMesh linkedMesh = linkedMeshes[i]; Skin skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.FindSkin(linkedMesh.skin); if (skin == null) throw new Exception("Slot not found: " + linkedMesh.skin); Attachment parent = skin.GetAttachment(linkedMesh.slotIndex, linkedMesh.parent); if (parent == null) throw new Exception("Parent mesh not found: " + linkedMesh.parent); linkedMesh.mesh.ParentMesh = (MeshAttachment)parent; linkedMesh.mesh.UpdateUVs(); } linkedMeshes.Clear(); // Events. if (root.ContainsKey("events")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) { var entryMap = (Dictionary<String, Object>)entry.Value; var data = new EventData(entry.Key); data.Int = GetInt(entryMap, "int", 0); data.Float = GetFloat(entryMap, "float", 0); data.String = GetString(entryMap, "string", string.Empty); skeletonData.events.Add(data); } } // Animations. if (root.ContainsKey("animations")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"]) { try { ReadAnimation((Dictionary<String, Object>)entry.Value, entry.Key, skeletonData); } catch (Exception e) { throw new Exception("Error reading animation: " + entry.Key, e); } } } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.events.TrimExcess(); skeletonData.animations.TrimExcess(); skeletonData.ikConstraints.TrimExcess(); return skeletonData; }
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)); }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) throw new ArgumentNullException("reader cannot be null."); SkeletonData skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary<String, Object>; if (root == null) throw new Exception("Invalid JSON."); // Bones. foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) throw new Exception("Parent bone not found: " + boneMap["parent"]); } BoneData boneData = new BoneData((String)boneMap["name"], parent); boneData.Length = getFloat(boneMap, "length", 0) * Scale; boneData.X = getFloat(boneMap, "x", 0) * Scale; boneData.Y = getFloat(boneMap, "y", 0) * Scale; boneData.Rotation = getFloat(boneMap, "rotation", 0); boneData.ScaleX = getFloat(boneMap, "scaleX", 1); boneData.ScaleY = getFloat(boneMap, "scaleY", 1); skeletonData.AddBone(boneData); } // Slots. if (root.ContainsKey("slots")) { var slots = (List<Object>)root["slots"]; foreach (Dictionary<String, Object> slotMap in (List<Object>)slots) { String slotName = (String)slotMap["name"]; String boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) throw new Exception("Slot bone not found: " + boneName); SlotData slotData = new SlotData(slotName, boneData); if (slotMap.ContainsKey("color")) { String color = (String)slotMap["color"]; slotData.R = toColor(color, 0); slotData.G = toColor(color, 1); slotData.B = toColor(color, 2); slotData.A = toColor(color, 3); } if (slotMap.ContainsKey("attachment")) slotData.AttachmentName = (String)slotMap["attachment"]; skeletonData.AddSlot(slotData); } } // Skins. if (root.ContainsKey("skins")) { Dictionary<String, Object> skinMap = (Dictionary<String, Object>)root["skins"]; foreach (KeyValuePair<String, Object> entry in skinMap) { Skin skin = new Skin(entry.Key); foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)entry.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair<String, Object> attachmentEntry in ((Dictionary<String, Object>)slotEntry.Value)) { Attachment attachment = readAttachment(skin, attachmentEntry.Key, (Dictionary<String, Object>)attachmentEntry.Value); skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment); } } skeletonData.AddSkin(skin); if (skin.Name == "default") skeletonData.DefaultSkin = skin; } } // Animations. if (root.ContainsKey("animations")) { Dictionary<String, Object> animationMap = (Dictionary<String, Object>)root["animations"]; foreach (KeyValuePair<String, Object> entry in animationMap) readAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData); } skeletonData.Bones.TrimExcess(); skeletonData.Slots.TrimExcess(); skeletonData.Skins.TrimExcess(); skeletonData.Animations.TrimExcess(); return skeletonData; }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader cannot be null."); } SkeletonData skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary <String, Object>; if (root == null) { throw new Exception("Invalid JSON."); } // Bones. foreach (Dictionary <String, Object> boneMap in (List <Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) { throw new Exception("Parent bone not found: " + boneMap["parent"]); } } BoneData boneData = new BoneData((String)boneMap["name"], parent); boneData.Length = GetFloat(boneMap, "length", 0) * Scale; boneData.X = GetFloat(boneMap, "x", 0) * Scale; boneData.Y = GetFloat(boneMap, "y", 0) * Scale; boneData.Rotation = GetFloat(boneMap, "rotation", 0); boneData.ScaleX = GetFloat(boneMap, "scaleX", 1); boneData.ScaleY = GetFloat(boneMap, "scaleY", 1); boneData.InheritScale = GetBoolean(boneMap, "inheritScale", true); boneData.InheritRotation = GetBoolean(boneMap, "inheritRotation", true); skeletonData.AddBone(boneData); } // Slots. if (root.ContainsKey("slots")) { var slots = (List <Object>)root["slots"]; foreach (Dictionary <String, Object> slotMap in (List <Object>)slots) { String slotName = (String)slotMap["name"]; String boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) { throw new Exception("Slot bone not found: " + boneName); } SlotData slotData = new SlotData(slotName, boneData); if (slotMap.ContainsKey("color")) { String color = (String)slotMap["color"]; slotData.R = ToColor(color, 0); slotData.G = ToColor(color, 1); slotData.B = ToColor(color, 2); slotData.A = ToColor(color, 3); } if (slotMap.ContainsKey("attachment")) { slotData.AttachmentName = (String)slotMap["attachment"]; } skeletonData.AddSlot(slotData); } } // Skins. if (root.ContainsKey("skins")) { var skinMap = (Dictionary <String, Object>)root["skins"]; foreach (KeyValuePair <String, Object> entry in skinMap) { Skin skin = new Skin(entry.Key); foreach (KeyValuePair <String, Object> slotEntry in (Dictionary <String, Object>)entry.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair <String, Object> attachmentEntry in ((Dictionary <String, Object>)slotEntry.Value)) { Attachment attachment = ReadAttachment(skin, attachmentEntry.Key, (Dictionary <String, Object>)attachmentEntry.Value); skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment); } } skeletonData.AddSkin(skin); if (skin.Name == "default") { skeletonData.DefaultSkin = skin; } } } // Animations. if (root.ContainsKey("animations")) { var animationMap = (Dictionary <String, Object>)root["animations"]; foreach (KeyValuePair <String, Object> entry in animationMap) { ReadAnimation(entry.Key, (Dictionary <String, Object>)entry.Value, skeletonData); } } skeletonData.Bones.TrimExcess(); skeletonData.Slots.TrimExcess(); skeletonData.Skins.TrimExcess(); skeletonData.Animations.TrimExcess(); return(skeletonData); }
public SkeletonData ReadSkeletonData (TextReader reader) { if (reader == null) throw new ArgumentNullException("reader cannot be null."); var skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary<String, Object>; if (root == null) throw new Exception("Invalid JSON."); // Skeleton. if (root.ContainsKey("skeleton")) { var skeletonMap = (Dictionary<String, Object>)root["skeleton"]; skeletonData.hash = (String)skeletonMap["hash"]; skeletonData.version = (String)skeletonMap["spine"]; skeletonData.width = GetFloat(skeletonMap, "width", 0); skeletonData.height = GetFloat(skeletonMap, "height", 0); } // Bones. foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) throw new Exception("Parent bone not found: " + boneMap["parent"]); } var boneData = new BoneData((String)boneMap["name"], parent); boneData.length = GetFloat(boneMap, "length", 0) * Scale; boneData.x = GetFloat(boneMap, "x", 0) * Scale; boneData.y = GetFloat(boneMap, "y", 0) * Scale; boneData.rotation = GetFloat(boneMap, "rotation", 0); boneData.scaleX = GetFloat(boneMap, "scaleX", 1); boneData.scaleY = GetFloat(boneMap, "scaleY", 1); boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true); boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true); skeletonData.bones.Add(boneData); } // IK constraints. if (root.ContainsKey("ik")) { foreach (Dictionary<String, Object> ikMap in (List<Object>)root["ik"]) { IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]); foreach (String boneName in (List<Object>)ikMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) throw new Exception("IK bone not found: " + boneName); ikConstraintData.bones.Add(bone); } String targetName = (String)ikMap["target"]; ikConstraintData.target = skeletonData.FindBone(targetName); if (ikConstraintData.target == null) throw new Exception("Target bone not found: " + targetName); ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1; ikConstraintData.mix = GetFloat(ikMap, "mix", 1); skeletonData.ikConstraints.Add(ikConstraintData); } } // Transform constraints. if (root.ContainsKey("transform")) { foreach (Dictionary<String, Object> transformMap in (List<Object>)root["ik"]) { TransformConstraintData transformConstraintData = new TransformConstraintData((String)transformMap["name"]); String boneName = (String)transformMap["bone"]; transformConstraintData.target = skeletonData.FindBone(boneName); if (transformConstraintData.target == null) throw new Exception("Bone not found: " + boneName); String targetName = (String)transformMap["target"]; transformConstraintData.target = skeletonData.FindBone(targetName); if (transformConstraintData.target == null) throw new Exception("Target bone not found: " + targetName); transformConstraintData.translateMix = GetFloat(transformMap, "mix", 1); transformConstraintData.x = GetFloat(transformMap, "x", 0); transformConstraintData.y = GetFloat(transformMap, "y", 0); skeletonData.transformConstraints.Add(transformConstraintData); } } // Slots. if (root.ContainsKey("slots")) { foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) { var slotName = (String)slotMap["name"]; var boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) throw new Exception("Slot bone not found: " + boneName); var slotData = new SlotData(slotName, boneData); if (slotMap.ContainsKey("color")) { var color = (String)slotMap["color"]; slotData.r = ToColor(color, 0); slotData.g = ToColor(color, 1); slotData.b = ToColor(color, 2); slotData.a = ToColor(color, 3); } if (slotMap.ContainsKey("attachment")) slotData.attachmentName = (String)slotMap["attachment"]; if (slotMap.ContainsKey("blend")) slotData.blendMode = (BlendMode)Enum.Parse(typeof(BlendMode), (String)slotMap["blend"], false); else slotData.blendMode = BlendMode.normal; skeletonData.slots.Add(slotData); } } // Skins. if (root.ContainsKey("skins")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["skins"]) { var skin = new Skin(entry.Key); foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)entry.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair<String, Object> attachmentEntry in ((Dictionary<String, Object>)slotEntry.Value)) { Attachment attachment = ReadAttachment(skin, attachmentEntry.Key, (Dictionary<String, Object>)attachmentEntry.Value); if (attachment != null) skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment); } } skeletonData.skins.Add(skin); if (skin.name == "default") skeletonData.defaultSkin = skin; } } // Events. if (root.ContainsKey("events")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) { var entryMap = (Dictionary<String, Object>)entry.Value; var eventData = new EventData(entry.Key); eventData.Int = GetInt(entryMap, "int", 0); eventData.Float = GetFloat(entryMap, "float", 0); eventData.String = GetString(entryMap, "string", null); skeletonData.events.Add(eventData); } } // Animations. if (root.ContainsKey("animations")) { foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"]) ReadAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData); } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.events.TrimExcess(); skeletonData.animations.TrimExcess(); skeletonData.ikConstraints.TrimExcess(); return skeletonData; }
public SkeletonData ReadSkeletonData(TextReader reader) { if (reader == null) { throw new ArgumentNullException("reader cannot be null."); } var skeletonData = new SkeletonData(); var root = Json.Deserialize(reader) as Dictionary <String, Object>; if (root == null) { throw new Exception("Invalid JSON."); } // Skeleton. if (root.ContainsKey("skeleton")) { var skeletonMap = (Dictionary <String, Object>)root["skeleton"]; skeletonData.hash = (String)skeletonMap["hash"]; skeletonData.version = (String)skeletonMap["spine"]; skeletonData.width = GetFloat(skeletonMap, "width", 0); skeletonData.height = GetFloat(skeletonMap, "height", 0); } // Bones. foreach (Dictionary <String, Object> boneMap in (List <Object>)root["bones"]) { BoneData parent = null; if (boneMap.ContainsKey("parent")) { parent = skeletonData.FindBone((String)boneMap["parent"]); if (parent == null) { throw new Exception("Parent bone not found: " + boneMap["parent"]); } } var boneData = new BoneData((String)boneMap["name"], parent); boneData.length = GetFloat(boneMap, "length", 0) * Scale; boneData.x = GetFloat(boneMap, "x", 0) * Scale; boneData.y = GetFloat(boneMap, "y", 0) * Scale; boneData.rotation = GetFloat(boneMap, "rotation", 0); boneData.scaleX = GetFloat(boneMap, "scaleX", 1); boneData.scaleY = GetFloat(boneMap, "scaleY", 1); boneData.flipX = GetBoolean(boneMap, "flipX", false); boneData.flipY = GetBoolean(boneMap, "flipY", false); boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true); boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true); skeletonData.bones.Add(boneData); } // IK constraints. if (root.ContainsKey("ik")) { foreach (Dictionary <String, Object> ikMap in (List <Object>)root["ik"]) { IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]); foreach (String boneName in (List <Object>)ikMap["bones"]) { BoneData bone = skeletonData.FindBone(boneName); if (bone == null) { throw new Exception("IK bone not found: " + boneName); } ikConstraintData.bones.Add(bone); } String targetName = (String)ikMap["target"]; ikConstraintData.target = skeletonData.FindBone(targetName); if (ikConstraintData.target == null) { throw new Exception("Target bone not found: " + targetName); } ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1; ikConstraintData.mix = GetFloat(ikMap, "mix", 1); skeletonData.ikConstraints.Add(ikConstraintData); } } // Slots. if (root.ContainsKey("slots")) { foreach (Dictionary <String, Object> slotMap in (List <Object>)root["slots"]) { var slotName = (String)slotMap["name"]; var boneName = (String)slotMap["bone"]; BoneData boneData = skeletonData.FindBone(boneName); if (boneData == null) { throw new Exception("Slot bone not found: " + boneName); } var slotData = new SlotData(slotName, boneData); if (slotMap.ContainsKey("color")) { var color = (String)slotMap["color"]; slotData.r = ToColor(color, 0); slotData.g = ToColor(color, 1); slotData.b = ToColor(color, 2); slotData.a = ToColor(color, 3); } if (slotMap.ContainsKey("attachment")) { slotData.attachmentName = (String)slotMap["attachment"]; } if (slotMap.ContainsKey("additive")) { slotData.additiveBlending = (bool)slotMap["additive"]; } skeletonData.slots.Add(slotData); } } // Skins. if (root.ContainsKey("skins")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["skins"]) { var skin = new Skin(entry.Key); foreach (KeyValuePair <String, Object> slotEntry in (Dictionary <String, Object>)entry.Value) { int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key); foreach (KeyValuePair <String, Object> attachmentEntry in ((Dictionary <String, Object>)slotEntry.Value)) { Attachment attachment = ReadAttachment(skin, attachmentEntry.Key, (Dictionary <String, Object>)attachmentEntry.Value); if (attachment != null) { skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment); } } } skeletonData.skins.Add(skin); if (skin.name == "default") { skeletonData.defaultSkin = skin; } } } // Events. if (root.ContainsKey("events")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["events"]) { var entryMap = (Dictionary <String, Object>)entry.Value; var eventData = new EventData(entry.Key); eventData.Int = GetInt(entryMap, "int", 0); eventData.Float = GetFloat(entryMap, "float", 0); eventData.String = GetString(entryMap, "string", null); skeletonData.events.Add(eventData); } } // Animations. if (root.ContainsKey("animations")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)root["animations"]) { ReadAnimation(entry.Key, (Dictionary <String, Object>)entry.Value, skeletonData); } } skeletonData.bones.TrimExcess(); skeletonData.slots.TrimExcess(); skeletonData.skins.TrimExcess(); skeletonData.animations.TrimExcess(); return(skeletonData); }
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)); }
/// <returns>May be null.</returns> public Attachment GetAttachment(String slotName, String attachmentName) { return(GetAttachment(data.FindSlotIndex(slotName), attachmentName)); }
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)); }