private void ReadVertices (Dictionary<String, Object> map, VertexAttachment attachment, int verticesLength) { attachment.WorldVerticesLength = verticesLength; float[] vertices = GetFloatArray(map, "vertices", 1); float scale = Scale; if (verticesLength == vertices.Length) { if (scale != 1) { for (int i = 0; i < vertices.Length; i++) { vertices[i] *= scale; } } attachment.vertices = vertices; return; } ExposedList<float> weights = new ExposedList<float>(verticesLength * 3 * 3); ExposedList<int> bones = new ExposedList<int>(verticesLength * 3); for (int i = 0, n = vertices.Length; i < n;) { int boneCount = (int)vertices[i++]; bones.Add(boneCount); for (int nn = i + boneCount * 4; i < nn; i += 4) { bones.Add((int)vertices[i]); weights.Add(vertices[i + 1] * this.Scale); weights.Add(vertices[i + 2] * this.Scale); weights.Add(vertices[i + 3]); } } attachment.bones = bones.ToArray(); attachment.vertices = weights.ToArray(); }
/// <summary>Returns true if a deform originally applied to the specified attachment should be applied to this attachment.</summary> virtual public bool ApplyDeform (VertexAttachment sourceAttachment) { return this == sourceAttachment; }
override public bool ApplyDeform (VertexAttachment sourceAttachment) { return this == sourceAttachment || (inheritDeform && parentMesh == sourceAttachment); }
private void ReadAnimation(String name, Stream input, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int slotIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case SLOT_COLOR: { ColorTimeline timeline = new ColorTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); int color = ReadInt(input); float r = ((color & 0xff000000) >> 24) / 255f; float g = ((color & 0x00ff0000) >> 16) / 255f; float b = ((color & 0x0000ff00) >> 8) / 255f; float a = ((color & 0x000000ff)) / 255f; timeline.SetFrame(frameIndex, time, r, g, b, a); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); break; } case SLOT_ATTACHMENT: { AttachmentTimeline timeline = new AttachmentTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input)); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); break; } } } } // Bone timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int boneIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case BONE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { timeline = new ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { timeline = new ShearTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]); break; } } } } // IK timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]); } // Transform constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); timeline.transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); } // Path constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); PathConstraintData data = skeletonData.pathConstraints.Items[index]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = ReadSByte(input); int frameCount = ReadVarint(input, true); switch (timelineType) { case PATH_POSITION: case PATH_SPACING: { PathConstraintPositionTimeline timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { timeline = new PathConstraintSpacingTimeline(frameCount); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) { timelineScale = scale; } } else { timeline = new PathConstraintPositionTimeline(frameCount); if (data.positionMode == PositionMode.Fixed) { timelineScale = scale; } } timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); break; } case PATH_MIX: { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); break; } } } } // Deform timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadVarint(input, true)]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int slotIndex = ReadVarint(input, true); for (int iii = 0, nnn = ReadVarint(input, true); iii < nnn; iii++) { VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, ReadString(input)); bool weighted = attachment.bones != null; float[] vertices = attachment.vertices; int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; int frameCount = ReadVarint(input, true); DeformTimeline timeline = new DeformTimeline(frameCount, skin); timeline.slotIndex = slotIndex; timeline.attachment = attachment; float[] originalVerts; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] deform; int start = 0; int end = ReadVarint(input, true); originalVerts = new float[end - start]; if (end == 0) { deform = weighted ? new float[deformLength] : vertices; } else { deform = new float[deformLength]; start = ReadVarint(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) { deform[v] = ReadFloat(input); originalVerts[v - start] = deform[v] / scale; } } else { for (int v = start; v < end; v++) { deform[v] = ReadFloat(input) * scale; originalVerts[v - start] = deform[v] / scale; } } if (!weighted) { for (int v = 0, vn = deform.Length; v < vn; v++) { deform[v] += vertices[v]; } } } timeline.SetFrame(frameIndex, time, deform, originalVerts, start); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadVarint(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int[] offsets = null; int slotCount = skeletonData.slots.Count; offsets = new int[slotCount]; for (int i = 0; i < drawOrderCount; i++) { float time = ReadFloat(input); int offsetCount = ReadVarint(input, true); int[] drawOrder = new int[slotCount]; for (int ii = slotCount - 1; ii >= 0; ii--) { drawOrder[ii] = -1; } int[] unchanged = new int[slotCount - offsetCount]; int originalIndex = 0, unchangedIndex = 0; for (int ii = 0; ii < offsetCount; ii++) { int slotIndex = ReadVarint(input, true); // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. int offset = ReadVarint(input, true); offsets[originalIndex] = offset; drawOrder[originalIndex + offset] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int ii = slotCount - 1; ii >= 0; ii--) { if (drawOrder[ii] == -1) { drawOrder[ii] = unchanged[--unchangedIndex]; } } timeline.SetFrame(i, time, drawOrder, offsets); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadVarint(input, true); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = ReadFloat(input); EventData eventData = skeletonData.events.Items[ReadVarint(input, true)]; Event e = new Event(time, eventData); e.Int = ReadVarint(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[eventCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
public static bool IsWeighted(this VertexAttachment va) { return(va.bones != null && va.bones.Length > 0); }
private void ReadAnimation(IDictionary <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 (IDictionary <String, Object>)map["slots"]) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); var timelineMap = (IDictionary <String, Object>)entry.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (IList <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "color") { var timeline = new ColorTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (IDictionary <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 (IDictionary <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 (IDictionary <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 = (IDictionary <String, Object>)entry.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (IList <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "rotate") { var timeline = new RotateTimeline(values.Count); timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (IDictionary <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 (IDictionary <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 (IDictionary <String, Object>)map["ik"]) { IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key); var values = (IList <Object>)constraintMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint); int frameIndex = 0; foreach (IDictionary <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(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 (IDictionary <String, Object>)map["transform"]) { TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key); var values = (IList <Object>)constraintMap.Value; var timeline = new TransformConstraintTimeline(values.Count); timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint); int frameIndex = 0; foreach (IDictionary <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 (IDictionary <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 = (IDictionary <String, Object>)constraintMap.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (IList <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 (IDictionary <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 (IDictionary <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 (IDictionary <String, Object>)map["deform"]) { Skin skin = skeletonData.FindSkin(deformMap.Key); foreach (KeyValuePair <String, Object> slotMap in (IDictionary <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 (IDictionary <String, Object>)slotMap.Value) { var values = (IList <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 (IDictionary <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 = (IList <Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"]; var timeline = new DrawOrderTimeline(values.Count); int slotCount = skeletonData.slots.Count; int frameIndex = 0; foreach (IDictionary <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 = (IList <Object>)drawOrderMap["offsets"]; int[] unchanged = new int[slotCount - offsets.Count]; int originalIndex = 0, unchangedIndex = 0; foreach (IDictionary <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 = (IList <Object>)map["events"]; var timeline = new EventTimeline(eventsMap.Count); int frameIndex = 0; foreach (IDictionary <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)); }
override public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha) { Slot slot = skeleton.slots.Items[slotIndex]; VertexAttachment slotAttachment = slot.attachment as VertexAttachment; if (slotAttachment == null || !slotAttachment.ApplyDeform(attachment)) { return; } float[] frames = this.frames; if (time < frames[0]) { return; // Time is before first frame. } float[][] frameVertices = this.frameVertices; int vertexCount = frameVertices[0].Length; var verticesArray = slot.attachmentVertices; if (verticesArray.Count != vertexCount) { alpha = 1; // Don't mix from uninitialized slot vertices. } // verticesArray.SetSize(vertexCount) // Ensure size and preemptively set count. if (verticesArray.Capacity < vertexCount) { verticesArray.Capacity = vertexCount; } verticesArray.Count = vertexCount; float[] vertices = verticesArray.Items; if (time >= frames[frames.Length - 1]) // Time is after last frame. { float[] lastVertices = frameVertices[frames.Length - 1]; if (alpha < 1) { for (int i = 0; i < vertexCount; i++) { float vertex = vertices[i]; vertices[i] = vertex + (lastVertices[i] - vertex) * alpha; } } else { Array.Copy(lastVertices, 0, vertices, 0, vertexCount); } return; } // Interpolate between the previous frame and the current frame. int frame = Animation.binarySearch(frames, time); float[] prevVertices = frameVertices[frame - 1]; float[] nextVertices = frameVertices[frame]; float frameTime = frames[frame]; float percent = GetCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); if (alpha < 1) { for (int i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; float vertex = vertices[i]; vertices[i] = vertex + (prev + (nextVertices[i] - prev) * percent - vertex) * alpha; } } else { for (int i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; vertices[i] = prev + (nextVertices[i] - prev) * percent; } } }
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)); }
override public bool ApplyDeform(VertexAttachment sourceAttachment) { return(this == sourceAttachment || (inheritDeform && parentMesh == sourceAttachment)); }
/// <summary>Returns true if a deform originally applied to the specified attachment should be applied to this attachment.</summary> virtual public bool ApplyDeform(VertexAttachment sourceAttachment) { return(this == sourceAttachment); }