OLD | NEW |
1 part of sprites; | 1 part of sprites; |
2 | 2 |
3 double convertDegrees2Radians(double degrees) => degrees * Math.PI/180.8; | 3 double convertDegrees2Radians(double degrees) => degrees * Math.PI/180.8; |
4 | 4 |
5 double convertRadians2Degrees(double radians) => radians * 180.0/Math.PI; | 5 double convertRadians2Degrees(double radians) => radians * 180.0/Math.PI; |
6 | 6 |
7 class Node { | 7 class Node { |
8 | 8 |
9 // Member variables | 9 // Member variables |
10 | 10 |
11 SpriteBox _spriteBox; | 11 SpriteBox _spriteBox; |
12 Node _parent; | 12 Node _parent; |
13 | 13 |
14 Point _position; | 14 Point _position; |
15 double _rotation; | 15 double _rotation; |
16 | 16 |
17 bool _isMatrixDirty; | |
18 Matrix4 _transformMatrix; | 17 Matrix4 _transformMatrix; |
19 Matrix4 _transformMatrixFromWorld; | 18 Matrix4 _transformMatrixNodeToBox; |
| 19 Matrix4 _transformMatrixBoxToNode; |
20 | 20 |
21 double _scaleX; | 21 double _scaleX; |
22 double _scaleY; | 22 double _scaleY; |
23 | 23 |
24 bool visible; | 24 bool visible; |
25 | 25 |
26 double _zPosition; | 26 double _zPosition; |
27 int _addedOrder; | 27 int _addedOrder; |
28 int _childrenLastAddedOrder; | 28 int _childrenLastAddedOrder; |
29 bool _childrenNeedSorting; | 29 bool _childrenNeedSorting; |
30 | 30 |
31 bool paused = false; | 31 bool paused = false; |
32 | 32 |
| 33 bool _userInteractionEnabled = false; |
| 34 bool handleMultiplePointers = false; |
| 35 int _handlingPointer; |
| 36 |
33 List<Node>_children; | 37 List<Node>_children; |
34 | 38 |
35 // Constructors | 39 // Constructors |
36 | 40 |
37 Node() { | 41 Node() { |
38 _rotation = 0.0; | 42 _rotation = 0.0; |
39 _position = Point.origin; | 43 _position = Point.origin; |
40 _scaleX = _scaleY = 1.0; | 44 _scaleX = _scaleY = 1.0; |
41 _isMatrixDirty = false; | |
42 _transformMatrix = new Matrix4.identity(); | 45 _transformMatrix = new Matrix4.identity(); |
43 _children = []; | 46 _children = []; |
44 _childrenNeedSorting = false; | 47 _childrenNeedSorting = false; |
45 _childrenLastAddedOrder = 0; | 48 _childrenLastAddedOrder = 0; |
46 _zPosition = 0.0; | 49 _zPosition = 0.0; |
47 visible = true; | 50 visible = true; |
48 } | 51 } |
49 | 52 |
50 // Property setters and getters | 53 // Property setters and getters |
51 | 54 |
52 SpriteBox get spriteBox => _spriteBox; | 55 SpriteBox get spriteBox => _spriteBox; |
53 | 56 |
54 Node get parent => _parent; | 57 Node get parent => _parent; |
55 | 58 |
56 double get rotation => _rotation; | 59 double get rotation => _rotation; |
57 | 60 |
58 void set rotation(double rotation) { | 61 void set rotation(double rotation) { |
| 62 assert(rotation != null); |
59 _rotation = rotation; | 63 _rotation = rotation; |
60 _isMatrixDirty = true; | 64 _invalidateTransformMatrix(); |
61 } | 65 } |
62 | 66 |
63 Point get position => _position; | 67 Point get position => _position; |
64 | 68 |
65 void set position(Point position) { | 69 void set position(Point position) { |
| 70 assert(position != null); |
66 _position = position; | 71 _position = position; |
67 _isMatrixDirty = true; | 72 _invalidateTransformMatrix(); |
68 } | 73 } |
69 | 74 |
70 double get zPosition => _zPosition; | 75 double get zPosition => _zPosition; |
71 | 76 |
72 void set zPosition(double zPosition) { | 77 void set zPosition(double zPosition) { |
| 78 assert(zPosition != null); |
73 _zPosition = zPosition; | 79 _zPosition = zPosition; |
74 if (_parent != null) { | 80 if (_parent != null) { |
75 _parent._childrenNeedSorting = true; | 81 _parent._childrenNeedSorting = true; |
76 } | 82 } |
77 } | 83 } |
78 | 84 |
79 double get scale { | 85 double get scale { |
80 assert(_scaleX == _scaleY); | 86 assert(_scaleX == _scaleY); |
81 return _scaleX; | 87 return _scaleX; |
82 } | 88 } |
83 | 89 |
84 void set scale(double scale) { | 90 void set scale(double scale) { |
| 91 assert(scale != null); |
85 _scaleX = _scaleY = scale; | 92 _scaleX = _scaleY = scale; |
86 _isMatrixDirty = true; | 93 _invalidateTransformMatrix(); |
87 } | 94 } |
88 | 95 |
89 List<Node> get children => _children; | 96 List<Node> get children => _children; |
90 | 97 |
91 // Adding and removing children | 98 // Adding and removing children |
92 | 99 |
93 void addChild(Node child) { | 100 void addChild(Node child) { |
| 101 assert(child != null); |
94 assert(child._parent == null); | 102 assert(child._parent == null); |
95 | 103 |
96 _childrenNeedSorting = true; | 104 _childrenNeedSorting = true; |
97 _children.add(child); | 105 _children.add(child); |
98 child._parent = this; | 106 child._parent = this; |
99 child._spriteBox = this._spriteBox; | 107 child._spriteBox = this._spriteBox; |
100 _childrenLastAddedOrder += 1; | 108 _childrenLastAddedOrder += 1; |
101 child._addedOrder = _childrenLastAddedOrder; | 109 child._addedOrder = _childrenLastAddedOrder; |
| 110 if (_spriteBox != null) _spriteBox._eventTargets = null; |
102 } | 111 } |
103 | 112 |
104 void removeChild(Node child) { | 113 void removeChild(Node child) { |
| 114 assert(child != null); |
105 if (_children.remove(child)) { | 115 if (_children.remove(child)) { |
106 child._parent = null; | 116 child._parent = null; |
107 child._spriteBox = null; | 117 child._spriteBox = null; |
| 118 if (_spriteBox != null) _spriteBox._eventTargets = null; |
108 } | 119 } |
109 } | 120 } |
110 | 121 |
111 void removeFromParent() { | 122 void removeFromParent() { |
112 assert(_parent != null); | 123 assert(_parent != null); |
113 _parent.removeChild(this); | 124 _parent.removeChild(this); |
114 } | 125 } |
115 | 126 |
116 void removeAllChildren() { | 127 void removeAllChildren() { |
117 for (Node child in _children) { | 128 for (Node child in _children) { |
118 child._parent = null; | 129 child._parent = null; |
119 child._spriteBox = null; | 130 child._spriteBox = null; |
120 } | 131 } |
121 _children = []; | 132 _children = []; |
122 _childrenNeedSorting = false; | 133 _childrenNeedSorting = false; |
| 134 if (_spriteBox != null) _spriteBox._eventTargets = null; |
123 } | 135 } |
124 | 136 |
125 // Calculating the transformation matrix | 137 // Calculating the transformation matrix |
126 | 138 |
127 Matrix4 get transformMatrix { | 139 Matrix4 get transformMatrix { |
128 if (!_isMatrixDirty) { | 140 if (_transformMatrix != null) { |
129 return _transformMatrix; | 141 return _transformMatrix; |
130 } | 142 } |
131 | 143 |
132 double cx, sx, cy, sy; | 144 double cx, sx, cy, sy; |
133 | 145 |
134 if (_rotation == 0.0) { | 146 if (_rotation == 0.0) { |
135 cx = 1.0; | 147 cx = 1.0; |
136 sx = 0.0; | 148 sx = 0.0; |
137 cy = 1.0; | 149 cy = 1.0; |
138 sy = 0.0; | 150 sy = 0.0; |
139 } | 151 } |
140 else { | 152 else { |
141 double radiansX = convertDegrees2Radians(_rotation); | 153 double radiansX = convertDegrees2Radians(_rotation); |
142 double radiansY = convertDegrees2Radians(_rotation); | 154 double radiansY = convertDegrees2Radians(_rotation); |
143 | 155 |
144 cx = Math.cos(radiansX); | 156 cx = Math.cos(radiansX); |
145 sx = Math.sin(radiansX); | 157 sx = Math.sin(radiansX); |
146 cy = Math.cos(radiansY); | 158 cy = Math.cos(radiansY); |
147 sy = Math.sin(radiansY); | 159 sy = Math.sin(radiansY); |
148 } | 160 } |
149 | 161 |
150 // Create transformation matrix for scale, position and rotation | 162 // Create transformation matrix for scale, position and rotation |
151 _transformMatrix.setValues(cy * _scaleX, sy * _scaleX, 0.0, 0.0, | 163 _transformMatrix = new Matrix4(cy * _scaleX, sy * _scaleX, 0.0, 0.0, |
152 -sx * _scaleY, cx * _scaleY, 0.0, 0.0, | 164 -sx * _scaleY, cx * _scaleY, 0.0, 0.0, |
153 0.0, 0.0, 1.0, 0.0, | 165 0.0, 0.0, 1.0, 0.0, |
154 _position.x, _position.y, 0.0, 1.0 | 166 _position.x, _position.y, 0.0, 1.0); |
155 ); | |
156 | 167 |
157 return _transformMatrix; | 168 return _transformMatrix; |
158 } | 169 } |
159 | 170 |
| 171 void _invalidateTransformMatrix() { |
| 172 _transformMatrix = null; |
| 173 _invalidateToBoxTransformMatrix(); |
| 174 } |
| 175 |
| 176 void _invalidateToBoxTransformMatrix () { |
| 177 _transformMatrixNodeToBox = null; |
| 178 _transformMatrixBoxToNode = null; |
| 179 |
| 180 for (Node child in children) { |
| 181 child._invalidateToBoxTransformMatrix(); |
| 182 } |
| 183 } |
| 184 |
160 // Transforms to other nodes | 185 // Transforms to other nodes |
161 | 186 |
162 Matrix4 _nodeToBoxMatrix() { | 187 Matrix4 _nodeToBoxMatrix() { |
163 assert(_spriteBox != null); | 188 assert(_spriteBox != null); |
164 | 189 if (_transformMatrixNodeToBox != null) { |
165 Matrix4 t = transformMatrix; | 190 return _transformMatrixNodeToBox; |
166 | |
167 // Apply transforms from parents | |
168 Node p = this.parent; | |
169 while (p != null) { | |
170 t = new Matrix4.copy(p.transformMatrix).multiply(t); | |
171 p = p.parent; | |
172 } | 191 } |
173 | 192 |
174 // Apply transform from sprite box | 193 if (_parent == null) { |
175 t = new Matrix4.copy(_spriteBox.transformMatrix).multiply(t); | 194 // Base case, we are at the top |
176 | 195 assert(this == _spriteBox.rootNode); |
177 return t; | 196 _transformMatrixNodeToBox = new Matrix4.copy(_spriteBox.transformMatrix).m
ultiply(transformMatrix); |
| 197 } |
| 198 else { |
| 199 _transformMatrixNodeToBox = new Matrix4.copy(_parent._nodeToBoxMatrix()).m
ultiply(transformMatrix); |
| 200 } |
| 201 return _transformMatrixNodeToBox; |
178 } | 202 } |
179 | 203 |
180 Matrix4 _boxToNodeMatrix() { | 204 Matrix4 _boxToNodeMatrix() { |
181 assert(_spriteBox != null); | 205 assert(_spriteBox != null); |
182 | 206 |
183 Matrix4 t = _nodeToBoxMatrix(); | 207 if (_transformMatrixBoxToNode != null) { |
184 t.invert(); | 208 return _transformMatrixBoxToNode; |
| 209 } |
185 | 210 |
186 return t; | 211 _transformMatrixBoxToNode = new Matrix4.copy(_nodeToBoxMatrix()); |
| 212 _transformMatrixBoxToNode.invert(); |
| 213 |
| 214 return _transformMatrixBoxToNode; |
187 } | 215 } |
188 | 216 |
189 Point convertPointToNodeSpace(Point boxPoint) { | 217 Point convertPointToNodeSpace(Point boxPoint) { |
190 assert(boxPoint != null); | 218 assert(boxPoint != null); |
191 assert(_spriteBox != null); | 219 assert(_spriteBox != null); |
192 | 220 |
193 Vector4 v =_boxToNodeMatrix().transform(new Vector4(boxPoint.x, boxPoint.y,
0.0, 1.0)); | 221 Vector4 v =_boxToNodeMatrix().transform(new Vector4(boxPoint.x, boxPoint.y,
0.0, 1.0)); |
194 return new Point(v[0], v[1]); | 222 return new Point(v[0], v[1]); |
195 } | 223 } |
196 | 224 |
(...skipping 21 matching lines...) Expand all Loading... |
218 | 246 |
219 bool hitTest(Point nodePoint) { | 247 bool hitTest(Point nodePoint) { |
220 assert(nodePoint != null); | 248 assert(nodePoint != null); |
221 | 249 |
222 return false; | 250 return false; |
223 } | 251 } |
224 | 252 |
225 // Rendering | 253 // Rendering |
226 | 254 |
227 void visit(PictureRecorder canvas) { | 255 void visit(PictureRecorder canvas) { |
| 256 assert(canvas != null); |
228 if (!visible) return; | 257 if (!visible) return; |
229 | 258 |
230 prePaint(canvas); | 259 prePaint(canvas); |
231 paint(canvas); | 260 paint(canvas); |
232 visitChildren(canvas); | 261 visitChildren(canvas); |
233 postPaint(canvas); | 262 postPaint(canvas); |
234 } | 263 } |
235 | 264 |
236 void prePaint(PictureRecorder canvas) { | 265 void prePaint(PictureRecorder canvas) { |
237 canvas.save(); | 266 canvas.save(); |
238 | 267 |
239 // Get the transformation matrix and apply transform | 268 // Get the transformation matrix and apply transform |
240 canvas.concat(transformMatrix.storage); | 269 canvas.concat(transformMatrix.storage); |
241 } | 270 } |
242 | 271 |
243 void paint(PictureRecorder canvas) { | 272 void paint(PictureRecorder canvas) { |
244 | |
245 } | 273 } |
246 | 274 |
247 void visitChildren(PictureRecorder canvas) { | 275 void visitChildren(PictureRecorder canvas) { |
248 // Sort children primarily by zPosition, secondarily by added order | 276 // Sort children primarily by zPosition, secondarily by added order |
249 if (_childrenNeedSorting) { | 277 if (_childrenNeedSorting) { |
250 _children.sort((Node a, Node b) { | 278 _children.sort((Node a, Node b) { |
251 if (a._zPosition == b._zPosition) { | 279 if (a._zPosition == b._zPosition) { |
252 return a._addedOrder - b._addedOrder; | 280 return a._addedOrder - b._addedOrder; |
253 } | 281 } |
254 else if (a._zPosition > b._zPosition) { | 282 else if (a._zPosition > b._zPosition) { |
(...skipping 14 matching lines...) Expand all Loading... |
269 canvas.restore(); | 297 canvas.restore(); |
270 } | 298 } |
271 | 299 |
272 // Receiving update calls | 300 // Receiving update calls |
273 | 301 |
274 void update(double dt) { | 302 void update(double dt) { |
275 } | 303 } |
276 | 304 |
277 void spriteBoxPerformedLayout() { | 305 void spriteBoxPerformedLayout() { |
278 } | 306 } |
| 307 |
| 308 // Handling user interaction |
| 309 |
| 310 bool get userInteractionEnabled => _userInteractionEnabled; |
| 311 |
| 312 void set userInteractionEnabled(bool userInteractionEnabled) { |
| 313 _userInteractionEnabled = userInteractionEnabled; |
| 314 if (_spriteBox != null) _spriteBox._eventTargets = null; |
| 315 } |
| 316 |
| 317 bool handleEvent(SpriteBoxEvent event) { |
| 318 return false; |
| 319 } |
279 } | 320 } |
OLD | NEW |