flutter/examples/game/lib/transform_node.dart
2015-06-08 14:38:06 -07:00

151 lines
3.2 KiB
Dart

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.rotate(degrees2radians(_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();
}
void update(double dt) {
}
}