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 |