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

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

Powered by Google App Engine
This is Rietveld 408576698