blob: cdf06a63c59f354eef09104be15428f6fb3b383b [file] [log] [blame]
Jason Sams0826a6f2009-06-15 19:04:56 -07001/*
Stephen Hinesec6f2002012-07-10 16:16:22 -07002 * Copyright (C) 2009-2012 The Android Open Source Project
Jason Sams0826a6f2009-06-15 19:04:56 -07003 *
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
17package android.renderscript;
18
Artur Satayev2ebb31c2020-01-08 12:24:36 +000019import android.compat.annotation.UnsupportedAppUsage;
Jason Sams0826a6f2009-06-15 19:04:56 -070020
21
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070022/**
Tim Murrayc11e25c2013-04-09 11:01:01 -070023 * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
Jason Samse29d4712009-07-23 15:19:03 -070024 *
Xusong Wang8b4548c2021-01-05 10:09:52 -080025 * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
26 * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
27 * guide</a> for the proposed alternatives.
Jason Samse29d4712009-07-23 15:19:03 -070028 **/
Xusong Wang8b4548c2021-01-05 10:09:52 -080029@Deprecated
Jason Sams25430d02010-02-02 15:26:40 -080030public class Matrix4f {
Jason Sams0826a6f2009-06-15 19:04:56 -070031
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070032 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080033 * Creates a new identity 4x4 matrix
34 */
Jason Sams25430d02010-02-02 15:26:40 -080035 public Matrix4f() {
Jason Sams0826a6f2009-06-15 19:04:56 -070036 mMat = new float[16];
37 loadIdentity();
38 }
39
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070040 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080041 * Creates a new matrix and sets its values from the given
42 * parameter
43 *
44 * @param dataArray values to set the matrix to, must be 16
45 * floats long
46 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080047 public Matrix4f(float[] dataArray) {
48 mMat = new float[16];
49 System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
50 }
51
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070052 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080053 * Return a reference to the internal array representing matrix
54 * values. Modifying this array will also change the matrix
55 *
56 * @return internal array representing the matrix
57 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -080058 public float[] getArray() {
59 return mMat;
60 }
61
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070062 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080063 * Returns the value for a given row and column
64 *
Stephen Hinesec6f2002012-07-10 16:16:22 -070065 * @param x column of the value to return
66 * @param y row of the value to return
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080067 *
Stephen Hinesec6f2002012-07-10 16:16:22 -070068 * @return value in the yth row and xth column
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080069 */
Stephen Hinesec6f2002012-07-10 16:16:22 -070070 public float get(int x, int y) {
71 return mMat[x*4 + y];
Jason Sams0826a6f2009-06-15 19:04:56 -070072 }
73
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070074 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080075 * Sets the value for a given row and column
76 *
Stephen Hinesec6f2002012-07-10 16:16:22 -070077 * @param x column of the value to set
78 * @param y row of the value to set
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080079 */
Stephen Hinesec6f2002012-07-10 16:16:22 -070080 public void set(int x, int y, float v) {
81 mMat[x*4 + y] = v;
Jason Sams0826a6f2009-06-15 19:04:56 -070082 }
83
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070084 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -080085 * Sets the matrix values to identity
86 */
Jason Sams0826a6f2009-06-15 19:04:56 -070087 public void loadIdentity() {
88 mMat[0] = 1;
89 mMat[1] = 0;
90 mMat[2] = 0;
91 mMat[3] = 0;
92
93 mMat[4] = 0;
94 mMat[5] = 1;
95 mMat[6] = 0;
96 mMat[7] = 0;
Jason Sams25430d02010-02-02 15:26:40 -080097
Jason Sams0826a6f2009-06-15 19:04:56 -070098 mMat[8] = 0;
99 mMat[9] = 0;
100 mMat[10] = 1;
101 mMat[11] = 0;
102
103 mMat[12] = 0;
104 mMat[13] = 0;
105 mMat[14] = 0;
106 mMat[15] = 1;
107 }
108
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700109 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800110 * Sets the values of the matrix to those of the parameter
111 *
112 * @param src matrix to load the values from
113 */
Jason Sams25430d02010-02-02 15:26:40 -0800114 public void load(Matrix4f src) {
Alex Sakhartchoukb3b89f62010-12-29 08:43:49 -0800115 System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
Jason Sams0826a6f2009-06-15 19:04:56 -0700116 }
117
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700118 /**
Jason Sams8fd58532012-09-05 15:30:18 -0700119 * Sets the values of the matrix to those of the parameter
120 *
121 * @param src matrix to load the values from
122 * @hide
123 */
124 public void load(Matrix3f src) {
125 mMat[0] = src.mMat[0];
126 mMat[1] = src.mMat[1];
127 mMat[2] = src.mMat[2];
128 mMat[3] = 0;
129
130 mMat[4] = src.mMat[3];
131 mMat[5] = src.mMat[4];
132 mMat[6] = src.mMat[5];
133 mMat[7] = 0;
134
135 mMat[8] = src.mMat[6];
136 mMat[9] = src.mMat[7];
137 mMat[10] = src.mMat[8];
138 mMat[11] = 0;
139
140 mMat[12] = 0;
141 mMat[13] = 0;
142 mMat[14] = 0;
143 mMat[15] = 1;
144 }
145
146 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800147 * Sets current values to be a rotation matrix of certain angle
148 * about a given axis
149 *
150 * @param rot angle of rotation
151 * @param x rotation axis x
152 * @param y rotation axis y
153 * @param z rotation axis z
154 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700155 public void loadRotate(float rot, float x, float y, float z) {
156 float c, s;
157 mMat[3] = 0;
158 mMat[7] = 0;
159 mMat[11]= 0;
160 mMat[12]= 0;
161 mMat[13]= 0;
162 mMat[14]= 0;
163 mMat[15]= 1;
164 rot *= (float)(java.lang.Math.PI / 180.0f);
165 c = (float)java.lang.Math.cos(rot);
166 s = (float)java.lang.Math.sin(rot);
Jason Sams25430d02010-02-02 15:26:40 -0800167
Jason Sams0826a6f2009-06-15 19:04:56 -0700168 float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
169 if (!(len != 1)) {
170 float recipLen = 1.f / len;
171 x *= recipLen;
172 y *= recipLen;
173 z *= recipLen;
174 }
175 float nc = 1.0f - c;
176 float xy = x * y;
177 float yz = y * z;
178 float zx = z * x;
179 float xs = x * s;
180 float ys = y * s;
Jason Sams25430d02010-02-02 15:26:40 -0800181 float zs = z * s;
Jason Sams0826a6f2009-06-15 19:04:56 -0700182 mMat[ 0] = x*x*nc + c;
183 mMat[ 4] = xy*nc - zs;
184 mMat[ 8] = zx*nc + ys;
185 mMat[ 1] = xy*nc + zs;
186 mMat[ 5] = y*y*nc + c;
187 mMat[ 9] = yz*nc - xs;
188 mMat[ 2] = zx*nc - ys;
189 mMat[ 6] = yz*nc + xs;
190 mMat[10] = z*z*nc + c;
191 }
192
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700193 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800194 * Sets current values to be a scale matrix of given dimensions
195 *
196 * @param x scale component x
197 * @param y scale component y
198 * @param z scale component z
199 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700200 public void loadScale(float x, float y, float z) {
201 loadIdentity();
202 mMat[0] = x;
203 mMat[5] = y;
204 mMat[10] = z;
205 }
Jason Sams25430d02010-02-02 15:26:40 -0800206
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700207 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800208 * Sets current values to be a translation matrix of given
209 * dimensions
210 *
211 * @param x translation component x
212 * @param y translation component y
213 * @param z translation component z
214 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700215 public void loadTranslate(float x, float y, float z) {
216 loadIdentity();
217 mMat[12] = x;
218 mMat[13] = y;
219 mMat[14] = z;
220 }
221
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700222 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800223 * Sets current values to be the result of multiplying two given
224 * matrices
225 *
226 * @param lhs left hand side matrix
227 * @param rhs right hand side matrix
228 */
Jason Sams25430d02010-02-02 15:26:40 -0800229 public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
Jason Sams0826a6f2009-06-15 19:04:56 -0700230 for (int i=0 ; i<4 ; i++) {
231 float ri0 = 0;
232 float ri1 = 0;
233 float ri2 = 0;
234 float ri3 = 0;
235 for (int j=0 ; j<4 ; j++) {
236 float rhs_ij = rhs.get(i,j);
237 ri0 += lhs.get(j,0) * rhs_ij;
238 ri1 += lhs.get(j,1) * rhs_ij;
239 ri2 += lhs.get(j,2) * rhs_ij;
240 ri3 += lhs.get(j,3) * rhs_ij;
241 }
242 set(i,0, ri0);
243 set(i,1, ri1);
244 set(i,2, ri2);
245 set(i,3, ri3);
246 }
247 }
248
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700249 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800250 * Set current values to be an orthographic projection matrix
251 *
252 * @param l location of the left vertical clipping plane
253 * @param r location of the right vertical clipping plane
254 * @param b location of the bottom horizontal clipping plane
255 * @param t location of the top horizontal clipping plane
256 * @param n location of the near clipping plane
257 * @param f location of the far clipping plane
258 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700259 public void loadOrtho(float l, float r, float b, float t, float n, float f) {
260 loadIdentity();
261 mMat[0] = 2 / (r - l);
262 mMat[5] = 2 / (t - b);
263 mMat[10]= -2 / (f - n);
264 mMat[12]= -(r + l) / (r - l);
Jason Samsb37c0a52009-06-16 17:49:58 -0700265 mMat[13]= -(t + b) / (t - b);
266 mMat[14]= -(f + n) / (f - n);
Jason Sams0826a6f2009-06-15 19:04:56 -0700267 }
268
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700269 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800270 * Set current values to be an orthographic projection matrix
271 * with the right and bottom clipping planes set to the given
272 * values. Left and top clipping planes are set to 0. Near and
273 * far are set to -1, 1 respectively
274 *
275 * @param w location of the right vertical clipping plane
276 * @param h location of the bottom horizontal clipping plane
277 *
278 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800279 public void loadOrthoWindow(int w, int h) {
280 loadOrtho(0,w, h,0, -1,1);
281 }
282
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700283 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800284 * Sets current values to be a perspective projection matrix
285 *
286 * @param l location of the left vertical clipping plane
287 * @param r location of the right vertical clipping plane
288 * @param b location of the bottom horizontal clipping plane
289 * @param t location of the top horizontal clipping plane
290 * @param n location of the near clipping plane, must be positive
291 * @param f location of the far clipping plane, must be positive
292 *
293 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700294 public void loadFrustum(float l, float r, float b, float t, float n, float f) {
295 loadIdentity();
296 mMat[0] = 2 * n / (r - l);
297 mMat[5] = 2 * n / (t - b);
298 mMat[8] = (r + l) / (r - l);
299 mMat[9] = (t + b) / (t - b);
300 mMat[10]= -(f + n) / (f - n);
301 mMat[11]= -1;
302 mMat[14]= -2*f*n / (f - n);
303 mMat[15]= 0;
304 }
305
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700306 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800307 * Sets current values to be a perspective projection matrix
308 *
309 * @param fovy vertical field of view angle in degrees
310 * @param aspect aspect ratio of the screen
311 * @param near near cliping plane, must be positive
312 * @param far far clipping plane, must be positive
313 */
Alex Sakhartchouke27cdee2010-12-17 11:41:08 -0800314 public void loadPerspective(float fovy, float aspect, float near, float far) {
315 float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
316 float bottom = -top;
317 float left = bottom * aspect;
318 float right = top * aspect;
319 loadFrustum(left, right, bottom, top, near, far);
320 }
321
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700322 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800323 * Helper function to set the current values to a perspective
324 * projection matrix with aspect ratio defined by the parameters
325 * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
326 *
327 * @param w screen width
328 * @param h screen height
329 */
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -0800330 public void loadProjectionNormalized(int w, int h) {
331 // range -1,1 in the narrow axis at z = 0.
332 Matrix4f m1 = new Matrix4f();
333 Matrix4f m2 = new Matrix4f();
334
335 if(w > h) {
336 float aspect = ((float)w) / h;
337 m1.loadFrustum(-aspect,aspect, -1,1, 1,100);
338 } else {
339 float aspect = ((float)h) / w;
340 m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
341 }
342
343 m2.loadRotate(180, 0, 1, 0);
344 m1.loadMultiply(m1, m2);
345
346 m2.loadScale(-2, 2, 1);
347 m1.loadMultiply(m1, m2);
348
349 m2.loadTranslate(0, 0, 2);
350 m1.loadMultiply(m1, m2);
351
352 load(m1);
353 }
354
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700355 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800356 * Post-multiplies the current matrix by a given parameter
357 *
358 * @param rhs right hand side to multiply by
359 */
Jason Sams25430d02010-02-02 15:26:40 -0800360 public void multiply(Matrix4f rhs) {
361 Matrix4f tmp = new Matrix4f();
Jason Sams0826a6f2009-06-15 19:04:56 -0700362 tmp.loadMultiply(this, rhs);
363 load(tmp);
364 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700365 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800366 * Modifies the current matrix by post-multiplying it with a
367 * rotation matrix of certain angle about a given axis
368 *
369 * @param rot angle of rotation
370 * @param x rotation axis x
371 * @param y rotation axis y
372 * @param z rotation axis z
373 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700374 public void rotate(float rot, float x, float y, float z) {
Jason Sams25430d02010-02-02 15:26:40 -0800375 Matrix4f tmp = new Matrix4f();
Jason Sams0826a6f2009-06-15 19:04:56 -0700376 tmp.loadRotate(rot, x, y, z);
377 multiply(tmp);
378 }
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800379
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700380 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800381 * Modifies the current matrix by post-multiplying it with a
382 * scale matrix of given dimensions
383 *
384 * @param x scale component x
385 * @param y scale component y
386 * @param z scale component z
387 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700388 public void scale(float x, float y, float z) {
Jason Sams25430d02010-02-02 15:26:40 -0800389 Matrix4f tmp = new Matrix4f();
Jason Sams0826a6f2009-06-15 19:04:56 -0700390 tmp.loadScale(x, y, z);
391 multiply(tmp);
392 }
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800393
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700394 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800395 * Modifies the current matrix by post-multiplying it with a
396 * translation matrix of given dimensions
397 *
398 * @param x translation component x
399 * @param y translation component y
400 * @param z translation component z
401 */
Jason Sams0826a6f2009-06-15 19:04:56 -0700402 public void translate(float x, float y, float z) {
Jason Sams25430d02010-02-02 15:26:40 -0800403 Matrix4f tmp = new Matrix4f();
Jason Sams0826a6f2009-06-15 19:04:56 -0700404 tmp.loadTranslate(x, y, z);
405 multiply(tmp);
406 }
Alex Sakhartchoukfacd6fc2010-08-10 17:34:39 -0700407 private float computeCofactor(int i, int j) {
408 int c0 = (i+1) % 4;
409 int c1 = (i+2) % 4;
410 int c2 = (i+3) % 4;
411 int r0 = (j+1) % 4;
412 int r1 = (j+2) % 4;
413 int r2 = (j+3) % 4;
414
415 float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
416 mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
417 - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
418 mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
419 + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
420 mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
421
422 float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
423 return cofactor;
424 }
425
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700426 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800427 * Sets the current matrix to its inverse
428 */
Alex Sakhartchoukfacd6fc2010-08-10 17:34:39 -0700429 public boolean inverse() {
430
431 Matrix4f result = new Matrix4f();
432
433 for (int i = 0; i < 4; ++i) {
434 for (int j = 0; j < 4; ++j) {
435 result.mMat[4*i + j] = computeCofactor(i, j);
436 }
437 }
438
439 // Dot product of 0th column of source and 0th row of result
440 float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
441 mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
442
443 if (Math.abs(det) < 1e-6) {
444 return false;
445 }
446
447 det = 1.0f / det;
448 for (int i = 0; i < 16; ++i) {
449 mMat[i] = result.mMat[i] * det;
450 }
451
452 return true;
453 }
454
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700455 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800456 * Sets the current matrix to its inverse transpose
457 */
Alex Sakhartchoukfacd6fc2010-08-10 17:34:39 -0700458 public boolean inverseTranspose() {
459
460 Matrix4f result = new Matrix4f();
461
462 for (int i = 0; i < 4; ++i) {
463 for (int j = 0; j < 4; ++j) {
464 result.mMat[4*j + i] = computeCofactor(i, j);
465 }
466 }
467
468 float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
469 mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
470
471 if (Math.abs(det) < 1e-6) {
472 return false;
473 }
474
475 det = 1.0f / det;
476 for (int i = 0; i < 16; ++i) {
477 mMat[i] = result.mMat[i] * det;
478 }
479
480 return true;
481 }
482
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700483 /**
Alex Sakhartchoukec0d3352011-01-17 15:23:22 -0800484 * Sets the current matrix to its transpose
485 */
Alex Sakhartchouk518f0332010-08-05 10:28:43 -0700486 public void transpose() {
487 for(int i = 0; i < 3; ++i) {
488 for(int j = i + 1; j < 4; ++j) {
489 float temp = mMat[i*4 + j];
490 mMat[i*4 + j] = mMat[j*4 + i];
491 mMat[j*4 + i] = temp;
492 }
493 }
494 }
Jason Sams0826a6f2009-06-15 19:04:56 -0700495
Mathew Inwood15324472018-08-06 11:18:49 +0100496 @UnsupportedAppUsage
Jason Sams25430d02010-02-02 15:26:40 -0800497 final float[] mMat;
Jason Sams0826a6f2009-06-15 19:04:56 -0700498}