Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: sky/examples/game/lib/transform_node.dart

Issue 1180703002: Fixes matrix transformations in sprites (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698