1
1
import Matrix from "./renderer/Matrix.js" ;
2
+ import Drawable from "./renderer/Drawable.js" ;
2
3
import BitmapSkin from "./renderer/BitmapSkin.js" ;
3
4
import PenSkin from "./renderer/PenSkin.js" ;
4
5
import SpeechBubbleSkin from "./renderer/SpeechBubbleSkin.js" ;
@@ -8,7 +9,6 @@ import ShaderManager from "./renderer/ShaderManager.js";
8
9
import { effectNames , effectBitmasks } from "./renderer/effectInfo.js" ;
9
10
10
11
import Costume from "./Costume.js" ;
11
- import { Sprite , Stage } from "./Sprite.js" ;
12
12
13
13
export default class Renderer {
14
14
constructor ( project , renderTarget ) {
@@ -25,6 +25,7 @@ export default class Renderer {
25
25
}
26
26
27
27
this . _shaderManager = new ShaderManager ( this ) ;
28
+ this . _drawables = new WeakMap ( ) ;
28
29
this . _skins = new WeakMap ( ) ;
29
30
30
31
this . _currentShader = null ;
@@ -69,24 +70,33 @@ export default class Renderer {
69
70
// Retrieve a given object (e.g. costume or speech bubble)'s skin. If it doesn't exist, make one.
70
71
_getSkin ( obj ) {
71
72
if ( this . _skins . has ( obj ) ) {
72
- const skin = this . _skins . get ( obj ) ;
73
- return skin ;
74
- } else {
75
- let skin ;
76
-
77
- if ( obj instanceof Costume ) {
78
- if ( obj . isBitmap ) {
79
- skin = new BitmapSkin ( this , obj . img ) ;
80
- } else {
81
- skin = new VectorSkin ( this , obj . img ) ;
82
- }
73
+ return this . _skins . get ( obj ) ;
74
+ }
75
+
76
+ let skin ;
77
+
78
+ if ( obj instanceof Costume ) {
79
+ if ( obj . isBitmap ) {
80
+ skin = new BitmapSkin ( this , obj . img ) ;
83
81
} else {
84
- // If it's not a costume, assume it's a speech bubble.
85
- skin = new SpeechBubbleSkin ( this , obj ) ;
82
+ skin = new VectorSkin ( this , obj . img ) ;
86
83
}
87
- this . _skins . set ( obj , skin ) ;
88
- return skin ;
84
+ } else {
85
+ // If it's not a costume, assume it's a speech bubble.
86
+ skin = new SpeechBubbleSkin ( this , obj ) ;
89
87
}
88
+ this . _skins . set ( obj , skin ) ;
89
+ return skin ;
90
+ }
91
+
92
+ // Retrieve the renderer-specific data object for a given sprite or clone. If it doesn't exist, make one.
93
+ _getDrawable ( sprite ) {
94
+ if ( this . _drawables . has ( sprite ) ) {
95
+ return this . _drawables . get ( sprite ) ;
96
+ }
97
+ const drawable = new Drawable ( this , sprite ) ;
98
+ this . _drawables . set ( sprite , drawable ) ;
99
+ return drawable ;
90
100
}
91
101
92
102
// Create a framebuffer info object, which contains the following:
@@ -337,48 +347,6 @@ export default class Renderer {
337
347
return stage ;
338
348
}
339
349
340
- // Calculate the transform matrix for a sprite.
341
- // TODO: store the transform matrix in the sprite itself. That adds some complexity though,
342
- // so it's better off in another PR.
343
- _calculateSpriteMatrix ( spr ) {
344
- // These transforms are actually in reverse order because lol matrices
345
- const m = Matrix . create ( ) ;
346
- if ( ! ( spr instanceof Stage ) ) {
347
- Matrix . translate ( m , m , spr . x , spr . y ) ;
348
- switch ( spr . rotationStyle ) {
349
- case Sprite . RotationStyle . ALL_AROUND : {
350
- Matrix . rotate ( m , m , spr . scratchToRad ( spr . direction ) ) ;
351
- break ;
352
- }
353
- case Sprite . RotationStyle . LEFT_RIGHT : {
354
- if ( spr . direction < 0 ) Matrix . scale ( m , m , - 1 , 1 ) ;
355
- break ;
356
- }
357
- }
358
-
359
- const spriteScale = spr . size / 100 ;
360
- Matrix . scale ( m , m , spriteScale , spriteScale ) ;
361
- }
362
-
363
- const scalingFactor = 1 / spr . costume . resolution ;
364
- // Rotation centers are in non-Scratch space (positive y-values = down),
365
- // but these transforms are in Scratch space (negative y-values = down).
366
- Matrix . translate (
367
- m ,
368
- m ,
369
- - spr . costume . center . x * scalingFactor ,
370
- ( spr . costume . center . y - spr . costume . height ) * scalingFactor
371
- ) ;
372
- Matrix . scale (
373
- m ,
374
- m ,
375
- spr . costume . width * scalingFactor ,
376
- spr . costume . height * scalingFactor
377
- ) ;
378
-
379
- return m ;
380
- }
381
-
382
350
// Calculate the transform matrix for a speech bubble attached to a sprite.
383
351
_calculateSpeechBubbleMatrix ( spr , speechBubbleSkin ) {
384
352
const sprBounds = this . getBoundingBox ( spr ) ;
@@ -448,7 +416,7 @@ export default class Renderer {
448
416
this . _renderSkin (
449
417
this . _getSkin ( sprite . costume ) ,
450
418
options . drawMode ,
451
- this . _calculateSpriteMatrix ( sprite ) ,
419
+ this . _getDrawable ( sprite ) . getMatrix ( ) ,
452
420
spriteScale ,
453
421
sprite . effects ,
454
422
options . effectMask ,
@@ -472,7 +440,7 @@ export default class Renderer {
472
440
}
473
441
474
442
getBoundingBox ( sprite ) {
475
- return Rectangle . fromMatrix ( this . _calculateSpriteMatrix ( sprite ) ) ;
443
+ return Rectangle . fromMatrix ( this . _getDrawable ( sprite ) . getMatrix ( ) ) ;
476
444
}
477
445
478
446
// Mask drawing in to only areas where this sprite is opaque.
0 commit comments