@@ -267,7 +267,8 @@ class RenderWebGL extends EventEmitter {
267267 this . _yBottom = yBottom ;
268268 this . _yTop = yTop ;
269269
270- this . _projection = this . _makeOrthoProjection ( xLeft , xRight , yBottom , yTop ) ;
270+ // swap yBottom & yTop to fit Scratch convention of +y=up
271+ this . _projection = twgl . m4 . ortho ( xLeft , xRight , yBottom , yTop , - 1 , 1 ) ;
271272
272273 this . _setNativeSize ( Math . abs ( xRight - xLeft ) , Math . abs ( yBottom - yTop ) ) ;
273274 }
@@ -291,20 +292,6 @@ class RenderWebGL extends EventEmitter {
291292 this . emit ( RenderConstants . Events . NativeSizeChanged , { newSize : this . _nativeSize } ) ;
292293 }
293294
294- /**
295- * Build a projection matrix for Scratch coordinates. For example, `_makeOrthoProjection(-240,240,-180,180)` will
296- * mean the lower-left pixel is at (-240,-179) and the upper right pixel is at (239,180), matching Scratch 2.0.
297- * @param {number } xLeft - the left edge of the projection volume (-240)
298- * @param {number } xRight - the right edge of the projection volume (240)
299- * @param {number } yBottom - the bottom edge of the projection volume (-180)
300- * @param {number } yTop - the top edge of the projection volume (180)
301- * @returns {module:twgl/m4.Mat4 } - a projection matrix containing [xLeft,xRight) and (yBottom,yTop]
302- */
303- _makeOrthoProjection ( xLeft , xRight , yBottom , yTop ) {
304- // swap yBottom & yTop to fit Scratch convention of +y=up
305- return twgl . m4 . ortho ( xLeft , xRight , yBottom , yTop , - 1 , 1 ) ;
306- }
307-
308295 /**
309296 * Create a new bitmap skin from a snapshot of the provided bitmap data.
310297 * @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement } bitmapData - new contents for this skin.
@@ -542,7 +529,7 @@ class RenderWebGL extends EventEmitter {
542529 * Returns the position of the given drawableID in the draw list. This is
543530 * the absolute position irrespective of layer group.
544531 * @param {number } drawableID The drawable ID to find.
545- * @return {number } The position of the given drawable ID.
532+ * @return {number } The postion of the given drawable ID.
546533 */
547534 getDrawableOrder ( drawableID ) {
548535 return this . _drawList . indexOf ( drawableID ) ;
@@ -556,7 +543,7 @@ class RenderWebGL extends EventEmitter {
556543 * "go to back": setDrawableOrder(id, 1); (assuming stage at 0).
557544 * "go to front": setDrawableOrder(id, Infinity);
558545 * @param {int } drawableID ID of Drawable to reorder.
559- * @param {number } order New absolute order or relative order adjustment .
546+ * @param {number } order New absolute order or relative order adjusment .
560547 * @param {string= } group Name of layer group drawable belongs to.
561548 * Reordering will not take place if drawable cannot be found within the bounds
562549 * of the layer group.
@@ -727,7 +714,7 @@ class RenderWebGL extends EventEmitter {
727714
728715 /**
729716 * Check if a particular Drawable is touching a particular color.
730- * Unlike touching drawable, if the "tester" is invisible , we will still test.
717+ * Unlike touching drawable, if the "tester" is invisble , we will still test.
731718 * @param {int } drawableID The ID of the Drawable to check.
732719 * @param {Array<int> } color3b Test if the Drawable is touching this color.
733720 * @param {Array<int> } [mask3b] Optionally mask the check to this part of Drawable.
@@ -751,7 +738,7 @@ class RenderWebGL extends EventEmitter {
751738
752739 // if there are just too many pixels to CPU render efficiently, we need to let readPixels happen
753740 if ( bounds . width * bounds . height * ( candidates . length + 1 ) >= maxPixelsForCPU ) {
754- this . _isTouchingColorGpuStart ( drawableID , candidates . map ( ( { id} ) => id ) , bounds , color3b , mask3b ) ;
741+ this . _isTouchingColorGpuStart ( drawableID , candidates . map ( ( { id} ) => id ) . reverse ( ) , bounds , color3b , mask3b ) ;
755742 }
756743
757744 const drawable = this . _allDrawables [ drawableID ] ;
@@ -760,24 +747,24 @@ class RenderWebGL extends EventEmitter {
760747 const hasMask = Boolean ( mask3b ) ;
761748
762749 // Scratch Space - +y is top
763- for ( let y = 0 ; y < bounds . height ; ++ y ) {
764- if ( bounds . width * y * ( candidates . length + 1 ) >= maxPixelsForCPU ) {
765- return this . _isTouchingColorGpuFin ( bounds , color3b , y ) ;
750+ for ( let y = bounds . bottom ; y <= bounds . top ; y ++ ) {
751+ if ( bounds . width * ( y - bounds . bottom ) * ( candidates . length + 1 ) >= maxPixelsForCPU ) {
752+ return this . _isTouchingColorGpuFin ( bounds , color3b , y - bounds . bottom ) ;
766753 }
767- for ( let x = 0 ; x < bounds . width ; ++ x ) {
768- point [ 0 ] = bounds . left + x ; // bounds.left <= point[0] < bounds.right
769- point [ 1 ] = bounds . top - y ; // bounds.bottom < point[1] <= bounds.top ("flipped")
754+ for ( let x = bounds . left ; x <= bounds . right ; x ++ ) {
755+ point [ 1 ] = y ;
756+ point [ 0 ] = x ;
770757 // if we use a mask, check our sample color...
771758 if ( hasMask ?
772759 maskMatches ( Drawable . sampleColor4b ( point , drawable , color ) , mask3b ) :
773760 drawable . isTouching ( point ) ) {
774761 RenderWebGL . sampleColor3b ( point , candidates , color ) ;
775762 if ( debugCanvasContext ) {
776763 debugCanvasContext . fillStyle = `rgb(${ color [ 0 ] } ,${ color [ 1 ] } ,${ color [ 2 ] } )` ;
777- debugCanvasContext . fillRect ( x , y , 1 , 1 ) ;
764+ debugCanvasContext . fillRect ( x - bounds . left , bounds . bottom - y , 1 , 1 ) ;
778765 }
779766 // ...and the target color is drawn at this pixel
780- if ( colorMatches ( color3b , color , 0 ) ) {
767+ if ( colorMatches ( color , color3b , 0 ) ) {
781768 return true ;
782769 }
783770 }
@@ -807,7 +794,7 @@ class RenderWebGL extends EventEmitter {
807794 // Limit size of viewport to the bounds around the target Drawable,
808795 // and create the projection matrix for the draw.
809796 gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
810- const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
797+ const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
811798
812799 let fillBackgroundColor = this . _backgroundColor ;
813800
@@ -890,7 +877,7 @@ class RenderWebGL extends EventEmitter {
890877 const candidates = this . _candidatesTouching ( drawableID ,
891878 // even if passed an invisible drawable, we will NEVER touch it!
892879 candidateIDs . filter ( id => this . _allDrawables [ id ] . _visible ) ) ;
893- // if we are invisible we don't touch anything.
880+ // if we are invisble we don't touch anything.
894881 if ( candidates . length === 0 || ! this . _allDrawables [ drawableID ] . _visible ) {
895882 return false ;
896883 }
@@ -923,7 +910,7 @@ class RenderWebGL extends EventEmitter {
923910
924911 /**
925912 * Convert a client based x/y position on the canvas to a Scratch 3 world space
926- * Rectangle. This creates rectangles with a radius to cover selecting multiple
913+ * Rectangle. This creates recangles with a radius to cover selecting multiple
927914 * scratch pixels with touch / small render areas.
928915 *
929916 * @param {int } centerX The client x coordinate of the picking location.
@@ -1040,7 +1027,7 @@ class RenderWebGL extends EventEmitter {
10401027 for ( worldPos [ 0 ] = bounds . left ; worldPos [ 0 ] <= bounds . right ; worldPos [ 0 ] ++ ) {
10411028
10421029 // Check candidates in the reverse order they would have been
1043- // drawn. This will determine what candidate 's silhouette pixel
1030+ // drawn. This will determine what candiate 's silhouette pixel
10441031 // would have been drawn at the point.
10451032 for ( let d = candidateIDs . length - 1 ; d >= 0 ; d -- ) {
10461033 const id = candidateIDs [ d ] ;
@@ -1124,7 +1111,7 @@ class RenderWebGL extends EventEmitter {
11241111 // Limit size of viewport to the bounds around the target Drawable,
11251112 // and create the projection matrix for the draw.
11261113 gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1127- const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
1114+ const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
11281115
11291116 gl . clearColor ( 0 , 0 , 0 , 0 ) ;
11301117 gl . clear ( gl . COLOR_BUFFER_BIT ) ;
@@ -1199,7 +1186,7 @@ class RenderWebGL extends EventEmitter {
11991186 const pickY = bounds . top - scratchY ;
12001187
12011188 gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1202- const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
1189+ const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
12031190
12041191 gl . clearColor . apply ( gl , this . _backgroundColor ) ;
12051192 gl . clear ( gl . COLOR_BUFFER_BIT ) ;
@@ -1268,7 +1255,8 @@ class RenderWebGL extends EventEmitter {
12681255 }
12691256
12701257 /**
1271- * Filter a list of candidates for a touching query into only those that could possibly intersect the given bounds.
1258+ * Filter a list of candidates for a touching query into only those that
1259+ * could possibly intersect the given bounds.
12721260 * @param {int } drawableID - ID for drawable of query.
12731261 * @param {Array<int> } candidateIDs - Candidates for touching query.
12741262 * @return {?Array< {id, drawable, intersection} > } Filtered candidates with useful data.
@@ -1279,7 +1267,8 @@ class RenderWebGL extends EventEmitter {
12791267 if ( bounds === null ) {
12801268 return result ;
12811269 }
1282- for ( let index = 0 ; index < candidateIDs . length ; ++ index ) {
1270+ // iterate through the drawables list BACKWARDS - we want the top most item to be the first we check
1271+ for ( let index = candidateIDs . length - 1 ; index >= 0 ; index -- ) {
12831272 const id = candidateIDs [ index ] ;
12841273 if ( id !== drawableID ) {
12851274 const drawable = this . _allDrawables [ id ] ;
@@ -1439,7 +1428,7 @@ class RenderWebGL extends EventEmitter {
14391428
14401429 // Limit size of viewport to the bounds around the stamp Drawable and create the projection matrix for the draw.
14411430 gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1442- const projection = this . _makeOrthoProjection ( bounds . left , bounds . right , bounds . top , bounds . bottom ) ;
1431+ const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
14431432
14441433 gl . clearColor ( 0 , 0 , 0 , 0 ) ;
14451434 gl . clear ( gl . COLOR_BUFFER_BIT ) ;
@@ -1528,7 +1517,7 @@ class RenderWebGL extends EventEmitter {
15281517 * can skip superfluous extra state calls when it is already in that
15291518 * region. Since one region may be entered from within another a exit
15301519 * handle can also be registered that is called when a new region is about
1531- * to be entered to restore a common in-between state.
1520+ * to be entered to restore a common inbetween state.
15321521 *
15331522 * @param {any } regionId - id of the region to enter
15341523 * @param {function } enter - handle to call when first entering a region
@@ -1660,7 +1649,7 @@ class RenderWebGL extends EventEmitter {
16601649 *
16611650 * The determinant is useful in this case to know if AC is counter
16621651 * clockwise from AB. A positive value means the AC is counter
1663- * clockwise from AC. A negative value means AC is clockwise from AB.
1652+ * clockwise from AC. A negative value menas AC is clockwise from AB.
16641653 *
16651654 * @param {Float32Array } A A 2d vector in space.
16661655 * @param {Float32Array } B A 2d vector in space.
@@ -1765,15 +1754,16 @@ class RenderWebGL extends EventEmitter {
17651754 * Sample a "final" color from an array of drawables at a given scratch space.
17661755 * Will blend any alpha values with the drawables "below" it.
17671756 * @param {twgl.v3 } vec Scratch Vector Space to sample
1768- * @param {Array<Drawables> } drawables A list of drawables with the "bottom most" drawable at index 0
1757+ * @param {Array<Drawables> } drawables A list of drawables with the "top most"
1758+ * drawable at index 0
17691759 * @param {Uint8ClampedArray } dst The color3b space to store the answer in.
17701760 * @return {Uint8ClampedArray } The dst vector with everything blended down.
17711761 */
17721762 static sampleColor3b ( vec , drawables , dst ) {
17731763 dst = dst || new Uint8ClampedArray ( 3 ) ;
17741764 dst . fill ( 0 ) ;
17751765 let blendAlpha = 1 ;
1776- for ( let index = drawables . length - 1 ; blendAlpha !== 0 && index >= 0 ; -- index ) {
1766+ for ( let index = 0 ; blendAlpha !== 0 && index < drawables . length ; index ++ ) {
17771767 /*
17781768 if (left > vec[0] || right < vec[0] ||
17791769 bottom > vec[1] || top < vec[0]) {
0 commit comments