From d1b91f8037f99bbb26a51f6d7b720f23f6358aad Mon Sep 17 00:00:00 2001 From: David Thompson Date: Sun, 31 Jul 2022 12:39:49 -0400 Subject: node-2d: Apply local matrix when computing bounding box. --- starling/node-2d.scm | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/starling/node-2d.scm b/starling/node-2d.scm index 005d7f1..00cbf4b 100644 --- a/starling/node-2d.scm +++ b/starling/node-2d.scm @@ -395,16 +395,46 @@ (define-method (on-child-resize (node ) child) #t) -;; TODO: Take rotation and skew into consideration. (define-method (refresh-bounding-box (node )) (let ((bb (bounding-box node)) (p (position node)) (o (origin node)) - (s (scale node))) - (set-rect-x! bb (- (vec2-x p) (vec2-x o))) - (set-rect-y! bb (- (vec2-y p) (vec2-y o))) - (set-rect-width! bb (* (width node) (vec2-x s))) - (set-rect-height! bb (* (height node) (vec2-y s))) + (r (rotation node)) + (k (skew node)) + (w (width node)) + (h (height node))) + (if (and (= r 0.0) + (= (vec2-x k) 0.0) + (= (vec2-y k) 0.0)) + ;; Fast path: Node is axis-aligned and bounding box + ;; calculation is easy peasy. + (let ((s (scale node))) + (set-rect-x! bb (- (vec2-x p) (vec2-x o))) + (set-rect-y! bb (- (vec2-y p) (vec2-y o))) + (set-rect-width! bb (* w (vec2-x s))) + (set-rect-height! bb (* h (vec2-y s)))) + ;; Slow path: Node is rotated, skewed, or both. + (let* ((m (local-matrix node)) + (x0 (- (vec2-x p) (vec2-x o))) + (y0 (- (vec2-y p) (vec2-y o))) + (x1 (+ x0 w)) + (y1 (+ y0 h)) + (x2 (matrix4-transform-x m x0 y0)) + (y2 (matrix4-transform-y m x0 y0)) + (x3 (matrix4-transform-x m x1 y0)) + (y3 (matrix4-transform-y m x1 y0)) + (x4 (matrix4-transform-x m x1 y1)) + (y4 (matrix4-transform-y m x1 y1)) + (x5 (matrix4-transform-x m x0 y1)) + (y5 (matrix4-transform-y m x0 y1)) + (xmin (min x2 x3 x4 x5)) + (ymin (min y2 y3 y4 y5)) + (xmax (max x2 x3 x4 x5)) + (ymax (max y2 y3 y4 y5))) + (set-rect-x! bb xmin) + (set-rect-y! bb ymin) + (set-rect-width! bb (- xmax xmin)) + (set-rect-height! bb (- ymax ymin)))) (set! (dirty-bounding-box? node) #f))) (define-method (on-change (node ) slot old new) -- cgit v1.2.3