mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-15 19:41:36 +08:00
Add SetupPoseBounds and implement canvas transforms
This commit is contained in:
parent
4b391379e9
commit
5cae4737b5
@ -46,11 +46,7 @@ fun SpineViewComposable(modifier: Modifier = Modifier.fillMaxSize()) {
|
||||
"spineboy.atlas",
|
||||
"spineboy-pro.json",
|
||||
SpineController {
|
||||
it.skeleton.scaleY = -1f
|
||||
it.skeleton.setToSetupPose()
|
||||
|
||||
it.animationStateData.defaultMix = 0.2f
|
||||
it.animationState.setAnimation(0, "hoverboard", true)
|
||||
it.animationState.setAnimation(0, "walk", true)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -205,15 +205,12 @@ public class SkeletonRenderer {
|
||||
return commandList;
|
||||
}
|
||||
|
||||
public void render (Canvas canvas, Skeleton skeleton, float x, float y) {
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
public void render (Canvas canvas, Skeleton skeleton) {
|
||||
Array<RenderCommand> commands = render(skeleton);
|
||||
for (int i = 0; i < commands.size; i++) {
|
||||
RenderCommand command = commands.get(i);
|
||||
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, command.vertices.size, command.vertices.items, 0, command.uvs.items, 0,
|
||||
command.colors.items, 0, command.indices.items, 0, command.indices.size, command.texture.getPaint(command.blendMode));
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,11 @@
|
||||
|
||||
package com.esotericsoftware.spine.android;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.esotericsoftware.spine.android.bounds.Alignment;
|
||||
import com.esotericsoftware.spine.android.bounds.Bounds;
|
||||
import com.esotericsoftware.spine.android.bounds.BoundsProvider;
|
||||
import com.esotericsoftware.spine.android.bounds.SetupPoseBounds;
|
||||
import com.esotericsoftware.spine.android.utils.AndroidSkeletonDrawableLoader;
|
||||
|
||||
import android.content.Context;
|
||||
@ -47,9 +52,21 @@ import java.net.URL;
|
||||
public class SpineView extends View implements Choreographer.FrameCallback {
|
||||
private long lastTime = 0;
|
||||
private float delta = 0;
|
||||
private float offsetX = 0;
|
||||
private float offsetY = 0;
|
||||
private float scaleX = 1;
|
||||
private float scaleY = 1;
|
||||
private float x = 0;
|
||||
private float y = 0;
|
||||
|
||||
SkeletonRenderer renderer = new SkeletonRenderer();
|
||||
SpineController controller;
|
||||
|
||||
BoundsProvider boundsProvider = new SetupPoseBounds();
|
||||
|
||||
Bounds computedBounds = new Bounds();
|
||||
Alignment alignment = Alignment.CENTER;
|
||||
|
||||
public SpineView (Context context) {
|
||||
super(context);
|
||||
}
|
||||
@ -82,6 +99,9 @@ public class SpineView extends View implements Choreographer.FrameCallback {
|
||||
Thread backgroundThread = new Thread(() -> {
|
||||
final AndroidSkeletonDrawable skeletonDrawable = loader.load();
|
||||
mainHandler.post(() -> {
|
||||
computedBounds = boundsProvider.computeBounds(skeletonDrawable);
|
||||
updateCanvasTransform();
|
||||
|
||||
controller.init(skeletonDrawable);
|
||||
Choreographer.getInstance().postFrameCallback(SpineView.this);
|
||||
});
|
||||
@ -98,9 +118,31 @@ public class SpineView extends View implements Choreographer.FrameCallback {
|
||||
|
||||
controller.getDrawable().update(delta);
|
||||
|
||||
// TODO: Calculate scaling + position
|
||||
canvas.save();
|
||||
canvas.translate(offsetX, offsetY);
|
||||
canvas.scale(scaleX, scaleY * -1);
|
||||
canvas.translate(x, y);
|
||||
|
||||
renderer.render(canvas, controller.getSkeleton(), 500f, 1000f);
|
||||
renderer.render(canvas, controller.getSkeleton());
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
updateCanvasTransform();
|
||||
}
|
||||
|
||||
private void updateCanvasTransform() {
|
||||
x = (float) (-computedBounds.getX() - computedBounds.getWidth() / 2.0 - (alignment.getX() * computedBounds.getWidth() / 2.0));
|
||||
y = (float) (-computedBounds.getY() - computedBounds.getHeight() / 2.0 - (alignment.getY() * computedBounds.getHeight() / 2.0));
|
||||
|
||||
// contain
|
||||
scaleX = scaleY = (float) Math.min(getWidth() / computedBounds.getWidth(), getHeight() / computedBounds.getHeight());
|
||||
|
||||
offsetX = (float) (getWidth() / 2.0 + (alignment.getX() * getWidth() / 2.0));
|
||||
offsetY = (float) (getHeight() / 2.0 + (alignment.getY() * getHeight() / 2.0));
|
||||
}
|
||||
|
||||
// Choreographer.FrameCallback
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package com.esotericsoftware.spine.android.bounds;
|
||||
|
||||
public enum Alignment {
|
||||
TOP_LEFT(-1.0f, -1.0f),
|
||||
TOP_CENTER(0.0f, -1.0f),
|
||||
TOP_RIGHT(1.0f, -1.0f),
|
||||
CENTER_LEFT(-1.0f, 0.0f),
|
||||
CENTER(0.0f, 0.0f),
|
||||
CENTER_RIGHT(1.0f, 0.0f),
|
||||
BOTTOM_LEFT(-1.0f, 1.0f),
|
||||
BOTTOM_CENTER(0.0f, 1.0f),
|
||||
BOTTOM_RIGHT(1.0f, 1.0f);
|
||||
|
||||
private final float x;
|
||||
private final float y;
|
||||
|
||||
Alignment(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.esotericsoftware.spine.android.bounds;
|
||||
|
||||
public class Bounds {
|
||||
private double x;
|
||||
private double y;
|
||||
private double width;
|
||||
private double height;
|
||||
|
||||
public Bounds() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
}
|
||||
|
||||
public Bounds(double x, double y, double width, double height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(double width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(double height) {
|
||||
this.height = height;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.esotericsoftware.spine.android.bounds;
|
||||
|
||||
import com.esotericsoftware.spine.android.AndroidSkeletonDrawable;
|
||||
|
||||
public interface BoundsProvider {
|
||||
Bounds computeBounds(AndroidSkeletonDrawable drawable);
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.esotericsoftware.spine.android.bounds;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.FloatArray;
|
||||
import com.esotericsoftware.spine.android.AndroidSkeletonDrawable;
|
||||
|
||||
public class SetupPoseBounds implements BoundsProvider {
|
||||
|
||||
@Override
|
||||
public Bounds computeBounds(AndroidSkeletonDrawable drawable) {
|
||||
|
||||
Vector2 offset = new Vector2(0, 0);
|
||||
Vector2 size = new Vector2(0, 0);
|
||||
FloatArray floatArray = new FloatArray();
|
||||
|
||||
drawable.getSkeleton().getBounds(offset, size, floatArray);
|
||||
|
||||
return new Bounds(offset.x, offset.y, size.x, size.y);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user