4 * Copyright (C) 2005-2013 Team XBMC
7 * This Program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This Program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with XBMC; see the file COPYING. If not, see
19 * <http://www.gnu.org/licenses/>.
29 // under gcc, inline will only take place if optimizations are applied (-O). this will force inline even whith optimizations.
30 #define XBMC_FORCE_INLINE __attribute__((always_inline))
32 #define XBMC_FORCE_INLINE
35 typedef uint32_t color_t;
46 m[0][0] = 1.0f; m[0][1] = m[0][2] = m[0][3] = 0.0f;
47 m[1][0] = m[1][2] = m[1][3] = 0.0f; m[1][1] = 1.0f;
48 m[2][0] = m[2][1] = m[2][3] = 0.0f; m[2][2] = 1.0f;
52 static TransformMatrix CreateTranslation(float transX, float transY, float transZ = 0)
54 TransformMatrix translation;
55 translation.SetTranslation(transX, transY, transZ);
58 void SetTranslation(float transX, float transY, float transZ)
60 m[0][1] = m[0][2] = 0.0f; m[0][0] = 1.0f; m[0][3] = transX;
61 m[1][0] = m[1][2] = 0.0f; m[1][1] = 1.0f; m[1][3] = transY;
62 m[2][0] = m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = transZ;
64 identity = (transX == 0 && transY == 0 && transZ == 0);
66 static TransformMatrix CreateScaler(float scaleX, float scaleY, float scaleZ = 1.0f)
68 TransformMatrix scaler;
69 scaler.m[0][0] = scaleX;
70 scaler.m[1][1] = scaleY;
71 scaler.m[2][2] = scaleZ;
72 scaler.identity = (scaleX == 1 && scaleY == 1 && scaleZ == 1);
75 void SetScaler(float scaleX, float scaleY, float centerX, float centerY)
77 // Trans(centerX,centerY,centerZ)*Scale(scaleX,scaleY,scaleZ)*Trans(-centerX,-centerY,-centerZ)
78 float centerZ = 0.0f, scaleZ = 1.0f;
79 m[0][0] = scaleX; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = centerX*(1-scaleX);
80 m[1][0] = 0.0f; m[1][1] = scaleY; m[1][2] = 0.0f; m[1][3] = centerY*(1-scaleY);
81 m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = scaleZ; m[2][3] = centerZ*(1-scaleZ);
83 identity = (scaleX == 1 && scaleY == 1);
85 void SetXRotation(float angle, float y, float z, float ar = 1.0f)
86 { // angle about the X axis, centered at y,z where our coordinate system has aspect ratio ar.
87 // Trans(0,y,z)*Scale(1,1/ar,1)*RotateX(angle)*Scale(ar,1,1)*Trans(0,-y,-z);
88 float c = cos(angle); float s = sin(angle);
89 m[0][0] = ar; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f;
90 m[1][0] = 0.0f; m[1][1] = c/ar; m[1][2] = -s/ar; m[1][3] = (-y*c+s*z)/ar + y;
91 m[2][0] = 0.0f; m[2][1] = s; m[2][2] = c; m[2][3] = (-y*s-c*z) + z;
93 identity = (angle == 0);
95 void SetYRotation(float angle, float x, float z, float ar = 1.0f)
96 { // angle about the Y axis, centered at x,z where our coordinate system has aspect ratio ar.
97 // Trans(x,0,z)*Scale(1/ar,1,1)*RotateY(angle)*Scale(ar,1,1)*Trans(-x,0,-z);
98 float c = cos(angle); float s = sin(angle);
99 m[0][0] = c; m[0][1] = 0.0f; m[0][2] = -s/ar; m[0][3] = -x*c + s*z/ar + x;
100 m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f;
101 m[2][0] = ar*s; m[2][1] = 0.0f; m[2][2] = c; m[2][3] = -ar*x*s - c*z + z;
103 identity = (angle == 0);
105 static TransformMatrix CreateZRotation(float angle, float x, float y, float ar = 1.0f)
106 { // angle about the Z axis, centered at x,y where our coordinate system has aspect ratio ar.
107 // Trans(x,y,0)*Scale(1/ar,1,1)*RotateZ(angle)*Scale(ar,1,1)*Trans(-x,-y,0)
109 rot.SetZRotation(angle, x, y, ar);
112 void SetZRotation(float angle, float x, float y, float ar = 1.0f)
113 { // angle about the Z axis, centered at x,y where our coordinate system has aspect ratio ar.
114 // Trans(x,y,0)*Scale(1/ar,1,1)*RotateZ(angle)*Scale(ar,1,1)*Trans(-x,-y,0)
115 float c = cos(angle); float s = sin(angle);
116 m[0][0] = c; m[0][1] = -s/ar; m[0][2] = 0.0f; m[0][3] = -x*c + s*y/ar + x;
117 m[1][0] = s*ar; m[1][1] = c; m[1][2] = 0.0f; m[1][3] = -ar*x*s - c*y + y;
118 m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f;
120 identity = (angle == 0);
122 static TransformMatrix CreateFader(float a)
124 TransformMatrix fader;
128 void SetFader(float a)
130 m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f;
131 m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f;
132 m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f;
134 identity = (a == 1.0f);
137 // multiplication operators
138 const TransformMatrix &operator *=(const TransformMatrix &right)
147 float t00 = m[0][0] * right.m[0][0] + m[0][1] * right.m[1][0] + m[0][2] * right.m[2][0];
148 float t01 = m[0][0] * right.m[0][1] + m[0][1] * right.m[1][1] + m[0][2] * right.m[2][1];
149 float t02 = m[0][0] * right.m[0][2] + m[0][1] * right.m[1][2] + m[0][2] * right.m[2][2];
150 m[0][3] = m[0][0] * right.m[0][3] + m[0][1] * right.m[1][3] + m[0][2] * right.m[2][3] + m[0][3];
151 m[0][0] = t00; m[0][1] = t01; m[0][2] = t02;
152 t00 = m[1][0] * right.m[0][0] + m[1][1] * right.m[1][0] + m[1][2] * right.m[2][0];
153 t01 = m[1][0] * right.m[0][1] + m[1][1] * right.m[1][1] + m[1][2] * right.m[2][1];
154 t02 = m[1][0] * right.m[0][2] + m[1][1] * right.m[1][2] + m[1][2] * right.m[2][2];
155 m[1][3] = m[1][0] * right.m[0][3] + m[1][1] * right.m[1][3] + m[1][2] * right.m[2][3] + m[1][3];
156 m[1][0] = t00; m[1][1] = t01; m[1][2] = t02;
157 t00 = m[2][0] * right.m[0][0] + m[2][1] * right.m[1][0] + m[2][2] * right.m[2][0];
158 t01 = m[2][0] * right.m[0][1] + m[2][1] * right.m[1][1] + m[2][2] * right.m[2][1];
159 t02 = m[2][0] * right.m[0][2] + m[2][1] * right.m[1][2] + m[2][2] * right.m[2][2];
160 m[2][3] = m[2][0] * right.m[0][3] + m[2][1] * right.m[1][3] + m[2][2] * right.m[2][3] + m[2][3];
161 m[2][0] = t00; m[2][1] = t01; m[2][2] = t02;
162 alpha *= right.alpha;
167 TransformMatrix operator *(const TransformMatrix &right) const
173 TransformMatrix result;
174 result.m[0][0] = m[0][0] * right.m[0][0] + m[0][1] * right.m[1][0] + m[0][2] * right.m[2][0];
175 result.m[0][1] = m[0][0] * right.m[0][1] + m[0][1] * right.m[1][1] + m[0][2] * right.m[2][1];
176 result.m[0][2] = m[0][0] * right.m[0][2] + m[0][1] * right.m[1][2] + m[0][2] * right.m[2][2];
177 result.m[0][3] = m[0][0] * right.m[0][3] + m[0][1] * right.m[1][3] + m[0][2] * right.m[2][3] + m[0][3];
178 result.m[1][0] = m[1][0] * right.m[0][0] + m[1][1] * right.m[1][0] + m[1][2] * right.m[2][0];
179 result.m[1][1] = m[1][0] * right.m[0][1] + m[1][1] * right.m[1][1] + m[1][2] * right.m[2][1];
180 result.m[1][2] = m[1][0] * right.m[0][2] + m[1][1] * right.m[1][2] + m[1][2] * right.m[2][2];
181 result.m[1][3] = m[1][0] * right.m[0][3] + m[1][1] * right.m[1][3] + m[1][2] * right.m[2][3] + m[1][3];
182 result.m[2][0] = m[2][0] * right.m[0][0] + m[2][1] * right.m[1][0] + m[2][2] * right.m[2][0];
183 result.m[2][1] = m[2][0] * right.m[0][1] + m[2][1] * right.m[1][1] + m[2][2] * right.m[2][1];
184 result.m[2][2] = m[2][0] * right.m[0][2] + m[2][1] * right.m[1][2] + m[2][2] * right.m[2][2];
185 result.m[2][3] = m[2][0] * right.m[0][3] + m[2][1] * right.m[1][3] + m[2][2] * right.m[2][3] + m[2][3];
186 result.alpha = alpha * right.alpha;
187 result.identity = false;
191 inline void TransformPosition(float &x, float &y, float &z) const XBMC_FORCE_INLINE
193 float newX = m[0][0] * x + m[0][1] * y + m[0][2] * z + m[0][3];
194 float newY = m[1][0] * x + m[1][1] * y + m[1][2] * z + m[1][3];
195 z = m[2][0] * x + m[2][1] * y + m[2][2] * z + m[2][3];
200 inline void TransformPositionUnscaled(float &x, float &y, float &z) const XBMC_FORCE_INLINE
203 // calculate the norm of the transformed (but not translated) vectors involved
204 n = sqrt(m[0][0]*m[0][0] + m[0][1]*m[0][1] + m[0][2]*m[0][2]);
205 float newX = (m[0][0] * x + m[0][1] * y + m[0][2] * z)/n + m[0][3];
206 n = sqrt(m[1][0]*m[1][0] + m[1][1]*m[1][1] + m[1][2]*m[1][2]);
207 float newY = (m[1][0] * x + m[1][1] * y + m[1][2] * z)/n + m[1][3];
208 n = sqrt(m[2][0]*m[2][0] + m[2][1]*m[2][1] + m[2][2]*m[2][2]);
209 float newZ = (m[2][0] * x + m[2][1] * y + m[2][2] * z)/n + m[2][3];
215 inline void InverseTransformPosition(float &x, float &y) const XBMC_FORCE_INLINE
216 { // used for mouse - no way to find z
217 x -= m[0][3]; y -= m[1][3];
218 float detM = m[0][0]*m[1][1] - m[0][1]*m[1][0];
219 float newX = (m[1][1] * x - m[0][1] * y)/detM;
220 y = (-m[1][0] * x + m[0][0] * y)/detM;
224 inline float TransformXCoord(float x, float y, float z) const XBMC_FORCE_INLINE
226 return m[0][0] * x + m[0][1] * y + m[0][2] * z + m[0][3];
229 inline float TransformYCoord(float x, float y, float z) const XBMC_FORCE_INLINE
231 return m[1][0] * x + m[1][1] * y + m[1][2] * z + m[1][3];
234 inline float TransformZCoord(float x, float y, float z) const XBMC_FORCE_INLINE
236 return m[2][0] * x + m[2][1] * y + m[2][2] * z + m[2][3];
239 inline color_t TransformAlpha(color_t colour) const XBMC_FORCE_INLINE
241 return (color_t)(colour * alpha);