summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2022-07-31 12:39:49 -0400
committerDavid Thompson <dthompson2@worcester.edu>2022-07-31 12:39:49 -0400
commitd1b91f8037f99bbb26a51f6d7b720f23f6358aad (patch)
tree2abd89673da06399c3d73a754ec543c4171cdf71
parent06f4940a757c478b8474808961fae41c983c88d7 (diff)
node-2d: Apply local matrix when computing bounding box.
-rw-r--r--starling/node-2d.scm42
1 files 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 <node-2d>) child)
#t)
-;; TODO: Take rotation and skew into consideration.
(define-method (refresh-bounding-box (node <node-2d>))
(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 <node-2d>) slot old new)