summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sly/scene.scm51
1 files 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))))))