@@ -503,6 +503,38 @@ class Drawable {
503
503
return this . skin . isTouchingLinear ( getLocalPosition ( this , vec ) ) ;
504
504
}
505
505
506
+ /**
507
+ * Initialize a bounding rectangle with a set of convex hull points, taking into account that the points refer to
508
+ * pixel centers and not pixel edges.
509
+ * @param {Rectangle } rect The bounding rectangle to initialize
510
+ * @param {Array<Array.number> } points The convex hull points
511
+ */
512
+ _initRectangleFromConvexHullPoints ( rect , points ) {
513
+ rect . left = Infinity ;
514
+ rect . right = - Infinity ;
515
+ rect . top = - Infinity ;
516
+ rect . bottom = Infinity ;
517
+
518
+ // Each convex hull point is the center of a pixel. However, said pixels each have area. We must take into
519
+ // account the size of the pixels when calculating the bounds. The pixel dimensions depend on the scale and
520
+ // rotation (as we're treating pixels as squares, which change dimensions when rotated).
521
+
522
+ // The "Scratch-space" size of one texture pixel at the drawable's current size.
523
+ const pixelScale = ( this . scale [ 0 ] / 100 ) * ( this . skin . size [ 0 ] / this . skin . _silhouette . _width ) ;
524
+ // Half the size of a rotated pixel, if we assume pixels are shaped like squares.
525
+ // At 0 degrees of rotation, this will be 0.5. At 45 degrees, it'll be 0.707 (half the square root of 2), etc.
526
+ const halfPixel = ( Math . abs ( this . _rotationMatrix [ 0 ] ) + Math . abs ( this . _rotationMatrix [ 1 ] ) ) * 0.5 * pixelScale ;
527
+
528
+ for ( let i = 0 ; i < points . length ; i ++ ) {
529
+ const x = points [ i ] [ 0 ] ;
530
+ const y = points [ i ] [ 1 ] ;
531
+ if ( ( x - halfPixel ) < rect . left ) rect . left = x - halfPixel ;
532
+ if ( ( x + halfPixel ) > rect . right ) rect . right = x + halfPixel ;
533
+ if ( ( y + halfPixel ) > rect . top ) rect . top = y + halfPixel ;
534
+ if ( ( y - halfPixel ) < rect . bottom ) rect . bottom = y - halfPixel ;
535
+ }
536
+ }
537
+
506
538
/**
507
539
* Get the precise bounds for a Drawable.
508
540
* This function applies the transform matrix to the known convex hull,
@@ -521,7 +553,7 @@ class Drawable {
521
553
const transformedHullPoints = this . _getTransformedHullPoints ( ) ;
522
554
// Search through transformed points to generate box on axes.
523
555
result = result || new Rectangle ( ) ;
524
- result . initFromPointsAABB ( transformedHullPoints ) ;
556
+ this . _initRectangleFromConvexHullPoints ( result , transformedHullPoints ) ;
525
557
return result ;
526
558
}
527
559
@@ -545,7 +577,7 @@ class Drawable {
545
577
const filteredHullPoints = transformedHullPoints . filter ( p => p [ 1 ] > maxY - slice ) ;
546
578
// Search through filtered points to generate box on axes.
547
579
result = result || new Rectangle ( ) ;
548
- result . initFromPointsAABB ( filteredHullPoints ) ;
580
+ this . _initRectangleFromConvexHullPoints ( result , filteredHullPoints ) ;
549
581
return result ;
550
582
}
551
583
0 commit comments