Replaced flipx with mirror, and add flip, adapting to c3 names. Fix follower flip/mirror.

This commit is contained in:
Davide Tantillo 2026-02-25 15:26:51 +01:00
parent 758058ec39
commit d5b04ea1bd
7 changed files with 128 additions and 38 deletions

View File

@ -129,7 +129,7 @@ abstract class C3SkeletonRenderer<
const bones = skeleton.bones; const bones = skeleton.bones;
for (let i = 0, n = bones.length; i < n; i++) { for (let i = 0, n = bones.length; i < n; i++) {
const bone = bones[i]; const bone = bones[i];
if (!bone.parent) continue; // if (!bone.parent) continue;
const boneApplied = bone.applied; const boneApplied = bone.applied;
const { x: x1, y: y1 } = matrix.skeletonToGame(boneApplied.worldX, boneApplied.worldY); const { x: x1, y: y1 } = matrix.skeletonToGame(boneApplied.worldX, boneApplied.worldY);
const endX = boneApplied.worldX + bone.data.length * boneApplied.a; const endX = boneApplied.worldX + bone.data.length * boneApplied.a;

View File

@ -31,8 +31,13 @@
] ]
}, },
{ {
"id": "is-flipped-x", "id": "is-mirrored",
"scriptName": "IsFlippedX", "scriptName": "IsMirrored",
"isTrigger": false
},
{
"id": "is-flipped",
"scriptName": "IsFlipped",
"isTrigger": false "isTrigger": false
}, },
{ {
@ -95,12 +100,23 @@
] ]
}, },
{ {
"id": "flip-x", "id": "mirror",
"scriptName": "FlipX", "scriptName": "Mirror",
"highlight": false, "highlight": false,
"params": [ "params": [
{ {
"id": "is-flipped-x", "id": "is-mirrored",
"type": "boolean"
}
]
},
{
"id": "flip",
"scriptName": "Flip",
"highlight": false,
"params": [
{
"id": "is-flipped",
"type": "boolean" "type": "boolean"
} }
] ]

View File

@ -37,8 +37,12 @@ C3.Plugins.EsotericSoftware_SpineConstruct3.Acts =
this.setSkin(skinList.split(",")); this.setSkin(skinList.split(","));
}, },
FlipX (this: SDKInstanceClass, isFlippedX: boolean) { Mirror (this: SDKInstanceClass, isMirrored: boolean) {
this.flipX(isFlippedX); this.mirror(isMirrored);
},
Flip (this: SDKInstanceClass, isFlipped: boolean) {
this.flip(isFlipped);
}, },
SetAnimation (this: SDKInstanceClass, track: number, animation: string, loop = false) { SetAnimation (this: SDKInstanceClass, track: number, animation: string, loop = false) {

View File

@ -42,8 +42,11 @@ C3.Plugins.EsotericSoftware_SpineConstruct3.Cnds =
const animationMatches = animation === "" || this.triggeredEventAnimation === animation; const animationMatches = animation === "" || this.triggeredEventAnimation === animation;
return eventMatches && trackMatches && animationMatches; return eventMatches && trackMatches && animationMatches;
}, },
IsFlippedX (this: SpineC3Instance) { IsMirrored (this: SpineC3Instance) {
return this.isFlippedX; return this.isMirrored;
},
IsFlipped (this: SpineC3Instance) {
return this.isFlipped;
}, },
IsSkeletonLoaded (this: SpineC3Instance) { IsSkeletonLoaded (this: SpineC3Instance) {
return this.skeletonLoaded; return this.skeletonLoaded;

View File

@ -52,7 +52,8 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
propBoundsProvider: SpineBoundsProviderType = "setup"; propBoundsProvider: SpineBoundsProviderType = "setup";
propEnableCollision = false; propEnableCollision = false;
isFlippedX = false; isMirrored = false;
isFlipped = false;
collisionSpriteInstance?: IWorldInstance; collisionSpriteInstance?: IWorldInstance;
collisionSpriteClassName = ""; collisionSpriteClassName = "";
isPlaying = true; isPlaying = true;
@ -166,7 +167,7 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
this.y + this.propOffsetY, this.y + this.propOffsetY,
this.totalZ, this.totalZ,
this.angle + this.propOffsetAngle, this.angle + this.propOffsetAngle,
this.width / this.spineBounds.width * this.propScaleX * (this.isFlippedX ? -1 : 1), this.width / this.spineBounds.width * this.propScaleX,
this.height / this.spineBounds.height * this.propScaleY); this.height / this.spineBounds.height * this.propScaleY);
this.updateCollisionSprite(); this.updateCollisionSprite();
@ -848,6 +849,14 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
this.boneFollowers.delete(boneName); this.boneFollowers.delete(boneName);
} }
private mirrorFollower (instance: IWorldInstance) {
instance.setSize(-instance.width, instance.height);
}
private flipFollower (instance: IWorldInstance) {
instance.setSize(instance.width, -instance.height);
}
private updateBoneFollowers (matrix: C3Matrix) { private updateBoneFollowers (matrix: C3Matrix) {
if (this.boneFollowers.size === 0) return; if (this.boneFollowers.size === 0) return;
@ -872,8 +881,8 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
const rotatedOffsetX = follower.offsetX * cos - follower.offsetY * sin; const rotatedOffsetX = follower.offsetX * cos - follower.offsetY * sin;
const rotatedOffsetY = follower.offsetX * sin + follower.offsetY * cos; const rotatedOffsetY = follower.offsetX * sin + follower.offsetY * cos;
instance.x = x + rotatedOffsetX; instance.x = x + rotatedOffsetX * (this.isMirrored ? -1 : 1);
instance.y = y + rotatedOffsetY; instance.y = y + rotatedOffsetY * (this.isFlipped ? -1 : 1);
instance.angleDegrees = boneRotation + follower.offsetAngle; instance.angleDegrees = boneRotation + follower.offsetAngle;
} }
} }
@ -1101,8 +1110,34 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
* Skeleton * Skeleton
*/ */
public flipX (isFlippedX: boolean) { public mirror (isMirrored: boolean) {
this.isFlippedX = isFlippedX; if (isMirrored !== this.isMirrored) {
this.isMirrored = isMirrored;
this.width = -this.width
for (const [, followers] of this.boneFollowers) {
for (const follower of followers) {
const instance = this.runtime.getInstanceByUid(follower.uid) as IWorldInstance;
if (instance) this.mirrorFollower(instance);
}
}
}
}
public flip (isFlipped: boolean) {
if (isFlipped !== this.isFlipped) {
this.isFlipped = isFlipped;
this.height = -this.height;
for (const [, followers] of this.boneFollowers) {
for (const follower of followers) {
const instance = this.runtime.getInstanceByUid(follower.uid) as IWorldInstance;
if (instance) this.flipFollower(instance);
}
}
}
} }
public setPhysicsMode (mode: 0 | 1 | 2 | 3) { public setPhysicsMode (mode: 0 | 1 | 2 | 3) {

View File

@ -118,10 +118,15 @@
} }
} }
}, },
"is-flipped-x": { "is-mirrored": {
"list-name": "Is flipped X", "list-name": "Is mirrored",
"display-text": "Is flipped X", "display-text": "Is mirrored",
"description": "Check if the skeleton is flipped horizontally" "description": "Check if the skeleton is mirrored horizontally"
},
"is-flipped": {
"list-name": "Is flipped",
"display-text": "Is flipped",
"description": "Check if the skeleton is flipped vertically"
}, },
"is-skeleton-loaded": { "is-skeleton-loaded": {
"list-name": "Is skeleton loaded", "list-name": "Is skeleton loaded",
@ -180,14 +185,25 @@
} }
} }
}, },
"flip-x": { "mirror": {
"list-name": "Flip X", "list-name": "Mirror",
"display-text": "Set flip X to {0}", "display-text": "Set mirrored to {0}",
"description": "Flip the skeleton horizontally", "description": "Mirror the skeleton horizontally",
"params": { "params": {
"is-flipped-x": { "is-mirrored": {
"name": "Is flipped X", "name": "Is mirrored",
"desc": "True to flip the skeleton horizontally, false to show normally." "desc": "True to mirror the skeleton horizontally, false to show normally."
}
}
},
"flip": {
"list-name": "Flip",
"display-text": "Set flipped to {0}",
"description": "Flip the skeleton vertically",
"params": {
"is-flipped": {
"name": "Is flipped",
"desc": "True to flip the skeleton vertically, false to show normally."
} }
} }
}, },

View File

@ -118,10 +118,15 @@
} }
} }
}, },
"is-flipped-x": { "is-mirrored": {
"list-name": "是否水平翻转", "list-name": "是否镜像",
"display-text": "是否水平翻转", "display-text": "是否镜像",
"description": "检查骨架是否水平翻转" "description": "检查骨架是否水平镜像"
},
"is-flipped": {
"list-name": "是否翻转",
"display-text": "是否翻转",
"description": "检查骨架是否垂直翻转"
}, },
"is-skeleton-loaded": { "is-skeleton-loaded": {
"list-name": "骨架是否已加载", "list-name": "骨架是否已加载",
@ -180,14 +185,25 @@
} }
} }
}, },
"flip-x": { "mirror": {
"list-name": "水平翻转", "list-name": "镜像",
"display-text": "设置水平翻转为 {0}", "display-text": "设置镜像为 {0}",
"description": "水平翻转骨架", "description": "水平镜像骨架",
"params": { "params": {
"is-flipped-x": { "is-mirrored": {
"name": "是否水平翻转", "name": "是否镜像",
"desc": "设为true时水平翻转骨架设为false时正常显示。" "desc": "设为true时水平镜像骨架设为false时正常显示。"
}
}
},
"flip": {
"list-name": "翻转",
"display-text": "设置翻转为 {0}",
"description": "垂直翻转骨架",
"params": {
"is-flipped": {
"name": "是否翻转",
"desc": "设为true时垂直翻转骨架设为false时正常显示。"
} }
} }
}, },