• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009-2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.renderscript;
18 
19 import java.lang.Math;
20 import android.util.Log;
21 
22 
23 /**
24  * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
25  *
26  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
27  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
28  * guide</a> for the proposed alternatives.
29  **/
30 @Deprecated
31 public class Matrix4f {
32 
33     /**
34     * Creates a new identity 4x4 matrix
35     */
Matrix4f()36     public Matrix4f() {
37         mMat = new float[16];
38         loadIdentity();
39     }
40 
41     /**
42     * Creates a new matrix and sets its values from the given
43     * parameter
44     *
45     * @param dataArray values to set the matrix to, must be 16
46     *                  floats long
47     */
Matrix4f(float[] dataArray)48     public Matrix4f(float[] dataArray) {
49         mMat = new float[16];
50         System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
51     }
52 
53     /**
54     * Return a reference to the internal array representing matrix
55     * values. Modifying this array will also change the matrix
56     *
57     * @return internal array representing the matrix
58     */
getArray()59     public float[] getArray() {
60         return mMat;
61     }
62 
63     /**
64     * Returns the value for a given row and column
65     *
66     * @param x column of the value to return
67     * @param y row of the value to return
68     *
69     * @return value in the yth row and xth column
70     */
get(int x, int y)71     public float get(int x, int y) {
72         return mMat[x*4 + y];
73     }
74 
75     /**
76     * Sets the value for a given row and column
77     *
78     * @param x column of the value to set
79     * @param y row of the value to set
80     */
set(int x, int y, float v)81     public void set(int x, int y, float v) {
82         mMat[x*4 + y] = v;
83     }
84 
85     /**
86     * Sets the matrix values to identity
87     */
loadIdentity()88     public void loadIdentity() {
89         mMat[0] = 1;
90         mMat[1] = 0;
91         mMat[2] = 0;
92         mMat[3] = 0;
93 
94         mMat[4] = 0;
95         mMat[5] = 1;
96         mMat[6] = 0;
97         mMat[7] = 0;
98 
99         mMat[8] = 0;
100         mMat[9] = 0;
101         mMat[10] = 1;
102         mMat[11] = 0;
103 
104         mMat[12] = 0;
105         mMat[13] = 0;
106         mMat[14] = 0;
107         mMat[15] = 1;
108     }
109 
110     /**
111     * Sets the values of the matrix to those of the parameter
112     *
113     * @param src matrix to load the values from
114     */
load(Matrix4f src)115     public void load(Matrix4f src) {
116         System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
117     }
118 
119     /**
120     * Sets the values of the matrix to those of the parameter
121     *
122     * @param src matrix to load the values from
123     * @hide
124     */
load(Matrix3f src)125     public void load(Matrix3f src) {
126         mMat[0] = src.mMat[0];
127         mMat[1] = src.mMat[1];
128         mMat[2] = src.mMat[2];
129         mMat[3] = 0;
130 
131         mMat[4] = src.mMat[3];
132         mMat[5] = src.mMat[4];
133         mMat[6] = src.mMat[5];
134         mMat[7] = 0;
135 
136         mMat[8] = src.mMat[6];
137         mMat[9] = src.mMat[7];
138         mMat[10] = src.mMat[8];
139         mMat[11] = 0;
140 
141         mMat[12] = 0;
142         mMat[13] = 0;
143         mMat[14] = 0;
144         mMat[15] = 1;
145     }
146 
147     /**
148     * Sets current values to be a rotation matrix of certain angle
149     * about a given axis
150     *
151     * @param rot angle of rotation
152     * @param x rotation axis x
153     * @param y rotation axis y
154     * @param z rotation axis z
155     */
loadRotate(float rot, float x, float y, float z)156     public void loadRotate(float rot, float x, float y, float z) {
157         float c, s;
158         mMat[3] = 0;
159         mMat[7] = 0;
160         mMat[11]= 0;
161         mMat[12]= 0;
162         mMat[13]= 0;
163         mMat[14]= 0;
164         mMat[15]= 1;
165         rot *= (float)(java.lang.Math.PI / 180.0f);
166         c = (float)java.lang.Math.cos(rot);
167         s = (float)java.lang.Math.sin(rot);
168 
169         float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
170         if (!(len != 1)) {
171             float recipLen = 1.f / len;
172             x *= recipLen;
173             y *= recipLen;
174             z *= recipLen;
175         }
176         float nc = 1.0f - c;
177         float xy = x * y;
178         float yz = y * z;
179         float zx = z * x;
180         float xs = x * s;
181         float ys = y * s;
182         float zs = z * s;
183         mMat[ 0] = x*x*nc +  c;
184         mMat[ 4] =  xy*nc - zs;
185         mMat[ 8] =  zx*nc + ys;
186         mMat[ 1] =  xy*nc + zs;
187         mMat[ 5] = y*y*nc +  c;
188         mMat[ 9] =  yz*nc - xs;
189         mMat[ 2] =  zx*nc - ys;
190         mMat[ 6] =  yz*nc + xs;
191         mMat[10] = z*z*nc +  c;
192     }
193 
194     /**
195     * Sets current values to be a scale matrix of given dimensions
196     *
197     * @param x scale component x
198     * @param y scale component y
199     * @param z scale component z
200     */
loadScale(float x, float y, float z)201     public void loadScale(float x, float y, float z) {
202         loadIdentity();
203         mMat[0] = x;
204         mMat[5] = y;
205         mMat[10] = z;
206     }
207 
208     /**
209     * Sets current values to be a translation matrix of given
210     * dimensions
211     *
212     * @param x translation component x
213     * @param y translation component y
214     * @param z translation component z
215     */
loadTranslate(float x, float y, float z)216     public void loadTranslate(float x, float y, float z) {
217         loadIdentity();
218         mMat[12] = x;
219         mMat[13] = y;
220         mMat[14] = z;
221     }
222 
223     /**
224     * Sets current values to be the result of multiplying two given
225     * matrices
226     *
227     * @param lhs left hand side matrix
228     * @param rhs right hand side matrix
229     */
loadMultiply(Matrix4f lhs, Matrix4f rhs)230     public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
231         for (int i=0 ; i<4 ; i++) {
232             float ri0 = 0;
233             float ri1 = 0;
234             float ri2 = 0;
235             float ri3 = 0;
236             for (int j=0 ; j<4 ; j++) {
237                 float rhs_ij = rhs.get(i,j);
238                 ri0 += lhs.get(j,0) * rhs_ij;
239                 ri1 += lhs.get(j,1) * rhs_ij;
240                 ri2 += lhs.get(j,2) * rhs_ij;
241                 ri3 += lhs.get(j,3) * rhs_ij;
242             }
243             set(i,0, ri0);
244             set(i,1, ri1);
245             set(i,2, ri2);
246             set(i,3, ri3);
247         }
248     }
249 
250     /**
251     * Set current values to be an orthographic projection matrix
252     *
253     * @param l location of the left vertical clipping plane
254     * @param r location of the right vertical clipping plane
255     * @param b location of the bottom horizontal clipping plane
256     * @param t location of the top horizontal clipping plane
257     * @param n location of the near clipping plane
258     * @param f location of the far clipping plane
259     */
loadOrtho(float l, float r, float b, float t, float n, float f)260     public void loadOrtho(float l, float r, float b, float t, float n, float f) {
261         loadIdentity();
262         mMat[0] = 2 / (r - l);
263         mMat[5] = 2 / (t - b);
264         mMat[10]= -2 / (f - n);
265         mMat[12]= -(r + l) / (r - l);
266         mMat[13]= -(t + b) / (t - b);
267         mMat[14]= -(f + n) / (f - n);
268     }
269 
270     /**
271     * Set current values to be an orthographic projection matrix
272     * with the right and bottom clipping planes set to the given
273     * values. Left and top clipping planes are set to 0. Near and
274     * far are set to -1, 1 respectively
275     *
276     * @param w location of the right vertical clipping plane
277     * @param h location of the bottom horizontal clipping plane
278     *
279     */
loadOrthoWindow(int w, int h)280     public void loadOrthoWindow(int w, int h) {
281         loadOrtho(0,w, h,0, -1,1);
282     }
283 
284     /**
285     * Sets current values to be a perspective projection matrix
286     *
287     * @param l location of the left vertical clipping plane
288     * @param r location of the right vertical clipping plane
289     * @param b location of the bottom horizontal clipping plane
290     * @param t location of the top horizontal clipping plane
291     * @param n location of the near clipping plane, must be positive
292     * @param f location of the far clipping plane, must be positive
293     *
294     */
loadFrustum(float l, float r, float b, float t, float n, float f)295     public void loadFrustum(float l, float r, float b, float t, float n, float f) {
296         loadIdentity();
297         mMat[0] = 2 * n / (r - l);
298         mMat[5] = 2 * n / (t - b);
299         mMat[8] = (r + l) / (r - l);
300         mMat[9] = (t + b) / (t - b);
301         mMat[10]= -(f + n) / (f - n);
302         mMat[11]= -1;
303         mMat[14]= -2*f*n / (f - n);
304         mMat[15]= 0;
305     }
306 
307     /**
308     * Sets current values to be a perspective projection matrix
309     *
310     * @param fovy vertical field of view angle in degrees
311     * @param aspect aspect ratio of the screen
312     * @param near near cliping plane, must be positive
313     * @param far far clipping plane, must be positive
314     */
loadPerspective(float fovy, float aspect, float near, float far)315     public void loadPerspective(float fovy, float aspect, float near, float far) {
316         float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
317         float bottom = -top;
318         float left = bottom * aspect;
319         float right = top * aspect;
320         loadFrustum(left, right, bottom, top, near, far);
321     }
322 
323     /**
324     * Helper function to set the current values to a perspective
325     * projection matrix with aspect ratio defined by the parameters
326     * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
327     *
328     * @param w screen width
329     * @param h screen height
330     */
loadProjectionNormalized(int w, int h)331     public void loadProjectionNormalized(int w, int h) {
332         // range -1,1 in the narrow axis at z = 0.
333         Matrix4f m1 = new Matrix4f();
334         Matrix4f m2 = new Matrix4f();
335 
336         if(w > h) {
337             float aspect = ((float)w) / h;
338             m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
339         } else {
340             float aspect = ((float)h) / w;
341             m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
342         }
343 
344         m2.loadRotate(180, 0, 1, 0);
345         m1.loadMultiply(m1, m2);
346 
347         m2.loadScale(-2, 2, 1);
348         m1.loadMultiply(m1, m2);
349 
350         m2.loadTranslate(0, 0, 2);
351         m1.loadMultiply(m1, m2);
352 
353         load(m1);
354     }
355 
356     /**
357     * Post-multiplies the current matrix by a given parameter
358     *
359     * @param rhs right hand side to multiply by
360     */
multiply(Matrix4f rhs)361     public void multiply(Matrix4f rhs) {
362         Matrix4f tmp = new Matrix4f();
363         tmp.loadMultiply(this, rhs);
364         load(tmp);
365     }
366     /**
367     * Modifies the current matrix by post-multiplying it with a
368     * rotation matrix of certain angle about a given axis
369     *
370     * @param rot angle of rotation
371     * @param x rotation axis x
372     * @param y rotation axis y
373     * @param z rotation axis z
374     */
rotate(float rot, float x, float y, float z)375     public void rotate(float rot, float x, float y, float z) {
376         Matrix4f tmp = new Matrix4f();
377         tmp.loadRotate(rot, x, y, z);
378         multiply(tmp);
379     }
380 
381     /**
382     * Modifies the current matrix by post-multiplying it with a
383     * scale matrix of given dimensions
384     *
385     * @param x scale component x
386     * @param y scale component y
387     * @param z scale component z
388     */
scale(float x, float y, float z)389     public void scale(float x, float y, float z) {
390         Matrix4f tmp = new Matrix4f();
391         tmp.loadScale(x, y, z);
392         multiply(tmp);
393     }
394 
395     /**
396     * Modifies the current matrix by post-multiplying it with a
397     * translation matrix of given dimensions
398     *
399     * @param x translation component x
400     * @param y translation component y
401     * @param z translation component z
402     */
translate(float x, float y, float z)403     public void translate(float x, float y, float z) {
404         Matrix4f tmp = new Matrix4f();
405         tmp.loadTranslate(x, y, z);
406         multiply(tmp);
407     }
computeCofactor(int i, int j)408     private float computeCofactor(int i, int j) {
409         int c0 = (i+1) % 4;
410         int c1 = (i+2) % 4;
411         int c2 = (i+3) % 4;
412         int r0 = (j+1) % 4;
413         int r1 = (j+2) % 4;
414         int r2 = (j+3) % 4;
415 
416         float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
417                                             mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
418                      - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
419                                             mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
420                      + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
421                                             mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
422 
423         float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
424         return cofactor;
425     }
426 
427     /**
428     * Sets the current matrix to its inverse
429     */
inverse()430     public boolean inverse() {
431 
432         Matrix4f result = new Matrix4f();
433 
434         for (int i = 0; i < 4; ++i) {
435             for (int j = 0; j < 4; ++j) {
436                 result.mMat[4*i + j] = computeCofactor(i, j);
437             }
438         }
439 
440         // Dot product of 0th column of source and 0th row of result
441         float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
442                      mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
443 
444         if (Math.abs(det) < 1e-6) {
445             return false;
446         }
447 
448         det = 1.0f / det;
449         for (int i = 0; i < 16; ++i) {
450             mMat[i] = result.mMat[i] * det;
451         }
452 
453         return true;
454     }
455 
456     /**
457     * Sets the current matrix to its inverse transpose
458     */
inverseTranspose()459     public boolean inverseTranspose() {
460 
461         Matrix4f result = new Matrix4f();
462 
463         for (int i = 0; i < 4; ++i) {
464             for (int j = 0; j < 4; ++j) {
465                 result.mMat[4*j + i] = computeCofactor(i, j);
466             }
467         }
468 
469         float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
470                      mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
471 
472         if (Math.abs(det) < 1e-6) {
473             return false;
474         }
475 
476         det = 1.0f / det;
477         for (int i = 0; i < 16; ++i) {
478             mMat[i] = result.mMat[i] * det;
479         }
480 
481         return true;
482     }
483 
484     /**
485     * Sets the current matrix to its transpose
486     */
transpose()487     public void transpose() {
488         for(int i = 0; i < 3; ++i) {
489             for(int j = i + 1; j < 4; ++j) {
490                 float temp = mMat[i*4 + j];
491                 mMat[i*4 + j] = mMat[j*4 + i];
492                 mMat[j*4 + i] = temp;
493             }
494         }
495     }
496 
497     final float[] mMat;
498 }
499