From 69785bcd852d6344d19e755b7ea9cb38752b8156 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 29 Aug 2014 15:10:45 -0400 Subject: scene: Use dirty checking to improve rendering speed for static nodes. * sly/scene.scm (): Add transform field. (make-scene-node): Initialize transform. (scene-node-dirty?, recompute-transform!): New procedures. (draw-scene-node): Don't generate new transform if node isn't dirty. --- sly/scene.scm | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/sly/scene.scm b/sly/scene.scm index 9314eac..7f6ec5e 100644 --- a/sly/scene.scm +++ b/sly/scene.scm @@ -46,6 +46,7 @@ (prev-position scene-node-prev-position set-scene-node-prev-position!) (prev-scale scene-node-prev-scale set-scene-node-prev-scale!) (prev-rotation scene-node-prev-rotation set-scene-node-prev-rotation!) + (transform scene-node-transform set-scene-node-transform!) (uniforms scene-node-uniforms) (children scene-node-children)) @@ -56,10 +57,21 @@ (uniforms '()) (children '()) #:allow-other-keys) - (%make-scene-node position scale rotation uniforms children)) + (let ((node (%make-scene-node position scale rotation uniforms children))) + (update-scene-node node) + (recompute-transform! node 0) + node)) (define scene-node make-scene-node) +(define (scene-node-dirty? node) + (define (different? a b) + (not (equal? (a node) (b node)))) + + (or (different? scene-node-position scene-node-prev-position) + (different? scene-node-scale scene-node-prev-scale) + (different? scene-node-rotation scene-node-prev-rotation))) + (define (scene-root . children) (scene-node #:children children)) @@ -81,20 +93,33 @@ current (vector-interpolate prev current alpha))) +(define (recompute-transform! node alpha) + (signal-let ((position (scene-node-position node)) + (%scale (scene-node-scale node)) + (rotation (scene-node-rotation node))) + (let ((t (transform* + (translate + (interpolate position + (scene-node-prev-position node) + alpha)) + (quaternion->transform + (quaternion-slerp rotation + (scene-node-prev-rotation node) + alpha)) + (scale (interpolate %scale + (scene-node-prev-scale node) + alpha))))) + (set-scene-node-transform! node t) + t))) + (define (draw-scene-node node alpha transform) (signal-let ((node node)) (if (mesh? node) (draw-mesh node `(("mvp" ,transform))) - (signal-let ((position (scene-node-position node)) - (%scale (scene-node-scale node)) - (rotation (scene-node-rotation node)) - (children (scene-node-children node))) - (let ((transform (transform* - transform - (translate - (interpolate position - (scene-node-prev-position node) - alpha)) - (quaternion->transform rotation) - (scale %scale)))) + (let ((transform + (transform* transform + (if (scene-node-dirty? node) + (recompute-transform! node alpha) + (scene-node-transform node))))) + (signal-let ((children (scene-node-children node))) (for-each (cut draw-scene-node <> alpha transform) children)))))) -- cgit v1.2.3