static int Add(IntPtr L) { try { ToLua.CheckArgsCount(L, 2); Spine.ExposedList <Spine.Animation> obj = (Spine.ExposedList <Spine.Animation>)ToLua.CheckObject <Spine.ExposedList <Spine.Animation> >(L, 1); Spine.Animation arg0 = (Spine.Animation)ToLua.CheckObject <Spine.Animation>(L, 2); obj.Add(arg0); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha) { if (firedEvents == null) { return; } float[] array = this.frames; int num = array.Length; if (lastTime > time) { this.Apply(skeleton, lastTime, 2.14748365E+09f, firedEvents, alpha); lastTime = -1f; } else if (lastTime >= array[num - 1]) { return; } if (time < array[0]) { return; } int i; if (lastTime < array[0]) { i = 0; } else { i = Animation.binarySearch(array, lastTime); float num2 = array[i]; while (i > 0) { if (array[i - 1] != num2) { break; } i--; } } while (i < num && time >= array[i]) { firedEvents.Add(this.events[i]); i++; } }
/// <summary>Fires events for frames > lastTime and <= time.</summary> public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha) { if (firedEvents == null) { return; } float[] frames = this.frames; int frameCount = frames.Length; if (lastTime > time) // Fire events after last time for looped animations. { Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha); lastTime = -1f; } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame. { return; } if (time < frames[0]) { return; // Time is before first frame. } int frame; if (lastTime < frames[0]) { frame = 0; } else { frame = Animation.binarySearch(frames, lastTime); float frameTime = frames[frame]; while (frame > 0) // Fire multiple events with the same frame. { if (frames[frame - 1] != frameTime) { break; } frame--; } } for (; frame < frameCount && time >= frames[frame]; frame++) { firedEvents.Add(events[frame]); } }
public Skeleton(SkeletonData data) { if (data == null) { throw new ArgumentNullException("data cannot be null."); } this.data = data; bones = new ExposedList <Bone>(data.bones.Count); foreach (BoneData boneData in data.bones) { Bone parent = boneData.parent == null ? null : bones.Items[data.bones.IndexOf(boneData.parent)]; Bone bone = new Bone(boneData, this, parent); if (parent != null) { parent.children.Add(bone); } bones.Add(bone); } slots = new ExposedList <Slot>(data.slots.Count); drawOrder = new ExposedList <Slot>(data.slots.Count); foreach (SlotData slotData in data.slots) { Bone bone = bones.Items[data.bones.IndexOf(slotData.boneData)]; Slot slot = new Slot(slotData, bone); slots.Add(slot); drawOrder.Add(slot); } ikConstraints = new ExposedList <IkConstraint>(data.ikConstraints.Count); foreach (IkConstraintData ikConstraintData in data.ikConstraints) { ikConstraints.Add(new IkConstraint(ikConstraintData, this)); } transformConstraints = new ExposedList <TransformConstraint>(data.transformConstraints.Count); foreach (TransformConstraintData transformConstraintData in data.transformConstraints) { transformConstraints.Add(new TransformConstraint(transformConstraintData, this)); } UpdateCache(); UpdateWorldTransform(); }
public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha, MixPose pose, MixDirection direction) { if (firedEvents != null) { float[] frames = this.frames; int length = frames.Length; if (lastTime > time) { this.Apply(skeleton, lastTime, 2.147484E+09f, firedEvents, alpha, pose, direction); lastTime = -1f; } else if (lastTime >= frames[length - 1]) { return; } if (time >= frames[0]) { int num2; if (lastTime < frames[0]) { num2 = 0; } else { num2 = Animation.BinarySearch(frames, lastTime); float num3 = frames[num2]; while (num2 > 0) { if (frames[num2 - 1] != num3) { break; } num2--; } } while ((num2 < length) && (time >= frames[num2])) { firedEvents.Add(this.events[num2]); num2++; } } } }
public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha) { float[] array = this.frames; if (time < array[0]) { return; } int num; if (time >= array[array.Length - 1]) { num = array.Length - 1; } else { num = Animation.binarySearch(array, time) - 1; } ExposedList <Slot> drawOrder = skeleton.drawOrder; ExposedList <Slot> slots = skeleton.slots; int[] array2 = this.drawOrders[num]; if (array2 == null) { drawOrder.Clear(true); int i = 0; int count = slots.Count; while (i < count) { drawOrder.Add(slots.Items[i]); i++; } } else { int j = 0; int num2 = array2.Length; while (j < num2) { drawOrder.Items[j] = slots.Items[array2[j]]; j++; } } }
public void SetSlotsToSetupPose() { ExposedList <Slot> exposedList = slots; Slot[] items = exposedList.Items; drawOrder.Clear(); int i = 0; for (int count = exposedList.Count; i < count; i++) { drawOrder.Add(items[i]); } int j = 0; for (int count2 = exposedList.Count; j < count2; j++) { items[j].SetToSetupPose(); } }
public IkConstraint(IkConstraintData data, Skeleton skeleton) { if (data == null) { throw new ArgumentNullException("data", "data cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton", "skeleton cannot be null."); } this.data = data; mix = data.mix; bendDirection = data.bendDirection; bones = new ExposedList <Bone>(data.bones.Count); foreach (BoneData bone in data.bones) { bones.Add(skeleton.FindBone(bone.name)); } target = skeleton.FindBone(data.target.name); }
public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha, MixPose pose, MixDirection direction) { ExposedList <Slot> drawOrder = skeleton.drawOrder; ExposedList <Slot> slots = skeleton.slots; if (direction == MixDirection.Out && pose == MixPose.Setup) { Array.Copy(slots.Items, 0, drawOrder.Items, 0, slots.Count); return; } float[] array = frames; if (time < array[0]) { if (pose == MixPose.Setup) { Array.Copy(slots.Items, 0, drawOrder.Items, 0, slots.Count); } return; } int num = (!(time >= array[array.Length - 1])) ? (Animation.BinarySearch(array, time) - 1) : (array.Length - 1); int[] array2 = drawOrders[num]; if (array2 == null) { drawOrder.Clear(); int i = 0; for (int count = slots.Count; i < count; i++) { drawOrder.Add(slots.Items[i]); } return; } Slot[] items = drawOrder.Items; Slot[] items2 = slots.Items; int j = 0; for (int num2 = array2.Length; j < num2; j++) { items[j] = items2[array2[j]]; } }
void ReadTransformAnimation(ref ExposedList <Timeline> timelines, SkeletonDataStream input, ref float duration, float scale) { // Transform constraint timelines. for (int i = 0, n = SkeletonDataStream.sp_readVarint(input.ptr, 1); i < n; i++) { int index = SkeletonDataStream.sp_readVarint(input.ptr, 1); int frameCount = SkeletonDataStream.sp_readVarint(input.ptr, 1); TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); timeline.transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr)); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); } }
public void Apply(Skeleton skeleton, float lastTime, float time, ExposedList <Event> firedEvents, float alpha) { float[] frames = this.frames; if (time < frames[0]) { return; // Time is before first frame. } int frame; if (time >= frames[frames.Length - 1]) // Time is after last frame. { frame = frames.Length - 1; } else { frame = Animation.binarySearch(frames, time) - 1; } ExposedList <Slot> drawOrder = skeleton.drawOrder; ExposedList <Slot> slots = skeleton.slots; int[] drawOrderToSetupIndex = drawOrders[frame]; if (drawOrderToSetupIndex == null) { drawOrder.Clear(); for (int i = 0, n = slots.Count; i < n; i++) { drawOrder.Add(slots.Items[i]); } } else { var drawOrderItems = drawOrder.Items; var slotsItems = slots.Items; for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) { drawOrderItems[i] = slotsItems[drawOrderToSetupIndex[i]]; } } }
void ReadEventAnimation(ref ExposedList <Timeline> timelines, SkeletonDataStream input, ref float duration, float scale, ref SkeletonData skeletonData) { // Event timeline. int eventCount = SkeletonDataStream.sp_readVarint(input.ptr, 1); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = SkeletonDataStream.sp_readFloat(input.ptr); EventData eventData = skeletonData.events.Items[SkeletonDataStream.sp_readVarint(input.ptr, 1)]; Event e = new Event(time, eventData); e.Int = SkeletonDataStream.sp_readVarint(input.ptr, 0); e.Float = SkeletonDataStream.sp_readFloat(input.ptr); e.String = input.ReadBoolean() ? input.ReadString() : eventData.String; timeline.SetFrame(i, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[eventCount - 1]); } }
public PathConstraint(PathConstraintData data, Skeleton skeleton) { if (data == null) { throw new ArgumentNullException("data", "data cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton", "skeleton cannot be null."); } this.data = data; bones = new ExposedList <Bone>(data.Bones.Count); foreach (BoneData boneData in data.bones) { bones.Add(skeleton.FindBone(boneData.name)); } target = skeleton.FindSlot(data.target.name); position = data.position; spacing = data.spacing; rotateMix = data.rotateMix; translateMix = data.translateMix; }
/// <summary>Copy constructor.</summary> public PathConstraint(PathConstraint constraint, Skeleton skeleton) { if (constraint == null) { throw new ArgumentNullException("constraint cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton cannot be null."); } data = constraint.data; bones = new ExposedList <Bone>(constraint.Bones.Count); foreach (Bone bone in constraint.Bones) { bones.Add(skeleton.Bones.Items[bone.data.index]); } target = skeleton.slots.Items[constraint.target.data.index]; position = constraint.position; spacing = constraint.spacing; rotateMix = constraint.rotateMix; translateMix = constraint.translateMix; }
/// <summary>Copy constructor.</summary> public IkConstraint(IkConstraint constraint, Skeleton skeleton) { if (constraint == null) { throw new ArgumentNullException("constraint cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton cannot be null."); } data = constraint.data; bones = new ExposedList <Bone>(constraint.Bones.Count); foreach (Bone bone in constraint.Bones) { bones.Add(skeleton.Bones.Items[bone.data.index]); } target = skeleton.Bones.Items[constraint.target.data.index]; mix = constraint.mix; bendDirection = constraint.bendDirection; compress = constraint.compress; stretch = constraint.stretch; }
public TransformConstraint(TransformConstraintData data, Skeleton skeleton) { if (data == null) { throw new ArgumentNullException("data", "data cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton", "skeleton cannot be null."); } this.data = data; rotateMix = data.rotateMix; translateMix = data.translateMix; scaleMix = data.scaleMix; shearMix = data.shearMix; bones = new ExposedList <Bone>(); foreach (BoneData bone in data.bones) { bones.Add(skeleton.FindBone(bone.name)); } target = skeleton.FindBone(data.target.name); }
/// <summary>Copy constructor.</summary> public TransformConstraint(TransformConstraint constraint, Skeleton skeleton) { if (constraint == null) { throw new ArgumentNullException("constraint cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton cannot be null."); } data = constraint.data; bones = new ExposedList <Bone>(constraint.Bones.Count); foreach (Bone bone in constraint.Bones) { bones.Add(skeleton.Bones.Items[bone.data.index]); } target = skeleton.Bones.Items[constraint.target.data.index]; rotateMix = constraint.rotateMix; translateMix = constraint.translateMix; scaleMix = constraint.scaleMix; shearMix = constraint.shearMix; }
/// <summary>Copy constructor.</summary> public TransformConstraint(TransformConstraint constraint, Skeleton skeleton) { if (constraint == null) { throw new ArgumentNullException("constraint cannot be null."); } if (skeleton == null) { throw new ArgumentNullException("skeleton cannot be null."); } data = constraint.data; bones = new ExposedList <Bone>(constraint.Bones.Count); foreach (Bone bone in constraint.Bones) { bones.Add(skeleton.Bones.Items[bone.data.index]); } target = skeleton.Bones.Items[constraint.target.data.index]; mixRotate = constraint.mixRotate; mixX = constraint.mixX; mixY = constraint.mixY; mixScaleX = constraint.mixScaleX; mixScaleY = constraint.mixScaleY; mixShearY = constraint.mixShearY; }
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)); }
/// <summary> /// Clears any previous polygons, finds all visible bounding box attachments, /// and computes the world vertices for each bounding box's polygon.</summary> /// <param name="skeleton">The skeleton.</param> /// <param name="updateAabb"> /// If true, the axis aligned bounding box containing all the polygons is computed. /// If false, the SkeletonBounds AABB methods will always return true. /// </param> public void Update(Skeleton skeleton, bool updateAabb) { ExposedList <BoundingBoxAttachment> boundingBoxes = BoundingBoxes; ExposedList <Polygon> polygons = Polygons; ExposedList <Slot> slots = skeleton.slots; int slotCount = slots.Count; boundingBoxes.Clear(); for (int i = 0, n = polygons.Count; i < n; i++) { polygonPool.Add(polygons.Items[i]); } polygons.Clear(); for (int i = 0; i < slotCount; i++) { Slot slot = slots.Items[i]; if (!slot.bone.active) { continue; } BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment; if (boundingBox == null) { continue; } boundingBoxes.Add(boundingBox); Polygon polygon = null; int poolCount = polygonPool.Count; if (poolCount > 0) { polygon = polygonPool.Items[poolCount - 1]; polygonPool.RemoveAt(poolCount - 1); } else { polygon = new Polygon(); } polygons.Add(polygon); int count = boundingBox.worldVerticesLength; polygon.Count = count; if (polygon.Vertices.Length < count) { polygon.Vertices = new float[count]; } boundingBox.ComputeWorldVertices(slot, polygon.Vertices); } if (updateAabb) { AabbCompute(); } else { minX = int.MinValue; minY = int.MinValue; maxX = int.MaxValue; maxY = int.MaxValue; } }
private void ReadAnimation(String name, Dictionary <String, Object> map, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float duration = 0; var scale = this.Scale; if (map.ContainsKey("slots")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)map["slots"]) { String slotName = entry.Key; int slotIndex = skeletonData.FindSlotIndex(slotName); var timelineMap = (Dictionary <String, Object>)entry.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "color") { var timeline = new ColorTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; String c = (String)valueMap["color"]; timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3)); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]); } else if (timelineName == "attachment") { var timeline = new AttachmentTimeline(values.Count); timeline.slotIndex = slotIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } else { throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); } } } } if (map.ContainsKey("bones")) { foreach (KeyValuePair <String, Object> entry in (Dictionary <String, Object>)map["bones"]) { String boneName = entry.Key; int boneIndex = skeletonData.FindBoneIndex(boneName); if (boneIndex == -1) { throw new Exception("Bone not found: " + boneName); } var timelineMap = (Dictionary <String, Object>)entry.Value; foreach (KeyValuePair <String, Object> timelineEntry in timelineMap) { var values = (List <Object>)timelineEntry.Value; var timelineName = (String)timelineEntry.Key; if (timelineName == "rotate") { var timeline = new RotateTimeline(values.Count); timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]); } else if (timelineName == "translate" || timelineName == "scale" || timelineName == "shear") { TranslateTimeline timeline; float timelineScale = 1; if (timelineName == "scale") { timeline = new ScaleTimeline(values.Count); } else if (timelineName == "shear") { timeline = new ShearTimeline(values.Count); } else { timeline = new TranslateTimeline(values.Count); timelineScale = scale; } timeline.boneIndex = boneIndex; int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float x = GetFloat(valueMap, "x", 0); float y = GetFloat(valueMap, "y", 0); timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } else { throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); } } } } // IK timelines. if (map.ContainsKey("ik")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["ik"]) { IkConstraintData constraint = skeletonData.FindIkConstraint(constraintMap.Key); var values = (List <Object>)constraintMap.Value; var timeline = new IkConstraintTimeline(values.Count); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float mix = GetFloat(valueMap, "mix", 1); bool bendPositive = GetBoolean(valueMap, "bendPositive", true); timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]); } } // Transform constraint timelines. if (map.ContainsKey("transform")) { foreach (KeyValuePair <String, Object> constraintMap in (Dictionary <String, Object>)map["transform"]) { TransformConstraintData constraint = skeletonData.FindTransformConstraint(constraintMap.Key); var values = (List <Object>)constraintMap.Value; var timeline = new TransformConstraintTimeline(values.Count); timeline.transformConstraintIndex = skeletonData.transformConstraints.IndexOf(constraint); int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float time = (float)valueMap["time"]; float rotateMix = GetFloat(valueMap, "rotateMix", 1); float translateMix = GetFloat(valueMap, "translateMix", 1); float scaleMix = GetFloat(valueMap, "scaleMix", 1); float shearMix = GetFloat(valueMap, "shearMix", 1); timeline.SetFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]); } } // FFD timelines. if (map.ContainsKey("ffd")) { foreach (KeyValuePair <String, Object> ffdMap in (Dictionary <String, Object>)map["ffd"]) { Skin skin = skeletonData.FindSkin(ffdMap.Key); foreach (KeyValuePair <String, Object> slotMap in (Dictionary <String, Object>)ffdMap.Value) { int slotIndex = skeletonData.FindSlotIndex(slotMap.Key); foreach (KeyValuePair <String, Object> meshMap in (Dictionary <String, Object>)slotMap.Value) { var values = (List <Object>)meshMap.Value; var timeline = new FfdTimeline(values.Count); Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key); if (attachment == null) { throw new Exception("FFD attachment not found: " + meshMap.Key); } timeline.slotIndex = slotIndex; timeline.attachment = attachment; int vertexCount; if (attachment is MeshAttachment) { vertexCount = ((MeshAttachment)attachment).vertices.Length; } else { vertexCount = ((WeightedMeshAttachment)attachment).Weights.Length / 3 * 2; } int frameIndex = 0; foreach (Dictionary <String, Object> valueMap in values) { float[] vertices; if (!valueMap.ContainsKey("vertices")) { if (attachment is MeshAttachment) { vertices = ((MeshAttachment)attachment).vertices; } else { vertices = new float[vertexCount]; } } else { var verticesValue = (List <Object>)valueMap["vertices"]; vertices = new float[vertexCount]; int start = GetInt(valueMap, "offset", 0); if (scale == 1) { for (int i = 0, n = verticesValue.Count; i < n; i++) { vertices[i + start] = (float)verticesValue[i]; } } else { for (int i = 0, n = verticesValue.Count; i < n; i++) { vertices[i + start] = (float)verticesValue[i] * scale; } } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int i = 0; i < vertexCount; i++) { vertices[i] += meshVertices[i]; } } } timeline.SetFrame(frameIndex, (float)valueMap["time"], vertices); ReadCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } } } } if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) { var values = (List <Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"]; var timeline = new DrawOrderTimeline(values.Count); int slotCount = skeletonData.slots.Count; int frameIndex = 0; foreach (Dictionary <String, Object> drawOrderMap in values) { int[] drawOrder = null; if (drawOrderMap.ContainsKey("offsets")) { drawOrder = new int[slotCount]; for (int i = slotCount - 1; i >= 0; i--) { drawOrder[i] = -1; } var offsets = (List <Object>)drawOrderMap["offsets"]; int[] unchanged = new int[slotCount - offsets.Count]; int originalIndex = 0, unchangedIndex = 0; foreach (Dictionary <String, Object> offsetMap in offsets) { int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]); if (slotIndex == -1) { throw new Exception("Slot not found: " + offsetMap["slot"]); } // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. int index = originalIndex + (int)(float)offsetMap["offset"]; drawOrder[index] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int i = slotCount - 1; i >= 0; i--) { if (drawOrder[i] == -1) { drawOrder[i] = unchanged[--unchangedIndex]; } } } timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } if (map.ContainsKey("events")) { var eventsMap = (List <Object>)map["events"]; var timeline = new EventTimeline(eventsMap.Count); int frameIndex = 0; foreach (Dictionary <String, Object> eventMap in eventsMap) { EventData eventData = skeletonData.FindEvent((String)eventMap["name"]); if (eventData == null) { throw new Exception("Event not found: " + eventMap["name"]); } var e = new Event((float)eventMap["time"], eventData); e.Int = GetInt(eventMap, "int", eventData.Int); e.Float = GetFloat(eventMap, "float", eventData.Float); e.String = GetString(eventMap, "string", eventData.String); timeline.SetFrame(frameIndex++, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
private void ReadAnimation(String name, NewStream input, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int slotIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case SLOT_COLOR: { ColorTimeline timeline = new ColorTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); int color = ReadInt(input); float r = ((color & 0xff000000) >> 24) / 255f; float g = ((color & 0x00ff0000) >> 16) / 255f; float b = ((color & 0x0000ff00) >> 8) / 255f; float a = ((color & 0x000000ff)) / 255f; timeline.SetFrame(frameIndex, time, r, g, b, a); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(timeline.FrameCount - 1) * ColorTimeline.ENTRIES]); break; } case SLOT_ATTACHMENT: { AttachmentTimeline timeline = new AttachmentTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input)); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); break; } } } } // Bone timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int boneIndex = ReadVarint(input, true); for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadVarint(input, true); switch (timelineType) { case BONE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { timeline = new ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { timeline = new ShearTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]); break; } } } } // IK timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * IkConstraintTimeline.ENTRIES]); } // Transform constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); int frameCount = ReadVarint(input, true); TransformConstraintTimeline timeline = new TransformConstraintTimeline(frameCount); timeline.transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TransformConstraintTimeline.ENTRIES]); } // Path constraint timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { int index = ReadVarint(input, true); PathConstraintData data = skeletonData.pathConstraints.Items[index]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int timelineType = ReadSByte(input); int frameCount = ReadVarint(input, true); switch (timelineType) { case PATH_POSITION: case PATH_SPACING: { PathConstraintPositionTimeline timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { timeline = new PathConstraintSpacingTimeline(frameCount); if (data.spacingMode == SpacingMode.Length || data.spacingMode == SpacingMode.Fixed) { timelineScale = scale; } } else { timeline = new PathConstraintPositionTimeline(frameCount); if (data.positionMode == PositionMode.Fixed) { timelineScale = scale; } } timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); break; } case PATH_MIX: { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); break; } } } } // Deform timelines. for (int i = 0, n = ReadVarint(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadVarint(input, true)]; for (int ii = 0, nn = ReadVarint(input, true); ii < nn; ii++) { int slotIndex = ReadVarint(input, true); for (int iii = 0, nnn = ReadVarint(input, true); iii < nnn; iii++) { VertexAttachment attachment = (VertexAttachment)skin.GetAttachment(slotIndex, ReadString(input)); bool weighted = attachment.bones != null; float[] vertices = attachment.vertices; int deformLength = weighted ? vertices.Length / 3 * 2 : vertices.Length; int frameCount = ReadVarint(input, true); DeformTimeline timeline = new DeformTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] deform; int end = ReadVarint(input, true); if (end == 0) { deform = weighted ? new float[deformLength] : vertices; } else { deform = new float[deformLength]; int start = ReadVarint(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) { deform[v] = ReadFloat(input); } } else { for (int v = start; v < end; v++) { deform[v] = ReadFloat(input) * scale; } } if (!weighted) { for (int v = 0, vn = deform.Length; v < vn; v++) { deform[v] += vertices[v]; } } } timeline.SetFrame(frameIndex, time, deform); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadVarint(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { float time = ReadFloat(input); int offsetCount = ReadVarint(input, true); int[] drawOrder = new int[slotCount]; for (int ii = slotCount - 1; ii >= 0; ii--) { drawOrder[ii] = -1; } int[] unchanged = new int[slotCount - offsetCount]; int originalIndex = 0, unchangedIndex = 0; for (int ii = 0; ii < offsetCount; ii++) { int slotIndex = ReadVarint(input, true); // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. drawOrder[originalIndex + ReadVarint(input, true)] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int ii = slotCount - 1; ii >= 0; ii--) { if (drawOrder[ii] == -1) { drawOrder[ii] = unchanged[--unchangedIndex]; } } timeline.SetFrame(i, time, drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadVarint(input, true); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = ReadFloat(input); EventData eventData = skeletonData.events.Items[ReadVarint(input, true)]; Event e = new Event(time, eventData); e.Int = ReadVarint(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[eventCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
/** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping * area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */ internal bool Clip(float x1, float y1, float x2, float y2, float x3, float y3, ExposedList <float> clippingArea, ExposedList <float> output) { var originalOutput = output; var clipped = false; // Avoid copy at the end. ExposedList <float> input = null; if (clippingArea.Count % 4 >= 2) { input = output; output = scratch; } else { input = scratch; } input.Clear(); input.Add(x1); input.Add(y1); input.Add(x2); input.Add(y2); input.Add(x3); input.Add(y3); input.Add(x1); input.Add(y1); output.Clear(); float[] clippingVertices = clippingArea.Items; int clippingVerticesLast = clippingArea.Count - 4; for (int i = 0; ; i += 2) { float edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; float edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3]; float deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2; float[] inputVertices = input.Items; int inputVerticesLength = input.Count - 2, outputStart = output.Count; for (int ii = 0; ii < inputVerticesLength; ii += 2) { float inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; float inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3]; bool side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0; if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) { if (side2) // v1 inside, v2 inside { output.Add(inputX2); output.Add(inputY2); continue; } // v1 inside, v2 outside float c0 = inputY2 - inputY, c2 = inputX2 - inputX; float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY)); output.Add(edgeX + (edgeX2 - edgeX) * ua); output.Add(edgeY + (edgeY2 - edgeY) * ua); } else if (side2) // v1 outside, v2 inside { float c0 = inputY2 - inputY, c2 = inputX2 - inputX; float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY)); output.Add(edgeX + (edgeX2 - edgeX) * ua); output.Add(edgeY + (edgeY2 - edgeY) * ua); output.Add(inputX2); output.Add(inputY2); } clipped = true; } if (outputStart == output.Count) // All edges outside. { originalOutput.Clear(); return(true); } output.Add(output.Items[0]); output.Add(output.Items[1]); if (i == clippingVerticesLast) { break; } var temp = output; output = input; output.Clear(); input = temp; } if (originalOutput != output) { originalOutput.Clear(); for (int i = 0, n = output.Count - 2; i < n; i++) { originalOutput.Add(output.Items[i]); } } else { originalOutput.Resize(originalOutput.Count - 2); } return(clipped); }
void ReadPathAnimation(ref ExposedList <Timeline> timelines, SkeletonDataStream input, ref float duration, float scale, ref SkeletonData skeletonData) { // Path constraint timelines. for (int i = 0, n = SkeletonDataStream.sp_readVarint(input.ptr, 1); i < n; i++) { int index = SkeletonDataStream.sp_readVarint(input.ptr, 1); PathConstraintData data = skeletonData.pathConstraints.Items[index]; for (int ii = 0, nn = SkeletonDataStream.sp_readVarint(input.ptr, 1); ii < nn; ii++) { int timelineType = input.ReadSByte(); int frameCount = SkeletonDataStream.sp_readVarint(input.ptr, 1); 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, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr) * timelineScale); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintPositionTimeline.ENTRIES]); break; } case PATH_MIX: { PathConstraintMixTimeline timeline = new PathConstraintMixTimeline(frameCount); timeline.pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr)); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * PathConstraintMixTimeline.ENTRIES]); break; } } } } }
private void ReadAnimation(string name, Stream input, SkeletonData skeletonData) { ExposedList <Timeline> exposedList = new ExposedList <Timeline>(); float scale = this.Scale; float num = 0f; int i = 0; int num2 = SkeletonBinary.ReadVarint(input, true); while (i < num2) { int slotIndex = SkeletonBinary.ReadVarint(input, true); int j = 0; int num3 = SkeletonBinary.ReadVarint(input, true); while (j < num3) { int num4 = input.ReadByte(); int num5 = SkeletonBinary.ReadVarint(input, true); if (num4 != 1) { if (num4 == 0) { AttachmentTimeline attachmentTimeline = new AttachmentTimeline(num5); attachmentTimeline.slotIndex = slotIndex; for (int k = 0; k < num5; k++) { attachmentTimeline.SetFrame(k, this.ReadFloat(input), this.ReadString(input)); } exposedList.Add(attachmentTimeline); num = Math.Max(num, attachmentTimeline.frames[num5 - 1]); } } else { ColorTimeline colorTimeline = new ColorTimeline(num5); colorTimeline.slotIndex = slotIndex; for (int l = 0; l < num5; l++) { float time = this.ReadFloat(input); int num6 = SkeletonBinary.ReadInt(input); float r = (float)((num6 & 4278190080u) >> 24) / 255f; float g = (float)((num6 & 16711680) >> 16) / 255f; float b = (float)((num6 & 65280) >> 8) / 255f; float a = (float)(num6 & 255) / 255f; colorTimeline.SetFrame(l, time, r, g, b, a); if (l < num5 - 1) { this.ReadCurve(input, l, colorTimeline); } } exposedList.Add(colorTimeline); num = Math.Max(num, colorTimeline.frames[(colorTimeline.FrameCount - 1) * 5]); } j++; } i++; } int m = 0; int num7 = SkeletonBinary.ReadVarint(input, true); while (m < num7) { int boneIndex = SkeletonBinary.ReadVarint(input, true); int n = 0; int num8 = SkeletonBinary.ReadVarint(input, true); while (n < num8) { int num9 = input.ReadByte(); int num10 = SkeletonBinary.ReadVarint(input, true); switch (num9) { case 0: { RotateTimeline rotateTimeline = new RotateTimeline(num10); rotateTimeline.boneIndex = boneIndex; for (int num11 = 0; num11 < num10; num11++) { rotateTimeline.SetFrame(num11, this.ReadFloat(input), this.ReadFloat(input)); if (num11 < num10 - 1) { this.ReadCurve(input, num11, rotateTimeline); } } exposedList.Add(rotateTimeline); num = Math.Max(num, rotateTimeline.frames[(num10 - 1) * 2]); break; } case 1: case 2: case 3: { float num12 = 1f; TranslateTimeline translateTimeline; if (num9 == 2) { translateTimeline = new ScaleTimeline(num10); } else if (num9 == 3) { translateTimeline = new ShearTimeline(num10); } else { translateTimeline = new TranslateTimeline(num10); num12 = scale; } translateTimeline.boneIndex = boneIndex; for (int num13 = 0; num13 < num10; num13++) { translateTimeline.SetFrame(num13, this.ReadFloat(input), this.ReadFloat(input) * num12, this.ReadFloat(input) * num12); if (num13 < num10 - 1) { this.ReadCurve(input, num13, translateTimeline); } } exposedList.Add(translateTimeline); num = Math.Max(num, translateTimeline.frames[(num10 - 1) * 3]); break; } } n++; } m++; } int num14 = 0; int num15 = SkeletonBinary.ReadVarint(input, true); while (num14 < num15) { int ikConstraintIndex = SkeletonBinary.ReadVarint(input, true); int num16 = SkeletonBinary.ReadVarint(input, true); IkConstraintTimeline ikConstraintTimeline = new IkConstraintTimeline(num16); ikConstraintTimeline.ikConstraintIndex = ikConstraintIndex; for (int num17 = 0; num17 < num16; num17++) { ikConstraintTimeline.SetFrame(num17, this.ReadFloat(input), this.ReadFloat(input), (int)SkeletonBinary.ReadSByte(input)); if (num17 < num16 - 1) { this.ReadCurve(input, num17, ikConstraintTimeline); } } exposedList.Add(ikConstraintTimeline); num = Math.Max(num, ikConstraintTimeline.frames[(num16 - 1) * 3]); num14++; } int num18 = 0; int num19 = SkeletonBinary.ReadVarint(input, true); while (num18 < num19) { int transformConstraintIndex = SkeletonBinary.ReadVarint(input, true); int num20 = SkeletonBinary.ReadVarint(input, true); TransformConstraintTimeline transformConstraintTimeline = new TransformConstraintTimeline(num20); transformConstraintTimeline.transformConstraintIndex = transformConstraintIndex; for (int num21 = 0; num21 < num20; num21++) { transformConstraintTimeline.SetFrame(num21, this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input)); if (num21 < num20 - 1) { this.ReadCurve(input, num21, transformConstraintTimeline); } } exposedList.Add(transformConstraintTimeline); num = Math.Max(num, transformConstraintTimeline.frames[(num20 - 1) * 5]); num18++; } int num22 = 0; int num23 = SkeletonBinary.ReadVarint(input, true); while (num22 < num23) { int num24 = SkeletonBinary.ReadVarint(input, true); PathConstraintData pathConstraintData = skeletonData.pathConstraints.Items[num24]; int num25 = 0; int num26 = SkeletonBinary.ReadVarint(input, true); while (num25 < num26) { int num27 = (int)SkeletonBinary.ReadSByte(input); int num28 = SkeletonBinary.ReadVarint(input, true); if (num27 != 0 && num27 != 1) { if (num27 == 2) { PathConstraintMixTimeline pathConstraintMixTimeline = new PathConstraintMixTimeline(num28); pathConstraintMixTimeline.pathConstraintIndex = num24; for (int num29 = 0; num29 < num28; num29++) { pathConstraintMixTimeline.SetFrame(num29, this.ReadFloat(input), this.ReadFloat(input), this.ReadFloat(input)); if (num29 < num28 - 1) { this.ReadCurve(input, num29, pathConstraintMixTimeline); } } exposedList.Add(pathConstraintMixTimeline); num = Math.Max(num, pathConstraintMixTimeline.frames[(num28 - 1) * 3]); } } else { float num30 = 1f; PathConstraintPositionTimeline pathConstraintPositionTimeline; if (num27 == 1) { pathConstraintPositionTimeline = new PathConstraintSpacingTimeline(num28); if (pathConstraintData.spacingMode == SpacingMode.Length || pathConstraintData.spacingMode == SpacingMode.Fixed) { num30 = scale; } } else { pathConstraintPositionTimeline = new PathConstraintPositionTimeline(num28); if (pathConstraintData.positionMode == PositionMode.Fixed) { num30 = scale; } } pathConstraintPositionTimeline.pathConstraintIndex = num24; for (int num31 = 0; num31 < num28; num31++) { pathConstraintPositionTimeline.SetFrame(num31, this.ReadFloat(input), this.ReadFloat(input) * num30); if (num31 < num28 - 1) { this.ReadCurve(input, num31, pathConstraintPositionTimeline); } } exposedList.Add(pathConstraintPositionTimeline); num = Math.Max(num, pathConstraintPositionTimeline.frames[(num28 - 1) * 2]); } num25++; } num22++; } int num32 = 0; int num33 = SkeletonBinary.ReadVarint(input, true); while (num32 < num33) { Skin skin = skeletonData.skins.Items[SkeletonBinary.ReadVarint(input, true)]; int num34 = 0; int num35 = SkeletonBinary.ReadVarint(input, true); while (num34 < num35) { int slotIndex2 = SkeletonBinary.ReadVarint(input, true); int num36 = 0; int num37 = SkeletonBinary.ReadVarint(input, true); while (num36 < num37) { VertexAttachment vertexAttachment = (VertexAttachment)skin.GetAttachment(slotIndex2, this.ReadString(input)); bool flag = vertexAttachment.bones != null; float[] vertices = vertexAttachment.vertices; int num38 = (!flag) ? vertices.Length : (vertices.Length / 3 * 2); int num39 = SkeletonBinary.ReadVarint(input, true); DeformTimeline deformTimeline = new DeformTimeline(num39); deformTimeline.slotIndex = slotIndex2; deformTimeline.attachment = vertexAttachment; for (int num40 = 0; num40 < num39; num40++) { float time2 = this.ReadFloat(input); int num41 = SkeletonBinary.ReadVarint(input, true); float[] array; if (num41 == 0) { array = ((!flag) ? vertices : new float[num38]); } else { array = new float[num38]; int num42 = SkeletonBinary.ReadVarint(input, true); num41 += num42; if (scale == 1f) { for (int num43 = num42; num43 < num41; num43++) { array[num43] = this.ReadFloat(input); } } else { for (int num44 = num42; num44 < num41; num44++) { array[num44] = this.ReadFloat(input) * scale; } } if (!flag) { int num45 = 0; int num46 = array.Length; while (num45 < num46) { array[num45] += vertices[num45]; num45++; } } } deformTimeline.SetFrame(num40, time2, array); if (num40 < num39 - 1) { this.ReadCurve(input, num40, deformTimeline); } } exposedList.Add(deformTimeline); num = Math.Max(num, deformTimeline.frames[num39 - 1]); num36++; } num34++; } num32++; } int num47 = SkeletonBinary.ReadVarint(input, true); if (num47 > 0) { DrawOrderTimeline drawOrderTimeline = new DrawOrderTimeline(num47); int count = skeletonData.slots.Count; for (int num48 = 0; num48 < num47; num48++) { float time3 = this.ReadFloat(input); int num49 = SkeletonBinary.ReadVarint(input, true); int[] array2 = new int[count]; for (int num50 = count - 1; num50 >= 0; num50--) { array2[num50] = -1; } int[] array3 = new int[count - num49]; int num51 = 0; int num52 = 0; for (int num53 = 0; num53 < num49; num53++) { int num54 = SkeletonBinary.ReadVarint(input, true); while (num51 != num54) { array3[num52++] = num51++; } array2[num51 + SkeletonBinary.ReadVarint(input, true)] = num51++; } while (num51 < count) { array3[num52++] = num51++; } for (int num55 = count - 1; num55 >= 0; num55--) { if (array2[num55] == -1) { array2[num55] = array3[--num52]; } } drawOrderTimeline.SetFrame(num48, time3, array2); } exposedList.Add(drawOrderTimeline); num = Math.Max(num, drawOrderTimeline.frames[num47 - 1]); } int num56 = SkeletonBinary.ReadVarint(input, true); if (num56 > 0) { EventTimeline eventTimeline = new EventTimeline(num56); for (int num57 = 0; num57 < num56; num57++) { float time4 = this.ReadFloat(input); EventData eventData = skeletonData.events.Items[SkeletonBinary.ReadVarint(input, true)]; eventTimeline.SetFrame(num57, new Event(time4, eventData) { Int = SkeletonBinary.ReadVarint(input, false), Float = this.ReadFloat(input), String = ((!SkeletonBinary.ReadBoolean(input)) ? eventData.String : this.ReadString(input)) }); } exposedList.Add(eventTimeline); num = Math.Max(num, eventTimeline.frames[num56 - 1]); } exposedList.TrimExcess(); skeletonData.animations.Add(new Animation(name, exposedList, num)); }
public void UpdateCache() { ExposedList <IUpdatable> exposedList = this.updateCache; exposedList.Clear(true); ExposedList <Bone> exposedList2 = this.bones; int i = 0; int count = exposedList2.Count; while (i < count) { exposedList2.Items[i].sorted = false; i++; } ExposedList <IkConstraint> exposedList3 = this.ikConstraintsSorted; exposedList3.Clear(true); exposedList3.AddRange(this.ikConstraints); int count2 = exposedList3.Count; int j = 0; int num = count2; while (j < num) { IkConstraint ikConstraint = exposedList3.Items[j]; Bone parent = ikConstraint.bones.Items[0].parent; int num2 = 0; while (parent != null) { parent = parent.parent; num2++; } ikConstraint.level = num2; j++; } for (int k = 1; k < count2; k++) { IkConstraint ikConstraint2 = exposedList3.Items[k]; int level = ikConstraint2.level; int l; for (l = k - 1; l >= 0; l--) { IkConstraint ikConstraint3 = exposedList3.Items[l]; if (ikConstraint3.level < level) { break; } exposedList3.Items[l + 1] = ikConstraint3; } exposedList3.Items[l + 1] = ikConstraint2; } int m = 0; int count3 = exposedList3.Count; while (m < count3) { IkConstraint ikConstraint4 = exposedList3.Items[m]; Bone target = ikConstraint4.target; this.SortBone(target); ExposedList <Bone> exposedList4 = ikConstraint4.bones; Bone bone = exposedList4.Items[0]; this.SortBone(bone); exposedList.Add(ikConstraint4); this.SortReset(bone.children); exposedList4.Items[exposedList4.Count - 1].sorted = true; m++; } ExposedList <PathConstraint> exposedList5 = this.pathConstraints; int n = 0; int count4 = exposedList5.Count; while (n < count4) { PathConstraint pathConstraint = exposedList5.Items[n]; Slot target2 = pathConstraint.target; int index = target2.data.index; Bone bone2 = target2.bone; if (this.skin != null) { this.SortPathConstraintAttachment(this.skin, index, bone2); } if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) { this.SortPathConstraintAttachment(this.data.defaultSkin, index, bone2); } int num3 = 0; int count5 = this.data.skins.Count; while (num3 < count5) { this.SortPathConstraintAttachment(this.data.skins.Items[num3], index, bone2); num3++; } PathAttachment pathAttachment = target2.Attachment as PathAttachment; if (pathAttachment != null) { this.SortPathConstraintAttachment(pathAttachment, bone2); } ExposedList <Bone> exposedList6 = pathConstraint.bones; int count6 = exposedList6.Count; for (int num4 = 0; num4 < count6; num4++) { this.SortBone(exposedList6.Items[num4]); } exposedList.Add(pathConstraint); for (int num5 = 0; num5 < count6; num5++) { this.SortReset(exposedList6.Items[num5].children); } for (int num6 = 0; num6 < count6; num6++) { exposedList6.Items[num6].sorted = true; } n++; } ExposedList <TransformConstraint> exposedList7 = this.transformConstraints; int num7 = 0; int count7 = exposedList7.Count; while (num7 < count7) { TransformConstraint transformConstraint = exposedList7.Items[num7]; this.SortBone(transformConstraint.target); ExposedList <Bone> exposedList8 = transformConstraint.bones; int count8 = exposedList8.Count; for (int num8 = 0; num8 < count8; num8++) { this.SortBone(exposedList8.Items[num8]); } exposedList.Add(transformConstraint); for (int num9 = 0; num9 < count8; num9++) { this.SortReset(exposedList8.Items[num9].children); } for (int num10 = 0; num10 < count8; num10++) { exposedList8.Items[num10].sorted = true; } num7++; } int num11 = 0; int count9 = exposedList2.Count; while (num11 < count9) { this.SortBone(exposedList2.Items[num11]); num11++; } }
public void UpdateCache() { ExposedList <ExposedList <Bone> > exposedList = this.boneCache; ExposedList <IkConstraint> exposedList2 = this.ikConstraints; int count = exposedList2.Count; int num = count + 1; if (exposedList.Count > num) { exposedList.RemoveRange(num, exposedList.Count - num); } int i = 0; int count2 = exposedList.Count; while (i < count2) { exposedList.Items[i].Clear(true); i++; } while (exposedList.Count < num) { exposedList.Add(new ExposedList <Bone>()); } ExposedList <Bone> exposedList3 = exposedList.Items[0]; int j = 0; int count3 = this.bones.Count; while (j < count3) { Bone bone = this.bones.Items[j]; Bone bone2 = bone; int k; while (true) { k = 0; IL_143: while (k < count) { IkConstraint ikConstraint = exposedList2.Items[k]; Bone bone3 = ikConstraint.bones.Items[0]; Bone bone4 = ikConstraint.bones.Items[ikConstraint.bones.Count - 1]; while (bone2 != bone4) { if (bone4 == bone3) { k++; goto IL_143; } bone4 = bone4.parent; } goto Block_4; } bone2 = bone2.parent; if (bone2 == null) { goto Block_7; } } IL_164: j++; continue; Block_4: exposedList.Items[k].Add(bone); exposedList.Items[k + 1].Add(bone); goto IL_164; Block_7: exposedList3.Add(bone); goto IL_164; } }
void ReadBoneAnimation(ref ExposedList <Timeline> timelines, SkeletonDataStream input, ref float duration, float scale) { // Bone timelines. for (int i = 0, n = SkeletonDataStream.sp_readVarint(input.ptr, 1); i < n; i++) { int boneIndex = SkeletonDataStream.sp_readVarint(input.ptr, 1); for (int ii = 0, nn = SkeletonDataStream.sp_readVarint(input.ptr, 1); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = SkeletonDataStream.sp_readVarint(input.ptr, 1); switch (timelineType) { case BONE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr)); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * RotateTimeline.ENTRIES]); break; } case BONE_TRANSLATE: case BONE_SCALE: case BONE_SHEAR: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { timeline = new ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { timeline = new ShearTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, SkeletonDataStream.sp_readFloat(input.ptr), SkeletonDataStream.sp_readFloat(input.ptr) * timelineScale, SkeletonDataStream.sp_readFloat(input.ptr) * timelineScale); if (frameIndex < frameCount - 1) { SkeletonDataStream.sp_readCurve(input.ptr, frameIndex, timeline.curves); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[(frameCount - 1) * TranslateTimeline.ENTRIES]); break; } } } } }
private void ReadAnimation(String name, Stream input, SkeletonData skeletonData) { var timelines = new ExposedList <Timeline>(); float scale = Scale; float duration = 0; // Slot timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { int slotIndex = ReadInt(input, true); for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadInt(input, true); switch (timelineType) { case TIMELINE_COLOR: { ColorTimeline timeline = new ColorTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); int color = ReadInt(input); float r = ((color & 0xff000000) >> 24) / 255f; float g = ((color & 0x00ff0000) >> 16) / 255f; float b = ((color & 0x0000ff00) >> 8) / 255f; float a = ((color & 0x000000ff)) / 255f; timeline.SetFrame(frameIndex, time, r, g, b, a); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 5 - 5]); break; } case TIMELINE_ATTACHMENT: { AttachmentTimeline timeline = new AttachmentTimeline(frameCount); timeline.slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input)); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); break; } } } } // Bone timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { int boneIndex = ReadInt(input, true); for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int timelineType = input.ReadByte(); int frameCount = ReadInt(input, true); switch (timelineType) { case TIMELINE_ROTATE: { RotateTimeline timeline = new RotateTimeline(frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]); break; } case TIMELINE_TRANSLATE: case TIMELINE_SCALE: { TranslateTimeline timeline; float timelineScale = 1; if (timelineType == TIMELINE_SCALE) { timeline = new ScaleTimeline(frameCount); } else { timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input) * timelineScale); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]); break; } case TIMELINE_FLIPX: case TIMELINE_FLIPY: { FlipXTimeline timeline = timelineType == TIMELINE_FLIPX ? new FlipXTimeline(frameCount) : new FlipYTimeline( frameCount); timeline.boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadBoolean(input)); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]); break; } } } } // IK timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { IkConstraintData ikConstraint = skeletonData.ikConstraints.Items[ReadInt(input, true)]; int frameCount = ReadInt(input, true); IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount); timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint); for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input)); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]); } // FFD timelines. for (int i = 0, n = ReadInt(input, true); i < n; i++) { Skin skin = skeletonData.skins.Items[ReadInt(input, true)]; for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) { int slotIndex = ReadInt(input, true); for (int iii = 0, nnn = ReadInt(input, true); iii < nnn; iii++) { Attachment attachment = skin.GetAttachment(slotIndex, ReadString(input)); int frameCount = ReadInt(input, true); FFDTimeline timeline = new FFDTimeline(frameCount); timeline.slotIndex = slotIndex; timeline.attachment = attachment; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { float time = ReadFloat(input); float[] vertices; int vertexCount; if (attachment is MeshAttachment) { vertexCount = ((MeshAttachment)attachment).vertices.Length; } else { vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2; } int end = ReadInt(input, true); if (end == 0) { if (attachment is MeshAttachment) { vertices = ((MeshAttachment)attachment).vertices; } else { vertices = new float[vertexCount]; } } else { vertices = new float[vertexCount]; int start = ReadInt(input, true); end += start; if (scale == 1) { for (int v = start; v < end; v++) { vertices[v] = ReadFloat(input); } } else { for (int v = start; v < end; v++) { vertices[v] = ReadFloat(input) * scale; } } if (attachment is MeshAttachment) { float[] meshVertices = ((MeshAttachment)attachment).vertices; for (int v = 0, vn = vertices.Length; v < vn; v++) { vertices[v] += meshVertices[v]; } } } timeline.SetFrame(frameIndex, time, vertices); if (frameIndex < frameCount - 1) { ReadCurve(input, frameIndex, timeline); } } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[frameCount - 1]); } } } // Draw order timeline. int drawOrderCount = ReadInt(input, true); if (drawOrderCount > 0) { DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = skeletonData.slots.Count; for (int i = 0; i < drawOrderCount; i++) { int offsetCount = ReadInt(input, true); int[] drawOrder = new int[slotCount]; for (int ii = slotCount - 1; ii >= 0; ii--) { drawOrder[ii] = -1; } int[] unchanged = new int[slotCount - offsetCount]; int originalIndex = 0, unchangedIndex = 0; for (int ii = 0; ii < offsetCount; ii++) { int slotIndex = ReadInt(input, true); // Collect unchanged items. while (originalIndex != slotIndex) { unchanged[unchangedIndex++] = originalIndex++; } // Set changed items. drawOrder[originalIndex + ReadInt(input, true)] = originalIndex++; } // Collect remaining unchanged items. while (originalIndex < slotCount) { unchanged[unchangedIndex++] = originalIndex++; } // Fill in unchanged items. for (int ii = slotCount - 1; ii >= 0; ii--) { if (drawOrder[ii] == -1) { drawOrder[ii] = unchanged[--unchangedIndex]; } } timeline.SetFrame(i, ReadFloat(input), drawOrder); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]); } // Event timeline. int eventCount = ReadInt(input, true); if (eventCount > 0) { EventTimeline timeline = new EventTimeline(eventCount); for (int i = 0; i < eventCount; i++) { float time = ReadFloat(input); EventData eventData = skeletonData.events.Items[ReadInt(input, true)]; Event e = new Event(eventData); e.Int = ReadInt(input, false); e.Float = ReadFloat(input); e.String = ReadBoolean(input) ? ReadString(input) : eventData.String; timeline.SetFrame(i, time, e); } timelines.Add(timeline); duration = Math.Max(duration, timeline.frames[eventCount - 1]); } timelines.TrimExcess(); skeletonData.animations.Add(new Animation(name, timelines, duration)); }
/// <summary>Caches information about bones and constraints. Must be called if bones, constraints or weighted path attachments are added /// or removed.</summary> public void UpdateCache() { ExposedList <IUpdatable> updateCache = this.updateCache; updateCache.Clear(); ExposedList <Bone> bones = this.bones; for (int i = 0, n = bones.Count; i < n; i++) { bones.Items[i].sorted = false; } ExposedList <IkConstraint> ikConstraints = this.ikConstraintsSorted; ikConstraints.Clear(); ikConstraints.AddRange(this.ikConstraints); int ikCount = ikConstraints.Count; for (int i = 0, level, n = ikCount; i < n; i++) { IkConstraint ik = ikConstraints.Items[i]; Bone bone = ik.bones.Items[0].parent; for (level = 0; bone != null; level++) { bone = bone.parent; } ik.level = level; } for (int i = 1, ii; i < ikCount; i++) { IkConstraint ik = ikConstraints.Items[i]; int level = ik.level; for (ii = i - 1; ii >= 0; ii--) { IkConstraint other = ikConstraints.Items[ii]; if (other.level < level) { break; } ikConstraints.Items[ii + 1] = other; } ikConstraints.Items[ii + 1] = ik; } for (int i = 0, n = ikConstraints.Count; i < n; i++) { IkConstraint constraint = ikConstraints.Items[i]; Bone target = constraint.target; SortBone(target); ExposedList <Bone> constrained = constraint.bones; Bone parent = constrained.Items[0]; SortBone(parent); updateCache.Add(constraint); SortReset(parent.children); constrained.Items[constrained.Count - 1].sorted = true; } ExposedList <PathConstraint> pathConstraints = this.pathConstraints; for (int i = 0, n = pathConstraints.Count; i < n; i++) { PathConstraint constraint = pathConstraints.Items[i]; Slot slot = constraint.target; int slotIndex = slot.data.index; Bone slotBone = slot.bone; if (skin != null) { SortPathConstraintAttachment(skin, slotIndex, slotBone); } if (data.defaultSkin != null && data.defaultSkin != skin) { SortPathConstraintAttachment(data.defaultSkin, slotIndex, slotBone); } for (int ii = 0, nn = data.skins.Count; ii < nn; ii++) { SortPathConstraintAttachment(data.skins.Items[ii], slotIndex, slotBone); } PathAttachment attachment = slot.Attachment as PathAttachment; if (attachment != null) { SortPathConstraintAttachment(attachment, slotBone); } ExposedList <Bone> constrained = constraint.bones; int boneCount = constrained.Count; for (int ii = 0; ii < boneCount; ii++) { SortBone(constrained.Items[ii]); } updateCache.Add(constraint); for (int ii = 0; ii < boneCount; ii++) { SortReset(constrained.Items[ii].children); } for (int ii = 0; ii < boneCount; ii++) { constrained.Items[ii].sorted = true; } } ExposedList <TransformConstraint> transformConstraints = this.transformConstraints; for (int i = 0, n = transformConstraints.Count; i < n; i++) { TransformConstraint constraint = transformConstraints.Items[i]; SortBone(constraint.target); ExposedList <Bone> constrained = constraint.bones; int boneCount = constrained.Count; for (int ii = 0; ii < boneCount; ii++) { SortBone(constrained.Items[ii]); } updateCache.Add(constraint); for (int ii = 0; ii < boneCount; ii++) { SortReset(constrained.Items[ii].children); } for (int ii = 0; ii < boneCount; ii++) { constrained.Items[ii].sorted = true; } } for (int i = 0, n = bones.Count; i < n; i++) { SortBone(bones.Items[i]); } }