xref: /aosp_15_r20/frameworks/rs/rsMatrix4x4.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker #include "rsMatrix2x2.h"
18*e1eccf28SAndroid Build Coastguard Worker #include "rsMatrix3x3.h"
19*e1eccf28SAndroid Build Coastguard Worker #include "rsMatrix4x4.h"
20*e1eccf28SAndroid Build Coastguard Worker 
21*e1eccf28SAndroid Build Coastguard Worker #include "stdlib.h"
22*e1eccf28SAndroid Build Coastguard Worker #include "string.h"
23*e1eccf28SAndroid Build Coastguard Worker #include "math.h"
24*e1eccf28SAndroid Build Coastguard Worker 
25*e1eccf28SAndroid Build Coastguard Worker namespace android {
26*e1eccf28SAndroid Build Coastguard Worker namespace renderscript {
27*e1eccf28SAndroid Build Coastguard Worker 
28*e1eccf28SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
29*e1eccf28SAndroid Build Coastguard Worker // Heavy math functions
30*e1eccf28SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
31*e1eccf28SAndroid Build Coastguard Worker 
32*e1eccf28SAndroid Build Coastguard Worker 
33*e1eccf28SAndroid Build Coastguard Worker 
34*e1eccf28SAndroid Build Coastguard Worker 
35*e1eccf28SAndroid Build Coastguard Worker 
36*e1eccf28SAndroid Build Coastguard Worker // Returns true if the matrix was successfully inversed
inverse()37*e1eccf28SAndroid Build Coastguard Worker bool Matrix4x4::inverse() {
38*e1eccf28SAndroid Build Coastguard Worker     rs_matrix4x4 result;
39*e1eccf28SAndroid Build Coastguard Worker 
40*e1eccf28SAndroid Build Coastguard Worker     int i, j;
41*e1eccf28SAndroid Build Coastguard Worker     for (i = 0; i < 4; ++i) {
42*e1eccf28SAndroid Build Coastguard Worker         for (j = 0; j < 4; ++j) {
43*e1eccf28SAndroid Build Coastguard Worker             // computeCofactor for int i, int j
44*e1eccf28SAndroid Build Coastguard Worker             int c0 = (i+1) % 4;
45*e1eccf28SAndroid Build Coastguard Worker             int c1 = (i+2) % 4;
46*e1eccf28SAndroid Build Coastguard Worker             int c2 = (i+3) % 4;
47*e1eccf28SAndroid Build Coastguard Worker             int r0 = (j+1) % 4;
48*e1eccf28SAndroid Build Coastguard Worker             int r1 = (j+2) % 4;
49*e1eccf28SAndroid Build Coastguard Worker             int r2 = (j+3) % 4;
50*e1eccf28SAndroid Build Coastguard Worker 
51*e1eccf28SAndroid Build Coastguard Worker             float minor =
52*e1eccf28SAndroid Build Coastguard Worker                 (m[c0 + 4*r0] * (m[c1 + 4*r1] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r1]))
53*e1eccf28SAndroid Build Coastguard Worker                 - (m[c0 + 4*r1] * (m[c1 + 4*r0] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r0]))
54*e1eccf28SAndroid Build Coastguard Worker                 + (m[c0 + 4*r2] * (m[c1 + 4*r0] * m[c2 + 4*r1] - m[c1 + 4*r1] * m[c2 + 4*r0]));
55*e1eccf28SAndroid Build Coastguard Worker 
56*e1eccf28SAndroid Build Coastguard Worker             float cofactor = (i+j) & 1 ? -minor : minor;
57*e1eccf28SAndroid Build Coastguard Worker 
58*e1eccf28SAndroid Build Coastguard Worker             result.m[4*i + j] = cofactor;
59*e1eccf28SAndroid Build Coastguard Worker         }
60*e1eccf28SAndroid Build Coastguard Worker     }
61*e1eccf28SAndroid Build Coastguard Worker 
62*e1eccf28SAndroid Build Coastguard Worker     // Dot product of 0th column of source and 0th row of result
63*e1eccf28SAndroid Build Coastguard Worker     float det = m[0]*result.m[0] + m[4]*result.m[1] +
64*e1eccf28SAndroid Build Coastguard Worker                  m[8]*result.m[2] + m[12]*result.m[3];
65*e1eccf28SAndroid Build Coastguard Worker 
66*e1eccf28SAndroid Build Coastguard Worker     if (fabs(det) < 1e-6) {
67*e1eccf28SAndroid Build Coastguard Worker         return false;
68*e1eccf28SAndroid Build Coastguard Worker     }
69*e1eccf28SAndroid Build Coastguard Worker 
70*e1eccf28SAndroid Build Coastguard Worker     det = 1.0f / det;
71*e1eccf28SAndroid Build Coastguard Worker     for (i = 0; i < 16; ++i) {
72*e1eccf28SAndroid Build Coastguard Worker         m[i] = result.m[i] * det;
73*e1eccf28SAndroid Build Coastguard Worker     }
74*e1eccf28SAndroid Build Coastguard Worker 
75*e1eccf28SAndroid Build Coastguard Worker     return true;
76*e1eccf28SAndroid Build Coastguard Worker }
77*e1eccf28SAndroid Build Coastguard Worker 
78*e1eccf28SAndroid Build Coastguard Worker // Returns true if the matrix was successfully inversed
inverseTranspose()79*e1eccf28SAndroid Build Coastguard Worker bool Matrix4x4::inverseTranspose() {
80*e1eccf28SAndroid Build Coastguard Worker     rs_matrix4x4 result;
81*e1eccf28SAndroid Build Coastguard Worker 
82*e1eccf28SAndroid Build Coastguard Worker     int i, j;
83*e1eccf28SAndroid Build Coastguard Worker     for (i = 0; i < 4; ++i) {
84*e1eccf28SAndroid Build Coastguard Worker         for (j = 0; j < 4; ++j) {
85*e1eccf28SAndroid Build Coastguard Worker             // computeCofactor for int i, int j
86*e1eccf28SAndroid Build Coastguard Worker             int c0 = (i+1) % 4;
87*e1eccf28SAndroid Build Coastguard Worker             int c1 = (i+2) % 4;
88*e1eccf28SAndroid Build Coastguard Worker             int c2 = (i+3) % 4;
89*e1eccf28SAndroid Build Coastguard Worker             int r0 = (j+1) % 4;
90*e1eccf28SAndroid Build Coastguard Worker             int r1 = (j+2) % 4;
91*e1eccf28SAndroid Build Coastguard Worker             int r2 = (j+3) % 4;
92*e1eccf28SAndroid Build Coastguard Worker 
93*e1eccf28SAndroid Build Coastguard Worker             float minor = (m[c0 + 4*r0] * (m[c1 + 4*r1] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r1]))
94*e1eccf28SAndroid Build Coastguard Worker                          - (m[c0 + 4*r1] * (m[c1 + 4*r0] * m[c2 + 4*r2] - m[c1 + 4*r2] * m[c2 + 4*r0]))
95*e1eccf28SAndroid Build Coastguard Worker                          + (m[c0 + 4*r2] * (m[c1 + 4*r0] * m[c2 + 4*r1] - m[c1 + 4*r1] * m[c2 + 4*r0]));
96*e1eccf28SAndroid Build Coastguard Worker 
97*e1eccf28SAndroid Build Coastguard Worker             float cofactor = (i+j) & 1 ? -minor : minor;
98*e1eccf28SAndroid Build Coastguard Worker 
99*e1eccf28SAndroid Build Coastguard Worker             result.m[4*j + i] = cofactor;
100*e1eccf28SAndroid Build Coastguard Worker         }
101*e1eccf28SAndroid Build Coastguard Worker     }
102*e1eccf28SAndroid Build Coastguard Worker 
103*e1eccf28SAndroid Build Coastguard Worker     // Dot product of 0th column of source and 0th column of result
104*e1eccf28SAndroid Build Coastguard Worker     float det = m[0]*result.m[0] + m[4]*result.m[4] +
105*e1eccf28SAndroid Build Coastguard Worker                  m[8]*result.m[8] + m[12]*result.m[12];
106*e1eccf28SAndroid Build Coastguard Worker 
107*e1eccf28SAndroid Build Coastguard Worker     if (fabs(det) < 1e-6) {
108*e1eccf28SAndroid Build Coastguard Worker         return false;
109*e1eccf28SAndroid Build Coastguard Worker     }
110*e1eccf28SAndroid Build Coastguard Worker 
111*e1eccf28SAndroid Build Coastguard Worker     det = 1.0f / det;
112*e1eccf28SAndroid Build Coastguard Worker     for (i = 0; i < 16; ++i) {
113*e1eccf28SAndroid Build Coastguard Worker         m[i] = result.m[i] * det;
114*e1eccf28SAndroid Build Coastguard Worker     }
115*e1eccf28SAndroid Build Coastguard Worker 
116*e1eccf28SAndroid Build Coastguard Worker     return true;
117*e1eccf28SAndroid Build Coastguard Worker }
118*e1eccf28SAndroid Build Coastguard Worker 
transpose()119*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::transpose() {
120*e1eccf28SAndroid Build Coastguard Worker     int i, j;
121*e1eccf28SAndroid Build Coastguard Worker     float temp;
122*e1eccf28SAndroid Build Coastguard Worker     for (i = 0; i < 3; ++i) {
123*e1eccf28SAndroid Build Coastguard Worker         for (j = i + 1; j < 4; ++j) {
124*e1eccf28SAndroid Build Coastguard Worker             temp = m[i*4 + j];
125*e1eccf28SAndroid Build Coastguard Worker             m[i*4 + j] = m[j*4 + i];
126*e1eccf28SAndroid Build Coastguard Worker             m[j*4 + i] = temp;
127*e1eccf28SAndroid Build Coastguard Worker         }
128*e1eccf28SAndroid Build Coastguard Worker     }
129*e1eccf28SAndroid Build Coastguard Worker }
130*e1eccf28SAndroid Build Coastguard Worker 
131*e1eccf28SAndroid Build Coastguard Worker 
132*e1eccf28SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////
133*e1eccf28SAndroid Build Coastguard Worker 
loadIdentity()134*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadIdentity() {
135*e1eccf28SAndroid Build Coastguard Worker     m[0] = 1.f;
136*e1eccf28SAndroid Build Coastguard Worker     m[1] = 0.f;
137*e1eccf28SAndroid Build Coastguard Worker     m[2] = 0.f;
138*e1eccf28SAndroid Build Coastguard Worker     m[3] = 0.f;
139*e1eccf28SAndroid Build Coastguard Worker     m[4] = 0.f;
140*e1eccf28SAndroid Build Coastguard Worker     m[5] = 1.f;
141*e1eccf28SAndroid Build Coastguard Worker     m[6] = 0.f;
142*e1eccf28SAndroid Build Coastguard Worker     m[7] = 0.f;
143*e1eccf28SAndroid Build Coastguard Worker     m[8] = 0.f;
144*e1eccf28SAndroid Build Coastguard Worker     m[9] = 0.f;
145*e1eccf28SAndroid Build Coastguard Worker     m[10] = 1.f;
146*e1eccf28SAndroid Build Coastguard Worker     m[11] = 0.f;
147*e1eccf28SAndroid Build Coastguard Worker     m[12] = 0.f;
148*e1eccf28SAndroid Build Coastguard Worker     m[13] = 0.f;
149*e1eccf28SAndroid Build Coastguard Worker     m[14] = 0.f;
150*e1eccf28SAndroid Build Coastguard Worker     m[15] = 1.f;
151*e1eccf28SAndroid Build Coastguard Worker }
152*e1eccf28SAndroid Build Coastguard Worker 
load(const float * v)153*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::load(const float *v) {
154*e1eccf28SAndroid Build Coastguard Worker     memcpy(m, v, sizeof(m));
155*e1eccf28SAndroid Build Coastguard Worker }
156*e1eccf28SAndroid Build Coastguard Worker 
load(const rs_matrix4x4 * v)157*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::load(const rs_matrix4x4 *v) {
158*e1eccf28SAndroid Build Coastguard Worker     memcpy(m, v->m, sizeof(m));
159*e1eccf28SAndroid Build Coastguard Worker }
160*e1eccf28SAndroid Build Coastguard Worker 
load(const rs_matrix3x3 * v)161*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::load(const rs_matrix3x3 *v) {
162*e1eccf28SAndroid Build Coastguard Worker     m[0] = v->m[0];
163*e1eccf28SAndroid Build Coastguard Worker     m[1] = v->m[1];
164*e1eccf28SAndroid Build Coastguard Worker     m[2] = v->m[2];
165*e1eccf28SAndroid Build Coastguard Worker     m[3] = 0.f;
166*e1eccf28SAndroid Build Coastguard Worker     m[4] = v->m[3];
167*e1eccf28SAndroid Build Coastguard Worker     m[5] = v->m[4];
168*e1eccf28SAndroid Build Coastguard Worker     m[6] = v->m[5];
169*e1eccf28SAndroid Build Coastguard Worker     m[7] = 0.f;
170*e1eccf28SAndroid Build Coastguard Worker     m[8] = v->m[6];
171*e1eccf28SAndroid Build Coastguard Worker     m[9] = v->m[7];
172*e1eccf28SAndroid Build Coastguard Worker     m[10] = v->m[8];
173*e1eccf28SAndroid Build Coastguard Worker     m[11] = 0.f;
174*e1eccf28SAndroid Build Coastguard Worker     m[12] = 0.f;
175*e1eccf28SAndroid Build Coastguard Worker     m[13] = 0.f;
176*e1eccf28SAndroid Build Coastguard Worker     m[14] = 0.f;
177*e1eccf28SAndroid Build Coastguard Worker     m[15] = 1.f;
178*e1eccf28SAndroid Build Coastguard Worker }
179*e1eccf28SAndroid Build Coastguard Worker 
load(const rs_matrix2x2 * v)180*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::load(const rs_matrix2x2 *v) {
181*e1eccf28SAndroid Build Coastguard Worker     m[0] = v->m[0];
182*e1eccf28SAndroid Build Coastguard Worker     m[1] = v->m[1];
183*e1eccf28SAndroid Build Coastguard Worker     m[2] = 0.f;
184*e1eccf28SAndroid Build Coastguard Worker     m[3] = 0.f;
185*e1eccf28SAndroid Build Coastguard Worker     m[4] = v->m[2];
186*e1eccf28SAndroid Build Coastguard Worker     m[5] = v->m[3];
187*e1eccf28SAndroid Build Coastguard Worker     m[6] = 0.f;
188*e1eccf28SAndroid Build Coastguard Worker     m[7] = 0.f;
189*e1eccf28SAndroid Build Coastguard Worker     m[8] = 0.f;
190*e1eccf28SAndroid Build Coastguard Worker     m[9] = 0.f;
191*e1eccf28SAndroid Build Coastguard Worker     m[10] = 1.f;
192*e1eccf28SAndroid Build Coastguard Worker     m[11] = 0.f;
193*e1eccf28SAndroid Build Coastguard Worker     m[12] = 0.f;
194*e1eccf28SAndroid Build Coastguard Worker     m[13] = 0.f;
195*e1eccf28SAndroid Build Coastguard Worker     m[14] = 0.f;
196*e1eccf28SAndroid Build Coastguard Worker     m[15] = 1.f;
197*e1eccf28SAndroid Build Coastguard Worker }
198*e1eccf28SAndroid Build Coastguard Worker 
199*e1eccf28SAndroid Build Coastguard Worker 
loadRotate(float rot,float x,float y,float z)200*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadRotate(float rot, float x, float y, float z) {
201*e1eccf28SAndroid Build Coastguard Worker     float c, s;
202*e1eccf28SAndroid Build Coastguard Worker     m[3] = 0;
203*e1eccf28SAndroid Build Coastguard Worker     m[7] = 0;
204*e1eccf28SAndroid Build Coastguard Worker     m[11]= 0;
205*e1eccf28SAndroid Build Coastguard Worker     m[12]= 0;
206*e1eccf28SAndroid Build Coastguard Worker     m[13]= 0;
207*e1eccf28SAndroid Build Coastguard Worker     m[14]= 0;
208*e1eccf28SAndroid Build Coastguard Worker     m[15]= 1;
209*e1eccf28SAndroid Build Coastguard Worker     rot *= float(M_PI / 180.0f);
210*e1eccf28SAndroid Build Coastguard Worker     c = cosf(rot);
211*e1eccf28SAndroid Build Coastguard Worker     s = sinf(rot);
212*e1eccf28SAndroid Build Coastguard Worker 
213*e1eccf28SAndroid Build Coastguard Worker     const float len = x*x + y*y + z*z;
214*e1eccf28SAndroid Build Coastguard Worker     if (len != 1) {
215*e1eccf28SAndroid Build Coastguard Worker         const float recipLen = 1.f / sqrtf(len);
216*e1eccf28SAndroid Build Coastguard Worker         x *= recipLen;
217*e1eccf28SAndroid Build Coastguard Worker         y *= recipLen;
218*e1eccf28SAndroid Build Coastguard Worker         z *= recipLen;
219*e1eccf28SAndroid Build Coastguard Worker     }
220*e1eccf28SAndroid Build Coastguard Worker     const float nc = 1.0f - c;
221*e1eccf28SAndroid Build Coastguard Worker     const float xy = x * y;
222*e1eccf28SAndroid Build Coastguard Worker     const float yz = y * z;
223*e1eccf28SAndroid Build Coastguard Worker     const float zx = z * x;
224*e1eccf28SAndroid Build Coastguard Worker     const float xs = x * s;
225*e1eccf28SAndroid Build Coastguard Worker     const float ys = y * s;
226*e1eccf28SAndroid Build Coastguard Worker     const float zs = z * s;
227*e1eccf28SAndroid Build Coastguard Worker     m[ 0] = x*x*nc +  c;
228*e1eccf28SAndroid Build Coastguard Worker     m[ 4] =  xy*nc - zs;
229*e1eccf28SAndroid Build Coastguard Worker     m[ 8] =  zx*nc + ys;
230*e1eccf28SAndroid Build Coastguard Worker     m[ 1] =  xy*nc + zs;
231*e1eccf28SAndroid Build Coastguard Worker     m[ 5] = y*y*nc +  c;
232*e1eccf28SAndroid Build Coastguard Worker     m[ 9] =  yz*nc - xs;
233*e1eccf28SAndroid Build Coastguard Worker     m[ 2] =  zx*nc - ys;
234*e1eccf28SAndroid Build Coastguard Worker     m[ 6] =  yz*nc + xs;
235*e1eccf28SAndroid Build Coastguard Worker     m[10] = z*z*nc +  c;
236*e1eccf28SAndroid Build Coastguard Worker }
237*e1eccf28SAndroid Build Coastguard Worker 
loadScale(float x,float y,float z)238*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadScale(float x, float y, float z) {
239*e1eccf28SAndroid Build Coastguard Worker     loadIdentity();
240*e1eccf28SAndroid Build Coastguard Worker     set(0, 0, x);
241*e1eccf28SAndroid Build Coastguard Worker     set(1, 1, y);
242*e1eccf28SAndroid Build Coastguard Worker     set(2, 2, z);
243*e1eccf28SAndroid Build Coastguard Worker }
244*e1eccf28SAndroid Build Coastguard Worker 
loadTranslate(float x,float y,float z)245*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadTranslate(float x, float y, float z) {
246*e1eccf28SAndroid Build Coastguard Worker     loadIdentity();
247*e1eccf28SAndroid Build Coastguard Worker     m[12] = x;
248*e1eccf28SAndroid Build Coastguard Worker     m[13] = y;
249*e1eccf28SAndroid Build Coastguard Worker     m[14] = z;
250*e1eccf28SAndroid Build Coastguard Worker }
251*e1eccf28SAndroid Build Coastguard Worker 
loadMultiply(const rs_matrix4x4 * lhs,const rs_matrix4x4 * rhs)252*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadMultiply(const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
253*e1eccf28SAndroid Build Coastguard Worker     // Use a temporary variable to support the case where one of the inputs
254*e1eccf28SAndroid Build Coastguard Worker     // is also the destination, e.g. left.loadMultiply(left, right);
255*e1eccf28SAndroid Build Coastguard Worker     Matrix4x4 temp;
256*e1eccf28SAndroid Build Coastguard Worker     for (int i=0 ; i<4 ; i++) {
257*e1eccf28SAndroid Build Coastguard Worker         float ri0 = 0;
258*e1eccf28SAndroid Build Coastguard Worker         float ri1 = 0;
259*e1eccf28SAndroid Build Coastguard Worker         float ri2 = 0;
260*e1eccf28SAndroid Build Coastguard Worker         float ri3 = 0;
261*e1eccf28SAndroid Build Coastguard Worker         for (int j=0 ; j<4 ; j++) {
262*e1eccf28SAndroid Build Coastguard Worker             const float rhs_ij = ((const Matrix4x4 *)rhs)->get(i,j);
263*e1eccf28SAndroid Build Coastguard Worker             ri0 += ((const Matrix4x4 *)lhs)->get(j,0) * rhs_ij;
264*e1eccf28SAndroid Build Coastguard Worker             ri1 += ((const Matrix4x4 *)lhs)->get(j,1) * rhs_ij;
265*e1eccf28SAndroid Build Coastguard Worker             ri2 += ((const Matrix4x4 *)lhs)->get(j,2) * rhs_ij;
266*e1eccf28SAndroid Build Coastguard Worker             ri3 += ((const Matrix4x4 *)lhs)->get(j,3) * rhs_ij;
267*e1eccf28SAndroid Build Coastguard Worker         }
268*e1eccf28SAndroid Build Coastguard Worker         temp.set(i,0, ri0);
269*e1eccf28SAndroid Build Coastguard Worker         temp.set(i,1, ri1);
270*e1eccf28SAndroid Build Coastguard Worker         temp.set(i,2, ri2);
271*e1eccf28SAndroid Build Coastguard Worker         temp.set(i,3, ri3);
272*e1eccf28SAndroid Build Coastguard Worker     }
273*e1eccf28SAndroid Build Coastguard Worker     load(&temp);
274*e1eccf28SAndroid Build Coastguard Worker }
275*e1eccf28SAndroid Build Coastguard Worker 
loadOrtho(float left,float right,float bottom,float top,float near,float far)276*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
277*e1eccf28SAndroid Build Coastguard Worker     loadIdentity();
278*e1eccf28SAndroid Build Coastguard Worker     m[0] = 2.f / (right - left);
279*e1eccf28SAndroid Build Coastguard Worker     m[5] = 2.f / (top - bottom);
280*e1eccf28SAndroid Build Coastguard Worker     m[10]= -2.f / (far - near);
281*e1eccf28SAndroid Build Coastguard Worker     m[12]= -(right + left) / (right - left);
282*e1eccf28SAndroid Build Coastguard Worker     m[13]= -(top + bottom) / (top - bottom);
283*e1eccf28SAndroid Build Coastguard Worker     m[14]= -(far + near) / (far - near);
284*e1eccf28SAndroid Build Coastguard Worker }
285*e1eccf28SAndroid Build Coastguard Worker 
loadFrustum(float left,float right,float bottom,float top,float near,float far)286*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadFrustum(float left, float right, float bottom, float top, float near, float far) {
287*e1eccf28SAndroid Build Coastguard Worker     loadIdentity();
288*e1eccf28SAndroid Build Coastguard Worker     m[0] = 2.f * near / (right - left);
289*e1eccf28SAndroid Build Coastguard Worker     m[5] = 2.f * near / (top - bottom);
290*e1eccf28SAndroid Build Coastguard Worker     m[8] = (right + left) / (right - left);
291*e1eccf28SAndroid Build Coastguard Worker     m[9] = (top + bottom) / (top - bottom);
292*e1eccf28SAndroid Build Coastguard Worker     m[10]= -(far + near) / (far - near);
293*e1eccf28SAndroid Build Coastguard Worker     m[11]= -1.f;
294*e1eccf28SAndroid Build Coastguard Worker     m[14]= -2.f * far * near / (far - near);
295*e1eccf28SAndroid Build Coastguard Worker     m[15]= 0.f;
296*e1eccf28SAndroid Build Coastguard Worker }
297*e1eccf28SAndroid Build Coastguard Worker 
loadPerspective(float fovy,float aspect,float near,float far)298*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::loadPerspective(float fovy, float aspect, float near, float far) {
299*e1eccf28SAndroid Build Coastguard Worker     float top = near * tan((float) (fovy * M_PI / 360.0f));
300*e1eccf28SAndroid Build Coastguard Worker     float bottom = -top;
301*e1eccf28SAndroid Build Coastguard Worker     float left = bottom * aspect;
302*e1eccf28SAndroid Build Coastguard Worker     float right = top * aspect;
303*e1eccf28SAndroid Build Coastguard Worker     loadFrustum(left, right, bottom, top, near, far);
304*e1eccf28SAndroid Build Coastguard Worker }
305*e1eccf28SAndroid Build Coastguard Worker 
306*e1eccf28SAndroid Build Coastguard Worker // Note: This assumes that the input vector (in) is of length 3.
vectorMultiply(float * out,const float * in) const307*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::vectorMultiply(float *out, const float *in) const {
308*e1eccf28SAndroid Build Coastguard Worker     out[0] = (m[0] * in[0]) + (m[4] * in[1]) + (m[8] * in[2]) + m[12];
309*e1eccf28SAndroid Build Coastguard Worker     out[1] = (m[1] * in[0]) + (m[5] * in[1]) + (m[9] * in[2]) + m[13];
310*e1eccf28SAndroid Build Coastguard Worker     out[2] = (m[2] * in[0]) + (m[6] * in[1]) + (m[10] * in[2]) + m[14];
311*e1eccf28SAndroid Build Coastguard Worker     out[3] = (m[3] * in[0]) + (m[7] * in[1]) + (m[11] * in[2]) + m[15];
312*e1eccf28SAndroid Build Coastguard Worker }
313*e1eccf28SAndroid Build Coastguard Worker 
logv(const char * s) const314*e1eccf28SAndroid Build Coastguard Worker void Matrix4x4::logv(const char *s) const {
315*e1eccf28SAndroid Build Coastguard Worker     ALOGV("%s {%f, %f, %f, %f",  s, m[0], m[4], m[8], m[12]);
316*e1eccf28SAndroid Build Coastguard Worker     ALOGV("%s  %f, %f, %f, %f",  s, m[1], m[5], m[9], m[13]);
317*e1eccf28SAndroid Build Coastguard Worker     ALOGV("%s  %f, %f, %f, %f",  s, m[2], m[6], m[10], m[14]);
318*e1eccf28SAndroid Build Coastguard Worker     ALOGV("%s  %f, %f, %f, %f}", s, m[3], m[7], m[11], m[15]);
319*e1eccf28SAndroid Build Coastguard Worker }
320*e1eccf28SAndroid Build Coastguard Worker 
321*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript
322*e1eccf28SAndroid Build Coastguard Worker } // namespace android
323