18
18
import java .util .HashMap ;
19
19
20
20
import com .bladecoder .engine .model .ActorRenderer ;
21
-
22
21
import com .badlogic .gdx .graphics .Color ;
23
22
import com .badlogic .gdx .graphics .g2d .SpriteBatch ;
24
23
import com .badlogic .gdx .graphics .g2d .TextureAtlas ;
38
37
import com .esotericsoftware .spine .Animation ;
39
38
import com .esotericsoftware .spine .AnimationState ;
40
39
import com .esotericsoftware .spine .AnimationState .AnimationStateListener ;
40
+ import com .esotericsoftware .spine .attachments .Attachment ;
41
+ import com .esotericsoftware .spine .attachments .RegionAttachment ;
41
42
import com .esotericsoftware .spine .AnimationStateData ;
42
43
import com .esotericsoftware .spine .Event ;
43
44
import com .esotericsoftware .spine .Skeleton ;
44
45
import com .esotericsoftware .spine .SkeletonBinary ;
45
46
import com .esotericsoftware .spine .SkeletonBounds ;
46
47
import com .esotericsoftware .spine .SkeletonData ;
47
48
import com .esotericsoftware .spine .SkeletonRenderer ;
49
+ import com .esotericsoftware .spine .Slot ;
48
50
49
51
public class SpineRenderer implements ActorRenderer {
50
52
@@ -66,6 +68,7 @@ public class SpineRenderer implements ActorRenderer {
66
68
67
69
private SkeletonRenderer renderer ;
68
70
private SkeletonBounds bounds ;
71
+ private float width = 200 , height = 200 ;
69
72
70
73
private final HashMap <String , SkeletonCacheEntry > sourceCache = new HashMap <String , SkeletonCacheEntry >();
71
74
@@ -84,17 +87,15 @@ public SpineRenderer() {
84
87
private AnimationStateListener animationListener = new AnimationStateListener () {
85
88
@ Override
86
89
public void complete (int trackIndex , int loopCount ) {
87
- if (currentAnimationType == Tween .REPEAT
88
- && (currentCount == Tween .INFINITY || currentCount > loopCount )) {
90
+ if (currentAnimationType == Tween .REPEAT && (currentCount == Tween .INFINITY || currentCount > loopCount )) {
89
91
return ;
90
92
}
91
93
92
94
currentSource .animation .setTimeScale (0 );
93
95
if (animationCb != null || animationCbSer != null ) {
94
96
95
97
if (animationCb == null ) {
96
- animationCb = ActionCallbackSerialization
97
- .find (animationCbSer );
98
+ animationCb = ActionCallbackSerialization .find (animationCbSer );
98
99
animationCbSer = null ;
99
100
}
100
101
@@ -158,8 +159,7 @@ public String getInitAnimation() {
158
159
public String [] getInternalAnimations (String source ) {
159
160
retrieveSource (source );
160
161
161
- Array <Animation > animations = sourceCache .get (source ).skeleton
162
- .getData ().getAnimations ();
162
+ Array <Animation > animations = sourceCache .get (source ).skeleton .getData ().getAnimations ();
163
163
String [] result = new String [animations .size ];
164
164
165
165
for (int i = 0 ; i < animations .size ; i ++) {
@@ -188,33 +188,23 @@ public void draw(SpriteBatch batch, float x, float y, float scale) {
188
188
currentSource .skeleton .setX (x / scale );
189
189
currentSource .skeleton .setY (y / scale );
190
190
191
- batch .setTransformMatrix (batch .getTransformMatrix ().scale (scale ,
192
- scale , 1.0f ));
191
+ batch .setTransformMatrix (batch .getTransformMatrix ().scale (scale , scale , 1.0f ));
193
192
renderer .draw (batch , currentSource .skeleton );
194
- batch .setTransformMatrix (batch .getTransformMatrix ().scale (
195
- 1 / scale , 1 / scale , 1.0f ));
193
+ batch .setTransformMatrix (batch .getTransformMatrix ().scale (1 / scale , 1 / scale , 1.0f ));
196
194
} else {
197
195
x = x - getWidth () / 2 * scale ;
198
- RectangleRenderer .draw (batch , x , y , getWidth () * scale , getHeight ()
199
- * scale , Color .RED );
196
+ RectangleRenderer .draw (batch , x , y , getWidth () * scale , getHeight () * scale , Color .RED );
200
197
}
201
198
}
202
199
203
200
@ Override
204
201
public float getWidth () {
205
- if (bounds != null && bounds .getWidth () > 0 ) {
206
- return bounds .getWidth ();
207
- }
208
-
209
- return 200 ;
202
+ return width ;
210
203
}
211
204
212
205
@ Override
213
206
public float getHeight () {
214
- if (bounds != null && bounds .getHeight () > 0 )
215
- return bounds .getHeight ();
216
-
217
- return 200 ;
207
+ return height ;
218
208
}
219
209
220
210
@ Override
@@ -250,18 +240,15 @@ public void stand() {
250
240
}
251
241
252
242
@ Override
253
- public void startWalkFA (Vector2 p0 , Vector2 pf ) {
254
- String currentDirection = AnimationDesc .getFrameDirection (p0 .x , p0 .y ,
255
- pf );
243
+ public void walk (Vector2 p0 , Vector2 pf ) {
244
+ String currentDirection = AnimationDesc .getFrameDirection (p0 .x , p0 .y , pf );
256
245
StringBuilder sb = new StringBuilder ();
257
- sb .append (AnimationDesc .WALK_ANIM ).append ('.' )
258
- .append (currentDirection );
246
+ sb .append (AnimationDesc .WALK_ANIM ).append ('.' ).append (currentDirection );
259
247
startAnimation (sb .toString (), Tween .FROM_FA , 1 , null );
260
248
}
261
249
262
250
@ Override
263
- public void startAnimation (String id , int repeatType , int count ,
264
- ActionCallback cb ) {
251
+ public void startAnimation (String id , int repeatType , int count , ActionCallback cb ) {
265
252
AnimationDesc fa = getAnimation (id );
266
253
267
254
if (fa == null ) {
@@ -270,8 +257,7 @@ public void startAnimation(String id, int repeatType, int count,
270
257
return ;
271
258
}
272
259
273
- if (currentAnimation != null
274
- && currentAnimation .disposeWhenPlayed )
260
+ if (currentAnimation != null && currentAnimation .disposeWhenPlayed )
275
261
disposeSource (currentAnimation .source );
276
262
277
263
currentAnimation = fa ;
@@ -305,24 +291,67 @@ public void startAnimation(String id, int repeatType, int count,
305
291
}
306
292
307
293
lastAnimationTime = 0f ;
308
- setCurrentFA ();
294
+ setCurrentAnimation ();
309
295
}
310
296
311
- private void setCurrentFA () {
297
+ private void setCurrentAnimation () {
312
298
try {
313
- // currentSource.skeleton.setToSetupPose();
299
+ // TODO Make setup pose parametrizable in the AnimationDesc
300
+ currentSource .skeleton .setToSetupPose ();
314
301
currentSource .skeleton .setFlipX (flipX );
315
- currentSource .animation
316
- .setTimeScale (currentAnimation .duration );
317
- currentSource .animation .setAnimation (0 , currentAnimation .id ,
318
- currentAnimationType == Tween .REPEAT );
302
+ currentSource .animation .setTimeScale (currentAnimation .duration );
303
+ currentSource .animation .setAnimation (0 , currentAnimation .id , currentAnimationType == Tween .REPEAT );
319
304
update (lastAnimationTime );
320
- bounds . update ( currentSource . skeleton , true );
305
+ computeBounds ( );
321
306
} catch (Exception e ) {
322
307
EngineLogger .error ("SpineRenderer:setCurrentFA " + e .getMessage ());
323
308
}
324
309
}
325
310
311
+ private void computeBounds () {
312
+ bounds .update (currentSource .skeleton , true );
313
+
314
+ if (bounds .getWidth () > 0 && bounds .getHeight () > 0 ) {
315
+ width = bounds .getWidth ();
316
+ height = bounds .getHeight ();
317
+ } else {
318
+ currentSource .skeleton .updateWorldTransform ();
319
+
320
+ float minX = Float .MAX_VALUE ;
321
+ float minY = Float .MAX_VALUE ;
322
+ float maxX = Float .MIN_VALUE , maxY = Float .MIN_VALUE ;
323
+
324
+ Array <Slot > slots = currentSource .skeleton .getSlots ();
325
+
326
+ for (int i = 0 , n = slots .size ; i < n ; i ++) {
327
+ Slot slot = slots .get (i );
328
+ Attachment attachment = slot .getAttachment ();
329
+ if (attachment == null )
330
+ continue ;
331
+
332
+ if (!(attachment instanceof RegionAttachment ))
333
+ continue ;
334
+
335
+ ((RegionAttachment ) attachment ).updateWorldVertices (slot , false );
336
+
337
+ float [] vertices = ((RegionAttachment ) attachment ).getWorldVertices ();
338
+ for (int ii = 0 , nn = vertices .length ; ii < nn ; ii += 5 ) {
339
+ minX = Math .min (minX , vertices [ii ]);
340
+ minY = Math .min (minY , vertices [ii + 1 ]);
341
+ maxX = Math .max (maxX , vertices [ii ]);
342
+ maxY = Math .max (maxY , vertices [ii + 1 ]);
343
+ }
344
+ }
345
+
346
+ width = (maxX - minX );
347
+ height = (maxY - minY );
348
+
349
+ if (width <= 0 || height <= 0 ) {
350
+ width = height = 200 ;
351
+ }
352
+ }
353
+ }
354
+
326
355
private AnimationDesc getAnimation (String id ) {
327
356
AnimationDesc fa = fanims .get (id );
328
357
flipX = false ;
@@ -339,12 +368,10 @@ private AnimationDesc getAnimation(String id) {
339
368
// search for .left if .frontleft not found and viceversa
340
369
StringBuilder sb = new StringBuilder ();
341
370
342
- if (id .endsWith (AnimationDesc .FRONTLEFT )
343
- || id .endsWith (AnimationDesc .FRONTRIGHT )) {
371
+ if (id .endsWith (AnimationDesc .FRONTLEFT ) || id .endsWith (AnimationDesc .FRONTRIGHT )) {
344
372
sb .append (id .substring (0 , id .lastIndexOf ('.' ) + 1 ));
345
373
sb .append (AnimationDesc .FRONT );
346
- } else if (id .endsWith (AnimationDesc .BACKLEFT )
347
- || id .endsWith (AnimationDesc .BACKRIGHT )) {
374
+ } else if (id .endsWith (AnimationDesc .BACKLEFT ) || id .endsWith (AnimationDesc .BACKRIGHT )) {
348
375
sb .append (id .substring (0 , id .lastIndexOf ('.' ) + 1 ));
349
376
sb .append (AnimationDesc .BACK );
350
377
} else if (id .endsWith (AnimationDesc .LEFT )) {
@@ -367,12 +394,13 @@ private AnimationDesc getAnimation(String id) {
367
394
368
395
if (fa != null ) {
369
396
flipX = true ;
370
- } else if (s .endsWith (AnimationDesc .FRONT )
371
- || s .endsWith (AnimationDesc .BACK )) { // search for
372
- // only
373
- // right or
374
- // left
375
- // animations
397
+ } else if (s .endsWith (AnimationDesc .FRONT ) || s .endsWith (AnimationDesc .BACK )) { // search
398
+ // for
399
+ // only
400
+ // right
401
+ // or
402
+ // left
403
+ // animations
376
404
if (id .endsWith (AnimationDesc .LEFT )) {
377
405
sb .append (id .substring (0 , id .lastIndexOf ('.' ) + 1 ));
378
406
sb .append (AnimationDesc .LEFT );
@@ -426,14 +454,11 @@ private void retrieveSource(String source) {
426
454
}
427
455
428
456
if (entry .skeleton == null ) {
429
- TextureAtlas atlas = EngineAssetManager .getInstance ()
430
- .getTextureAtlas (source );
457
+ TextureAtlas atlas = EngineAssetManager .getInstance ().getTextureAtlas (source );
431
458
432
459
SkeletonBinary skel = new SkeletonBinary (atlas );
433
460
skel .setScale (EngineAssetManager .getInstance ().getScale ());
434
- SkeletonData skeletonData = skel
435
- .readSkeletonData (EngineAssetManager .getInstance ()
436
- .getSpine (source ));
461
+ SkeletonData skeletonData = skel .readSkeletonData (EngineAssetManager .getInstance ().getSpine (source ));
437
462
438
463
entry .skeleton = new Skeleton (skeletonData );
439
464
@@ -489,11 +514,10 @@ public void retrieveAssets() {
489
514
}
490
515
491
516
if (currentAnimation != null ) {
492
- SkeletonCacheEntry entry = sourceCache
493
- .get (currentAnimation .source );
517
+ SkeletonCacheEntry entry = sourceCache .get (currentAnimation .source );
494
518
currentSource = entry ;
495
519
496
- setCurrentFA ();
520
+ setCurrentAnimation ();
497
521
498
522
} else if (initAnimation != null ) {
499
523
startAnimation (initAnimation , Tween .FROM_FA , 1 , null );
@@ -522,8 +546,7 @@ public void write(Json json) {
522
546
if (currentAnimation != null )
523
547
currentAnimationId = currentAnimation .id ;
524
548
525
- json .writeValue ("currentAnimation" , currentAnimationId ,
526
- currentAnimationId == null ? null : String .class );
549
+ json .writeValue ("currentAnimation" , currentAnimationId , currentAnimationId == null ? null : String .class );
527
550
528
551
json .writeValue ("initAnimation" , initAnimation );
529
552
@@ -532,9 +555,8 @@ public void write(Json json) {
532
555
if (animationCbSer != null )
533
556
json .writeValue ("cb" , animationCbSer );
534
557
else
535
- json .writeValue ("cb" ,
536
- ActionCallbackSerialization .find (animationCb ),
537
- animationCb == null ? null : String .class );
558
+ json .writeValue ("cb" , ActionCallbackSerialization .find (animationCb ), animationCb == null ? null
559
+ : String .class );
538
560
539
561
json .writeValue ("currentCount" , currentCount );
540
562
json .writeValue ("currentAnimationType" , currentAnimationType );
@@ -545,25 +567,19 @@ public void write(Json json) {
545
567
@ Override
546
568
public void read (Json json , JsonValue jsonData ) {
547
569
548
- fanims = json .readValue ("fanims" , HashMap .class , AnimationDesc .class ,
549
- jsonData );
570
+ fanims = json .readValue ("fanims" , HashMap .class , AnimationDesc .class , jsonData );
550
571
551
- String currentAnimationId = json .readValue (
552
- "currentAnimation" , String .class , jsonData );
572
+ String currentAnimationId = json .readValue ("currentAnimation" , String .class , jsonData );
553
573
554
574
if (currentAnimationId != null )
555
- currentAnimation = (AtlasAnimationDesc ) fanims
556
- .get (currentAnimationId );
575
+ currentAnimation = (AtlasAnimationDesc ) fanims .get (currentAnimationId );
557
576
558
- initAnimation = json .readValue ("initAnimation" , String .class ,
559
- jsonData );
577
+ initAnimation = json .readValue ("initAnimation" , String .class , jsonData );
560
578
561
579
flipX = json .readValue ("flipX" , Boolean .class , jsonData );
562
580
animationCbSer = json .readValue ("cb" , String .class , jsonData );
563
581
currentCount = json .readValue ("currentCount" , Integer .class , jsonData );
564
- currentAnimationType = json .readValue ("currentAnimationType" ,
565
- Integer .class , jsonData );
566
- lastAnimationTime = json .readValue ("lastAnimationTime" , Float .class ,
567
- jsonData );
582
+ currentAnimationType = json .readValue ("currentAnimationType" , Integer .class , jsonData );
583
+ lastAnimationTime = json .readValue ("lastAnimationTime" , Float .class , jsonData );
568
584
}
569
585
}
0 commit comments