Procházet zdrojové kódy

Add more documentation

Denis Andrasec před 1 rokem
rodič
revize
42be887994
16 změnil soubory, kde provedl 262 přidání a 48 odebrání
  1. 3 3
      spine-android/app/src/main/java/com/esotericsoftware/spine/DressUp.kt
  2. 59 30
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidSkeletonDrawable.java
  3. 4 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTexture.java
  4. 35 9
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTextureAtlas.java
  5. 4 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/DebugRenderer.java
  6. 61 2
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SkeletonRenderer.java
  7. 1 1
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SpineView.java
  8. 3 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/Alignment.java
  9. 4 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/Bounds.java
  10. 4 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/BoundsProvider.java
  11. 10 1
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/ContentMode.java
  12. 24 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/RawBounds.java
  13. 4 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/SetupPoseBounds.java
  14. 19 1
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/SkinAndAnimationBounds.java
  15. 7 1
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/HttpUtils.java
  16. 20 0
      spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/SkeletonDataUtils.java

+ 3 - 3
spine-android/app/src/main/java/com/esotericsoftware/spine/DressUp.kt

@@ -112,11 +112,11 @@ fun DressUp(nav: NavHostController) {
             skeleton.setToSetupPose()
             skeleton.update(0f)
             skeleton.updateWorldTransform(Skeleton.Physics.update)
-            skinImages[skin.getName()] = drawable.renderToBitmap(
-                renderer,
+            skinImages[skin.getName()] = renderer.renderToBitmap(
                 with(localDensity) { thumbnailSize.dp.toPx() },
                 with(localDensity) { thumbnailSize.dp.toPx() },
-                0xffffffff.toInt()
+                0xffffffff.toInt(),
+                skeleton,
             ).asImageBitmap()
             selectedSkins[skin.getName()] = false
         }

+ 59 - 30
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidSkeletonDrawable.java

@@ -7,7 +7,9 @@ import android.graphics.Paint;
 import android.graphics.RectF;
 
 import com.badlogic.gdx.math.Vector2;
+import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.FloatArray;
+import com.esotericsoftware.spine.Animation;
 import com.esotericsoftware.spine.AnimationState;
 import com.esotericsoftware.spine.AnimationStateData;
 import com.esotericsoftware.spine.Skeleton;
@@ -17,6 +19,25 @@ import com.esotericsoftware.spine.android.utils.SkeletonDataUtils;
 import java.io.File;
 import java.net.URL;
 
+/**
+ * A {@link AndroidSkeletonDrawable} bundles loading updating updating an {@link AndroidTextureAtlas}, {@link Skeleton}, and {@link AnimationState}
+ * into a single easy-to-use class.
+ *
+ * Use the {@link AndroidSkeletonDrawable#fromAsset(String, String, Context)}, {@link AndroidSkeletonDrawable#fromFile(File, File)},
+ * or {@link AndroidSkeletonDrawable#fromHttp(URL, URL, File)} methods to construct a {@link AndroidSkeletonDrawable}. To have
+ * multiple skeleton drawable instances share the same {@link AndroidTextureAtlas} and {@link SkeletonData}, use the constructor.
+ *
+ * You can then directly access the {@link AndroidSkeletonDrawable#getAtlas()}, {@link AndroidSkeletonDrawable#getSkeletonData()},
+ * {@link AndroidSkeletonDrawable#getSkeleton()}, {@link AndroidSkeletonDrawable#getAnimationStateData()}, and {@link AndroidSkeletonDrawable#getAnimationState()}
+ * to query and animate the skeleton. Use the {@link AnimationState} to queue animations on one or more tracks
+ * via {@link AnimationState#setAnimation(int, Animation, boolean)} or {@link AnimationState#addAnimation(int, Animation, boolean, float)}.
+ *
+ * To update the {@link AnimationState} and apply it to the {@link Skeleton}, call the {@link AndroidSkeletonDrawable#update(float)} function, providing it
+ * a delta time in seconds to advance the animations.
+ *
+ * To render the current pose of the {@link Skeleton}, use {@link SkeletonRenderer#render(Skeleton)}, {@link SkeletonRenderer#renderToCanvas(Canvas, Array)},
+ * {@link SkeletonRenderer#renderToBitmap(float, float, int, Skeleton)}, depending on your needs.
+ */
 public class AndroidSkeletonDrawable {
 
     private final AndroidTextureAtlas atlas;
@@ -29,6 +50,9 @@ public class AndroidSkeletonDrawable {
 
     private final AnimationState animationState;
 
+    /**
+     * Constructs a new skeleton drawable from the given (possibly shared) {@link AndroidTextureAtlas} and {@link SkeletonData}.
+     */
     public AndroidSkeletonDrawable(AndroidTextureAtlas atlas, SkeletonData skeletonData) {
         this.atlas = atlas;
         this.skeletonData = skeletonData;
@@ -40,6 +64,11 @@ public class AndroidSkeletonDrawable {
         skeleton.updateWorldTransform(Skeleton.Physics.none);
     }
 
+    /**
+     * Updates the {@link AnimationState} using the {@code delta} time given in seconds, applies the
+     * animation state to the {@link Skeleton} and updates the world transforms of the skeleton
+     * to calculate its current pose.
+     */
     public void update(float delta) {
         animationState.update(delta);
         animationState.apply(skeleton);
@@ -48,71 +77,71 @@ public class AndroidSkeletonDrawable {
         skeleton.updateWorldTransform(Skeleton.Physics.update);
     }
 
+    /**
+     * Get the {@link AndroidTextureAtlas}
+     */
     public AndroidTextureAtlas getAtlas() {
         return atlas;
     }
 
+    /**
+     * Get the {@link Skeleton}
+     */
     public Skeleton getSkeleton() {
         return skeleton;
     }
 
+    /**
+     * Get the {@link SkeletonData}
+     */
     public SkeletonData getSkeletonData() {
         return skeletonData;
     }
 
+    /**
+     * Get the {@link AnimationStateData}
+     */
     public AnimationStateData getAnimationStateData() {
         return animationStateData;
     }
 
+    /**
+     * Get the {@link AnimationState}
+     */
     public AnimationState getAnimationState() {
         return animationState;
     }
 
+    /**
+     * Constructs a new skeleton drawable from the {@code atlasFileName} and {@code skeletonFileName} from the the apps resources using {@link Context}.
+     *
+     * Throws an exception in case the data could not be loaded.
+     */
     public static AndroidSkeletonDrawable fromAsset (String atlasFileName, String skeletonFileName, Context context) {
         AndroidTextureAtlas atlas = AndroidTextureAtlas.fromAsset(atlasFileName, context);
         SkeletonData skeletonData = SkeletonDataUtils.fromAsset(atlas, skeletonFileName, context);
         return new AndroidSkeletonDrawable(atlas, skeletonData);
     }
 
+    /**
+     * Constructs a new skeleton drawable from the {@code atlasFile} and {@code skeletonFile}.
+     *
+     * Throws an exception in case the data could not be loaded.
+     */
     public static AndroidSkeletonDrawable fromFile (File atlasFile, File skeletonFile) {
         AndroidTextureAtlas atlas = AndroidTextureAtlas.fromFile(atlasFile);
         SkeletonData skeletonData = SkeletonDataUtils.fromFile(atlas, skeletonFile);
         return new AndroidSkeletonDrawable(atlas, skeletonData);
     }
 
+    /**
+     * Constructs a new skeleton drawable from the {@code atlasUrl} and {@code skeletonUrl}.
+     *
+     * Throws an exception in case the data could not be loaded.
+     */
     public static AndroidSkeletonDrawable fromHttp (URL atlasUrl, URL skeletonUrl, File targetDirectory) {
         AndroidTextureAtlas atlas = AndroidTextureAtlas.fromHttp(atlasUrl, targetDirectory);
         SkeletonData skeletonData = SkeletonDataUtils.fromHttp(atlas, skeletonUrl, targetDirectory);
         return new AndroidSkeletonDrawable(atlas, skeletonData);
     }
-
-    public Bitmap renderToBitmap(SkeletonRenderer renderer, float width, float height, int bgColor) {
-        Vector2 offset = new Vector2(0, 0);
-        Vector2 size = new Vector2(0, 0);
-        FloatArray floatArray = new FloatArray();
-
-        getSkeleton().getBounds(offset, size, floatArray);
-
-        RectF bounds = new RectF(offset.x, offset.y, offset.x + size.x, offset.y + size.y);
-        float scale = (1 / (bounds.width() > bounds.height() ? bounds.width() / width : bounds.height() / height));
-
-        Bitmap bitmap = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-
-        Paint paint = new Paint();
-        paint.setColor(bgColor);
-        paint.setStyle(Paint.Style.FILL);
-
-        // Draw background
-        canvas.drawRect(0, 0, width, height, paint);
-
-        // Transform canvas
-        canvas.translate(width / 2, height / 2);
-        canvas.scale(scale, -scale);
-        canvas.translate(-(bounds.left + bounds.width() / 2), -(bounds.top + bounds.height() / 2));
-
-        renderer.render(canvas, renderer.render(skeleton));
-
-        return bitmap;
-    }
 }

+ 4 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTexture.java

@@ -40,6 +40,10 @@ import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Shader;
 
+/**
+ * A class holding an {@link Bitmap} of an {@link AndroidTextureAtlas} page image with it's associated
+ * blend modes and paints.
+ */
 public class AndroidTexture extends Texture {
 	private Bitmap bitmap;
 	private ObjectMap<BlendMode, Paint> paints = new ObjectMap<>();

+ 35 - 9
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/AndroidTextureAtlas.java

@@ -49,16 +49,25 @@ import com.esotericsoftware.spine.android.utils.HttpUtils;
 import android.content.Context;
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
+import android.graphics.Paint;
 import android.graphics.BitmapFactory;
 import android.os.Build;
 
+/**
+ * Atlas data loaded from a `.atlas` file and its corresponding `.png` files. For each atlas image,
+ * a corresponding {@link Bitmap} and {@link Paint} is constructed, which are used when rendering a skeleton
+ * that uses this atlas.
+ *
+ * Use the static methods {@link AndroidTextureAtlas#fromAsset(String, Context)}, {@link AndroidTextureAtlas#fromFile(File)},
+ * and {@link AndroidTextureAtlas#fromHttp(URL, File)} to load an atlas.
+ */
 public class AndroidTextureAtlas {
-	private static interface BitmapLoader {
+	private interface BitmapLoader {
 		Bitmap load (String path);
 	}
 
-	private Array<AndroidTexture> textures = new Array<>();
-	private Array<AtlasRegion> regions = new Array<>();
+	private final Array<AndroidTexture> textures = new Array<>();
+	private final Array<AtlasRegion> regions = new Array<>();
 
 	private AndroidTextureAtlas (TextureAtlasData data, BitmapLoader bitmapLoader) {
 		for (TextureAtlasData.Page page : data.getPages()) {
@@ -85,8 +94,10 @@ public class AndroidTextureAtlas {
 		}
 	}
 
-	/** Returns the first region found with the specified name. This method uses string comparison to find the region, so the
-	 * result should be cached rather than calling this method multiple times. */
+	/**
+	 * Returns the first region found with the specified name. This method uses string comparison to find the region, so the
+	 * result should be cached rather than calling this method multiple times.
+	 */
 	public @Null AtlasRegion findRegion (String name) {
 		for (int i = 0, n = regions.size; i < n; i++)
 			if (regions.get(i).name.equals(name)) return regions.get(i);
@@ -101,7 +112,12 @@ public class AndroidTextureAtlas {
 		return regions;
 	}
 
-	static public AndroidTextureAtlas fromAsset(String atlasFileName, Context context) {
+	/**
+	 * Loads an {@link AndroidTextureAtlas} from the file {@code atlasFileName} from assets using {@link Context}.
+	 *
+	 * Throws a {@link RuntimeException} in case the atlas could not be loaded.
+	 */
+	public static AndroidTextureAtlas fromAsset(String atlasFileName, Context context) {
 		TextureAtlasData data = new TextureAtlasData();
 		AssetManager assetManager = context.getAssets();
 
@@ -131,7 +147,12 @@ public class AndroidTextureAtlas {
         });
 	}
 
-	static public AndroidTextureAtlas fromFile(File atlasFile) {
+	/**
+	 * Loads an {@link AndroidTextureAtlas} from the file {@code atlasFileName}.
+	 *
+	 * Throws a {@link RuntimeException} in case the atlas could not be loaded.
+	 */
+	public static AndroidTextureAtlas fromFile(File atlasFile) {
 		TextureAtlasData data;
 		try {
 			data = loadTextureAtlasData(atlasFile);
@@ -148,7 +169,12 @@ public class AndroidTextureAtlas {
 		});
 	}
 
-	static public AndroidTextureAtlas fromHttp(URL atlasUrl, File targetDirectory) {
+	/**
+	 * Loads an {@link AndroidTextureAtlas} from the URL {@code atlasURL}.
+	 *
+	 * Throws a {@link Exception} in case the atlas could not be loaded.
+	 */
+	public static AndroidTextureAtlas fromHttp(URL atlasUrl, File targetDirectory) {
 		File atlasFile = HttpUtils.downloadFrom(atlasUrl, targetDirectory);
 		TextureAtlasData data;
 		try {
@@ -188,7 +214,7 @@ public class AndroidTextureAtlas {
 		}
 	}
 
-	static private TextureAtlasData loadTextureAtlasData(File atlasFile) {
+	private static TextureAtlasData loadTextureAtlasData(File atlasFile) {
 		TextureAtlasData data = new TextureAtlasData();
 		FileHandle inputFile = new FileHandle() {
 			@Override

+ 4 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/DebugRenderer.java

@@ -7,6 +7,10 @@ import android.graphics.RectF;
 import com.badlogic.gdx.utils.Array;
 import com.esotericsoftware.spine.Bone;
 
+/**
+ * Renders debug information for a {@link AndroidSkeletonDrawable}, like bone locations, to a {@link Canvas}.
+ * See {@link DebugRenderer#render}.
+ */
 public class DebugRenderer {
 
     public void render(AndroidSkeletonDrawable drawable, Canvas canvas, Array<SkeletonRenderer.RenderCommand> commands) {

+ 61 - 2
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SkeletonRenderer.java

@@ -30,6 +30,7 @@
 package com.esotericsoftware.spine.android;
 
 import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.utils.Array;
 import com.badlogic.gdx.utils.FloatArray;
 import com.badlogic.gdx.utils.IntArray;
@@ -44,9 +45,22 @@ import com.esotericsoftware.spine.attachments.MeshAttachment;
 import com.esotericsoftware.spine.attachments.RegionAttachment;
 import com.esotericsoftware.spine.utils.SkeletonClipping;
 
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
 
+/**
+ * Is responsible to transform the {@link Skeleton} with its current pose to {@link SkeletonRenderer.RenderCommand} commands
+ * and render them to a {@link Canvas}.
+ */
 public class SkeletonRenderer {
+
+	/**
+	 * Stores the vertices, indices, and atlas page index to be used for rendering one or more attachments
+	 * of a {@link Skeleton} to a {@link Canvas}. See the implementation of {@link SkeletonRenderer#render(Skeleton)} and
+	 * {@link SkeletonRenderer#renderToCanvas(Canvas, Array)} on how to use this data to render it to a {@link Canvas}.
+	 */
 	public static class RenderCommand implements Pool.Poolable {
 		FloatArray vertices = new FloatArray(32);
 		FloatArray uvs = new FloatArray(32);
@@ -76,7 +90,10 @@ public class SkeletonRenderer {
 	};
 	private final Array<RenderCommand> commandList = new Array<RenderCommand>();
 
-	public Array<RenderCommand> render (Skeleton skeleton) {
+	/**
+	 * Created the {@link RenderCommand} commands from the skeletons current pose.
+	 */
+	public Array<RenderCommand> render(Skeleton skeleton) {
 		Color color = null, skeletonColor = skeleton.getColor();
 		float r = skeletonColor.r, g = skeletonColor.g, b = skeletonColor.b, a = skeletonColor.a;
 
@@ -211,7 +228,11 @@ public class SkeletonRenderer {
 		return commandList;
 	}
 
-	public void render (Canvas canvas, Array<RenderCommand> commands) {
+	/**
+	 * Renders the {@link RenderCommand} commands created from the skeleton current pose to the given {@link Canvas}.
+	 * Does not perform any scaling or fitting.
+	 */
+	public void renderToCanvas(Canvas canvas, Array<RenderCommand> commands) {
 		for (int i = 0; i < commands.size; i++) {
 			RenderCommand command = commands.get(i);
 
@@ -219,4 +240,42 @@ public class SkeletonRenderer {
 				command.colors.items, 0, command.indices.items, 0, command.indices.size, command.texture.getPaint(command.blendMode));
 		}
 	}
+
+	/**
+	 * Renders the {@link Skeleton} with its current pose to a {@link Bitmap}.
+	 *
+	 * @param width    The width of the bitmap in pixels.
+	 * @param height   The height of the bitmap in pixels.
+	 * @param bgColor  The background color.
+	 * @param skeleton The skeleton to render.
+	 */
+	public Bitmap renderToBitmap(float width, float height, int bgColor, Skeleton skeleton) {
+		Vector2 offset = new Vector2(0, 0);
+		Vector2 size = new Vector2(0, 0);
+		FloatArray floatArray = new FloatArray();
+
+		skeleton.getBounds(offset, size, floatArray);
+
+		RectF bounds = new RectF(offset.x, offset.y, offset.x + size.x, offset.y + size.y);
+		float scale = (1 / (bounds.width() > bounds.height() ? bounds.width() / width : bounds.height() / height));
+
+		Bitmap bitmap = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.ARGB_8888);
+		Canvas canvas = new Canvas(bitmap);
+
+		Paint paint = new Paint();
+		paint.setColor(bgColor);
+		paint.setStyle(Paint.Style.FILL);
+
+		// Draw background
+		canvas.drawRect(0, 0, width, height, paint);
+
+		// Transform canvas
+		canvas.translate(width / 2, height / 2);
+		canvas.scale(scale, -scale);
+		canvas.translate(-(bounds.left + bounds.width() / 2), -(bounds.top + bounds.height() / 2));
+
+		renderToCanvas(canvas, render(skeleton));
+
+		return bitmap;
+	}
 }

+ 1 - 1
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/SpineView.java

@@ -424,7 +424,7 @@ public class SpineView extends View implements Choreographer.FrameCallback {
 
 		controller.callOnBeforePaint(canvas);
 		Array<SkeletonRenderer.RenderCommand> commands = renderer.render(controller.getSkeleton());
-		renderer.render(canvas, commands);
+		renderer.renderToCanvas(canvas, commands);
 		controller.callOnAfterPaint(canvas, commands);
 
 		canvas.restore();

+ 3 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/Alignment.java

@@ -1,5 +1,8 @@
 package com.esotericsoftware.spine.android.bounds;
 
+/**
+ * How a view should be aligned within another view.
+ */
 public enum Alignment {
     TOP_LEFT(-1.0f, -1.0f),
     TOP_CENTER(0.0f, -1.0f),

+ 4 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/Bounds.java

@@ -4,6 +4,10 @@ import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.utils.FloatArray;
 import com.esotericsoftware.spine.Skeleton;
 
+/**
+ * Bounds denoted by the top left corner coordinates {@code x} and {@code y}
+ * and the {@code width} and {@code height}.
+ */
 public class Bounds {
     private double x;
     private double y;

+ 4 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/BoundsProvider.java

@@ -2,6 +2,10 @@ package com.esotericsoftware.spine.android.bounds;
 
 import com.esotericsoftware.spine.android.AndroidSkeletonDrawable;
 
+/**
+ * A {@link BoundsProvider} that calculates the bounding box of the skeleton based on the visible
+ * attachments in the setup pose.
+ */
 public interface BoundsProvider {
     Bounds computeBounds(AndroidSkeletonDrawable drawable);
 }

+ 10 - 1
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/ContentMode.java

@@ -1,6 +1,15 @@
 package com.esotericsoftware.spine.android.bounds;
 
+/**
+ * How a view should be inscribed into another view.
+ */
 public enum ContentMode {
+    /**
+     * As large as possible while still containing the source view entirely within the target view.
+     */
     FIT,
-    FILL;
+    /**
+     * Fill the target view by distorting the source's aspect ratio.
+     */
+    FILL
 }

+ 24 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/RawBounds.java

@@ -0,0 +1,24 @@
+package com.esotericsoftware.spine.android.bounds;
+import com.esotericsoftware.spine.android.AndroidSkeletonDrawable;
+
+/**
+ * A {@link BoundsProvider} that returns fixed bounds.
+ */
+public class RawBounds implements BoundsProvider {
+    final Double x;
+    final Double y;
+    final Double width;
+    final Double height;
+
+    public RawBounds(Double x, Double y, Double width, Double height) {
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+    }
+
+    @Override
+    public Bounds computeBounds(AndroidSkeletonDrawable drawable) {
+        return new Bounds(x, y, width, height);
+    }
+}

+ 4 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/SetupPoseBounds.java

@@ -4,6 +4,10 @@ import com.badlogic.gdx.math.Vector2;
 import com.badlogic.gdx.utils.FloatArray;
 import com.esotericsoftware.spine.android.AndroidSkeletonDrawable;
 
+/**
+ * A {@link BoundsProvider} that calculates the bounding box of the skeleton based on the visible
+ * attachments in the setup pose.
+ */
 public class SetupPoseBounds implements BoundsProvider {
 
     @Override

+ 19 - 1
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/bounds/SkinAndAnimationBounds.java

@@ -8,22 +8,40 @@ import com.esotericsoftware.spine.android.AndroidSkeletonDrawable;
 import java.util.Collections;
 import java.util.List;
 
+/**
+ * A {@link BoundsProvider} that calculates the bounding box needed for a combination of skins
+ * and an animation.
+ */
 public class SkinAndAnimationBounds implements BoundsProvider {
     private final List<String> skins;
     private final String animation;
     private final double stepTime;
 
-    // Constructor
+    /**
+     * Constructs a new provider that will use the given {@code skins} and {@code animation} to calculate
+     * the bounding box of the skeleton. If no skins are given, the default skin is used.
+     * The {@code stepTime}, given in seconds, defines at what interval the bounds should be sampled
+     * across the entire animation.
+     */
     public SkinAndAnimationBounds(List<String> skins, String animation, double stepTime) {
         this.skins = (skins == null || skins.isEmpty()) ? Collections.singletonList("default") : skins;
         this.animation = animation;
         this.stepTime = stepTime;
     }
 
+    /**
+     * Constructs a new provider that will use the given {@code skins} and {@code animation} to calculate
+     * the bounding box of the skeleton. If no skins are given, the default skin is used.
+     * The {@code stepTime} has default value 0.1.
+     */
     public SkinAndAnimationBounds(List<String> skins, String animation) {
         this(skins, animation, 0.1);
     }
 
+    /**
+     * Constructs a new provider that will use the given {@code skins} and {@code animation} to calculate
+     * the bounding box of the skeleton. The default skin is used. The {@code stepTime} has default value 0.1.
+     */
     public SkinAndAnimationBounds(String animation) {
         this(Collections.emptyList(), animation, 0.1);
     }

+ 7 - 1
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/HttpUtils.java

@@ -12,8 +12,14 @@ import java.net.HttpURLConnection;
 import java.net.URL;
 import java.nio.file.Files;
 
+/**
+ * Helper to load http resources.
+ */
 public class HttpUtils {
-
+    /**
+     * Download a file from an url into a target directory. It keeps the name from the {@code url}.
+     * This should NOT be executed on the main run loop.
+     */
     public static File downloadFrom(URL url, File targetDirectory) throws RuntimeException {
         HttpURLConnection urlConnection = null;
         InputStream inputStream = null;

+ 20 - 0
spine-android/spine-android/src/main/java/com/esotericsoftware/spine/android/utils/SkeletonDataUtils.java

@@ -17,8 +17,17 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 
+/**
+ * Helper to load {@link SkeletonData} from assets.
+ */
 public class SkeletonDataUtils {
 
+    /**
+     * Loads a {@link SkeletonData} from the file {@code skeletonFile} in assets using {@link Context}.
+     * Uses the provided {@link AndroidTextureAtlas} to resolve attachment images.
+     *
+     * Throws a {@link RuntimeException} in case the skeleton data could not be loaded.
+     */
     public static SkeletonData fromAsset(AndroidTextureAtlas atlas, String skeletonFileName, Context context) {
         AndroidAtlasAttachmentLoader attachmentLoader = new AndroidAtlasAttachmentLoader(atlas);
 
@@ -39,6 +48,12 @@ public class SkeletonDataUtils {
         }
         return skeletonData;
     }
+
+    /**
+     * Loads a {@link SkeletonData} from the file {@code skeletonFile}. Uses the provided {@link AndroidTextureAtlas} to resolve attachment images.
+     *
+     * Throws a {@link RuntimeException} in case the skeleton data could not be loaded.
+     */
     public static SkeletonData fromFile(AndroidTextureAtlas atlas, File skeletonFile) {
         AndroidAtlasAttachmentLoader attachmentLoader = new AndroidAtlasAttachmentLoader(atlas);
 
@@ -52,6 +67,11 @@ public class SkeletonDataUtils {
         return skeletonLoader.readSkeletonData(new FileHandle(skeletonFile));
     }
 
+    /**
+     * Loads a {@link SkeletonData} from the URL {@code skeletonURL}. Uses the provided {@link AndroidTextureAtlas} to resolve attachment images.
+     *
+     * Throws a {@link RuntimeException} in case the skeleton data could not be loaded.
+     */
     public static SkeletonData fromHttp(AndroidTextureAtlas atlas, URL skeletonUrl, File targetDirectory) {
         File skeletonFile = HttpUtils.downloadFrom(skeletonUrl, targetDirectory);
         return fromFile(atlas, skeletonFile);