| OLD | NEW |
| (Empty) |
| 1 part of sprites; | |
| 2 | |
| 3 double degrees2radians(double degrees) => degrees * Math.PI/180.8; | |
| 4 | |
| 5 double radians2degrees(double radians) => radians * 180.0/Math.PI; | |
| 6 | |
| 7 class TransformNode { | |
| 8 | |
| 9 // Member variables | |
| 10 | |
| 11 SpriteBox _spriteBox; | |
| 12 TransformNode _parent; | |
| 13 | |
| 14 Vector2 _position; | |
| 15 double _rotation; | |
| 16 | |
| 17 bool _isMatrixDirty; | |
| 18 Matrix3 _transform; | |
| 19 Matrix3 _pivotTransform; | |
| 20 | |
| 21 double _width; | |
| 22 double _height; | |
| 23 | |
| 24 double _scaleX; | |
| 25 double _scaleY; | |
| 26 | |
| 27 Vector2 _pivot; | |
| 28 | |
| 29 bool visible; | |
| 30 | |
| 31 double _zPosition; | |
| 32 int _addedOrder; | |
| 33 int _childrenLastAddedOrder; | |
| 34 bool _childrenNeedSorting; | |
| 35 | |
| 36 List<TransformNode>_children; | |
| 37 | |
| 38 // Constructors | |
| 39 | |
| 40 TransformNode() { | |
| 41 _width = 0.0; | |
| 42 _height = 0.0; | |
| 43 _rotation = 0.0; | |
| 44 _pivot = new Vector2(0.0, 0.0); | |
| 45 _position = new Vector2(0.0, 0.0); | |
| 46 _scaleX = _scaleY = 1.0; | |
| 47 _isMatrixDirty = false; | |
| 48 _transform = new Matrix3.identity(); | |
| 49 _pivotTransform = new Matrix3.identity(); | |
| 50 _children = []; | |
| 51 _childrenNeedSorting = false; | |
| 52 _childrenLastAddedOrder = 0; | |
| 53 visible = true; | |
| 54 } | |
| 55 | |
| 56 // Property setters and getters | |
| 57 | |
| 58 SpriteBox get spriteBox => _spriteBox; | |
| 59 | |
| 60 TransformNode get parent => _parent; | |
| 61 | |
| 62 double get rotation => _rotation; | |
| 63 | |
| 64 void set rotation(double rotation) { | |
| 65 _rotation = rotation; | |
| 66 _isMatrixDirty = true; | |
| 67 } | |
| 68 | |
| 69 Vector2 get position => _position; | |
| 70 | |
| 71 void set position(Vector2 position) { | |
| 72 _position = position; | |
| 73 _isMatrixDirty = true; | |
| 74 } | |
| 75 | |
| 76 double get width => _width; | |
| 77 | |
| 78 void set width(double width) { | |
| 79 _width = width; | |
| 80 _isMatrixDirty = true; | |
| 81 } | |
| 82 | |
| 83 double get height => _height; | |
| 84 | |
| 85 void set height(double height) { | |
| 86 _height = height; | |
| 87 _isMatrixDirty = true; | |
| 88 } | |
| 89 | |
| 90 Vector2 get pivot => _pivot; | |
| 91 | |
| 92 void set pivot(Vector2 pivot) { | |
| 93 _pivot = pivot; | |
| 94 _isMatrixDirty = true; | |
| 95 } | |
| 96 | |
| 97 double get zPosition => _zPosition; | |
| 98 | |
| 99 void set zPosition(double zPosition) { | |
| 100 _zPosition = zPosition; | |
| 101 if (_parent != null) { | |
| 102 _parent._childrenNeedSorting = true; | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 double get scale { | |
| 107 assert(_scaleX == _scaleY); | |
| 108 return _scaleX; | |
| 109 } | |
| 110 | |
| 111 void set scale(double scale) { | |
| 112 _scaleX = _scaleY = scale; | |
| 113 _isMatrixDirty = true; | |
| 114 } | |
| 115 | |
| 116 List<TransformNode> get children => _children; | |
| 117 | |
| 118 // Adding and removing children | |
| 119 | |
| 120 void addChild(TransformNode child) { | |
| 121 assert(child._parent == null); | |
| 122 | |
| 123 _childrenNeedSorting = true; | |
| 124 _children.add(child); | |
| 125 child._parent = this; | |
| 126 child._spriteBox = this._spriteBox; | |
| 127 _childrenLastAddedOrder += 1; | |
| 128 child._addedOrder = _childrenLastAddedOrder; | |
| 129 } | |
| 130 | |
| 131 void removeChild(TransformNode child) { | |
| 132 if (_children.remove(child)) { | |
| 133 child._parent = null; | |
| 134 child._spriteBox = null; | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 void removeFromParent() { | |
| 139 assert(_parent != null); | |
| 140 _parent.removeFromParent(); | |
| 141 } | |
| 142 | |
| 143 void removeAllChildren() { | |
| 144 for (TransformNode child in _children) { | |
| 145 child._parent = null; | |
| 146 child._spriteBox = null; | |
| 147 } | |
| 148 _children = []; | |
| 149 _childrenNeedSorting = false; | |
| 150 } | |
| 151 | |
| 152 // Calculating the transformation matrix | |
| 153 | |
| 154 Matrix3 get transformMatrix { | |
| 155 if (!_isMatrixDirty) { | |
| 156 return _transform; | |
| 157 } | |
| 158 | |
| 159 Vector2 pivotInPoints = new Vector2(_width * _pivot[0], _height * _pivot[1])
; | |
| 160 | |
| 161 double cx, sx, cy, sy; | |
| 162 | |
| 163 if (_rotation == 0) { | |
| 164 cx = 1.0; | |
| 165 sx = 0.0; | |
| 166 cy = 1.0; | |
| 167 sy = 0.0; | |
| 168 } | |
| 169 else { | |
| 170 double radiansX = degrees2radians(_rotation); | |
| 171 double radiansY = degrees2radians(_rotation); | |
| 172 | |
| 173 cx = Math.cos(radiansX); | |
| 174 sx = Math.sin(radiansX); | |
| 175 cy = Math.cos(radiansY); | |
| 176 sy = Math.sin(radiansY); | |
| 177 } | |
| 178 | |
| 179 // TODO: Add support for scale | |
| 180 double scaleX = 1.0; | |
| 181 double scaleY = 1.0; | |
| 182 | |
| 183 // Create transformation matrix for scale, position and rotation | |
| 184 _transform.setValues(cy * scaleX, sy * scaleX, 0.0, | |
| 185 -sx * scaleY, cx * scaleY, 0.0, | |
| 186 _position[0], _position[1], 1.0); | |
| 187 | |
| 188 if (_pivot.x != 0 || _pivot.y != 0) { | |
| 189 _pivotTransform.setValues(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, pivotInPoints[0],
pivotInPoints[1], 1.0); | |
| 190 _transform.multiply(_pivotTransform); | |
| 191 } | |
| 192 | |
| 193 return _transform; | |
| 194 } | |
| 195 | |
| 196 // Rendering | |
| 197 | |
| 198 void visit(PictureRecorder canvas) { | |
| 199 if (!visible) return; | |
| 200 | |
| 201 prePaint(canvas); | |
| 202 paint(canvas); | |
| 203 visitChildren(canvas); | |
| 204 postPaint(canvas); | |
| 205 } | |
| 206 | |
| 207 void prePaint(PictureRecorder canvas) { | |
| 208 canvas.save(); | |
| 209 | |
| 210 canvas.translate(_position[0], _position[1]); | |
| 211 canvas.rotate(degrees2radians(_rotation)); | |
| 212 canvas.scale(_scaleX, _scaleY); | |
| 213 canvas.translate(-_width*_pivot[0], -_height*_pivot[1]); | |
| 214 | |
| 215 // TODO: Use transformation matrix instead of individual calls | |
| 216 // List<double> matrix = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]; | |
| 217 // this.transformMatrix.copyIntoArray(matrix); | |
| 218 // canvas.concat(matrix); | |
| 219 } | |
| 220 | |
| 221 void paint(PictureRecorder canvas) { | |
| 222 | |
| 223 } | |
| 224 | |
| 225 void visitChildren(PictureRecorder canvas) { | |
| 226 // Sort children primarily by zPosition, secondarily by added order | |
| 227 if (_childrenNeedSorting) { | |
| 228 _children.sort((TransformNode a, TransformNode b) { | |
| 229 if (a._zPosition == b._zPosition) { | |
| 230 return b._addedOrder - a._addedOrder; | |
| 231 } | |
| 232 else if (a._zPosition > b._zPosition) { | |
| 233 return 1; | |
| 234 } | |
| 235 else { | |
| 236 return -1; | |
| 237 } | |
| 238 }); | |
| 239 _childrenNeedSorting = false; | |
| 240 } | |
| 241 | |
| 242 // Visit each child | |
| 243 _children.forEach((child) => child.visit(canvas)); | |
| 244 } | |
| 245 | |
| 246 void postPaint(PictureRecorder canvas) { | |
| 247 canvas.restore(); | |
| 248 } | |
| 249 | |
| 250 // Receiving update calls | |
| 251 | |
| 252 void update(double dt) { | |
| 253 | |
| 254 } | |
| 255 } | |
| OLD | NEW |