@@ -256,8 +256,7 @@ class RenderWebGL extends EventEmitter {
256
256
this . _yBottom = yBottom ;
257
257
this . _yTop = yTop ;
258
258
259
- // swap yBottom & yTop to fit Scratch convention of +y=up
260
- this . _projection = twgl . m4 . ortho ( xLeft , xRight , yBottom , yTop , - 1 , 1 ) ;
259
+ this . _projection = this . _makeOrthoProjection ( xLeft , xRight , yBottom , yTop ) ;
261
260
262
261
this . _setNativeSize ( Math . abs ( xRight - xLeft ) , Math . abs ( yBottom - yTop ) ) ;
263
262
}
@@ -281,6 +280,20 @@ class RenderWebGL extends EventEmitter {
281
280
this . emit ( RenderConstants . Events . NativeSizeChanged , { newSize : this . _nativeSize } ) ;
282
281
}
283
282
283
+ /**
284
+ * Build a projection matrix for Scratch coordinates. For example, `_makeOrthoProjection(-240,240,-180,180)` will
285
+ * mean the lower-left pixel is at (-240,-179) and the upper right pixel is at (239,180), matching Scratch 2.0.
286
+ * @param {number } xLeft - the left edge of the projection volume (-240)
287
+ * @param {number } xRight - the right edge of the projection volume (240)
288
+ * @param {number } yBottom - the bottom edge of the projection volume (-180)
289
+ * @param {number } yTop - the top edge of the projection volume (180)
290
+ * @returns {module:twgl/m4.Mat4 } - a projection matrix containing [xLeft,xRight) and (yBottom,yTop]
291
+ */
292
+ _makeOrthoProjection ( xLeft , xRight , yBottom , yTop ) {
293
+ // swap yBottom & yTop to fit Scratch convention of +y=up
294
+ return twgl . m4 . ortho ( xLeft , xRight , yBottom , yTop , - 1 , 1 ) ;
295
+ }
296
+
284
297
/**
285
298
* Create a new bitmap skin from a snapshot of the provided bitmap data.
286
299
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement } bitmapData - new contents for this skin.
@@ -518,7 +531,7 @@ class RenderWebGL extends EventEmitter {
518
531
* Returns the position of the given drawableID in the draw list. This is
519
532
* the absolute position irrespective of layer group.
520
533
* @param {number } drawableID The drawable ID to find.
521
- * @return {number } The postion of the given drawable ID.
534
+ * @return {number } The position of the given drawable ID.
522
535
*/
523
536
getDrawableOrder ( drawableID ) {
524
537
return this . _drawList . indexOf ( drawableID ) ;
@@ -532,7 +545,7 @@ class RenderWebGL extends EventEmitter {
532
545
* "go to back": setDrawableOrder(id, 1); (assuming stage at 0).
533
546
* "go to front": setDrawableOrder(id, Infinity);
534
547
* @param {int } drawableID ID of Drawable to reorder.
535
- * @param {number } order New absolute order or relative order adjusment .
548
+ * @param {number } order New absolute order or relative order adjustment .
536
549
* @param {string= } group Name of layer group drawable belongs to.
537
550
* Reordering will not take place if drawable cannot be found within the bounds
538
551
* of the layer group.
@@ -703,7 +716,7 @@ class RenderWebGL extends EventEmitter {
703
716
704
717
/**
705
718
* Check if a particular Drawable is touching a particular color.
706
- * Unlike touching drawable, if the "tester" is invisble , we will still test.
719
+ * Unlike touching drawable, if the "tester" is invisible , we will still test.
707
720
* @param {int } drawableID The ID of the Drawable to check.
708
721
* @param {Array<int> } color3b Test if the Drawable is touching this color.
709
722
* @param {Array<int> } [mask3b] Optionally mask the check to this part of Drawable.
@@ -728,23 +741,23 @@ class RenderWebGL extends EventEmitter {
728
741
const color = __touchingColor ;
729
742
const hasMask = Boolean ( mask3b ) ;
730
743
731
- for ( let y = bounds . bottom ; y <= bounds . top ; y ++ ) {
732
- if ( bounds . width * ( y - bounds . bottom ) * ( candidates . length + 1 ) >= __cpuTouchingColorPixelCount ) {
733
- return this . _isTouchingColorGpuFin ( bounds , color3b , y - bounds . bottom ) ;
744
+ // Scratch Space - +y is top
745
+ for ( let y = 0 ; y < bounds . height ; ++ y ) {
746
+ if ( bounds . width * y * ( candidates . length + 1 ) >= __cpuTouchingColorPixelCount ) {
747
+ return this . _isTouchingColorGpuFin ( bounds , color3b , y ) ;
734
748
}
735
- // Scratch Space - +y is top
736
- for ( let x = bounds . left ; x <= bounds . right ; x ++ ) {
737
- point [ 1 ] = y ;
738
- point [ 0 ] = x ;
739
- if (
740
- // if we use a mask, check our sample color
741
- ( hasMask ?
742
- maskMatches ( Drawable . sampleColor4b ( point , drawable , color ) , mask3b ) :
743
- drawable . isTouching ( point ) ) &&
744
- // and the target color is drawn at this pixel
745
- colorMatches ( RenderWebGL . sampleColor3b ( point , candidates , color ) , color3b , 0 )
746
- ) {
747
- return true ;
749
+ for ( let x = 0 ; x < bounds . width ; ++ x ) {
750
+ point [ 0 ] = bounds . left + x ; // bounds.left <= point[0] < bounds.right
751
+ point [ 1 ] = bounds . top - y ; // bounds.bottom < point[1] <= bounds.top ("flipped")
752
+ // if we use a mask, check our sample color...
753
+ if ( hasMask ?
754
+ maskMatches ( Drawable . sampleColor4b ( point , drawable , color ) , mask3b ) :
755
+ drawable . isTouching ( point ) ) {
756
+ RenderWebGL . sampleColor3b ( point , candidates , color ) ;
757
+ // ...and the target color is drawn at this pixel
758
+ if ( colorMatches ( color , color3b , 0 ) ) {
759
+ return true ;
760
+ }
748
761
}
749
762
}
750
763
}
@@ -760,7 +773,7 @@ class RenderWebGL extends EventEmitter {
760
773
// Limit size of viewport to the bounds around the target Drawable,
761
774
// and create the projection matrix for the draw.
762
775
gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
763
- const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
776
+ const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
764
777
765
778
let fillBackgroundColor = this . _backgroundColor ;
766
779
@@ -843,7 +856,7 @@ class RenderWebGL extends EventEmitter {
843
856
const candidates = this . _candidatesTouching ( drawableID ,
844
857
// even if passed an invisible drawable, we will NEVER touch it!
845
858
candidateIDs . filter ( id => this . _allDrawables [ id ] . _visible ) ) ;
846
- // if we are invisble we don't touch anything.
859
+ // if we are invisible we don't touch anything.
847
860
if ( candidates . length === 0 || ! this . _allDrawables [ drawableID ] . _visible ) {
848
861
return false ;
849
862
}
@@ -876,7 +889,7 @@ class RenderWebGL extends EventEmitter {
876
889
877
890
/**
878
891
* Convert a client based x/y position on the canvas to a Scratch 3 world space
879
- * Rectangle. This creates recangles with a radius to cover selecting multiple
892
+ * Rectangle. This creates rectangles with a radius to cover selecting multiple
880
893
* scratch pixels with touch / small render areas.
881
894
*
882
895
* @param {int } centerX The client x coordinate of the picking location.
@@ -993,7 +1006,7 @@ class RenderWebGL extends EventEmitter {
993
1006
for ( worldPos [ 0 ] = bounds . left ; worldPos [ 0 ] <= bounds . right ; worldPos [ 0 ] ++ ) {
994
1007
995
1008
// Check candidates in the reverse order they would have been
996
- // drawn. This will determine what candiate 's silhouette pixel
1009
+ // drawn. This will determine what candidate 's silhouette pixel
997
1010
// would have been drawn at the point.
998
1011
for ( let d = candidateIDs . length - 1 ; d >= 0 ; d -- ) {
999
1012
const id = candidateIDs [ d ] ;
@@ -1077,7 +1090,7 @@ class RenderWebGL extends EventEmitter {
1077
1090
// Limit size of viewport to the bounds around the target Drawable,
1078
1091
// and create the projection matrix for the draw.
1079
1092
gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1080
- const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
1093
+ const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
1081
1094
1082
1095
gl . clearColor ( 0 , 0 , 0 , 0 ) ;
1083
1096
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
@@ -1152,7 +1165,7 @@ class RenderWebGL extends EventEmitter {
1152
1165
const pickY = bounds . top - scratchY ;
1153
1166
1154
1167
gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1155
- const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
1168
+ const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
1156
1169
1157
1170
gl . clearColor . apply ( gl , this . _backgroundColor ) ;
1158
1171
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
@@ -1395,7 +1408,7 @@ class RenderWebGL extends EventEmitter {
1395
1408
1396
1409
// Limit size of viewport to the bounds around the stamp Drawable and create the projection matrix for the draw.
1397
1410
gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1398
- const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
1411
+ const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
1399
1412
1400
1413
gl . clearColor ( 0 , 0 , 0 , 0 ) ;
1401
1414
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
@@ -1484,7 +1497,7 @@ class RenderWebGL extends EventEmitter {
1484
1497
* can skip superfluous extra state calls when it is already in that
1485
1498
* region. Since one region may be entered from within another a exit
1486
1499
* handle can also be registered that is called when a new region is about
1487
- * to be entered to restore a common inbetween state.
1500
+ * to be entered to restore a common in-between state.
1488
1501
*
1489
1502
* @param {any } regionId - id of the region to enter
1490
1503
* @param {function } enter - handle to call when first entering a region
@@ -1616,7 +1629,7 @@ class RenderWebGL extends EventEmitter {
1616
1629
*
1617
1630
* The determinant is useful in this case to know if AC is counter
1618
1631
* clockwise from AB. A positive value means the AC is counter
1619
- * clockwise from AC. A negative value menas AC is clockwise from AB.
1632
+ * clockwise from AC. A negative value means AC is clockwise from AB.
1620
1633
*
1621
1634
* @param {Float32Array } A A 2d vector in space.
1622
1635
* @param {Float32Array } B A 2d vector in space.
0 commit comments