Skip to content

Commit efa5f8a

Browse files
committed
Experimental Transform implementation
1 parent 0e0fceb commit efa5f8a

1 file changed

Lines changed: 252 additions & 0 deletions

File tree

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// This is an abstraction for a transformation
2+
// matrix. It shouldn't contain anything that
3+
// is not specific to that.
4+
function Transform(x, y)
5+
{
6+
// We should definitely build a matrix pool
7+
// instancing typed arrays at runtime is very expensive.
8+
this.local = new Float32Array([1, 0, 0, 1, x, y]);
9+
this.world = new Float32Array([1, 0, 0, 1, 0, 0]);
10+
// More experienced developer can just access the
11+
// local and world matrices. For developer who want
12+
// easy access to specific components of the matrix
13+
// they can use the decomposition functions.
14+
}
15+
// This functions only apply to local matrix
16+
Transform.prototype.setTranslate = function (x, y)
17+
{
18+
var local = this.local;
19+
local[4] = x;
20+
local[5] = y;
21+
};
22+
Transform.prototype.setScale = function (x, y)
23+
{
24+
var local = this.local;
25+
local[0] = x;
26+
local[3] = y;
27+
};
28+
Transform.prototype.setRotation = function (radian)
29+
{
30+
var tcos = Math.cos(radian);
31+
var tsin = Math.sin(radian);
32+
var local = this.local;
33+
local[0] = cr + sr;
34+
local[1] = cr + sr;
35+
local[2] = -sr + cr;
36+
local[3] = -sr + cr;
37+
};
38+
Transform.prototype.translate = function (x, y)
39+
{
40+
var local = this.local;
41+
local[4] = local[0] * x + local[2] * y + local[4];
42+
local[5] = local[1] * x + local[3] * y + local[5];
43+
};
44+
Transform.prototype.scale = function (x, y)
45+
{
46+
var local = this.local;
47+
local[0] = local[0] * x;
48+
local[1] = local[1] * x;
49+
local[2] = local[2] * y;
50+
local[3] = local[3] * y;
51+
};
52+
Transform.prototype.rotate = function (radian)
53+
{
54+
var local = this.local;
55+
var a = local[0];
56+
var b = local[1];
57+
var c = local[2];
58+
var d = local[3];
59+
var tcos = Math.cos(radian);
60+
var tsin = Math.sin(radian);
61+
62+
local[0] = a * tcos + c * tsin;
63+
local[1] = b * tcos + d * tsin;
64+
local[2] = a * -tsin + c * tcos;
65+
local[3] = b * -tsin + d * tcos;
66+
};
67+
Transform.prototype.transform = function (a, b, c, d, tx, ty)
68+
{
69+
var local = this.local;
70+
var local0 = local[0];
71+
var local1 = local[1];
72+
var local2 = local[2];
73+
var local3 = local[3];
74+
75+
var a2 = a * local0 + b * local2;
76+
var b2 = a * local1 + b * local3;
77+
var c2 = c * local0 + d * local2;
78+
var d2 = c * local1 + d * local3;
79+
var e2 = tx * local0 + ty * local2 + local[4];
80+
var f2 = tx * local1 + ty * local3 + local[5];
81+
82+
this.setTransform(a2, b2, c2, d2, e2, f2);
83+
};
84+
Transform.prototype.setTransform = function (a, b, c, d, tx, ty)
85+
{
86+
var local = this.local;
87+
local[0] = a;
88+
local[1] = b;
89+
local[2] = c;
90+
local[3] = d;
91+
local[4] = tx;
92+
local[5] = ty;
93+
};
94+
Transform.prototype.loadIdentity = function ()
95+
{
96+
var local = this.local;
97+
local[0] = 1;
98+
local[1] = 0;
99+
local[2] = 0;
100+
local[3] = 1;
101+
local[4] = 0;
102+
local[5] = 0;
103+
};
104+
// This is the only function that operates on the world transform
105+
// Should only be called once per frame.
106+
Transform.prototype.updateWorldMatrix = function (parentTransform)
107+
{
108+
var local = this.local;
109+
var world = this.world;
110+
var parent = parentTransform;
111+
112+
world[0] = parent[0] * local[0] + parent[1] * local[2];
113+
world[1] = parent[0] * local[1] + parent[1] * local[3];
114+
world[2] = parent[2] * local[0] + parent[3] * local[2];
115+
world[3] = parent[2] * local[1] + parent[3] * local[3];
116+
world[4] = parent[4] * local[0] + parent[5] * local[2] + local[4];
117+
world[5] = parent[4] * local[1] + parent[5] * local[3] + local[5];
118+
};
119+
120+
// Explicit functions describe cost of operation
121+
// Should only be used by users. If transform is
122+
// needed it should be applied by the regular
123+
// matrix multiplication.
124+
// WARNING: THESE ARE EXPENSIVE!!
125+
126+
// Local
127+
Transform.prototype.getTranslate = function (vec2)
128+
{
129+
var local = this.local;
130+
vec2[0] = local[0];
131+
vec2[1] = local[1];
132+
return vec2;
133+
};
134+
Transform.prototype.getScale = function (vec2)
135+
{
136+
var local = this.local;
137+
var a = local[0];
138+
var c = local[2];
139+
var b = local[1];
140+
var d = local[3];
141+
var a2 = a * a;
142+
var c2 = c * c;
143+
var b2 = b * b;
144+
var d2 = d * d;
145+
var sy = Math.sqrt(b2 + d2);
146+
var sx = Math.sqrt(a2 + c2);
147+
vec2[0] = sx;
148+
vec2[1] = sy;
149+
return vec2;
150+
};
151+
Transform.prototype.getTranslateX = function ()
152+
{
153+
return this.local[4];
154+
};
155+
156+
Transform.prototype.getTranslateY = function ()
157+
{
158+
return this.local[5];
159+
};
160+
Transform.prototype.getScaleX = function ()
161+
{
162+
var local = this.local;
163+
var a = local[0];
164+
var c = local[2];
165+
var a2 = a * a;
166+
var c2 = c * c;
167+
var sx = Math.sqrt(a2 + c2);
168+
return sx;
169+
};
170+
Transform.prototype.getScaleY = function ()
171+
{
172+
var local = this.local;
173+
var b = local[1];
174+
var d = local[3];
175+
var b2 = b * b;
176+
var d2 = d * d;
177+
var sy = Math.sqrt(b2 + d2);
178+
return sx;
179+
};
180+
Transform.prototype.getRotation = function ()
181+
{
182+
var local = this.local;
183+
var a = local[0];
184+
var c = local[2];
185+
var a2 = a * a;
186+
var c2 = c * c;
187+
return Math.acos(a / Math.sqrt(a2 + c2)) * (Math.atan(-c / a) < 0 ? -1 : 1);
188+
};
189+
190+
// World
191+
Transform.prototype.getWorldTranslate = function (vec2)
192+
{
193+
var world = this.world;
194+
vec2[0] = world[0];
195+
vec2[1] = world[1];
196+
return vec2;
197+
};
198+
Transform.prototype.getWorldScale = function (vec2)
199+
{
200+
var world = this.world;
201+
var a = world[0];
202+
var c = world[2];
203+
var b = world[1];
204+
var d = world[3];
205+
var a2 = a * a;
206+
var c2 = c * c;
207+
var b2 = b * b;
208+
var d2 = d * d;
209+
var sy = Math.sqrt(b2 + d2);
210+
var sx = Math.sqrt(a2 + c2);
211+
vec2[0] = sx;
212+
vec2[1] = sy;
213+
return vec2;
214+
};
215+
Transform.prototype.getWorldTranslateX = function ()
216+
{
217+
return this.world[4];
218+
};
219+
220+
Transform.prototype.getWorldTranslateY = function ()
221+
{
222+
return this.world[5];
223+
};
224+
Transform.prototype.getWorldScaleX = function ()
225+
{
226+
var world = this.world;
227+
var a = world[0];
228+
var c = world[2];
229+
var a2 = a * a;
230+
var c2 = c * c;
231+
var sx = Math.sqrt(a2 + c2);
232+
return sx;
233+
};
234+
Transform.prototype.getWorldScaleY = function ()
235+
{
236+
var world = this.world;
237+
var b = world[1];
238+
var d = world[3];
239+
var b2 = b * b;
240+
var d2 = d * d;
241+
var sy = Math.sqrt(b2 + d2);
242+
return sx;
243+
};
244+
Transform.prototype.getWorldRotation = function ()
245+
{
246+
var world = this.world;
247+
var a = world[0];
248+
var c = world[2];
249+
var a2 = a * a;
250+
var c2 = c * c;
251+
return Math.acos(a / Math.sqrt(a2 + c2)) * (Math.atan(-c / a) < 0 ? -1 : 1);
252+
};

0 commit comments

Comments
 (0)