public void Update (Skeleton skeleton, bool updateAabb) { List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes; List<Polygon> polygons = Polygons; List<Slot> slots = skeleton.slots; int slotCount = slots.Count; float x = skeleton.x, y = skeleton.y; boundingBoxes.Clear(); foreach (Polygon polygon in polygons) polygonPool.Add(polygon); polygons.Clear(); for (int i = 0; i < slotCount; i++) { Slot slot = slots[i]; 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[poolCount - 1]; polygonPool.RemoveAt(poolCount - 1); } else polygon = new Polygon(); polygons.Add(polygon); int count = boundingBox.Vertices.Length; polygon.Count = count; if (polygon.Vertices.Length < count) polygon.Vertices = new float[count]; boundingBox.ComputeWorldVertices(x, y, slot.bone, polygon.Vertices); } if (updateAabb) aabbCompute(); }
public Slot (SlotData data, Skeleton skeleton, Bone bone) { if (data == null) throw new ArgumentNullException("data cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); if (bone == null) throw new ArgumentNullException("bone cannot be null."); this.data = data; this.skeleton = skeleton; this.bone = bone; SetToSetupPose(); }
public void Draw (Skeleton skeleton) { List<Slot> drawOrder = skeleton.DrawOrder; float x = skeleton.X, y = skeleton.Y; float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A; for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; RegionAttachment regionAttachment = slot.Attachment as RegionAttachment; if (regionAttachment != null) { BlendState blend = slot.Data.AdditiveBlending ? BlendState.Additive : defaultBlendState; if (device.BlendState != blend) { End(); device.BlendState = blend; } SpriteBatchItem item = batcher.CreateBatchItem(); AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject; item.Texture = (Texture2D)region.page.rendererObject; Color color; float a = skeletonA * slot.A; if (premultipliedAlpha) color = new Color(skeletonR * slot.R * a, skeletonG * slot.G * a, skeletonB * slot.B * a, a); else color = new Color(skeletonR * slot.R, skeletonG * slot.G, skeletonB * slot.B, a); item.vertexTL.Color = color; item.vertexBL.Color = color; item.vertexBR.Color = color; item.vertexTR.Color = color; float[] vertices = this.vertices; regionAttachment.ComputeWorldVertices(x, y, slot.Bone, vertices); item.vertexTL.Position.X = vertices[RegionAttachment.X1]; item.vertexTL.Position.Y = vertices[RegionAttachment.Y1]; item.vertexTL.Position.Z = 0; item.vertexBL.Position.X = vertices[RegionAttachment.X2]; item.vertexBL.Position.Y = vertices[RegionAttachment.Y2]; item.vertexBL.Position.Z = 0; item.vertexBR.Position.X = vertices[RegionAttachment.X3]; item.vertexBR.Position.Y = vertices[RegionAttachment.Y3]; item.vertexBR.Position.Z = 0; item.vertexTR.Position.X = vertices[RegionAttachment.X4]; item.vertexTR.Position.Y = vertices[RegionAttachment.Y4]; item.vertexTR.Position.Z = 0; float[] uvs = regionAttachment.UVs; item.vertexTL.TextureCoordinate.X = uvs[RegionAttachment.X1]; item.vertexTL.TextureCoordinate.Y = uvs[RegionAttachment.Y1]; item.vertexBL.TextureCoordinate.X = uvs[RegionAttachment.X2]; item.vertexBL.TextureCoordinate.Y = uvs[RegionAttachment.Y2]; item.vertexBR.TextureCoordinate.X = uvs[RegionAttachment.X3]; item.vertexBR.TextureCoordinate.Y = uvs[RegionAttachment.Y3]; item.vertexTR.TextureCoordinate.X = uvs[RegionAttachment.X4]; item.vertexTR.TextureCoordinate.Y = uvs[RegionAttachment.Y4]; } } }
/// <summary>Poses the skeleton at the specified time for this animation mixed with the current pose.</summary> /// <param name="lastTime">The last time the animation was applied.</param> /// <param name="events">Any triggered events are added.</param> /// <param name="alpha">The amount of this animation that affects the current pose.</param> public void Mix (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events, float alpha) { if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null."); if (loop && duration != 0) { time %= duration; lastTime %= duration; } List<Timeline> timelines = this.timelines; for (int i = 0, n = timelines.Count; i < n; i++) timelines[i].Apply(skeleton, lastTime, time, events, alpha); }
public void Apply (Skeleton skeleton) { List<Event> events = this.events; for (int i = 0; i < tracks.Count; i++) { TrackEntry current = tracks[i]; if (current == null) continue; events.Clear(); float time = current.time; bool loop = current.loop; if (!loop && time > current.endTime) time = current.endTime; TrackEntry previous = current.previous; if (previous == null) current.animation.Apply(skeleton, current.lastTime, time, loop, events); else { float previousTime = previous.time; if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime; previous.animation.Apply(skeleton, previousTime, previousTime, previous.loop, null); float alpha = current.mixTime / current.mixDuration; if (alpha >= 1) { alpha = 1; current.previous = null; } current.animation.Mix(skeleton, current.lastTime, time, loop, events, alpha); } for (int ii = 0, nn = events.Count; ii < nn; ii++) { Event e = events[ii]; current.OnEvent(this, i, e); if (Event != null) Event(this, new EventTriggeredArgs(i, e)); } current.lastTime = current.time; } }
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. int frameIndex; if (time >= frames[frames.Length - 1]) // Time is after last frame. frameIndex = frames.Length - 1; else frameIndex = Animation.binarySearch(frames, time, 1) - 1; List<Slot> drawOrder = skeleton.drawOrder; List<Slot> slots = skeleton.slots; int[] drawOrderToSetupIndex = drawOrders[frameIndex]; if (drawOrderToSetupIndex == null) { drawOrder.Clear(); drawOrder.AddRange(slots); } else { for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++) drawOrder[i] = slots[drawOrderToSetupIndex[i]]; } }
/// <summary>Fires events for frames > lastTime and <= time.</summary> public void Apply (Skeleton skeleton, float lastTime, float time, List<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 frameIndex; if (lastTime < frames[0]) frameIndex = 0; else { frameIndex = Animation.binarySearch(frames, lastTime, 1); float frame = frames[frameIndex]; while (frameIndex > 0) { // Fire multiple events with the same frame. if (frames[frameIndex - 1] != frame) break; frameIndex--; } } for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++) firedEvents.Add(events[frameIndex]); }
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. int frameIndex; if (time >= frames[frames.Length - 1]) // Time is after last frame. frameIndex = frames.Length - 1; else frameIndex = Animation.binarySearch(frames, time, 1) - 1; String attachmentName = attachmentNames[frameIndex]; skeleton.slots[slotIndex].Attachment = attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName); }
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. Slot slot = skeleton.slots[slotIndex]; if (time >= frames[frames.Length - 5]) { // Time is after last frame. int i = frames.Length - 1; slot.r = frames[i - 3]; slot.g = frames[i - 2]; slot.b = frames[i - 1]; slot.a = frames[i]; return; } // Interpolate between the last frame and the current frame. int frameIndex = Animation.binarySearch(frames, time, 5); float lastFrameR = frames[frameIndex - 4]; float lastFrameG = frames[frameIndex - 3]; float lastFrameB = frames[frameIndex - 2]; float lastFrameA = frames[frameIndex - 1]; float frameTime = frames[frameIndex]; float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime); percent = GetCurvePercent(frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); float r = lastFrameR + (frames[frameIndex + FRAME_R] - lastFrameR) * percent; float g = lastFrameG + (frames[frameIndex + FRAME_G] - lastFrameG) * percent; float b = lastFrameB + (frames[frameIndex + FRAME_B] - lastFrameB) * percent; float a = lastFrameA + (frames[frameIndex + FRAME_A] - lastFrameA) * percent; if (alpha < 1) { slot.r += (r - slot.r) * alpha; slot.g += (g - slot.g) * alpha; slot.b += (b - slot.b) * alpha; slot.a += (a - slot.a) * alpha; } else { slot.r = r; slot.g = g; slot.b = b; slot.a = a; } }
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. Bone bone = skeleton.bones[boneIndex]; if (time >= frames[frames.Length - 3]) { // Time is after last frame. bone.scaleX += (bone.data.scaleX - 1 + frames[frames.Length - 2] - bone.scaleX) * alpha; bone.scaleY += (bone.data.scaleY - 1 + frames[frames.Length - 1] - bone.scaleY) * alpha; return; } // Interpolate between the last frame and the current frame. int frameIndex = Animation.binarySearch(frames, time, 3); float lastFrameX = frames[frameIndex - 2]; float lastFrameY = frames[frameIndex - 1]; float frameTime = frames[frameIndex]; float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime); percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + FRAME_X] - lastFrameX) * percent - bone.scaleX) * alpha; bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + FRAME_Y] - lastFrameY) * percent - bone.scaleY) * alpha; }
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) { float[] frames = this.frames; if (time < frames[0]) return; // Time is before first frame. Bone bone = skeleton.bones[boneIndex]; float amount; if (time >= frames[frames.Length - 2]) { // Time is after last frame. amount = bone.data.rotation + frames[frames.Length - 1] - bone.rotation; while (amount > 180) amount -= 360; while (amount < -180) amount += 360; bone.rotation += amount * alpha; return; } // Interpolate between the last frame and the current frame. int frameIndex = Animation.binarySearch(frames, time, 2); float lastFrameValue = frames[frameIndex - 1]; float frameTime = frames[frameIndex]; float percent = 1 - (time - frameTime) / (frames[frameIndex + LAST_FRAME_TIME] - frameTime); percent = GetCurvePercent(frameIndex / 2 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent)); amount = frames[frameIndex + FRAME_VALUE] - lastFrameValue; while (amount > 180) amount -= 360; while (amount < -180) amount += 360; amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation; while (amount > 180) amount -= 360; while (amount < -180) amount += 360; bone.rotation += amount * alpha; }
abstract public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha);
public void Load(Vector2 position,string name,float scale, float acceleration) { this.name = name; //----------Spine---------- skeletonRenderer = new SkeletonRenderer(Game1.graphics.GraphicsDevice); skeletonRenderer.PremultipliedAlpha = true; Atlas atlas = new Atlas("spine/sprites/" + name + ".atlas", new XnaTextureLoader(Game1.graphics.GraphicsDevice)); SkeletonJson json = new SkeletonJson(atlas); json.Scale = scale; skeleton = new Skeleton(json.ReadSkeletonData("spine/sprites/" + name + ".json")); skeleton.SetSlotsToSetupPose(); // Without this the skin attachments won't be attached. See SetSkin. // Define mixing between animations. AnimationStateData animationStateData = new AnimationStateData(skeleton.Data); float fading_standard = 0.2f; switch (name) { case "bonepuker": animationStateData.SetMix("idle", "run", acceleration); animationStateData.SetMix("run", "idle", acceleration); animationStateData.SetMix("idle", "jump", 0.3f); animationStateData.SetMix("run", "jump", 0.3f); animationStateData.SetMix("jump", "run", 0.1f); animationStateData.SetMix("jump", "idle", 0.3f); animationStateData.SetMix("jump", "die", 0.3f); animationStateData.SetMix("run", "die", 0.1f); animationStateData.SetMix("idle", "die", 0.2f); animationStateData.SetMix("smash", "idle", 0.2f); animationStateData.SetMix("smash", "run", 0.2f); animationStateData.SetMix("smash", "jump", 0.2f); //Fading für Attack dürfte so nicht funktionieren, da Attack auf einem anderen Track ausgeführt wird animationStateData.SetMix("attack", "idle", 0.1f); animationStateData.SetMix("attack", "run", 0.1f); animationStateData.SetMix("attack", "jump", 0.1f); break; case "ashbrett": fading_standard = 0.2f; animationStateData.SetMix("idle", "walk", fading_standard); animationStateData.SetMix("idle", "jump", fading_standard); animationStateData.SetMix("idle", "attack", fading_standard); animationStateData.SetMix("idle", "close", fading_standard); animationStateData.SetMix("idle", "defend", fading_standard); animationStateData.SetMix("idle", "die", fading_standard); animationStateData.SetMix("idle", "hit", fading_standard); animationStateData.SetMix("idle", "super_attack", fading_standard); animationStateData.SetMix("walk", "idle", fading_standard); animationStateData.SetMix("walk", "jump", fading_standard); animationStateData.SetMix("walk", "attack", fading_standard); animationStateData.SetMix("walk", "close", fading_standard); animationStateData.SetMix("walk", "defend", fading_standard); animationStateData.SetMix("walk", "die", fading_standard); animationStateData.SetMix("walk", "hit", fading_standard); animationStateData.SetMix("walk", "super_attack", fading_standard); animationStateData.SetMix("jump", "idle", fading_standard); animationStateData.SetMix("jump", "walk", fading_standard); animationStateData.SetMix("jump", "attack", fading_standard); animationStateData.SetMix("jump", "close", fading_standard); animationStateData.SetMix("jump", "defend", fading_standard); animationStateData.SetMix("jump", "die", fading_standard); animationStateData.SetMix("jump", "hit", fading_standard); animationStateData.SetMix("jump", "super_attack", fading_standard); animationStateData.SetMix("attack", "idle", fading_standard); animationStateData.SetMix("attack", "walk", fading_standard); animationStateData.SetMix("attack", "jump", fading_standard); animationStateData.SetMix("attack", "close", fading_standard); animationStateData.SetMix("attack", "defend", fading_standard); animationStateData.SetMix("attack", "die", fading_standard); animationStateData.SetMix("attack", "hit", fading_standard); animationStateData.SetMix("attack", "super_attack", fading_standard); animationStateData.SetMix("close", "idle", fading_standard); animationStateData.SetMix("close", "walk", fading_standard); animationStateData.SetMix("close", "jump", fading_standard); animationStateData.SetMix("close", "attack", fading_standard); animationStateData.SetMix("close", "defend", fading_standard); animationStateData.SetMix("close", "die", fading_standard); animationStateData.SetMix("close", "hit", fading_standard); animationStateData.SetMix("close", "super_attack", fading_standard); animationStateData.SetMix("defend", "idle", fading_standard); animationStateData.SetMix("defend", "walk", fading_standard); animationStateData.SetMix("defend", "jump", fading_standard); animationStateData.SetMix("defend", "attack", fading_standard); animationStateData.SetMix("defend", "close", fading_standard); animationStateData.SetMix("defend", "die", fading_standard); animationStateData.SetMix("defend", "hit", fading_standard); animationStateData.SetMix("defend", "super_attack", fading_standard); animationStateData.SetMix("hit", "idle", fading_standard); animationStateData.SetMix("hit", "walk", fading_standard); animationStateData.SetMix("hit", "jump", fading_standard); animationStateData.SetMix("hit", "attack", fading_standard); animationStateData.SetMix("hit", "close", fading_standard); animationStateData.SetMix("hit", "die", fading_standard); animationStateData.SetMix("hit", "defend", fading_standard); animationStateData.SetMix("hit", "super_attack", fading_standard); animationStateData.SetMix("super_attack", "idle", fading_standard); animationStateData.SetMix("super_attack", "walk", fading_standard); animationStateData.SetMix("super_attack", "jump", fading_standard); animationStateData.SetMix("super_attack", "attack", fading_standard); animationStateData.SetMix("super_attack", "close", fading_standard); animationStateData.SetMix("super_attack", "die", fading_standard); animationStateData.SetMix("super_attack", "defend", fading_standard); animationStateData.SetMix("super_attack", "hit", fading_standard); break; case "fluffy": fading_standard = 0.2f; animationStateData.SetMix("attack", "die", fading_standard); animationStateData.SetMix("attack", "smash_die", fading_standard); animationStateData.SetMix("attack", "idle", fading_standard); animationStateData.SetMix("attack", "walk", fading_standard); animationStateData.SetMix("idle", "die", fading_standard); animationStateData.SetMix("idle", "smash_die", fading_standard); animationStateData.SetMix("idle", "attack", fading_standard); animationStateData.SetMix("idle", "walk", fading_standard); animationStateData.SetMix("walk", "die", fading_standard); animationStateData.SetMix("walk", "smash_die", fading_standard); animationStateData.SetMix("walk", "attack", fading_standard); animationStateData.SetMix("walk", "idle", fading_standard); break; case "skullmonkey": fading_standard = 0.2f; animationStateData.SetMix("attack", "dying", fading_standard); animationStateData.SetMix("attack", "sitting", fading_standard); animationStateData.SetMix("attack", "walking", fading_standard); animationStateData.SetMix("sitting", "dying", fading_standard); animationStateData.SetMix("sitting", "attack", fading_standard); animationStateData.SetMix("sitting", "walking", fading_standard); animationStateData.SetMix("walking", "dying", fading_standard); animationStateData.SetMix("walking", "attack", fading_standard); animationStateData.SetMix("walking", "sitting", fading_standard); break; case "sweetcheeks": fading_standard = 0.2f; animationStateData.SetMix("attack", "die", fading_standard); animationStateData.SetMix("attack", "hit", fading_standard); animationStateData.SetMix("attack", "idle", fading_standard); animationStateData.SetMix("attack", "jump", fading_standard); animationStateData.SetMix("attack", "run", fading_standard); animationStateData.SetMix("attack", "scream", fading_standard); animationStateData.SetMix("hit", "die", fading_standard); animationStateData.SetMix("hit", "attack", fading_standard); animationStateData.SetMix("hit", "idle", fading_standard); animationStateData.SetMix("hit", "jump", fading_standard); animationStateData.SetMix("hit", "run", fading_standard); animationStateData.SetMix("hit", "scream", fading_standard); animationStateData.SetMix("idle", "die", fading_standard); animationStateData.SetMix("idle", "attack", fading_standard); animationStateData.SetMix("idle", "hit", fading_standard); animationStateData.SetMix("idle", "jump", fading_standard); animationStateData.SetMix("idle", "run", fading_standard); animationStateData.SetMix("idle", "scream", fading_standard); animationStateData.SetMix("jump", "die", fading_standard); animationStateData.SetMix("jump", "attack", fading_standard); animationStateData.SetMix("jump", "hit", fading_standard); animationStateData.SetMix("jump", "idle", fading_standard); animationStateData.SetMix("jump", "run", fading_standard); animationStateData.SetMix("jump", "scream", fading_standard); animationStateData.SetMix("run", "die", fading_standard); animationStateData.SetMix("run", "attack", fading_standard); animationStateData.SetMix("run", "hit", fading_standard); animationStateData.SetMix("run", "idle", fading_standard); animationStateData.SetMix("run", "jump", fading_standard); animationStateData.SetMix("run", "scream", fading_standard); animationStateData.SetMix("scream", "die", fading_standard); animationStateData.SetMix("scream", "attack", fading_standard); animationStateData.SetMix("scream", "hit", fading_standard); animationStateData.SetMix("scream", "idle", fading_standard); animationStateData.SetMix("scream", "jump", fading_standard); animationStateData.SetMix("scream", "run", fading_standard); break; } animationState = new AnimationState(animationStateData); // Event handling for all animations. /* animationState.Start += Start; animationState.End += End; animationState.Complete += Complete; animationState.Event += Event; * */ skeleton.x = position.X; skeleton.y = position.Y; }