@@ -70,6 +70,8 @@ export interface ISpineOptions {
70
70
* a dark tint mesh in the skeleton.
71
71
* */
72
72
slotMeshFactory ?: ( ) => ISlotMesh ;
73
+ /** True, if the atlas images are premultiplied alpha. If not passed, the value is read from the atlas file. */
74
+ pma ?: boolean ;
73
75
}
74
76
75
77
/**
@@ -111,7 +113,7 @@ export class Spine extends Container {
111
113
this . _debug = value ;
112
114
}
113
115
114
- protected slotMeshFactory : ( ) => ISlotMesh = ( ) => new SlotMesh ( ) ;
116
+ protected slotMeshFactory : ( pma : boolean ) => ISlotMesh = ( pma : boolean ) => new SlotMesh ( pma ) ;
115
117
116
118
beforeUpdateWorldTransforms : ( object : Spine ) => void = ( ) => { } ;
117
119
afterUpdateWorldTransforms : ( object : Spine ) => void = ( ) => { } ;
@@ -143,6 +145,8 @@ export class Spine extends Container {
143
145
144
146
private lightColor = new Color ( ) ;
145
147
private darkColor = new Color ( ) ;
148
+ private twoColorTint = false ;
149
+ private pma = false ;
146
150
147
151
constructor ( skeletonData : SkeletonData , options ?: ISpineOptions ) {
148
152
super ( ) ;
@@ -151,6 +155,7 @@ export class Spine extends Container {
151
155
const animData = new AnimationStateData ( skeletonData ) ;
152
156
this . state = new AnimationState ( animData ) ;
153
157
this . autoUpdate = options ?. autoUpdate ?? true ;
158
+ this . pma = options ?. pma ?? false ;
154
159
this . initializeMeshFactory ( options ) ;
155
160
this . skeleton . setToSetupPose ( ) ;
156
161
this . skeleton . updateWorldTransform ( Physics . update ) ;
@@ -162,7 +167,8 @@ export class Spine extends Container {
162
167
} else {
163
168
for ( let i = 0 ; i < this . skeleton . slots . length ; i ++ ) {
164
169
if ( this . skeleton . slots [ i ] . data . darkColor ) {
165
- this . slotMeshFactory = options ?. slotMeshFactory ?? ( ( ) => new DarkSlotMesh ( ) ) ;
170
+ this . twoColorTint = true ;
171
+ this . slotMeshFactory = options ?. slotMeshFactory ?? ( ( pma : boolean ) => new DarkSlotMesh ( pma ) ) ;
166
172
break ;
167
173
}
168
174
}
@@ -228,7 +234,7 @@ export class Spine extends Container {
228
234
*/
229
235
protected getMeshForSlot ( slot : Slot ) : ISlotMesh {
230
236
if ( ! this . meshesCache . has ( slot ) ) {
231
- let mesh = this . slotMeshFactory ( ) ;
237
+ let mesh = this . slotMeshFactory ( this . pma ) ;
232
238
this . addChild ( mesh ) ;
233
239
this . meshesCache . set ( slot , mesh ) ;
234
240
return mesh ;
@@ -412,27 +418,47 @@ export class Spine extends Container {
412
418
skeletonColor . a * slotColor . a * attachmentColor . a ,
413
419
) ;
414
420
415
- if ( slot . darkColor != null ) {
416
- const premultipliedAlpha = attachment . region ?. texture . texture . baseTexture . alphaMode == 2 ;
417
- // const premultipliedAlpha = false;
421
+ const mesh = this . getMeshForSlot ( slot ) ;
422
+ const premultipliedAlpha = mesh . pma ;
423
+ if ( premultipliedAlpha ) {
424
+ this . lightColor . r *= this . lightColor . a ;
425
+ this . lightColor . g *= this . lightColor . a ;
426
+ this . lightColor . b *= this . lightColor . a ;
427
+ }
428
+
429
+ if ( ! slot . darkColor )
430
+ this . darkColor . set ( 0 , 0 , 0 , 1.0 ) ;
431
+ else {
418
432
if ( premultipliedAlpha ) {
419
- this . darkColor . setFromColor ( slot . darkColor ) ;
420
- this . darkColor . a = 0.0 ;
421
- // this.darkColor.r = slot.darkColor.r * this.lightColor.a;
422
- // this.darkColor.g = slot.darkColor.g * this.lightColor.a;
423
- // this.darkColor.b = slot.darkColor.b * this.lightColor.a;
424
- // this.darkColor.a = 1.0;
433
+ this . darkColor . r = slot . darkColor . r * this . lightColor . a ;
434
+ this . darkColor . g = slot . darkColor . g * this . lightColor . a ;
435
+ this . darkColor . b = slot . darkColor . b * this . lightColor . a ;
425
436
} else {
426
437
this . darkColor . setFromColor ( slot . darkColor ) ;
427
- // this.darkColor.r = slot.darkColor.r * this.lightColor.a;
428
- // this.darkColor.g = slot.darkColor.g * this.lightColor.a;
429
- // this.darkColor.b = slot.darkColor.b * this.lightColor.a;
430
- this . darkColor . a = 0.0 ;
431
438
}
432
- } else {
433
- this . darkColor . set ( 0 , 0 , 0 , 0 ) ;
439
+ this . darkColor . a = premultipliedAlpha ? 1.0 : 0.0 ;
434
440
}
435
441
442
+ // if (slot.darkColor != null) {
443
+ // // const premultipliedAlpha = false;
444
+ // if (premultipliedAlpha) {
445
+ // this.darkColor.setFromColor(slot.darkColor);
446
+ // this.darkColor.a = 0.0;
447
+ // this.darkColor.r = slot.darkColor.r * this.lightColor.a;
448
+ // this.darkColor.g = slot.darkColor.g * this.lightColor.a;
449
+ // this.darkColor.b = slot.darkColor.b * this.lightColor.a;
450
+ // this.darkColor.a = 1.0;
451
+ // } else {
452
+ // this.darkColor.setFromColor(slot.darkColor);
453
+ // // this.darkColor.r = slot.darkColor.r * this.lightColor.a;
454
+ // // this.darkColor.g = slot.darkColor.g * this.lightColor.a;
455
+ // // this.darkColor.b = slot.darkColor.b * this.lightColor.a;
456
+ // this.darkColor.a = 0.0;
457
+ // }
458
+ // } else {
459
+ // this.darkColor.set(0, 0, 0, 0);
460
+ // }
461
+
436
462
let finalVertices : NumberArrayLike ;
437
463
let finalVerticesLength : number ;
438
464
let finalIndices : NumberArrayLike ;
@@ -463,6 +489,9 @@ export class Spine extends Container {
463
489
verts [ tempV ++ ] = this . darkColor . g ;
464
490
verts [ tempV ++ ] = this . darkColor . b ;
465
491
verts [ tempV ++ ] = this . darkColor . a ;
492
+ if ( slot . data . name == "orangeball3" ) {
493
+ // console.log(this.darkColor)
494
+ }
466
495
}
467
496
}
468
497
finalVertices = this . verticesCache ;
@@ -476,7 +505,6 @@ export class Spine extends Container {
476
505
continue ;
477
506
}
478
507
479
- const mesh = this . getMeshForSlot ( slot ) ;
480
508
mesh . zIndex = zIndex ;
481
509
mesh . updateFromSpineData ( texture , slot . data . blendMode , slot . data . name , finalVertices , finalVerticesLength , finalIndices , finalIndicesLength , useDarkColor ) ;
482
510
}
@@ -579,19 +607,21 @@ export class Spine extends Container {
579
607
* @returns {Spine } The Spine game object instantiated
580
608
*/
581
609
public static from ( skeletonAssetName : string , atlasAssetName : string , options ?: ISpineOptions ) : Spine {
610
+ let opt = { ...options } ;
582
611
const cacheKey = `${ skeletonAssetName } -${ atlasAssetName } -${ options ?. scale ?? 1 } ` ;
583
612
let skeletonData = Spine . skeletonCache [ cacheKey ] ;
584
613
if ( skeletonData ) {
585
614
return new Spine ( skeletonData , options ) ;
586
615
}
587
616
const skeletonAsset = Assets . get < any | Uint8Array > ( skeletonAssetName ) ;
588
617
const atlasAsset = Assets . get < TextureAtlas > ( atlasAssetName ) ;
618
+ opt . pma = options ?. pma ?? atlasAsset . pages . findIndex ( ( { pma } ) => pma ) > - 1 ;
589
619
const attachmentLoader = new AtlasAttachmentLoader ( atlasAsset ) ;
590
620
let parser = skeletonAsset instanceof Uint8Array ? new SkeletonBinary ( attachmentLoader ) : new SkeletonJson ( attachmentLoader ) ;
591
621
parser . scale = options ?. scale ?? 1 ;
592
622
skeletonData = parser . readSkeletonData ( skeletonAsset ) ;
593
623
Spine . skeletonCache [ cacheKey ] = skeletonData ;
594
- return new this ( skeletonData , options ) ;
624
+ return new this ( skeletonData , opt ) ;
595
625
}
596
626
597
627
public get tint ( ) : number {
@@ -614,6 +644,7 @@ Skeleton.yDown = true;
614
644
*/
615
645
export interface ISlotMesh extends DisplayObject {
616
646
name : string ;
647
+ pma : boolean ;
617
648
updateFromSpineData (
618
649
slotTexture : SpineTexture ,
619
650
slotBlendMode : BlendMode ,
0 commit comments