mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[ts][pixi-v7][pixi-v8] Slot objects follow bone using local matrix making its transform equivalent to the one of the slot. See #3015.
This commit is contained in:
parent
6133cabd7e
commit
e5f7ffbb80
@ -55,25 +55,34 @@
|
|||||||
const bone = spineGO.skeleton.findBone("replaceMe");
|
const bone = spineGO.skeleton.findBone("replaceMe");
|
||||||
|
|
||||||
const myObject = {
|
const myObject = {
|
||||||
parentScaleX: 1, parentScaleY: 1, parentRotation: 0,
|
parentScaleX: 1, parentScaleY: 1, parentRotation: 0, parentShearX: 0, parentShearY: 0,
|
||||||
parent2ScaleX: 1, parent2ScaleY: 1, parent2Rotation: 0,
|
parent2ScaleX: 1, parent2ScaleY: 1, parent2Rotation: 0, parent2ShearX: 0, parent2ShearY: 0,
|
||||||
scaleX: 1, scaleY: 1, rotation: 0,
|
scaleX: 1, scaleY: 1, rotation: 0,
|
||||||
|
shearX: 0, shearY: 0,
|
||||||
|
spriteAlpha: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const gui = new lil.GUI({});
|
const gui = new lil.GUI({});
|
||||||
gui.add(myObject, 'parentScaleX').min(-3).max(3).step(0.1).name('parentScaleX').onChange(value => parentBone.pose.scaleX = value);
|
gui.add(myObject, 'parentScaleX').min(-3).max(3).step(0.1).name('parentScaleX').onChange(value => parentBone.pose.scaleX = value);
|
||||||
gui.add(myObject, 'parentScaleY').min(-3).max(3).step(0.1).name('parentScaleY').onChange(value => parentBone.pose.scaleY = value);
|
gui.add(myObject, 'parentScaleY').min(-3).max(3).step(0.1).name('parentScaleY').onChange(value => parentBone.pose.scaleY = value);
|
||||||
gui.add(myObject, 'parentRotation').min(-180).max(180).step(1).name('parentRotation').onChange(value => parentBone.pose.rotation = value);
|
gui.add(myObject, 'parentRotation').min(-180).max(180).step(1).name('parentRotation').onChange(value => parentBone.pose.rotation = value);
|
||||||
|
gui.add(myObject, 'parentShearX').min(-180).max(180).step(1).name('parentShearX').onChange(value => parentBone.pose.shearX = value);
|
||||||
|
gui.add(myObject, 'parentShearY').min(-180).max(180).step(1).name('parentShearY').onChange(value => parentBone.pose.shearY = value);
|
||||||
gui.add(myObject, 'parent2ScaleX').min(-3).max(3).step(0.1).name('parent2ScaleX').onChange(value => parent2Bone.pose.scaleX = value);
|
gui.add(myObject, 'parent2ScaleX').min(-3).max(3).step(0.1).name('parent2ScaleX').onChange(value => parent2Bone.pose.scaleX = value);
|
||||||
gui.add(myObject, 'parent2ScaleY').min(-3).max(3).step(0.1).name('parent2ScaleY').onChange(value => parent2Bone.pose.scaleY = value);
|
gui.add(myObject, 'parent2ScaleY').min(-3).max(3).step(0.1).name('parent2ScaleY').onChange(value => parent2Bone.pose.scaleY = value);
|
||||||
gui.add(myObject, 'parent2Rotation').min(-180).max(180).step(1).name('parent2Rotation').onChange(value => parent2Bone.pose.rotation = value);
|
gui.add(myObject, 'parent2Rotation').min(-180).max(180).step(1).name('parent2Rotation').onChange(value => parent2Bone.pose.rotation = value);
|
||||||
|
gui.add(myObject, 'parent2ShearX').min(-180).max(180).step(1).name('parent2ShearX').onChange(value => parent2Bone.pose.shearX = value);
|
||||||
|
gui.add(myObject, 'parent2ShearY').min(-180).max(180).step(1).name('parent2ShearY').onChange(value => parent2Bone.pose.shearY = value);
|
||||||
gui.add(myObject, 'scaleX').min(-3).max(3).step(0.1).name('scaleX').onChange(value => bone.pose.scaleX = value);
|
gui.add(myObject, 'scaleX').min(-3).max(3).step(0.1).name('scaleX').onChange(value => bone.pose.scaleX = value);
|
||||||
gui.add(myObject, 'scaleY').min(-3).max(3).step(0.1).name('scaleY').onChange(value => bone.pose.scaleY = value);
|
gui.add(myObject, 'scaleY').min(-3).max(3).step(0.1).name('scaleY').onChange(value => bone.pose.scaleY = value);
|
||||||
gui.add(myObject, 'rotation').min(-180).max(180).step(1).name('rotation').onChange(value => bone.pose.rotation = value);
|
gui.add(myObject, 'rotation').min(-180).max(180).step(1).name('rotation').onChange(value => bone.pose.rotation = value);
|
||||||
|
gui.add(myObject, 'shearX').min(-180).max(180).step(1).name('shearX').onChange(value => bone.pose.shearX = value);
|
||||||
|
gui.add(myObject, 'shearY').min(-180).max(180).step(1).name('shearY').onChange(value => bone.pose.shearY = value);
|
||||||
|
gui.add(myObject, 'spriteAlpha').min(0).max(1).step(0.01).name('spriteAlpha').onChange(value => sprite.alpha = value);
|
||||||
|
|
||||||
// add instructions
|
// add instructions
|
||||||
const basicText = new PIXI.Text(
|
const basicText = new PIXI.Text(
|
||||||
"This example shows that slot objects follow scale and rotation from ancestors too, but if a rotation on a bone occurs scale won't work anymore on ancestors.",
|
"This example shows that slot objects can follow scale, shear and rotation from ancestors too.",
|
||||||
{ fontSize: 20, fill: "white", wordWrap: true, wordWrapWidth: 300 }
|
{ fontSize: 20, fill: "white", wordWrap: true, wordWrapWidth: 300 }
|
||||||
);
|
);
|
||||||
basicText.position.set(10, 10);
|
basicText.position.set(10, 10);
|
||||||
|
|||||||
@ -540,25 +540,16 @@ export class Spine extends Container {
|
|||||||
slotObject.visible = this.skeleton.drawOrder.includes(slot) && followAttachmentValue;
|
slotObject.visible = this.skeleton.drawOrder.includes(slot) && followAttachmentValue;
|
||||||
|
|
||||||
if (slotObject.visible) {
|
if (slotObject.visible) {
|
||||||
const applied = slot.bone.applied;
|
let applied = slot.bone.applied;
|
||||||
slotObject.position.set(applied.worldX, applied.worldY);
|
|
||||||
slotObject.angle = applied.getWorldRotationX();
|
|
||||||
|
|
||||||
let bone: Bone | null = slot.bone;
|
const matrix = slotObject.localTransform;
|
||||||
let cumulativeScaleX = 1;
|
matrix.a = applied.a;
|
||||||
let cumulativeScaleY = 1;
|
matrix.b = applied.c;
|
||||||
while (bone) {
|
matrix.c = -applied.b;
|
||||||
cumulativeScaleX *= bone.applied.scaleX;
|
matrix.d = -applied.d;
|
||||||
cumulativeScaleY *= bone.applied.scaleY;
|
matrix.tx = applied.worldX;
|
||||||
bone = bone.parent;
|
matrix.ty = applied.worldY;
|
||||||
};
|
slotObject.transform.setFromMatrix(matrix);
|
||||||
|
|
||||||
if (cumulativeScaleX < 0) slotObject.angle -= 180;
|
|
||||||
|
|
||||||
slotObject.scale.set(
|
|
||||||
applied.getWorldScaleX() * Math.sign(cumulativeScaleX),
|
|
||||||
applied.getWorldScaleY() * Math.sign(cumulativeScaleY),
|
|
||||||
);
|
|
||||||
|
|
||||||
slotObject.zIndex = zIndex + 1;
|
slotObject.zIndex = zIndex + 1;
|
||||||
slotObject.alpha = this.skeleton.color.a * pose.color.a;
|
slotObject.alpha = this.skeleton.color.a * pose.color.a;
|
||||||
|
|||||||
@ -54,25 +54,34 @@
|
|||||||
const bone = spineGO.skeleton.findBone("replaceMe");
|
const bone = spineGO.skeleton.findBone("replaceMe");
|
||||||
|
|
||||||
const myObject = {
|
const myObject = {
|
||||||
parentScaleX: 1, parentScaleY: 1, parentRotation: 0,
|
parentScaleX: 1, parentScaleY: 1, parentRotation: 0, parentShearX: 0, parentShearY: 0,
|
||||||
parent2ScaleX: 1, parent2ScaleY: 1, parent2Rotation: 0,
|
parent2ScaleX: 1, parent2ScaleY: 1, parent2Rotation: 0, parent2ShearX: 0, parent2ShearY: 0,
|
||||||
scaleX: 1, scaleY: 1, rotation: 0,
|
scaleX: 1, scaleY: 1, rotation: 0,
|
||||||
|
shearX: 0, shearY: 0,
|
||||||
|
spriteAlpha: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const gui = new lil.GUI({});
|
const gui = new lil.GUI({});
|
||||||
gui.add(myObject, 'parentScaleX').min(-3).max(3).step(0.1).name('parentScaleX').onChange(value => parentBone.pose.scaleX = value);
|
gui.add(myObject, 'parentScaleX').min(-3).max(3).step(0.1).name('parentScaleX').onChange(value => parentBone.pose.scaleX = value);
|
||||||
gui.add(myObject, 'parentScaleY').min(-3).max(3).step(0.1).name('parentScaleY').onChange(value => parentBone.pose.scaleY = value);
|
gui.add(myObject, 'parentScaleY').min(-3).max(3).step(0.1).name('parentScaleY').onChange(value => parentBone.pose.scaleY = value);
|
||||||
gui.add(myObject, 'parentRotation').min(-180).max(180).step(1).name('parentRotation').onChange(value => parentBone.pose.rotation = value);
|
gui.add(myObject, 'parentRotation').min(-180).max(180).step(1).name('parentRotation').onChange(value => parentBone.pose.rotation = value);
|
||||||
|
gui.add(myObject, 'parentShearX').min(-180).max(180).step(1).name('parentShearX').onChange(value => parentBone.pose.shearX = value);
|
||||||
|
gui.add(myObject, 'parentShearY').min(-180).max(180).step(1).name('parentShearY').onChange(value => parentBone.pose.shearY = value);
|
||||||
gui.add(myObject, 'parent2ScaleX').min(-3).max(3).step(0.1).name('parent2ScaleX').onChange(value => parent2Bone.pose.scaleX = value);
|
gui.add(myObject, 'parent2ScaleX').min(-3).max(3).step(0.1).name('parent2ScaleX').onChange(value => parent2Bone.pose.scaleX = value);
|
||||||
gui.add(myObject, 'parent2ScaleY').min(-3).max(3).step(0.1).name('parent2ScaleY').onChange(value => parent2Bone.pose.scaleY = value);
|
gui.add(myObject, 'parent2ScaleY').min(-3).max(3).step(0.1).name('parent2ScaleY').onChange(value => parent2Bone.pose.scaleY = value);
|
||||||
gui.add(myObject, 'parent2Rotation').min(-180).max(180).step(1).name('parent2Rotation').onChange(value => parent2Bone.pose.rotation = value);
|
gui.add(myObject, 'parent2Rotation').min(-180).max(180).step(1).name('parent2Rotation').onChange(value => parent2Bone.pose.rotation = value);
|
||||||
|
gui.add(myObject, 'parent2ShearX').min(-180).max(180).step(1).name('parent2ShearX').onChange(value => parent2Bone.pose.shearX = value);
|
||||||
|
gui.add(myObject, 'parent2ShearY').min(-180).max(180).step(1).name('parent2ShearY').onChange(value => parent2Bone.pose.shearY = value);
|
||||||
gui.add(myObject, 'scaleX').min(-3).max(3).step(0.1).name('scaleX').onChange(value => bone.pose.scaleX = value);
|
gui.add(myObject, 'scaleX').min(-3).max(3).step(0.1).name('scaleX').onChange(value => bone.pose.scaleX = value);
|
||||||
gui.add(myObject, 'scaleY').min(-3).max(3).step(0.1).name('scaleY').onChange(value => bone.pose.scaleY = value);
|
gui.add(myObject, 'scaleY').min(-3).max(3).step(0.1).name('scaleY').onChange(value => bone.pose.scaleY = value);
|
||||||
gui.add(myObject, 'rotation').min(-180).max(180).step(1).name('rotation').onChange(value => bone.pose.rotation = value);
|
gui.add(myObject, 'rotation').min(-180).max(180).step(1).name('rotation').onChange(value => bone.pose.rotation = value);
|
||||||
|
gui.add(myObject, 'shearX').min(-180).max(180).step(1).name('shearX').onChange(value => bone.pose.shearX = value);
|
||||||
|
gui.add(myObject, 'shearY').min(-180).max(180).step(1).name('shearY').onChange(value => bone.pose.shearY = value);
|
||||||
|
gui.add(myObject, 'spriteAlpha').min(0).max(1).step(0.01).name('spriteAlpha').onChange(value => sprite.alpha = value);
|
||||||
|
|
||||||
// add instructions
|
// add instructions
|
||||||
const basicText = new PIXI.Text({
|
const basicText = new PIXI.Text({
|
||||||
text: "This example shows that slot objects follow scale and rotation from ancestors too, but if a rotation on a bone occurs scale won't work anymore on ancestors.",
|
text: "This example shows that slot objects can follow scale, shear and rotation from ancestors too.",
|
||||||
style: { fontSize: 20, fill: "white", wordWrap: true, wordWrapWidth: 300 }
|
style: { fontSize: 20, fill: "white", wordWrap: true, wordWrapWidth: 300 }
|
||||||
});
|
});
|
||||||
basicText.position.set(10, 10);
|
basicText.position.set(10, 10);
|
||||||
|
|||||||
@ -785,26 +785,16 @@ export class Spine extends ViewContainer {
|
|||||||
container.visible = this.skeleton.drawOrder.includes(slot) && followAttachmentValue;
|
container.visible = this.skeleton.drawOrder.includes(slot) && followAttachmentValue;
|
||||||
|
|
||||||
if (container.visible) {
|
if (container.visible) {
|
||||||
let bone: Bone | null = slot.bone;
|
let applied = slot.bone.applied;
|
||||||
|
|
||||||
const applied = bone.applied;
|
const matrix = container.localTransform;
|
||||||
container.position.set(applied.worldX, applied.worldY);
|
matrix.a = applied.a;
|
||||||
container.angle = applied.getWorldRotationX();
|
matrix.b = applied.c;
|
||||||
|
matrix.c = -applied.b;
|
||||||
let cumulativeScaleX = 1;
|
matrix.d = -applied.d;
|
||||||
let cumulativeScaleY = 1;
|
matrix.tx = applied.worldX;
|
||||||
while (bone) {
|
matrix.ty = applied.worldY;
|
||||||
cumulativeScaleX *= bone.applied.scaleX;
|
container.setFromMatrix(matrix);
|
||||||
cumulativeScaleY *= bone.applied.scaleY;
|
|
||||||
bone = bone.parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (cumulativeScaleX < 0) container.angle -= 180;
|
|
||||||
|
|
||||||
container.scale.set(
|
|
||||||
applied.getWorldScaleX() * Math.sign(cumulativeScaleX),
|
|
||||||
applied.getWorldScaleY() * Math.sign(cumulativeScaleY),
|
|
||||||
);
|
|
||||||
|
|
||||||
container.alpha = this.skeleton.color.a * pose.color.a;
|
container.alpha = this.skeleton.color.a * pose.color.a;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user