Set sizenow affects also followers. Followers are scaled on their local axis because C3 lacks of a transformation matrix and does not allow to control shear, that would be necessary to scale wrt parent axis.

This commit is contained in:
Davide Tantillo 2026-03-23 15:41:16 +01:00
parent 05344e805c
commit 0f671e1cca

View File

@ -35,7 +35,16 @@ const spine = globalThis.spine;
spine.Skeleton.yDown = true;
type BoneOverride = Partial<BoneLocal> & { mode: "game" | "local" };
type BoneFollower = { uid: number, offsetX: number, offsetY: number, offsetAngle: number };
type BoneFollower = {
uid: number,
offsetX: number,
offsetY: number,
offsetAngle: number,
originalWidth: number,
originalHeight: number,
refSkeletonWidth: number,
refSkeletonHeight: number,
};
class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
propAtlas = "";
@ -844,7 +853,16 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
return;
}
const follower = { uid, offsetX, offsetY, offsetAngle };
const instance = this.runtime.getInstanceByUid(uid) as IWorldInstance;
if (!instance) return;
const follower: BoneFollower = {
uid, offsetX, offsetY, offsetAngle,
originalWidth: Math.abs(instance.width),
originalHeight: Math.abs(instance.height),
refSkeletonWidth: Math.abs(this.width),
refSkeletonHeight: Math.abs(this.height),
};
const followers = this.boneFollowers.get(boneName);
if (!followers) {
this.boneFollowers.set(boneName, [follower]);
@ -852,11 +870,8 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
followers.push(follower);
}
const instance = this.runtime.getInstanceByUid(uid) as IWorldInstance;
if (instance) {
if (this.isMirrored) this.mirrorFollower(instance);
if (this.isFlipped) this.flipFollower(instance);
}
if (this.isMirrored) this.mirrorFollower(instance);
if (this.isFlipped) this.flipFollower(instance);
this.isPlaying = true;
}
@ -878,6 +893,32 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
this.boneFollowers.delete(boneName);
}
setSize (w: number, h: number): void {
const prevW = this.width;
const prevH = this.height;
super.setSize(w, h);
if (prevW === 0 || prevH === 0) return;
const mirrorChanged = (prevW > 0) !== (this.width > 0);
const flipChanged = (prevH > 0) !== (this.height > 0);
if (mirrorChanged) this.isMirrored = !this.isMirrored;
if (flipChanged) this.isFlipped = !this.isFlipped;
if (this.boneFollowers.size === 0) return;
if (!mirrorChanged && !flipChanged) return;
for (const [, followers] of this.boneFollowers) {
for (const follower of followers) {
const instance = this.runtime.getInstanceByUid(follower.uid) as IWorldInstance;
if (!instance) continue;
if (mirrorChanged) this.mirrorFollower(instance);
if (flipChanged) this.flipFollower(instance);
}
}
}
private mirrorFollower (instance: IWorldInstance) {
instance.setSize(-instance.width, instance.height);
}
@ -925,6 +966,15 @@ class SpineC3Instance extends globalThis.ISDKWorldInstanceBase {
const angle = boneRotation + follower.offsetAngle;
instance.angleDegrees = gameObjectAngleDeg + (negateAngle ? -angle : angle);
const sx = Math.abs(this.width) / follower.refSkeletonWidth;
const sy = Math.abs(this.height) / follower.refSkeletonHeight;
const mirrorSign = this.isMirrored ? -1 : 1;
const flipSign = this.isFlipped ? -1 : 1;
instance.setSize(
follower.originalWidth * sx * mirrorSign,
follower.originalHeight * sy * flipSign
);
}
}
}