xref: /aosp_15_r20/cts/tests/openglperf2/jni/graphics/Matrix.cpp (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker  * Copyright (C) 2013 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker  *
4*b7c941bbSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5*b7c941bbSAndroid Build Coastguard Worker  * in compliance with the License. You may obtain a copy of the License at
6*b7c941bbSAndroid Build Coastguard Worker  *
7*b7c941bbSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
8*b7c941bbSAndroid Build Coastguard Worker  *
9*b7c941bbSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software distributed under the License
10*b7c941bbSAndroid Build Coastguard Worker  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11*b7c941bbSAndroid Build Coastguard Worker  * or implied. See the License for the specific language governing permissions and limitations under
12*b7c941bbSAndroid Build Coastguard Worker  * the License.
13*b7c941bbSAndroid Build Coastguard Worker  */
14*b7c941bbSAndroid Build Coastguard Worker 
15*b7c941bbSAndroid Build Coastguard Worker #include "Matrix.h"
16*b7c941bbSAndroid Build Coastguard Worker #include <string.h>
17*b7c941bbSAndroid Build Coastguard Worker #include <cmath>
18*b7c941bbSAndroid Build Coastguard Worker 
19*b7c941bbSAndroid Build Coastguard Worker #define LOG_TAG "CTS_OPENGL"
20*b7c941bbSAndroid Build Coastguard Worker #define LOG_NDEBUG 0
21*b7c941bbSAndroid Build Coastguard Worker #include "android/log.h"
22*b7c941bbSAndroid Build Coastguard Worker 
Matrix()23*b7c941bbSAndroid Build Coastguard Worker Matrix::Matrix() {
24*b7c941bbSAndroid Build Coastguard Worker     identity();
25*b7c941bbSAndroid Build Coastguard Worker }
26*b7c941bbSAndroid Build Coastguard Worker 
Matrix(const Matrix & src)27*b7c941bbSAndroid Build Coastguard Worker Matrix::Matrix(const Matrix& src) {
28*b7c941bbSAndroid Build Coastguard Worker     loadWith(src);
29*b7c941bbSAndroid Build Coastguard Worker }
30*b7c941bbSAndroid Build Coastguard Worker 
print(const char * label)31*b7c941bbSAndroid Build Coastguard Worker void Matrix::print(const char* label) {
32*b7c941bbSAndroid Build Coastguard Worker     __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%c", *label);
33*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++) {
34*b7c941bbSAndroid Build Coastguard Worker         const float* d = &(mData[i * 4]);
35*b7c941bbSAndroid Build Coastguard Worker         __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%f %f %f %f\n", d[0], d[1], d[2], d[3]);
36*b7c941bbSAndroid Build Coastguard Worker     }
37*b7c941bbSAndroid Build Coastguard Worker }
38*b7c941bbSAndroid Build Coastguard Worker 
equals(const Matrix & src)39*b7c941bbSAndroid Build Coastguard Worker bool Matrix::equals(const Matrix& src) {
40*b7c941bbSAndroid Build Coastguard Worker     bool equals = true;
41*b7c941bbSAndroid Build Coastguard Worker     const float* d = src.mData;
42*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < MATRIX_SIZE && equals; i++) {
43*b7c941bbSAndroid Build Coastguard Worker         if (mData[i] != d[i]) {
44*b7c941bbSAndroid Build Coastguard Worker             equals = false;
45*b7c941bbSAndroid Build Coastguard Worker         }
46*b7c941bbSAndroid Build Coastguard Worker     }
47*b7c941bbSAndroid Build Coastguard Worker     return equals;
48*b7c941bbSAndroid Build Coastguard Worker }
49*b7c941bbSAndroid Build Coastguard Worker 
loadWith(const Matrix & src)50*b7c941bbSAndroid Build Coastguard Worker void Matrix::loadWith(const Matrix& src) {
51*b7c941bbSAndroid Build Coastguard Worker     memcpy(mData, src.mData, MATRIX_SIZE * sizeof(float));
52*b7c941bbSAndroid Build Coastguard Worker }
53*b7c941bbSAndroid Build Coastguard Worker 
identity()54*b7c941bbSAndroid Build Coastguard Worker void Matrix::identity() {
55*b7c941bbSAndroid Build Coastguard Worker     mData[0] = 1.0f;
56*b7c941bbSAndroid Build Coastguard Worker     mData[1] = 0.0f;
57*b7c941bbSAndroid Build Coastguard Worker     mData[2] = 0.0f;
58*b7c941bbSAndroid Build Coastguard Worker     mData[3] = 0.0f;
59*b7c941bbSAndroid Build Coastguard Worker 
60*b7c941bbSAndroid Build Coastguard Worker     mData[4] = 0.0f;
61*b7c941bbSAndroid Build Coastguard Worker     mData[5] = 1.0f;
62*b7c941bbSAndroid Build Coastguard Worker     mData[6] = 0.0f;
63*b7c941bbSAndroid Build Coastguard Worker     mData[7] = 0.0f;
64*b7c941bbSAndroid Build Coastguard Worker 
65*b7c941bbSAndroid Build Coastguard Worker     mData[8] = 0.0f;
66*b7c941bbSAndroid Build Coastguard Worker     mData[9] = 0.0f;
67*b7c941bbSAndroid Build Coastguard Worker     mData[10] = 1.0f;
68*b7c941bbSAndroid Build Coastguard Worker     mData[11] = 0.0f;
69*b7c941bbSAndroid Build Coastguard Worker 
70*b7c941bbSAndroid Build Coastguard Worker     mData[12] = 0.0f;
71*b7c941bbSAndroid Build Coastguard Worker     mData[13] = 0.0f;
72*b7c941bbSAndroid Build Coastguard Worker     mData[14] = 0.0f;
73*b7c941bbSAndroid Build Coastguard Worker     mData[15] = 1.0f;
74*b7c941bbSAndroid Build Coastguard Worker }
75*b7c941bbSAndroid Build Coastguard Worker 
translate(float x,float y,float z)76*b7c941bbSAndroid Build Coastguard Worker void Matrix::translate(float x, float y, float z) {
77*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = newTranslate(x, y, z);
78*b7c941bbSAndroid Build Coastguard Worker     Matrix* temp = new Matrix(*this);
79*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL && temp != NULL) {
80*b7c941bbSAndroid Build Coastguard Worker         multiply(*temp, *m);
81*b7c941bbSAndroid Build Coastguard Worker     }
82*b7c941bbSAndroid Build Coastguard Worker     delete m;
83*b7c941bbSAndroid Build Coastguard Worker     delete temp;
84*b7c941bbSAndroid Build Coastguard Worker }
85*b7c941bbSAndroid Build Coastguard Worker 
scale(float x,float y,float z)86*b7c941bbSAndroid Build Coastguard Worker void Matrix::scale(float x, float y, float z) {
87*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = newScale(x, y, z);
88*b7c941bbSAndroid Build Coastguard Worker     Matrix* temp = new Matrix(*this);
89*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL && temp != NULL) {
90*b7c941bbSAndroid Build Coastguard Worker         multiply(*temp, *m);
91*b7c941bbSAndroid Build Coastguard Worker     }
92*b7c941bbSAndroid Build Coastguard Worker     delete m;
93*b7c941bbSAndroid Build Coastguard Worker     delete temp;
94*b7c941bbSAndroid Build Coastguard Worker }
95*b7c941bbSAndroid Build Coastguard Worker 
rotate(float radians,float x,float y,float z)96*b7c941bbSAndroid Build Coastguard Worker void Matrix::rotate(float radians, float x, float y, float z) {
97*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = newRotate(radians, x, y, z);
98*b7c941bbSAndroid Build Coastguard Worker     Matrix* temp = new Matrix(*this);
99*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL && temp != NULL) {
100*b7c941bbSAndroid Build Coastguard Worker         multiply(*temp, *m);
101*b7c941bbSAndroid Build Coastguard Worker     }
102*b7c941bbSAndroid Build Coastguard Worker     delete m;
103*b7c941bbSAndroid Build Coastguard Worker     delete temp;
104*b7c941bbSAndroid Build Coastguard Worker }
105*b7c941bbSAndroid Build Coastguard Worker 
multiply(const Matrix & l,const Matrix & r)106*b7c941bbSAndroid Build Coastguard Worker void Matrix::multiply(const Matrix& l, const Matrix& r) {
107*b7c941bbSAndroid Build Coastguard Worker     float const* const lhs = l.mData;
108*b7c941bbSAndroid Build Coastguard Worker     float const* const rhs = r.mData;
109*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++) {
110*b7c941bbSAndroid Build Coastguard Worker         const int i4 = i * 4;
111*b7c941bbSAndroid Build Coastguard Worker         float x = 0;
112*b7c941bbSAndroid Build Coastguard Worker         float y = 0;
113*b7c941bbSAndroid Build Coastguard Worker         float z = 0;
114*b7c941bbSAndroid Build Coastguard Worker         float w = 0;
115*b7c941bbSAndroid Build Coastguard Worker 
116*b7c941bbSAndroid Build Coastguard Worker         for (int j = 0; j < 4; j++) {
117*b7c941bbSAndroid Build Coastguard Worker             const int j4 = j * 4;
118*b7c941bbSAndroid Build Coastguard Worker             const float e = rhs[i4 + j];
119*b7c941bbSAndroid Build Coastguard Worker             x += lhs[j4 + 0] * e;
120*b7c941bbSAndroid Build Coastguard Worker             y += lhs[j4 + 1] * e;
121*b7c941bbSAndroid Build Coastguard Worker             z += lhs[j4 + 2] * e;
122*b7c941bbSAndroid Build Coastguard Worker             w += lhs[j4 + 3] * e;
123*b7c941bbSAndroid Build Coastguard Worker         }
124*b7c941bbSAndroid Build Coastguard Worker 
125*b7c941bbSAndroid Build Coastguard Worker         mData[i4 + 0] = x;
126*b7c941bbSAndroid Build Coastguard Worker         mData[i4 + 1] = y;
127*b7c941bbSAndroid Build Coastguard Worker         mData[i4 + 2] = z;
128*b7c941bbSAndroid Build Coastguard Worker         mData[i4 + 3] = w;
129*b7c941bbSAndroid Build Coastguard Worker     }
130*b7c941bbSAndroid Build Coastguard Worker }
131*b7c941bbSAndroid Build Coastguard Worker 
newLookAt(float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)132*b7c941bbSAndroid Build Coastguard Worker Matrix* Matrix::newLookAt(float eyeX, float eyeY, float eyeZ, float centerX,
133*b7c941bbSAndroid Build Coastguard Worker         float centerY, float centerZ, float upX, float upY, float upZ) {
134*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = new Matrix();
135*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL) {
136*b7c941bbSAndroid Build Coastguard Worker         // See the OpenGL GLUT documentation for gluLookAt for a description
137*b7c941bbSAndroid Build Coastguard Worker         // of the algorithm. We implement it in a straightforward way:
138*b7c941bbSAndroid Build Coastguard Worker 
139*b7c941bbSAndroid Build Coastguard Worker         float fx = centerX - eyeX;
140*b7c941bbSAndroid Build Coastguard Worker         float fy = centerY - eyeY;
141*b7c941bbSAndroid Build Coastguard Worker         float fz = centerZ - eyeZ;
142*b7c941bbSAndroid Build Coastguard Worker 
143*b7c941bbSAndroid Build Coastguard Worker         // Normalize f
144*b7c941bbSAndroid Build Coastguard Worker         float rlf = 1.0f / (float) sqrt(fx * fx + fy * fy + fz * fz);
145*b7c941bbSAndroid Build Coastguard Worker         fx *= rlf;
146*b7c941bbSAndroid Build Coastguard Worker         fy *= rlf;
147*b7c941bbSAndroid Build Coastguard Worker         fz *= rlf;
148*b7c941bbSAndroid Build Coastguard Worker 
149*b7c941bbSAndroid Build Coastguard Worker         // compute s = f x up (x means "cross product")
150*b7c941bbSAndroid Build Coastguard Worker         float sx = fy * upZ - fz * upY;
151*b7c941bbSAndroid Build Coastguard Worker         float sy = fz * upX - fx * upZ;
152*b7c941bbSAndroid Build Coastguard Worker         float sz = fx * upY - fy * upX;
153*b7c941bbSAndroid Build Coastguard Worker 
154*b7c941bbSAndroid Build Coastguard Worker         // and normalize s
155*b7c941bbSAndroid Build Coastguard Worker         float rls = 1.0f / (float) sqrt(sx * sx + sy * sy + sz * sz);
156*b7c941bbSAndroid Build Coastguard Worker         sx *= rls;
157*b7c941bbSAndroid Build Coastguard Worker         sy *= rls;
158*b7c941bbSAndroid Build Coastguard Worker         sz *= rls;
159*b7c941bbSAndroid Build Coastguard Worker 
160*b7c941bbSAndroid Build Coastguard Worker         // compute u = s x f
161*b7c941bbSAndroid Build Coastguard Worker         float ux = sy * fz - sz * fy;
162*b7c941bbSAndroid Build Coastguard Worker         float uy = sz * fx - sx * fz;
163*b7c941bbSAndroid Build Coastguard Worker         float uz = sx * fy - sy * fx;
164*b7c941bbSAndroid Build Coastguard Worker 
165*b7c941bbSAndroid Build Coastguard Worker         float* d = m->mData;
166*b7c941bbSAndroid Build Coastguard Worker         d[0] = sx;
167*b7c941bbSAndroid Build Coastguard Worker         d[1] = ux;
168*b7c941bbSAndroid Build Coastguard Worker         d[2] = -fx;
169*b7c941bbSAndroid Build Coastguard Worker         d[3] = 0.0f;
170*b7c941bbSAndroid Build Coastguard Worker 
171*b7c941bbSAndroid Build Coastguard Worker         d[4] = sy;
172*b7c941bbSAndroid Build Coastguard Worker         d[5] = uy;
173*b7c941bbSAndroid Build Coastguard Worker         d[6] = -fy;
174*b7c941bbSAndroid Build Coastguard Worker         d[7] = 0.0f;
175*b7c941bbSAndroid Build Coastguard Worker 
176*b7c941bbSAndroid Build Coastguard Worker         d[8] = sz;
177*b7c941bbSAndroid Build Coastguard Worker         d[9] = uz;
178*b7c941bbSAndroid Build Coastguard Worker         d[10] = -fz;
179*b7c941bbSAndroid Build Coastguard Worker         d[11] = 0.0f;
180*b7c941bbSAndroid Build Coastguard Worker 
181*b7c941bbSAndroid Build Coastguard Worker         d[12] = 0.0f;
182*b7c941bbSAndroid Build Coastguard Worker         d[13] = 0.0f;
183*b7c941bbSAndroid Build Coastguard Worker         d[14] = 0.0f;
184*b7c941bbSAndroid Build Coastguard Worker         d[15] = 1.0f;
185*b7c941bbSAndroid Build Coastguard Worker 
186*b7c941bbSAndroid Build Coastguard Worker         m->translate(-eyeX, -eyeY, -eyeZ);
187*b7c941bbSAndroid Build Coastguard Worker     }
188*b7c941bbSAndroid Build Coastguard Worker     return m;
189*b7c941bbSAndroid Build Coastguard Worker }
190*b7c941bbSAndroid Build Coastguard Worker 
newFrustum(float left,float right,float bottom,float top,float near,float far)191*b7c941bbSAndroid Build Coastguard Worker Matrix* Matrix::newFrustum(float left, float right, float bottom, float top,
192*b7c941bbSAndroid Build Coastguard Worker         float near, float far) {
193*b7c941bbSAndroid Build Coastguard Worker     const float r_width = 1.0f / (right - left);
194*b7c941bbSAndroid Build Coastguard Worker     const float r_height = 1.0f / (top - bottom);
195*b7c941bbSAndroid Build Coastguard Worker     const float r_depth = 1.0f / (near - far);
196*b7c941bbSAndroid Build Coastguard Worker     const float x = 2.0f * (near * r_width);
197*b7c941bbSAndroid Build Coastguard Worker     const float y = 2.0f * (near * r_height);
198*b7c941bbSAndroid Build Coastguard Worker     const float A = (right + left) * r_width;
199*b7c941bbSAndroid Build Coastguard Worker     const float B = (top + bottom) * r_height;
200*b7c941bbSAndroid Build Coastguard Worker     const float C = (far + near) * r_depth;
201*b7c941bbSAndroid Build Coastguard Worker     const float D = 2.0f * (far * near * r_depth);
202*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = new Matrix();
203*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL) {
204*b7c941bbSAndroid Build Coastguard Worker         float* d = m->mData;
205*b7c941bbSAndroid Build Coastguard Worker         d[0] = x;
206*b7c941bbSAndroid Build Coastguard Worker         d[5] = y;
207*b7c941bbSAndroid Build Coastguard Worker         d[8] = A;
208*b7c941bbSAndroid Build Coastguard Worker         d[9] = B;
209*b7c941bbSAndroid Build Coastguard Worker         d[10] = C;
210*b7c941bbSAndroid Build Coastguard Worker         d[14] = D;
211*b7c941bbSAndroid Build Coastguard Worker         d[11] = -1.0f;
212*b7c941bbSAndroid Build Coastguard Worker         d[1] = 0.0f;
213*b7c941bbSAndroid Build Coastguard Worker         d[2] = 0.0f;
214*b7c941bbSAndroid Build Coastguard Worker         d[3] = 0.0f;
215*b7c941bbSAndroid Build Coastguard Worker         d[4] = 0.0f;
216*b7c941bbSAndroid Build Coastguard Worker         d[6] = 0.0f;
217*b7c941bbSAndroid Build Coastguard Worker         d[7] = 0.0f;
218*b7c941bbSAndroid Build Coastguard Worker         d[12] = 0.0f;
219*b7c941bbSAndroid Build Coastguard Worker         d[13] = 0.0f;
220*b7c941bbSAndroid Build Coastguard Worker         d[15] = 0.0f;
221*b7c941bbSAndroid Build Coastguard Worker     }
222*b7c941bbSAndroid Build Coastguard Worker     return m;
223*b7c941bbSAndroid Build Coastguard Worker }
224*b7c941bbSAndroid Build Coastguard Worker 
newTranslate(float x,float y,float z)225*b7c941bbSAndroid Build Coastguard Worker Matrix* Matrix::newTranslate(float x, float y, float z) {
226*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = new Matrix();
227*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL) {
228*b7c941bbSAndroid Build Coastguard Worker         float* d = m->mData;
229*b7c941bbSAndroid Build Coastguard Worker         d[12] = x;
230*b7c941bbSAndroid Build Coastguard Worker         d[13] = y;
231*b7c941bbSAndroid Build Coastguard Worker         d[14] = z;
232*b7c941bbSAndroid Build Coastguard Worker     }
233*b7c941bbSAndroid Build Coastguard Worker     return m;
234*b7c941bbSAndroid Build Coastguard Worker }
newScale(float x,float y,float z)235*b7c941bbSAndroid Build Coastguard Worker Matrix* Matrix::newScale(float x, float y, float z) {
236*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = new Matrix();
237*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL) {
238*b7c941bbSAndroid Build Coastguard Worker         float* d = m->mData;
239*b7c941bbSAndroid Build Coastguard Worker         d[0] = x;
240*b7c941bbSAndroid Build Coastguard Worker         d[5] = y;
241*b7c941bbSAndroid Build Coastguard Worker         d[10] = z;
242*b7c941bbSAndroid Build Coastguard Worker     }
243*b7c941bbSAndroid Build Coastguard Worker     return m;
244*b7c941bbSAndroid Build Coastguard Worker }
newRotate(float radians,float x,float y,float z)245*b7c941bbSAndroid Build Coastguard Worker Matrix* Matrix::newRotate(float radians, float x, float y, float z) {
246*b7c941bbSAndroid Build Coastguard Worker     Matrix* m = new Matrix();
247*b7c941bbSAndroid Build Coastguard Worker     if (m != NULL) {
248*b7c941bbSAndroid Build Coastguard Worker         float* d = m->mData;
249*b7c941bbSAndroid Build Coastguard Worker         d[3] = 0;
250*b7c941bbSAndroid Build Coastguard Worker         d[7] = 0;
251*b7c941bbSAndroid Build Coastguard Worker         d[11] = 0;
252*b7c941bbSAndroid Build Coastguard Worker         d[12] = 0;
253*b7c941bbSAndroid Build Coastguard Worker         d[13] = 0;
254*b7c941bbSAndroid Build Coastguard Worker         d[14] = 0;
255*b7c941bbSAndroid Build Coastguard Worker         d[15] = 1;
256*b7c941bbSAndroid Build Coastguard Worker         float s = (float) sinf(radians);
257*b7c941bbSAndroid Build Coastguard Worker         float c = (float) cosf(radians);
258*b7c941bbSAndroid Build Coastguard Worker         if (1.0f == x && 0.0f == y && 0.0f == z) {
259*b7c941bbSAndroid Build Coastguard Worker             d[5] = c;
260*b7c941bbSAndroid Build Coastguard Worker             d[10] = c;
261*b7c941bbSAndroid Build Coastguard Worker             d[6] = s;
262*b7c941bbSAndroid Build Coastguard Worker             d[9] = -s;
263*b7c941bbSAndroid Build Coastguard Worker             d[1] = 0;
264*b7c941bbSAndroid Build Coastguard Worker             d[2] = 0;
265*b7c941bbSAndroid Build Coastguard Worker             d[4] = 0;
266*b7c941bbSAndroid Build Coastguard Worker             d[8] = 0;
267*b7c941bbSAndroid Build Coastguard Worker             d[0] = 1;
268*b7c941bbSAndroid Build Coastguard Worker         } else if (0.0f == x && 1.0f == y && 0.0f == z) {
269*b7c941bbSAndroid Build Coastguard Worker             d[0] = c;
270*b7c941bbSAndroid Build Coastguard Worker             d[10] = c;
271*b7c941bbSAndroid Build Coastguard Worker             d[8] = s;
272*b7c941bbSAndroid Build Coastguard Worker             d[2] = -s;
273*b7c941bbSAndroid Build Coastguard Worker             d[1] = 0;
274*b7c941bbSAndroid Build Coastguard Worker             d[4] = 0;
275*b7c941bbSAndroid Build Coastguard Worker             d[6] = 0;
276*b7c941bbSAndroid Build Coastguard Worker             d[9] = 0;
277*b7c941bbSAndroid Build Coastguard Worker             d[5] = 1;
278*b7c941bbSAndroid Build Coastguard Worker         } else if (0.0f == x && 0.0f == y && 1.0f == z) {
279*b7c941bbSAndroid Build Coastguard Worker             d[0] = c;
280*b7c941bbSAndroid Build Coastguard Worker             d[5] = c;
281*b7c941bbSAndroid Build Coastguard Worker             d[1] = s;
282*b7c941bbSAndroid Build Coastguard Worker             d[4] = -s;
283*b7c941bbSAndroid Build Coastguard Worker             d[2] = 0;
284*b7c941bbSAndroid Build Coastguard Worker             d[6] = 0;
285*b7c941bbSAndroid Build Coastguard Worker             d[8] = 0;
286*b7c941bbSAndroid Build Coastguard Worker             d[9] = 0;
287*b7c941bbSAndroid Build Coastguard Worker             d[10] = 1;
288*b7c941bbSAndroid Build Coastguard Worker         } else {
289*b7c941bbSAndroid Build Coastguard Worker             float len = sqrt((x * x) + (y * y) + (z * z));
290*b7c941bbSAndroid Build Coastguard Worker             if (1.0f != len) {
291*b7c941bbSAndroid Build Coastguard Worker                 float recipLen = 1.0f / len;
292*b7c941bbSAndroid Build Coastguard Worker                 x *= recipLen;
293*b7c941bbSAndroid Build Coastguard Worker                 y *= recipLen;
294*b7c941bbSAndroid Build Coastguard Worker                 z *= recipLen;
295*b7c941bbSAndroid Build Coastguard Worker             }
296*b7c941bbSAndroid Build Coastguard Worker             float nc = 1.0f - c;
297*b7c941bbSAndroid Build Coastguard Worker             float xy = x * y;
298*b7c941bbSAndroid Build Coastguard Worker             float yz = y * z;
299*b7c941bbSAndroid Build Coastguard Worker             float zx = z * x;
300*b7c941bbSAndroid Build Coastguard Worker             float xs = x * s;
301*b7c941bbSAndroid Build Coastguard Worker             float ys = y * s;
302*b7c941bbSAndroid Build Coastguard Worker             float zs = z * s;
303*b7c941bbSAndroid Build Coastguard Worker             d[0] = x * x * nc + c;
304*b7c941bbSAndroid Build Coastguard Worker             d[4] = xy * nc - zs;
305*b7c941bbSAndroid Build Coastguard Worker             d[8] = zx * nc + ys;
306*b7c941bbSAndroid Build Coastguard Worker             d[1] = xy * nc + zs;
307*b7c941bbSAndroid Build Coastguard Worker             d[5] = y * y * nc + c;
308*b7c941bbSAndroid Build Coastguard Worker             d[9] = yz * nc - xs;
309*b7c941bbSAndroid Build Coastguard Worker             d[2] = zx * nc - ys;
310*b7c941bbSAndroid Build Coastguard Worker             d[6] = yz * nc + xs;
311*b7c941bbSAndroid Build Coastguard Worker             d[10] = z * z * nc + c;
312*b7c941bbSAndroid Build Coastguard Worker         }
313*b7c941bbSAndroid Build Coastguard Worker     }
314*b7c941bbSAndroid Build Coastguard Worker     return m;
315*b7c941bbSAndroid Build Coastguard Worker }
316*b7c941bbSAndroid Build Coastguard Worker 
multiplyVector(float * result,const Matrix & lhs,const float * rhs)317*b7c941bbSAndroid Build Coastguard Worker void Matrix::multiplyVector(float* result, const Matrix& lhs,
318*b7c941bbSAndroid Build Coastguard Worker         const float* rhs) {
319*b7c941bbSAndroid Build Coastguard Worker     const float* d = lhs.mData;
320*b7c941bbSAndroid Build Coastguard Worker     const float x = rhs[0];
321*b7c941bbSAndroid Build Coastguard Worker     const float y = rhs[1];
322*b7c941bbSAndroid Build Coastguard Worker     const float z = rhs[2];
323*b7c941bbSAndroid Build Coastguard Worker     const float w = rhs[3];
324*b7c941bbSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++) {
325*b7c941bbSAndroid Build Coastguard Worker         const int j = i * 4;
326*b7c941bbSAndroid Build Coastguard Worker         result[i] = d[j + 0] * x + d[j + 1] * y + d[j + 2] * z + d[j + 3] * w;
327*b7c941bbSAndroid Build Coastguard Worker     }
328*b7c941bbSAndroid Build Coastguard Worker }
329