Index: sky/examples/game/lib/transform_node.dart |
diff --git a/sky/examples/game/lib/transform_node.dart b/sky/examples/game/lib/transform_node.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4ceae3313aaf2e28a81ed8bf81a5d71b1c83004d |
--- /dev/null |
+++ b/sky/examples/game/lib/transform_node.dart |
@@ -0,0 +1,146 @@ |
+part of sprites; |
+ |
+double degrees2radians(double degrees) => degrees * Math.PI/180.8; |
+ |
+double radians2degrees(double radians) => radians * 180.0/Math.PI; |
+ |
+class TransformNode { |
+ Vector2 _position; |
+ double _rotation; |
+ |
+ bool _isMatrixDirty; |
+ Matrix3 _transform; |
+ Matrix3 _pivotTransform; |
+ |
+ double _width; |
+ double _height; |
+ |
+ Vector2 _pivot; |
+ |
+ List<TransformNode>children; |
+ |
+ |
+ TransformNode() { |
+ _width = 0.0; |
+ _height = 0.0; |
+ _rotation = 0.0; |
+ _pivot = new Vector2(0.0, 0.0); |
+ _position = new Vector2(0.0, 0.0); |
+ _isMatrixDirty = false; |
+ _transform = new Matrix3.identity(); |
+ _pivotTransform = new Matrix3.identity(); |
+ children = []; |
+ } |
+ |
+ double get rotation => _rotation; |
+ |
+ void set rotation(double rotation) { |
+ _rotation = rotation; |
+ _isMatrixDirty = true; |
+ } |
+ |
+ |
+ Vector2 get position => _position; |
+ |
+ void set position(Vector2 position) { |
+ _position = position; |
+ _isMatrixDirty = true; |
+ } |
+ |
+ double get width => _width; |
+ |
+ void set width(double width) { |
+ _width = width; |
+ _isMatrixDirty = true; |
+ } |
+ |
+ |
+ double get height => _height; |
+ |
+ void set height(double height) { |
+ _height = height; |
+ _isMatrixDirty = true; |
+ } |
+ |
+ Vector2 get pivot => _pivot; |
+ |
+ void set pivot(Vector2 pivot) { |
+ _pivot = pivot; |
+ _isMatrixDirty = true; |
+ } |
+ |
+ |
+ Matrix3 get transformMatrix { |
+ if (!_isMatrixDirty) { |
+ return _transform; |
+ } |
+ |
+ Vector2 pivotInPoints = new Vector2(_width * _pivot[0], _height * _pivot[1]); |
+ |
+ double cx, sx, cy, sy; |
+ |
+ if (_rotation == 0) { |
+ cx = 1.0; |
+ sx = 0.0; |
+ cy = 1.0; |
+ sy = 0.0; |
+ } |
+ else { |
+ double radiansX = degrees2radians(_rotation); |
+ double radiansY = degrees2radians(_rotation); |
+ |
+ cx = Math.cos(radiansX); |
+ sx = Math.sin(radiansX); |
+ cy = Math.cos(radiansY); |
+ sy = Math.sin(radiansY); |
+ } |
+ |
+ // TODO: Add support for scale |
+ double scaleX = 1.0; |
+ double scaleY = 1.0; |
+ |
+ // Create transformation matrix for scale, position and rotation |
+ _transform.setValues(cy * scaleX, sy * scaleX, 0.0, |
+ -sx * scaleY, cx * scaleY, 0.0, |
+ _position[0], _position[1], 1.0); |
+ |
+ if (_pivot.x != 0 || _pivot.y != 0) { |
+ _pivotTransform.setValues(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, pivotInPoints[0], pivotInPoints[1], 1.0); |
+ _transform.multiply(_pivotTransform); |
+ } |
+ |
+ return _transform; |
+ } |
+ |
+ void visit(PictureRecorder canvas) { |
+ prePaint(canvas); |
+ paint(canvas); |
+ visitChildren(canvas); |
+ postPaint(canvas); |
+ } |
+ |
+ void prePaint(PictureRecorder canvas) { |
+ canvas.save(); |
+ |
+ canvas.translate(_position[0], _position[1]); |
+ canvas.rotateDegrees(_rotation); |
+ canvas.translate(-_width*_pivot[0], -_height*_pivot[1]); |
+ |
+ // TODO: Use transformation matrix instead of individual calls |
+// List<double> matrix = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; |
+// this.transformMatrix.copyIntoArray(matrix); |
+// canvas.concat(matrix); |
+ } |
+ |
+ void paint(PictureRecorder canvas) { |
+ |
+ } |
+ |
+ void visitChildren(PictureRecorder canvas) { |
+ children.forEach((child) => child.visit(canvas)); |
+ } |
+ |
+ void postPaint(PictureRecorder canvas) { |
+ canvas.restore(); |
+ } |
+} |