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;
for (let i = 0, n = bones.length; i < n; i++) {
const bone = bones[i];
if (!bone.parent) continue;
// if (!bone.parent) continue;
const boneApplied = bone.applied;
const { x: x1, y: y1 } = matrix.skeletonToGame(boneApplied.worldX, boneApplied.worldY);
const endX = boneApplied.worldX + bone.data.length * boneApplied.a;

View File

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

View File

@ -37,8 +37,12 @@ C3.Plugins.EsotericSoftware_SpineConstruct3.Acts =
this.setSkin(skinList.split(","));
},
FlipX (this: SDKInstanceClass, isFlippedX: boolean) {
this.flipX(isFlippedX);
Mirror (this: SDKInstanceClass, isMirrored: boolean) {
this.mirror(isMirrored);
},
Flip (this: SDKInstanceClass, isFlipped: boolean) {
this.flip(isFlipped);
},
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;
return eventMatches && trackMatches && animationMatches;
},
IsFlippedX (this: SpineC3Instance) {
return this.isFlippedX;
IsMirrored (this: SpineC3Instance) {
return this.isMirrored;
},
IsFlipped (this: SpineC3Instance) {
return this.isFlipped;
},
IsSkeletonLoaded (this: SpineC3Instance) {
return this.skeletonLoaded;

View File

@ -52,7 +52,8 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
propBoundsProvider: SpineBoundsProviderType = "setup";
propEnableCollision = false;
isFlippedX = false;
isMirrored = false;
isFlipped = false;
collisionSpriteInstance?: IWorldInstance;
collisionSpriteClassName = "";
isPlaying = true;
@ -166,7 +167,7 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
this.y + this.propOffsetY,
this.totalZ,
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.updateCollisionSprite();
@ -848,6 +849,14 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
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) {
if (this.boneFollowers.size === 0) return;
@ -872,8 +881,8 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
const rotatedOffsetX = follower.offsetX * cos - follower.offsetY * sin;
const rotatedOffsetY = follower.offsetX * sin + follower.offsetY * cos;
instance.x = x + rotatedOffsetX;
instance.y = y + rotatedOffsetY;
instance.x = x + rotatedOffsetX * (this.isMirrored ? -1 : 1);
instance.y = y + rotatedOffsetY * (this.isFlipped ? -1 : 1);
instance.angleDegrees = boneRotation + follower.offsetAngle;
}
}
@ -1101,8 +1110,34 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
* Skeleton
*/
public flipX (isFlippedX: boolean) {
this.isFlippedX = isFlippedX;
public mirror (isMirrored: boolean) {
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) {

View File

@ -118,10 +118,15 @@
}
}
},
"is-flipped-x": {
"list-name": "Is flipped X",
"display-text": "Is flipped X",
"description": "Check if the skeleton is flipped horizontally"
"is-mirrored": {
"list-name": "Is mirrored",
"display-text": "Is mirrored",
"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": {
"list-name": "Is skeleton loaded",
@ -180,14 +185,25 @@
}
}
},
"flip-x": {
"list-name": "Flip X",
"display-text": "Set flip X to {0}",
"description": "Flip the skeleton horizontally",
"mirror": {
"list-name": "Mirror",
"display-text": "Set mirrored to {0}",
"description": "Mirror the skeleton horizontally",
"params": {
"is-flipped-x": {
"name": "Is flipped X",
"desc": "True to flip the skeleton horizontally, false to show normally."
"is-mirrored": {
"name": "Is mirrored",
"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": {
"list-name": "是否水平翻转",
"display-text": "是否水平翻转",
"description": "检查骨架是否水平翻转"
"is-mirrored": {
"list-name": "是否镜像",
"display-text": "是否镜像",
"description": "检查骨架是否水平镜像"
},
"is-flipped": {
"list-name": "是否翻转",
"display-text": "是否翻转",
"description": "检查骨架是否垂直翻转"
},
"is-skeleton-loaded": {
"list-name": "骨架是否已加载",
@ -180,14 +185,25 @@
}
}
},
"flip-x": {
"list-name": "水平翻转",
"display-text": "设置水平翻转为 {0}",
"description": "水平翻转骨架",
"mirror": {
"list-name": "镜像",
"display-text": "设置镜像为 {0}",
"description": "水平镜像骨架",
"params": {
"is-flipped-x": {
"name": "是否水平翻转",
"desc": "设为true时水平翻转骨架设为false时正常显示。"
"is-mirrored": {
"name": "是否镜像",
"desc": "设为true时水平镜像骨架设为false时正常显示。"
}
}
},
"flip": {
"list-name": "翻转",
"display-text": "设置翻转为 {0}",
"description": "垂直翻转骨架",
"params": {
"is-flipped": {
"name": "是否翻转",
"desc": "设为true时垂直翻转骨架设为false时正常显示。"
}
}
},