From 28862c94bc3abf1bd8c8081cf348313bb317789f Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Sun, 9 Jun 2019 16:14:36 +0200 Subject: [PATCH] Javadocs, argument checks, minor clean up. --- .../com/esotericsoftware/spine/Animation.java | 19 +- .../spine/AnimationState.java | 22 ++- .../com/esotericsoftware/spine/BlendMode.java | 2 +- .../src/com/esotericsoftware/spine/Bone.java | 2 + .../com/esotericsoftware/spine/BoneData.java | 1 + .../src/com/esotericsoftware/spine/Event.java | 1 + .../com/esotericsoftware/spine/EventData.java | 2 + .../esotericsoftware/spine/IkConstraint.java | 4 + .../spine/PathConstraint.java | 1 + .../spine/PathConstraintData.java | 4 + .../com/esotericsoftware/spine/Skeleton.java | 16 +- .../spine/SkeletonBinary.java | 1 + .../spine/SkeletonBounds.java | 7 +- .../esotericsoftware/spine/SkeletonJson.java | 2 + .../spine/SkeletonRenderer.java | 169 +++++++++--------- .../spine/SkeletonRendererDebug.java | 3 + .../src/com/esotericsoftware/spine/Skin.java | 15 +- .../com/esotericsoftware/spine/SlotData.java | 2 + .../spine/TransformConstraint.java | 1 + .../com/esotericsoftware/spine/Updatable.java | 4 +- .../spine/attachments/AttachmentType.java | 2 +- .../spine/attachments/MeshAttachment.java | 2 +- 22 files changed, 167 insertions(+), 115 deletions(-) diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java index ef50d9546..ea6dc210d 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Animation.java @@ -70,7 +70,8 @@ public class Animation { /** Applies all the animation's timelines to the specified skeleton. *

* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. - * @param loop If true, the animation repeats after {@link #getDuration()}. */ + * @param loop If true, the animation repeats after {@link #getDuration()}. + * @param events May be null to ignore fired events. */ public void apply (Skeleton skeleton, float lastTime, float time, boolean loop, Array events, float alpha, MixBlend blend, MixDirection direction) { if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null."); @@ -144,12 +145,12 @@ public class Animation { * (exclusive) and time (inclusive). * @param time The time within the animation. Most timelines find the key before and the key after this time so they can * interpolate between the keys. - * @param events If any events are fired, they are added to this list. Can be null to ignore firing events or if the - * timeline does not fire events. + * @param events If any events are fired, they are added to this list. Can be null to ignore fired events or if the timeline + * does not fire events. * @param alpha 0 applies the current or setup value (depending on blend). 1 applies the timeline value. * Between 0 and 1 applies a value between the current or setup value and the timeline value. By adjusting * alpha over time, an animation can be mixed in or out. alpha can also be useful to - * apply animations on top of each other (layered). + * apply animations on top of each other (layering). * @param blend Controls how mixing is applied when alpha < 1. * @param direction Indicates whether the timeline is mixing in or out. Used by timelines which perform instant transitions, * such as {@link DrawOrderTimeline} or {@link AttachmentTimeline}. */ @@ -160,7 +161,8 @@ public class Animation { public int getPropertyId (); } - /** Controls how a timeline value is mixed with the setup pose value or current pose value. + /** Controls how a timeline value is mixed with the setup pose value or current pose value when a timeline's alpha + * < 1. *

* See Timeline {@link Timeline#apply(Skeleton, float, float, Array, float, MixBlend, MixDirection)}. */ static public enum MixBlend { @@ -181,7 +183,9 @@ public class Animation { /** Transitions from the current value to the current value plus the timeline value. No change is made before the first key * (the current value is kept until the first key). *

- * add is intended for animations layered on top of others, not for the first animations applied. */ + * add is intended for animations layered on top of others, not for the first animations applied. Properties + * keyed by additive animations must be set manually or by another animation before applying the additive animations, else + * the property values will increase continually. */ add } @@ -779,7 +783,8 @@ public class Animation { this.slotIndex = index; } - /** The index of the slot in {@link Skeleton#getSlots()} that will be changed. */ + /** The index of the slot in {@link Skeleton#getSlots()} that will be changed. The {@link Slot#getDarkColor()} must not be + * null. */ public int getSlotIndex () { return slotIndex; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java index b3680d3aa..59d924843 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java @@ -462,6 +462,7 @@ public class AnimationState { * It may be desired to use {@link AnimationState#setEmptyAnimation(int, float)} to mix the skeletons back to the setup pose, * rather than leaving them in their current pose. */ public void clearTrack (int trackIndex) { + if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0."); if (trackIndex >= tracks.size) return; TrackEntry current = tracks.get(trackIndex); if (current == null) return; @@ -521,6 +522,7 @@ public class AnimationState { * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept * after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */ public TrackEntry setAnimation (int trackIndex, Animation animation, boolean loop) { + if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0."); if (animation == null) throw new IllegalArgumentException("animation cannot be null."); boolean interrupt = true; TrackEntry current = expandToIndex(trackIndex); @@ -560,6 +562,7 @@ public class AnimationState { * @return A track entry to allow further customization of animation playback. References to the track entry must not be kept * after the {@link AnimationStateListener#dispose(TrackEntry)} event occurs. */ public TrackEntry addAnimation (int trackIndex, Animation animation, boolean loop, float delay) { + if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0."); if (animation == null) throw new IllegalArgumentException("animation cannot be null."); TrackEntry last = expandToIndex(trackIndex); @@ -783,6 +786,7 @@ public class AnimationState { /** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */ public TrackEntry getCurrent (int trackIndex) { + if (trackIndex < 0) throw new IllegalArgumentException("trackIndex must be >= 0."); if (trackIndex >= tracks.size) return null; return tracks.get(trackIndex); } @@ -892,6 +896,7 @@ public class AnimationState { } public void setAnimation (Animation animation) { + if (animation == null) throw new IllegalArgumentException("animation cannot be null."); this.animation = animation; } @@ -1124,6 +1129,7 @@ public class AnimationState { } public void setMixBlend (MixBlend mixBlend) { + if (mixBlend == null) throw new IllegalArgumentException("mixBlend cannot be null."); this.mixBlend = mixBlend; } @@ -1178,40 +1184,40 @@ public class AnimationState { private final Array objects = new Array(); boolean drainDisabled; - public void start (TrackEntry entry) { + void start (TrackEntry entry) { objects.add(EventType.start); objects.add(entry); animationsChanged = true; } - public void interrupt (TrackEntry entry) { + void interrupt (TrackEntry entry) { objects.add(EventType.interrupt); objects.add(entry); } - public void end (TrackEntry entry) { + void end (TrackEntry entry) { objects.add(EventType.end); objects.add(entry); animationsChanged = true; } - public void dispose (TrackEntry entry) { + void dispose (TrackEntry entry) { objects.add(EventType.dispose); objects.add(entry); } - public void complete (TrackEntry entry) { + void complete (TrackEntry entry) { objects.add(EventType.complete); objects.add(entry); } - public void event (TrackEntry entry, Event event) { + void event (TrackEntry entry, Event event) { objects.add(EventType.event); objects.add(entry); objects.add(event); } - public void drain () { + void drain () { if (drainDisabled) return; // Not reentrant. drainDisabled = true; @@ -1260,7 +1266,7 @@ public class AnimationState { drainDisabled = false; } - public void clear () { + void clear () { objects.clear(); } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BlendMode.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BlendMode.java index afc2e938b..519f0c711 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BlendMode.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BlendMode.java @@ -55,5 +55,5 @@ public enum BlendMode { return dest; } - static public BlendMode[] values = values(); + static public final BlendMode[] values = values(); } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java index 97aaa608e..bea33470d 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Bone.java @@ -538,6 +538,7 @@ public class Bone implements Updatable { /** Transforms a point from world coordinates to the bone's local coordinates. */ public Vector2 worldToLocal (Vector2 world) { + if (world == null) throw new IllegalArgumentException("world cannot be null."); float invDet = 1 / (a * d - b * c); float x = world.x - worldX, y = world.y - worldY; world.x = x * d * invDet - y * b * invDet; @@ -547,6 +548,7 @@ public class Bone implements Updatable { /** Transforms a point from the bone's local coordinates to world coordinates. */ public Vector2 localToWorld (Vector2 local) { + if (local == null) throw new IllegalArgumentException("local cannot be null."); float x = local.x, y = local.y; local.x = x * a + y * b + worldX; local.y = x * c + y * d + worldY; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java index 4ad76961e..337dde645 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/BoneData.java @@ -173,6 +173,7 @@ public class BoneData { } public void setTransformMode (TransformMode transformMode) { + if (transformMode == null) throw new IllegalArgumentException("transformMode cannot be null."); this.transformMode = transformMode; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Event.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Event.java index 2a639dfc1..9d97d31c4 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Event.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Event.java @@ -73,6 +73,7 @@ public class Event { } public void setString (String stringValue) { + if (stringValue == null) throw new IllegalArgumentException("stringValue cannot be null."); this.stringValue = stringValue; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/EventData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/EventData.java index e7d9030da..fd5a0f5ce 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/EventData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/EventData.java @@ -65,6 +65,7 @@ public class EventData { } public void setString (String stringValue) { + if (stringValue == null) throw new IllegalArgumentException("stringValue cannot be null."); this.stringValue = stringValue; } @@ -73,6 +74,7 @@ public class EventData { } public void setAudioPath (String audioPath) { + if (audioPath == null) throw new IllegalArgumentException("audioPath cannot be null."); this.audioPath = audioPath; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java index 106b756d5..5c26ee50e 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/IkConstraint.java @@ -106,6 +106,7 @@ public class IkConstraint implements Updatable { } public void setTarget (Bone target) { + if (target == null) throw new IllegalArgumentException("target cannot be null."); this.target = target; } @@ -162,6 +163,7 @@ public class IkConstraint implements Updatable { /** Applies 1 bone IK. The target is specified in the world coordinate system. */ static public void apply (Bone bone, float targetX, float targetY, boolean compress, boolean stretch, boolean uniform, float alpha) { + if (bone == null) throw new IllegalArgumentException("bone cannot be null."); if (!bone.appliedValid) bone.updateAppliedTransform(); Bone p = bone.parent; float id = 1 / (p.a * p.d - p.b * p.c); @@ -188,6 +190,8 @@ public class IkConstraint implements Updatable { /** Applies 2 bone IK. The target is specified in the world coordinate system. * @param child A direct descendant of the parent bone. */ static public void apply (Bone parent, Bone child, float targetX, float targetY, int bendDir, boolean stretch, float alpha) { + if (parent == null) throw new IllegalArgumentException("parent cannot be null."); + if (child == null) throw new IllegalArgumentException("child cannot be null."); if (alpha == 0) { child.updateWorldTransform(); return; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java index e0307213e..ae82d96c0 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraint.java @@ -497,6 +497,7 @@ public class PathConstraint implements Updatable { } public void setTarget (Slot target) { + if (target == null) throw new IllegalArgumentException("target cannot be null."); this.target = target; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraintData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraintData.java index 47841beb6..d73d2a1ca 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraintData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/PathConstraintData.java @@ -58,6 +58,7 @@ public class PathConstraintData extends ConstraintData { } public void setTarget (SlotData target) { + if (target == null) throw new IllegalArgumentException("target cannot be null."); this.target = target; } @@ -67,6 +68,7 @@ public class PathConstraintData extends ConstraintData { } public void setPositionMode (PositionMode positionMode) { + if (positionMode == null) throw new IllegalArgumentException("positionMode cannot be null."); this.positionMode = positionMode; } @@ -76,6 +78,7 @@ public class PathConstraintData extends ConstraintData { } public void setSpacingMode (SpacingMode spacingMode) { + if (spacingMode == null) throw new IllegalArgumentException("spacingMode cannot be null."); this.spacingMode = spacingMode; } @@ -85,6 +88,7 @@ public class PathConstraintData extends ConstraintData { } public void setRotateMode (RotateMode rotateMode) { + if (rotateMode == null) throw new IllegalArgumentException("rotateMode cannot be null."); this.rotateMode = rotateMode; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java index af8e53440..41e42d27a 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skeleton.java @@ -362,6 +362,7 @@ public class Skeleton { * See World transforms in the Spine * Runtimes Guide. */ public void updateWorldTransform (Bone parent) { + if (parent == null) throw new IllegalArgumentException("parent cannot be null."); // This partial update avoids computing the world transform for constrained bones when 1) the bone is not updated // before the constraint, 2) the constraint only needs to access the applied local transform, and 3) the constraint calls // updateWorldTransform. @@ -462,6 +463,7 @@ public class Skeleton { return bones; } + /** The list of bones and constraints, sorted in the order they should be updated, as computed by {@link #updateCache()}. */ public Array getUpdateCache () { return updateCache; } @@ -473,7 +475,7 @@ public class Skeleton { } /** Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it - * multiple times. + * repeatedly. * @return May be null. */ public Bone findBone (String boneName) { if (boneName == null) throw new IllegalArgumentException("boneName cannot be null."); @@ -491,7 +493,7 @@ public class Skeleton { } /** Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it - * multiple times. + * repeatedly. * @return May be null. */ public Slot findSlot (String slotName) { if (slotName == null) throw new IllegalArgumentException("slotName cannot be null."); @@ -607,7 +609,7 @@ public class Skeleton { } /** Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method - * than to call it multiple times. + * than to call it repeatedly. * @return May be null. */ public IkConstraint findIkConstraint (String constraintName) { if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null."); @@ -625,7 +627,7 @@ public class Skeleton { } /** Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of - * this method than to call it multiple times. + * this method than to call it repeatedly. * @return May be null. */ public TransformConstraint findTransformConstraint (String constraintName) { if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null."); @@ -643,7 +645,7 @@ public class Skeleton { } /** Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method - * than to call it multiple times. + * than to call it repeatedly. * @return May be null. */ public PathConstraint findPathConstraint (String constraintName) { if (constraintName == null) throw new IllegalArgumentException("constraintName cannot be null."); @@ -658,10 +660,11 @@ public class Skeleton { /** Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. * @param offset An output value, the distance from the skeleton origin to the bottom left corner of the AABB. * @param size An output value, the width and height of the AABB. - * @param temp Working memory. */ + * @param temp Working memory to temporarily store attachments' computed world vertices. */ public void getBounds (Vector2 offset, Vector2 size, FloatArray temp) { if (offset == null) throw new IllegalArgumentException("offset cannot be null."); if (size == null) throw new IllegalArgumentException("size cannot be null."); + if (temp == null) throw new IllegalArgumentException("temp cannot be null."); Array drawOrder = this.drawOrder; float minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE; for (int i = 0, n = drawOrder.size; i < n; i++) { @@ -748,6 +751,7 @@ public class Skeleton { this.y = y; } + /** Sets the skeleton X and Y position, which is added to the root bone worldX and worldY position. */ public void setPosition (float x, float y) { this.x = x; this.y = y; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java index 36881ff91..d58ba5a67 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBinary.java @@ -122,6 +122,7 @@ public class SkeletonBinary { } public void setScale (float scale) { + if (scale == 0) throw new IllegalArgumentException("scale cannot be 0."); this.scale = scale; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBounds.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBounds.java index 9b6f36c8a..602ac18f1 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBounds.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonBounds.java @@ -35,8 +35,8 @@ import com.badlogic.gdx.utils.Pool; import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.BoundingBoxAttachment; -/** Collects each {@link BoundingBoxAttachment} that is visible and computes the world vertices for its polygon. The polygon - * vertices are provided along with convenience methods for doing hit detection. */ +/** Collects each visible {@link BoundingBoxAttachment} and computes the world vertices for its polygon. The polygon vertices are + * provided along with convenience methods for doing hit detection. */ public class SkeletonBounds { private float minX, minY, maxX, maxY; private Array boundingBoxes = new Array(); @@ -135,6 +135,7 @@ public class SkeletonBounds { /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */ public boolean aabbIntersectsSkeleton (SkeletonBounds bounds) { + if (bounds == null) throw new IllegalArgumentException("bounds cannot be null."); return minX < bounds.maxX && maxX > bounds.minX && minY < bounds.maxY && maxY > bounds.minY; } @@ -149,6 +150,7 @@ public class SkeletonBounds { /** Returns true if the polygon contains the point. */ public boolean containsPoint (FloatArray polygon, float x, float y) { + if (polygon == null) throw new IllegalArgumentException("polygon cannot be null."); float[] vertices = polygon.items; int nn = polygon.size; @@ -178,6 +180,7 @@ public class SkeletonBounds { /** Returns true if the polygon contains any part of the line segment. */ public boolean intersectsSegment (FloatArray polygon, float x1, float y1, float x2, float y2) { + if (polygon == null) throw new IllegalArgumentException("polygon cannot be null."); float[] vertices = polygon.items; int nn = polygon.size; diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java index 5e3010483..6e984eac7 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonJson.java @@ -99,10 +99,12 @@ public class SkeletonJson { } public void setScale (float scale) { + if (scale == 0) throw new IllegalArgumentException("scale cannot be 0."); this.scale = scale; } protected JsonValue parse (FileHandle file) { + if (file == null) throw new IllegalArgumentException("file cannot be null."); return new JsonReader().parse(file); } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java index 233ffd688..3f3284acb 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java @@ -29,14 +29,6 @@ package com.esotericsoftware.spine; -import com.esotericsoftware.spine.attachments.Attachment; -import com.esotericsoftware.spine.attachments.ClippingAttachment; -import com.esotericsoftware.spine.attachments.MeshAttachment; -import com.esotericsoftware.spine.attachments.RegionAttachment; -import com.esotericsoftware.spine.attachments.SkeletonAttachment; -import com.esotericsoftware.spine.utils.SkeletonClipping; -import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; - import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Batch; @@ -47,6 +39,14 @@ import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.NumberUtils; import com.badlogic.gdx.utils.ShortArray; +import com.esotericsoftware.spine.attachments.Attachment; +import com.esotericsoftware.spine.attachments.ClippingAttachment; +import com.esotericsoftware.spine.attachments.MeshAttachment; +import com.esotericsoftware.spine.attachments.RegionAttachment; +import com.esotericsoftware.spine.attachments.SkeletonAttachment; +import com.esotericsoftware.spine.utils.SkeletonClipping; +import com.esotericsoftware.spine.utils.TwoColorPolygonBatch; + public class SkeletonRenderer { static private final short[] quadTriangles = {0, 1, 2, 2, 3, 0}; @@ -72,10 +72,13 @@ public class SkeletonRenderer { if (batch instanceof TwoColorPolygonBatch) { draw((TwoColorPolygonBatch)batch, skeleton); return; - } else if (batch instanceof PolygonSpriteBatch) { + } + if (batch instanceof PolygonSpriteBatch) { draw((PolygonSpriteBatch)batch, skeleton); return; } + if (batch == null) throw new IllegalArgumentException("batch cannot be null."); + if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null."); VertexEffect vertexEffect = this.vertexEffect; if (vertexEffect != null) vertexEffect.begin(skeleton); @@ -148,12 +151,12 @@ public class SkeletonRenderer { * next. */ @SuppressWarnings("null") public void draw (PolygonSpriteBatch batch, Skeleton skeleton) { - Vector2 tempPos = this.temp; - Vector2 tempUv = this.temp2; - Color tempLight = this.temp3; - Color tempDark = this.temp4; - Color temp5 = this.temp5; - Color temp6 = this.temp6; + if (batch == null) throw new IllegalArgumentException("batch cannot be null."); + if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null."); + + Vector2 tempPosition = this.temp, tempUV = this.temp2; + Color tempLight1 = this.temp3, tempDark1 = this.temp4; + Color tempLight2 = this.temp5, tempDark2 = this.temp6; VertexEffect vertexEffect = this.vertexEffect; if (vertexEffect != null) vertexEffect.begin(skeleton); @@ -231,21 +234,21 @@ public class SkeletonRenderer { clippedTriangles.size); } else { if (vertexEffect != null) { - temp5.set(NumberUtils.floatToIntColor(c)); - temp6.set(0); + tempLight1.set(NumberUtils.floatToIntColor(c)); + tempDark1.set(0); for (int v = 0, u = 0; v < verticesLength; v += 5, u += 2) { - tempPos.x = vertices[v]; - tempPos.y = vertices[v + 1]; - tempLight.set(temp5); - tempDark.set(temp6); - tempUv.x = uvs[u]; - tempUv.y = uvs[u + 1]; - vertexEffect.transform(tempPos, tempUv, tempLight, tempDark); - vertices[v] = tempPos.x; - vertices[v + 1] = tempPos.y; - vertices[v + 2] = tempLight.toFloatBits(); - vertices[v + 3] = tempUv.x; - vertices[v + 4] = tempUv.y; + tempPosition.x = vertices[v]; + tempPosition.y = vertices[v + 1]; + tempLight2.set(tempLight1); + tempDark2.set(tempDark1); + tempUV.x = uvs[u]; + tempUV.y = uvs[u + 1]; + vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); + vertices[v] = tempPosition.x; + vertices[v + 1] = tempPosition.y; + vertices[v + 2] = tempLight2.toFloatBits(); + vertices[v + 3] = tempUV.x; + vertices[v + 4] = tempUV.y; } } else { for (int v = 2, u = 0; v < verticesLength; v += 5, u += 2) { @@ -271,12 +274,12 @@ public class SkeletonRenderer { * next. */ @SuppressWarnings("null") public void draw (TwoColorPolygonBatch batch, Skeleton skeleton) { - Vector2 tempPos = this.temp; - Vector2 tempUv = this.temp2; - Color tempLight = this.temp3; - Color tempDark = this.temp4; - Color temp5 = this.temp5; - Color temp6 = this.temp6; + if (batch == null) throw new IllegalArgumentException("batch cannot be null."); + if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null."); + + Vector2 tempPosition = this.temp, tempUV = this.temp2; + Color tempLight1 = this.temp3, tempDark1 = this.temp4; + Color tempLight2 = this.temp5, tempDark2 = this.temp6; VertexEffect vertexEffect = this.vertexEffect; if (vertexEffect != null) vertexEffect.begin(skeleton); @@ -363,22 +366,22 @@ public class SkeletonRenderer { clippedTriangles.size); } else { if (vertexEffect != null) { - temp5.set(NumberUtils.floatToIntColor(light)); - temp6.set(NumberUtils.floatToIntColor(dark)); + tempLight1.set(NumberUtils.floatToIntColor(light)); + tempDark1.set(NumberUtils.floatToIntColor(dark)); for (int v = 0, u = 0; v < verticesLength; v += 6, u += 2) { - tempPos.x = vertices[v]; - tempPos.y = vertices[v + 1]; - tempLight.set(temp5); - tempDark.set(temp6); - tempUv.x = uvs[u]; - tempUv.y = uvs[u + 1]; - vertexEffect.transform(tempPos, tempUv, tempLight, tempDark); - vertices[v] = tempPos.x; - vertices[v + 1] = tempPos.y; - vertices[v + 2] = tempLight.toFloatBits(); - vertices[v + 3] = tempDark.toFloatBits(); - vertices[v + 4] = tempUv.x; - vertices[v + 5] = tempUv.y; + tempPosition.x = vertices[v]; + tempPosition.y = vertices[v + 1]; + tempLight2.set(tempLight1); + tempDark2.set(tempDark1); + tempUV.x = uvs[u]; + tempUV.y = uvs[u + 1]; + vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); + vertices[v] = tempPosition.x; + vertices[v + 1] = tempPosition.y; + vertices[v + 2] = tempLight2.toFloatBits(); + vertices[v + 3] = tempDark2.toFloatBits(); + vertices[v + 4] = tempUV.x; + vertices[v + 5] = tempUV.y; } } else { for (int v = 2, u = 0; v < verticesLength; v += 6, u += 2) { @@ -399,45 +402,42 @@ public class SkeletonRenderer { } private void applyVertexEffect (float[] vertices, int verticesLength, int stride, float light, float dark) { - Vector2 tempPos = this.temp; - Vector2 tempUv = this.temp2; - Color tempLight = this.temp3; - Color tempDark = this.temp4; - Color temp5 = this.temp5; - Color temp6 = this.temp6; + Vector2 tempPosition = this.temp, tempUV = this.temp2; + Color tempLight1 = this.temp3, tempDark1 = this.temp4; + Color tempLight2 = this.temp5, tempDark2 = this.temp6; VertexEffect vertexEffect = this.vertexEffect; - temp5.set(NumberUtils.floatToIntColor(light)); - temp6.set(NumberUtils.floatToIntColor(dark)); + tempLight1.set(NumberUtils.floatToIntColor(light)); + tempDark1.set(NumberUtils.floatToIntColor(dark)); if (stride == 5) { for (int v = 0; v < verticesLength; v += stride) { - tempPos.x = vertices[v]; - tempPos.y = vertices[v + 1]; - tempUv.x = vertices[v + 3]; - tempUv.y = vertices[v + 4]; - tempLight.set(temp5); - tempDark.set(temp6); - vertexEffect.transform(tempPos, tempUv, tempLight, tempDark); - vertices[v] = tempPos.x; - vertices[v + 1] = tempPos.y; - vertices[v + 2] = tempLight.toFloatBits(); - vertices[v + 3] = tempUv.x; - vertices[v + 4] = tempUv.y; + tempPosition.x = vertices[v]; + tempPosition.y = vertices[v + 1]; + tempUV.x = vertices[v + 3]; + tempUV.y = vertices[v + 4]; + tempLight2.set(tempLight1); + tempDark2.set(tempDark1); + vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); + vertices[v] = tempPosition.x; + vertices[v + 1] = tempPosition.y; + vertices[v + 2] = tempLight2.toFloatBits(); + vertices[v + 3] = tempUV.x; + vertices[v + 4] = tempUV.y; } } else { for (int v = 0; v < verticesLength; v += stride) { - tempPos.x = vertices[v]; - tempPos.y = vertices[v + 1]; - tempUv.x = vertices[v + 4]; - tempUv.y = vertices[v + 5]; - tempLight.set(temp5); - tempDark.set(temp6); - vertexEffect.transform(tempPos, tempUv, tempLight, tempDark); - vertices[v] = tempPos.x; - vertices[v + 1] = tempPos.y; - vertices[v + 2] = tempLight.toFloatBits(); - vertices[v + 3] = tempDark.toFloatBits(); - vertices[v + 4] = tempUv.x; - vertices[v + 5] = tempUv.y; + tempPosition.x = vertices[v]; + tempPosition.y = vertices[v + 1]; + tempUV.x = vertices[v + 4]; + tempUV.y = vertices[v + 5]; + tempLight2.set(tempLight1); + tempDark2.set(tempDark1); + vertexEffect.transform(tempPosition, tempUV, tempLight2, tempDark2); + vertices[v] = tempPosition.x; + vertices[v + 1] = tempPosition.y; + vertices[v + 2] = tempLight2.toFloatBits(); + vertices[v + 3] = tempDark2.toFloatBits(); + vertices[v + 4] = tempUV.x; + vertices[v + 5] = tempUV.y; } } } @@ -450,14 +450,17 @@ public class SkeletonRenderer { this.premultipliedAlpha = premultipliedAlpha; } + /** @return May be null. */ public VertexEffect getVertexEffect () { return vertexEffect; } + /** @param vertexEffect May be null. */ public void setVertexEffect (VertexEffect vertexEffect) { this.vertexEffect = vertexEffect; } + /** Modifies the skeleton or vertex positions, UVs, or colors during rendering. */ static public interface VertexEffect { public void begin (Skeleton skeleton); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java index 2097dd742..c5dc08d3e 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRendererDebug.java @@ -67,10 +67,13 @@ public class SkeletonRendererDebug { } public SkeletonRendererDebug (ShapeRenderer shapes) { + if (shapes == null) throw new IllegalArgumentException("shapes cannot be null."); this.shapes = shapes; } public void draw (Skeleton skeleton) { + if (skeleton == null) throw new IllegalArgumentException("skeleton cannot be null."); + Gdx.gl.glEnable(GL20.GL_BLEND); int srcFunc = premultipliedAlpha ? GL20.GL_ONE : GL20.GL_SRC_ALPHA; Gdx.gl.glBlendFunc(srcFunc, GL20.GL_ONE_MINUS_SRC_ALPHA); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java index bf571f3e4..f3bd7df4e 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Skin.java @@ -31,6 +31,7 @@ package com.esotericsoftware.spine; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.OrderedMap; + import com.esotericsoftware.spine.attachments.Attachment; import com.esotericsoftware.spine.attachments.MeshAttachment; @@ -53,13 +54,15 @@ public class Skin { /** Adds an attachment to the skin for the specified slot index and name. */ public void setAttachment (int slotIndex, String name, Attachment attachment) { - if (attachment == null) throw new IllegalArgumentException("attachment cannot be null."); if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0."); + if (attachment == null) throw new IllegalArgumentException("attachment cannot be null."); attachments.put(new SkinEntry(slotIndex, name, attachment), attachment); } /** Adds all attachments, bones, and constraints from the specified skin to this skin. */ public void addSkin (Skin skin) { + if (skin == null) throw new IllegalArgumentException("skin cannot be null."); + for (BoneData data : skin.bones) if (!bones.contains(data, true)) bones.add(data); @@ -70,8 +73,11 @@ public class Skin { setAttachment(entry.slotIndex, entry.name, entry.attachment); } - /** Adds all attachments, bones, and constraints from the specified skin to this skin. Attachments are deep copied. */ + /** Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not + * copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. */ public void copySkin (Skin skin) { + if (skin == null) throw new IllegalArgumentException("skin cannot be null."); + for (BoneData data : skin.bones) if (!bones.contains(data, true)) bones.add(data); @@ -80,8 +86,7 @@ public class Skin { for (SkinEntry entry : skin.attachments.keys()) { if (entry.attachment instanceof MeshAttachment) - setAttachment(entry.slotIndex, entry.name, - entry.attachment != null ? ((MeshAttachment)entry.attachment).newLinkedMesh() : null); + setAttachment(entry.slotIndex, entry.name, ((MeshAttachment)entry.attachment).newLinkedMesh()); else setAttachment(entry.slotIndex, entry.name, entry.attachment != null ? entry.attachment.copy() : null); } @@ -108,6 +113,8 @@ public class Skin { /** Returns all attachments in this skin for the specified slot index. */ public void getAttachments (int slotIndex, Array attachments) { + if (slotIndex < 0) throw new IllegalArgumentException("slotIndex must be >= 0."); + if (attachments == null) throw new IllegalArgumentException("attachments cannot be null."); for (SkinEntry entry : this.attachments.keys()) if (entry.slotIndex == slotIndex) attachments.add(entry); } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SlotData.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SlotData.java index fd878e240..f52a5f276 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SlotData.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SlotData.java @@ -77,6 +77,7 @@ public class SlotData { return darkColor; } + /** @param darkColor May be null. */ public void setDarkColor (Color darkColor) { this.darkColor = darkColor; } @@ -97,6 +98,7 @@ public class SlotData { } public void setBlendMode (BlendMode blendMode) { + if (blendMode == null) throw new IllegalArgumentException("blendMode cannot be null."); this.blendMode = blendMode; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java index 7ef3520b9..8434c2a5f 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/TransformConstraint.java @@ -301,6 +301,7 @@ public class TransformConstraint implements Updatable { } public void setTarget (Bone target) { + if (target == null) throw new IllegalArgumentException("target cannot be null."); this.target = target; } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java index cb6c9b62a..115d80153 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/Updatable.java @@ -33,8 +33,8 @@ package com.esotericsoftware.spine; public interface Updatable { public void update (); - /** Returns false when this item has not been updated because a skine is required and the {@link Skeleton#getSkin() active - * skin} does not contain this item. + /** Returns false when this item has not been updated because a skin is required and the {@link Skeleton#getSkin() active skin} + * does not contain this item. * @see Skin#getBones() * @see Skin#getConstraints() */ public boolean isActive (); diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java index 251bae68c..c1e813595 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/AttachmentType.java @@ -32,5 +32,5 @@ package com.esotericsoftware.spine.attachments; public enum AttachmentType { region, boundingbox, mesh, linkedmesh, path, point, clipping; - static public AttachmentType[] values = values(); + static public final AttachmentType[] values = values(); } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java index e69016afa..07bfe8eba 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/attachments/MeshAttachment.java @@ -259,7 +259,7 @@ public class MeshAttachment extends VertexAttachment { return copy; } - /** Returns a new mesh with this mesh set as the {@link #parentMesh}. **/ + /** Returns a new mesh with the {@link #parentMesh} set to this mesh's parent mesh, if any, else to this mesh. **/ public MeshAttachment newLinkedMesh () { MeshAttachment mesh = new MeshAttachment(name); mesh.region = region;