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