mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
Changed scaleX and scaleY props meaning, they are now offset ratio with the bounds. Removed usage of skeleton scale, in favor of C3Matrix scale.
Add getter/setter to editor instance for numeric properties. Width and height changes scale the skeleton, not only bbox.
This commit is contained in:
parent
adfb71b5d3
commit
329ff5b073
@ -41,20 +41,24 @@ export class C3Matrix {
|
||||
public prevX = Infinity;
|
||||
public prevY = Infinity;
|
||||
public prevAngle = Infinity;
|
||||
public prevScaleX = Infinity;
|
||||
public prevScaleY = Infinity;
|
||||
|
||||
private tempPoint = new Vector2();
|
||||
|
||||
public update (x: number, y: number, angle: number) {
|
||||
if (this.prevX === x && this.prevY === y && this.prevAngle === angle) return false;
|
||||
public update (x: number, y: number, angle: number, scaleX = 1, scaleY = 1) {
|
||||
if (this.prevX === x && this.prevY === y && this.prevAngle === angle && this.prevScaleX === scaleX && this.prevScaleY === scaleY) return false;
|
||||
this.prevX = x;
|
||||
this.prevY = y;
|
||||
this.prevAngle = angle;
|
||||
this.prevScaleX = scaleX;
|
||||
this.prevScaleY = scaleY;
|
||||
const cos = Math.cos(angle);
|
||||
const sin = Math.sin(angle);
|
||||
this.a = cos;
|
||||
this.b = sin;
|
||||
this.c = -sin;
|
||||
this.d = cos;
|
||||
this.a = scaleX * cos;
|
||||
this.b = scaleX * sin;
|
||||
this.c = -scaleY * sin;
|
||||
this.d = scaleY * cos;
|
||||
this.tx = x;
|
||||
this.ty = y;
|
||||
return true;
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
import { type BlendMode, type Bone, ClippingAttachment, MathUtils, MeshAttachment, PathAttachment, RegionAttachment, RenderCommand, type Skeleton, SkeletonRendererCore, Utils, Vector2 } from "@esotericsoftware/spine-core";
|
||||
import { type BlendMode, type Bone, ClippingAttachment, MathUtils, MeshAttachment, PathAttachment, RegionAttachment, type RenderCommand, type Skeleton, SkeletonRendererCore, Utils, Vector2 } from "@esotericsoftware/spine-core";
|
||||
import type { C3Matrix } from "./C3Matrix";
|
||||
import { BlendingModeSpineToC3, type C3TextureEditor, type C3TextureRuntime } from "./C3Texture";
|
||||
|
||||
|
||||
@ -41,6 +41,8 @@ interface GameObject {
|
||||
state?: AnimationState,
|
||||
}
|
||||
|
||||
export type SpineBoundsProviderType = "setup" | "animation-skin" | "AABB";
|
||||
|
||||
export interface SpineBoundsProvider {
|
||||
/** Returns the bounding box for the skeleton, in skeleton space. */
|
||||
calculateBounds (gameObject: GameObject): Rectangle;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { AnimationState, AnimationStateListener, AssetLoader, Bone, C3Matrix, C3RendererRuntime, Event, NumberArrayLike, RegionAttachment, Skeleton, Skin, Slot, TextureAtlas, } from "@esotericsoftware/spine-construct3-lib";
|
||||
import type { AnimationState, AnimationStateListener, AssetLoader, Bone, C3Matrix, C3RendererRuntime, Event, NumberArrayLike, RegionAttachment, Skeleton, Skin, Slot, SpineBoundsProvider, SpineBoundsProviderType, TextureAtlas, } from "@esotericsoftware/spine-construct3-lib";
|
||||
|
||||
const C3 = globalThis.C3;
|
||||
const spine = globalThis.spine;
|
||||
@ -17,9 +17,10 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
propScaleX = 1;
|
||||
propScaleY = 1;
|
||||
propDebugSkeleton = false;
|
||||
propBoundsProvider: SpineBoundsProviderType = "setup";
|
||||
|
||||
isFlippedX = false;
|
||||
isPlaying = false;
|
||||
isPlaying = true;
|
||||
animationSpeed = 1.0;
|
||||
physicsMode = spine.Physics.update;
|
||||
customSkins: Record<string, Skin> = {};
|
||||
@ -43,6 +44,13 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
private matrix: C3Matrix;
|
||||
private requestRedraw = false;
|
||||
|
||||
private spineBounds = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 200,
|
||||
height: 200,
|
||||
};
|
||||
|
||||
private verticesTemp = spine.Utils.newFloatArray(2 * 1024);
|
||||
|
||||
private boneFollowers = new Map<string, { uid: number, offsetX: number, offsetY: number, offsetAngle: number }>();
|
||||
@ -71,7 +79,9 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
this.propSkin = skinProp === "" ? [] : skinProp.split(",");
|
||||
this.propAnimation = properties[4] as string;
|
||||
this.propDebugSkeleton = properties[5] as boolean;
|
||||
|
||||
const boundsProviderIndex = properties[6] as number;
|
||||
this.propBoundsProvider = boundsProviderIndex === 0 ? "setup" : "animation-skin";
|
||||
// properties[7] is PROP_BOUNDS_PROVIDER_MOVE
|
||||
this.propOffsetX = properties[8] as number;
|
||||
this.propOffsetY = properties[9] as number;
|
||||
this.propOffsetAngle = properties[10] as number;
|
||||
@ -115,7 +125,9 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
this.matrix.update(
|
||||
this.x + this.propOffsetX,
|
||||
this.y + this.propOffsetY,
|
||||
this.angle + this.propOffsetAngle);
|
||||
this.angle + this.propOffsetAngle,
|
||||
this.width / this.spineBounds.width * this.propScaleX * (this.isFlippedX ? -1 : 1),
|
||||
this.height / this.spineBounds.height * this.propScaleY);
|
||||
|
||||
if (this.isPlaying) this.update(this.dt);
|
||||
}
|
||||
@ -266,8 +278,8 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
pose.y = y;
|
||||
} else {
|
||||
const { x, y } = matrix.gameToSkeleton(touchX - handleObject.offsetX, touchY - handleObject.offsetY);
|
||||
pose.x = x / skeleton.scaleX;
|
||||
pose.y = -y / skeleton.scaleY * spine.Skeleton.yDir;
|
||||
pose.x = x;
|
||||
pose.y = -y * spine.Skeleton.yDir;
|
||||
}
|
||||
} else if (!this.prevLeftClickDown) {
|
||||
const applied = bone.applied;
|
||||
@ -422,8 +434,7 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
|
||||
this._setSkin();
|
||||
|
||||
this.skeleton.scaleX = this.isFlippedX ? -this.propScaleX : this.propScaleX;
|
||||
this.skeleton.scaleY = this.propScaleY;
|
||||
this.calculateBounds();
|
||||
|
||||
this.update(0);
|
||||
|
||||
@ -431,6 +442,28 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
this._trigger(C3.Plugins.EsotericSoftware_SpineConstruct3.Cnds.OnSkeletonLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
private calculateBounds () {
|
||||
const { skeleton } = this;
|
||||
if (!skeleton) return;
|
||||
|
||||
let boundsProvider: SpineBoundsProvider;
|
||||
console.log(this.propBoundsProvider);
|
||||
if (this.propBoundsProvider === "animation-skin") {
|
||||
const { propSkin, propAnimation } = this;
|
||||
if ((propSkin && propSkin.length > 0) || propAnimation) {
|
||||
boundsProvider = new spine.SkinsAndAnimationBoundsProvider(propAnimation, propSkin);
|
||||
} else {
|
||||
boundsProvider = new spine.SetupPoseBoundsProvider();
|
||||
}
|
||||
} else if (this.propBoundsProvider === "setup") {
|
||||
boundsProvider = new spine.SetupPoseBoundsProvider();
|
||||
} else {
|
||||
boundsProvider = new spine.AABBRectangleBoundsProvider(0, 0, 100, 100);
|
||||
}
|
||||
|
||||
this.spineBounds = boundsProvider.calculateBounds(this);
|
||||
}
|
||||
/**********/
|
||||
|
||||
/*
|
||||
@ -742,7 +775,6 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
const { x, y } = matrix.boneToGame(bone);
|
||||
const boneRotation = bone.applied.getWorldRotationX();
|
||||
|
||||
// Apply rotation to offset
|
||||
const rotationRadians = boneRotation * Math.PI / 180;
|
||||
const cos = Math.cos(rotationRadians);
|
||||
const sin = Math.sin(rotationRadians);
|
||||
@ -912,11 +944,6 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
|
||||
|
||||
public flipX (isFlippedX: boolean) {
|
||||
this.isFlippedX = isFlippedX;
|
||||
|
||||
const { skeleton } = this;
|
||||
if (skeleton) {
|
||||
skeleton.scaleX = isFlippedX ? -this.propScaleX : this.propScaleX;
|
||||
}
|
||||
}
|
||||
|
||||
public setPhysicsMode (mode: 0 | 1 | 2 | 3) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// / <reference types="editor/sdk" />
|
||||
|
||||
import type { AnimationState, AssetLoader, C3Matrix, C3RendererEditor, Skeleton, SpineBoundsProvider, TextureAtlas, } from "@esotericsoftware/spine-construct3-lib";
|
||||
import type { AnimationState, AssetLoader, C3Matrix, C3RendererEditor, Skeleton, SpineBoundsProvider, SpineBoundsProviderType, TextureAtlas, } from "@esotericsoftware/spine-construct3-lib";
|
||||
import type { SpineC3PluginType } from "./type";
|
||||
|
||||
const SDK = globalThis.SDK;
|
||||
@ -9,8 +9,6 @@ const PLUGIN_CLASS = SDK.Plugins.EsotericSoftware_SpineConstruct3;
|
||||
|
||||
let spine: typeof globalThis.spine;
|
||||
|
||||
type SpineBoundsProviderType = "setup" | "animation-skin" | "AABB";
|
||||
|
||||
class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
private layoutView?: SDK.UI.ILayoutView;
|
||||
private renderer?: SDK.Gfx.IWebGLRenderer;
|
||||
@ -33,6 +31,8 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
private positionModePrevX = 0;
|
||||
private positionModePrevY = 0;
|
||||
private positionModePrevAngle = 0;
|
||||
private positionModePrevWidth = 0;
|
||||
private positionModePrevHeight = 0;
|
||||
|
||||
/*
|
||||
* C3 GameObjects have two sizes:
|
||||
@ -46,14 +46,14 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
* In a Spine C3 GameObject:
|
||||
* - the original size is equivalent to spineBounds that is set selecting the BoundsProvider
|
||||
* - changing the C3 GameObject size from the editor will scale the skeleton by using skeleton.scaleX/Y
|
||||
* This information is stored into (PROP_SKELETON_SCALE_X and Y) and later passed to the runtime
|
||||
* This information is stored into (PROP_SKELETON_OFFSET_SCALE_X and Y) and later passed to the runtime
|
||||
* - the origin is position at the skeleton root
|
||||
*
|
||||
* positioningBounds allows to offset the position and the size of the C3 GameObject
|
||||
* with the one of the skeleton. When selected it allows to:
|
||||
* - move the C3 GameObjects position (visually the rectangle) keeping the skeleton still.
|
||||
* This is obtained by adding an offset to the GameObject position.
|
||||
* This information is stored into (PROP_SKELETON_SCALE_X and Y) and later passed to the runtime
|
||||
* This information is stored into (PROP_SKELETON_OFFSET_SCALE_X and Y) and later passed to the runtime
|
||||
* - scale the C3 GameObjects keeping the skeleton.scaleX/Y as-is.
|
||||
*/
|
||||
private spineBounds = {
|
||||
@ -137,6 +137,8 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
}
|
||||
|
||||
if (id === PLUGIN_CLASS.PROP_BOUNDS_PROVIDER) {
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_PROVIDER_MOVE, false);
|
||||
this.positioningBounds = false;
|
||||
this.resetBounds(true);
|
||||
this.layoutView?.Refresh();
|
||||
return
|
||||
@ -148,11 +150,8 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
this.positionModePrevX = this._inst.GetX();
|
||||
this.positionModePrevY = this._inst.GetY();
|
||||
this.positionModePrevAngle = this._inst.GetAngle();
|
||||
} else {
|
||||
const scaleX = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_X) as number;
|
||||
const scaleY = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_Y) as number;
|
||||
this.spineBounds.width = this._inst.GetWidth() / scaleX;
|
||||
this.spineBounds.height = this._inst.GetHeight() / scaleY;
|
||||
this.positionModePrevWidth = this._inst.GetWidth();
|
||||
this.positionModePrevHeight = this._inst.GetHeight();
|
||||
}
|
||||
this.positioningBounds = value;
|
||||
return
|
||||
@ -175,35 +174,26 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
|
||||
const rectX = _inst.GetX();
|
||||
const rectY = _inst.GetY();
|
||||
|
||||
if (this.positioningBounds) {
|
||||
const rectAngle = _inst.GetAngle();
|
||||
let offsetX = _inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X) as number;
|
||||
let offsetY = _inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y) as number;
|
||||
let offsetAngle = _inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE) as number;
|
||||
|
||||
if (!this.positioningBounds) {
|
||||
offsetX += rectX;
|
||||
offsetY += rectY;
|
||||
offsetAngle += rectAngle;
|
||||
this.propOffsetX += this.positionModePrevX - rectX;
|
||||
this.propOffsetY += this.positionModePrevY - rectY;
|
||||
this.propOffsetAngle = this.propOffsetAngle + this.positionModePrevAngle - rectAngle;
|
||||
|
||||
const baseScaleX = _inst.GetWidth() / this.spineBounds.width;
|
||||
const baseScaleY = _inst.GetHeight() / this.spineBounds.height;
|
||||
skeleton.scaleX = baseScaleX;
|
||||
skeleton.scaleY = baseScaleY;
|
||||
_inst.SetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_X, baseScaleX);
|
||||
_inst.SetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_Y, baseScaleY);
|
||||
} else {
|
||||
offsetX += this.positionModePrevX;
|
||||
offsetY += this.positionModePrevY;
|
||||
offsetAngle += this.positionModePrevAngle;
|
||||
_inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X, offsetX - rectX);
|
||||
_inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y, offsetY - rectY);
|
||||
_inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE, offsetAngle - rectAngle);
|
||||
this.positionModePrevX = rectX;
|
||||
this.positionModePrevY = rectY;
|
||||
this.positionModePrevAngle = rectAngle;
|
||||
|
||||
skeleton.scaleX = _inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_X) as number;
|
||||
skeleton.scaleY = _inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_Y) as number;
|
||||
const currentWidth = _inst.GetWidth();
|
||||
const currentHeight = _inst.GetHeight();
|
||||
if (currentWidth !== this.positionModePrevWidth || currentHeight !== this.positionModePrevHeight) {
|
||||
this.propScaleX = this.propScaleX * this.positionModePrevWidth / currentWidth;
|
||||
this.propScaleY = this.propScaleY * this.positionModePrevHeight / currentHeight;
|
||||
this.positionModePrevWidth = currentWidth;
|
||||
this.positionModePrevHeight = currentHeight;
|
||||
}
|
||||
}
|
||||
|
||||
this.update(0);
|
||||
@ -349,18 +339,21 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
}
|
||||
|
||||
public resetBounds (keepScale = false) {
|
||||
const { _inst } = this;
|
||||
|
||||
if (!this.skeleton || !this.textureAtlas) {
|
||||
this._inst.SetSize(200, 200);
|
||||
_inst.SetSize(200, 200);
|
||||
this.spineBounds.width = 200;
|
||||
this.spineBounds.height = 200;
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X, 0);
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y, 0);
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE, 0);
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_X, 1);
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_Y, 1);
|
||||
this.propOffsetX = 0;
|
||||
this.propOffsetY = 0;
|
||||
this.propOffsetAngle = 0;
|
||||
this.propScaleX = 1;
|
||||
this.propScaleY = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const { width: oldBoundsWidth, height: oldBoundsHeight } = this.spineBounds;
|
||||
this.setBoundsFromBoundsProvider();
|
||||
if (this.getErrorsString()) {
|
||||
this.spineBoundsInit = false;
|
||||
@ -369,43 +362,37 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
|
||||
this.spineBoundsInit = true;
|
||||
|
||||
const { x, y, width, height } = this.spineBounds;
|
||||
this._inst.SetOrigin(-x / width, -y / height);
|
||||
let { x, y, width, height } = this.spineBounds;
|
||||
_inst.SetOrigin(-x / width, -y / height);
|
||||
|
||||
let scaleX = 1;
|
||||
let scaleY = 1;
|
||||
if (keepScale) {
|
||||
scaleX = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_X) as number;
|
||||
scaleY = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_Y) as number;
|
||||
width *= (_inst.GetWidth() / oldBoundsWidth) * this.propScaleX;
|
||||
height *= (_inst.GetHeight() / oldBoundsHeight) * this.propScaleY;
|
||||
}
|
||||
this._inst.SetSize(width * scaleX, height * scaleY);
|
||||
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X, 0);
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y, 0);
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE, 0);
|
||||
_inst.SetSize(width, height);
|
||||
_inst.SetXY(_inst.GetX() + this.propOffsetX, _inst.GetY() + this.propOffsetY);
|
||||
_inst.SetAngle(_inst.GetAngle() + this.propOffsetAngle);
|
||||
|
||||
this.propOffsetX = 0;
|
||||
this.propOffsetY = 0;
|
||||
this.propOffsetAngle = 0;
|
||||
this.propScaleX = 1;
|
||||
this.propScaleY = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
private initBounds () {
|
||||
if (this.spineBoundsInit) return;
|
||||
if (this.spineBoundsInit || !this.skeleton) return;
|
||||
|
||||
const offsetX = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X) as number;
|
||||
const offsetY = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y) as number;
|
||||
const offsetAngle = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE) as number;
|
||||
const shiftedBounds = offsetX !== 0 || offsetY !== 0 || offsetAngle !== 0;
|
||||
|
||||
const scaleX = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_X) as number;
|
||||
const scaleY = this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_SCALE_Y) as number;
|
||||
const scaledBounds = scaleX !== 1 || scaleY !== 1;
|
||||
|
||||
if (!shiftedBounds && !scaledBounds) {
|
||||
this.resetBounds();
|
||||
return;
|
||||
}
|
||||
const matchesOldBounds = this._inst.GetWidth() === this.spineBounds.width && this._inst.GetHeight() === this.spineBounds.height;
|
||||
|
||||
this.setBoundsFromBoundsProvider();
|
||||
this.spineBounds.width = this._inst.GetWidth() / scaleX;
|
||||
this.spineBounds.height = this._inst.GetHeight() / scaleY;
|
||||
|
||||
const { x, y, width, height } = this.spineBounds;
|
||||
this._inst.SetOrigin(-x / width, -y / height);
|
||||
|
||||
if (matchesOldBounds) this._inst.SetSize(width, height);
|
||||
|
||||
this.spineBoundsInit = true;
|
||||
}
|
||||
@ -473,13 +460,59 @@ class SpineC3PluginInstance extends SDK.IWorldInstanceBase {
|
||||
state.update(delta);
|
||||
skeleton.update(delta);
|
||||
state.apply(skeleton);
|
||||
|
||||
const actualScaleX = (this._inst.GetWidth() / this.spineBounds.width) * this.propScaleX;
|
||||
const actualScaleY = (this._inst.GetHeight() / this.spineBounds.height) * this.propScaleY;
|
||||
|
||||
this.matrix.update(
|
||||
this._inst.GetX() + (this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X) as number),
|
||||
this._inst.GetY() + (this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y) as number),
|
||||
this._inst.GetAngle() + (this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE) as number));
|
||||
this._inst.GetX() + this.propOffsetX,
|
||||
this._inst.GetY() + this.propOffsetY,
|
||||
this._inst.GetAngle() + this.propOffsetAngle,
|
||||
actualScaleX,
|
||||
actualScaleY);
|
||||
skeleton.updateWorldTransform(spine.Physics.update);
|
||||
}
|
||||
|
||||
private get propScaleX () {
|
||||
return this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_OFFSET_SCALE_X) as number
|
||||
}
|
||||
|
||||
private set propScaleX (value: number) {
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_OFFSET_SCALE_X, value);
|
||||
}
|
||||
|
||||
private get propScaleY () {
|
||||
return this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_OFFSET_SCALE_Y) as number
|
||||
}
|
||||
|
||||
private set propScaleY (value: number) {
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_SKELETON_OFFSET_SCALE_Y, value);
|
||||
}
|
||||
|
||||
private get propOffsetX () {
|
||||
return this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X) as number;
|
||||
}
|
||||
|
||||
private set propOffsetX (value: number) {
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_X, value);
|
||||
}
|
||||
|
||||
private get propOffsetY () {
|
||||
return this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y) as number;
|
||||
}
|
||||
|
||||
private set propOffsetY (value: number) {
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_Y, value);
|
||||
}
|
||||
|
||||
private get propOffsetAngle () {
|
||||
return this._inst.GetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE) as number;
|
||||
}
|
||||
|
||||
private set propOffsetAngle (value: number) {
|
||||
this._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_OFFSET_ANGLE, value);
|
||||
}
|
||||
|
||||
GetTexture () {
|
||||
const image = this.GetObjectType().GetImage();
|
||||
return super.GetTexture(image);
|
||||
|
||||
@ -46,13 +46,13 @@
|
||||
"name": "Position bounds",
|
||||
"desc": "Keep the skeleton in a fixed position while adjusting the size and position of the bounds."
|
||||
},
|
||||
"spine-scale-x": {
|
||||
"name": "Scale X",
|
||||
"desc": "Scale X"
|
||||
"spine-offset-scale-x": {
|
||||
"name": "Offset Scale X",
|
||||
"desc": "Offset Scale X"
|
||||
},
|
||||
"spine-scale-y": {
|
||||
"name": "Scale Y",
|
||||
"desc": "Scale Y"
|
||||
"spine-offset-scale-y": {
|
||||
"name": "Offset Scale Y",
|
||||
"desc": "Offset Scale Y"
|
||||
},
|
||||
"spine-debug-skeleton": {
|
||||
"name": "Debug skeleton",
|
||||
|
||||
@ -46,13 +46,13 @@
|
||||
"name": "位置边界",
|
||||
"desc": "在调整边界大小和位置时保持骨架固定在一个位置。"
|
||||
},
|
||||
"spine-scale-x": {
|
||||
"name": "X缩放",
|
||||
"desc": "X缩放"
|
||||
"spine-offset-scale-x": {
|
||||
"name": "偏移缩放X",
|
||||
"desc": "偏移缩放X"
|
||||
},
|
||||
"spine-scale-y": {
|
||||
"name": "Y缩放",
|
||||
"desc": "Y缩放"
|
||||
"spine-offset-scale-y": {
|
||||
"name": "偏移缩放Y",
|
||||
"desc": "偏移缩放Y"
|
||||
},
|
||||
"spine-debug-skeleton": {
|
||||
"name": "调试骨架",
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import type { SpineBoundsProviderType } from "@esotericsoftware/spine-construct3-lib";
|
||||
|
||||
import type { SDKEditorInstanceClass } from "./instance.ts";
|
||||
|
||||
const SDK = globalThis.SDK;
|
||||
@ -29,12 +31,12 @@ const PLUGIN_CLASS = class SpineC3Plugin extends SDK.IPluginBase {
|
||||
static PROP_BOUNDS_OFFSET_X = "spine-bounds-offset-x";
|
||||
static PROP_BOUNDS_OFFSET_Y = "spine-bounds-offset-y";
|
||||
static PROP_BOUNDS_OFFSET_ANGLE = "spine-bounds-offset-angle";
|
||||
static PROP_SKELETON_SCALE_X = "spine-scale-x";
|
||||
static PROP_SKELETON_SCALE_Y = "spine-scale-y";
|
||||
static PROP_SKELETON_OFFSET_SCALE_X = "spine-offset-scale-x";
|
||||
static PROP_SKELETON_OFFSET_SCALE_Y = "spine-offset-scale-y";
|
||||
static PROP_DEBUG_SKELETON = "spine-debug-skeleton";
|
||||
|
||||
static TYPE_BOUNDS_SETUP = "setup";
|
||||
static TYPE_BOUNDS_ANIMATION_SKIN = "animation-skin";
|
||||
static TYPE_BOUNDS_SETUP: SpineBoundsProviderType = "setup";
|
||||
static TYPE_BOUNDS_ANIMATION_SKIN: SpineBoundsProviderType = "animation-skin";
|
||||
|
||||
constructor () {
|
||||
super(PLUGIN_ID);
|
||||
@ -91,11 +93,12 @@ const PLUGIN_CLASS = class SpineC3Plugin extends SDK.IPluginBase {
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_BOUNDS_OFFSET_X, 0),
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_BOUNDS_OFFSET_Y, 0),
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_BOUNDS_OFFSET_ANGLE, 0),
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_SKELETON_SCALE_X, 1),
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_SKELETON_SCALE_Y, 1),
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_SKELETON_OFFSET_SCALE_X, 1),
|
||||
new SDK.PluginProperty("float", SpineC3Plugin.PROP_SKELETON_OFFSET_SCALE_Y, 1),
|
||||
new SDK.PluginProperty("link", "set-bounds", {
|
||||
linkCallback: (instance) => {
|
||||
const sdkInst = instance as SDKEditorInstanceClass;
|
||||
sdkInst._inst.SetPropertyValue(PLUGIN_CLASS.PROP_BOUNDS_PROVIDER_MOVE, false);
|
||||
sdkInst.resetBounds(true);
|
||||
},
|
||||
callbackType: "for-each-instance"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user