2 * Copyright (C) 2009-2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android
.support
.v8
.renderscript
;
19 import java
.lang
.Math
;
20 import android
.util
.Log
;
24 * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
27 public class Matrix4f
{
30 * Creates a new identity 4x4 matrix
38 * Creates a new matrix and sets its values from the given
41 * @param dataArray values to set the matrix to, must be 16
44 public Matrix4f(float[] dataArray
) {
46 System
.arraycopy(dataArray
, 0, mMat
, 0, mMat
.length
);
50 * Return a reference to the internal array representing matrix
51 * values. Modifying this array will also change the matrix
53 * @return internal array representing the matrix
55 public float[] getArray() {
60 * Returns the value for a given row and column
62 * @param x column of the value to return
63 * @param y row of the value to return
65 * @return value in the yth row and xth column
67 public float get(int x
, int y
) {
72 * Sets the value for a given row and column
74 * @param x column of the value to set
75 * @param y row of the value to set
77 public void set(int x
, int y
, float v
) {
82 * Sets the matrix values to identity
84 public void loadIdentity() {
107 * Sets the values of the matrix to those of the parameter
109 * @param src matrix to load the values from
111 public void load(Matrix4f src
) {
112 System
.arraycopy(src
.getArray(), 0, mMat
, 0, mMat
.length
);
116 * Sets the values of the matrix to those of the parameter
118 * @param src matrix to load the values from
121 public void load(Matrix3f src
) {
122 mMat
[0] = src
.mMat
[0];
123 mMat
[1] = src
.mMat
[1];
124 mMat
[2] = src
.mMat
[2];
127 mMat
[4] = src
.mMat
[3];
128 mMat
[5] = src
.mMat
[4];
129 mMat
[6] = src
.mMat
[5];
132 mMat
[8] = src
.mMat
[6];
133 mMat
[9] = src
.mMat
[7];
134 mMat
[10] = src
.mMat
[8];
144 * Sets current values to be a rotation matrix of certain angle
147 * @param rot angle of rotation
148 * @param x rotation axis x
149 * @param y rotation axis y
150 * @param z rotation axis z
152 public void loadRotate(float rot
, float x
, float y
, float z
) {
161 rot
*= (float)(java
.lang
.Math
.PI
/ 180.0f
);
162 c
= (float)java
.lang
.Math
.cos(rot
);
163 s
= (float)java
.lang
.Math
.sin(rot
);
165 float len
= (float)java
.lang
.Math
.sqrt(x
*x
+ y
*y
+ z
*z
);
167 float recipLen
= 1.f
/ len
;
179 mMat
[ 0] = x
*x
*nc
+ c
;
180 mMat
[ 4] = xy
*nc
- zs
;
181 mMat
[ 8] = zx
*nc
+ ys
;
182 mMat
[ 1] = xy
*nc
+ zs
;
183 mMat
[ 5] = y
*y
*nc
+ c
;
184 mMat
[ 9] = yz
*nc
- xs
;
185 mMat
[ 2] = zx
*nc
- ys
;
186 mMat
[ 6] = yz
*nc
+ xs
;
187 mMat
[10] = z
*z
*nc
+ c
;
191 * Sets current values to be a scale matrix of given dimensions
193 * @param x scale component x
194 * @param y scale component y
195 * @param z scale component z
197 public void loadScale(float x
, float y
, float z
) {
205 * Sets current values to be a translation matrix of given
208 * @param x translation component x
209 * @param y translation component y
210 * @param z translation component z
212 public void loadTranslate(float x
, float y
, float z
) {
220 * Sets current values to be the result of multiplying two given
223 * @param lhs left hand side matrix
224 * @param rhs right hand side matrix
226 public void loadMultiply(Matrix4f lhs
, Matrix4f rhs
) {
227 for (int i
=0 ; i
<4 ; i
++) {
232 for (int j
=0 ; j
<4 ; j
++) {
233 float rhs_ij
= rhs
.get(i
,j
);
234 ri0
+= lhs
.get(j
,0) * rhs_ij
;
235 ri1
+= lhs
.get(j
,1) * rhs_ij
;
236 ri2
+= lhs
.get(j
,2) * rhs_ij
;
237 ri3
+= lhs
.get(j
,3) * rhs_ij
;
247 * Set current values to be an orthographic projection matrix
249 * @param l location of the left vertical clipping plane
250 * @param r location of the right vertical clipping plane
251 * @param b location of the bottom horizontal clipping plane
252 * @param t location of the top horizontal clipping plane
253 * @param n location of the near clipping plane
254 * @param f location of the far clipping plane
256 public void loadOrtho(float l
, float r
, float b
, float t
, float n
, float f
) {
258 mMat
[0] = 2 / (r
- l
);
259 mMat
[5] = 2 / (t
- b
);
260 mMat
[10]= -2 / (f
- n
);
261 mMat
[12]= -(r
+ l
) / (r
- l
);
262 mMat
[13]= -(t
+ b
) / (t
- b
);
263 mMat
[14]= -(f
+ n
) / (f
- n
);
267 * Set current values to be an orthographic projection matrix
268 * with the right and bottom clipping planes set to the given
269 * values. Left and top clipping planes are set to 0. Near and
270 * far are set to -1, 1 respectively
272 * @param w location of the right vertical clipping plane
273 * @param h location of the bottom horizontal clipping plane
276 public void loadOrthoWindow(int w
, int h
) {
277 loadOrtho(0,w
, h
,0, -1,1);
281 * Sets current values to be a perspective projection matrix
283 * @param l location of the left vertical clipping plane
284 * @param r location of the right vertical clipping plane
285 * @param b location of the bottom horizontal clipping plane
286 * @param t location of the top horizontal clipping plane
287 * @param n location of the near clipping plane, must be positive
288 * @param f location of the far clipping plane, must be positive
291 public void loadFrustum(float l
, float r
, float b
, float t
, float n
, float f
) {
293 mMat
[0] = 2 * n
/ (r
- l
);
294 mMat
[5] = 2 * n
/ (t
- b
);
295 mMat
[8] = (r
+ l
) / (r
- l
);
296 mMat
[9] = (t
+ b
) / (t
- b
);
297 mMat
[10]= -(f
+ n
) / (f
- n
);
299 mMat
[14]= -2*f
*n
/ (f
- n
);
304 * Sets current values to be a perspective projection matrix
306 * @param fovy vertical field of view angle in degrees
307 * @param aspect aspect ratio of the screen
308 * @param near near cliping plane, must be positive
309 * @param far far clipping plane, must be positive
311 public void loadPerspective(float fovy
, float aspect
, float near
, float far
) {
312 float top
= near
* (float)Math
.tan((float) (fovy
* Math
.PI
/ 360.0f
));
314 float left
= bottom
* aspect
;
315 float right
= top
* aspect
;
316 loadFrustum(left
, right
, bottom
, top
, near
, far
);
320 * Helper function to set the current values to a perspective
321 * projection matrix with aspect ratio defined by the parameters
322 * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
324 * @param w screen width
325 * @param h screen height
327 public void loadProjectionNormalized(int w
, int h
) {
328 // range -1,1 in the narrow axis at z = 0.
329 Matrix4f m1
= new Matrix4f();
330 Matrix4f m2
= new Matrix4f();
333 float aspect
= ((float)w
) / h
;
334 m1
.loadFrustum(-aspect
,aspect
, -1,1, 1,100);
336 float aspect
= ((float)h
) / w
;
337 m1
.loadFrustum(-1,1, -aspect
,aspect
, 1,100);
340 m2
.loadRotate(180, 0, 1, 0);
341 m1
.loadMultiply(m1
, m2
);
343 m2
.loadScale(-2, 2, 1);
344 m1
.loadMultiply(m1
, m2
);
346 m2
.loadTranslate(0, 0, 2);
347 m1
.loadMultiply(m1
, m2
);
353 * Post-multiplies the current matrix by a given parameter
355 * @param rhs right hand side to multiply by
357 public void multiply(Matrix4f rhs
) {
358 Matrix4f tmp
= new Matrix4f();
359 tmp
.loadMultiply(this, rhs
);
363 * Modifies the current matrix by post-multiplying it with a
364 * rotation matrix of certain angle about a given axis
366 * @param rot angle of rotation
367 * @param x rotation axis x
368 * @param y rotation axis y
369 * @param z rotation axis z
371 public void rotate(float rot
, float x
, float y
, float z
) {
372 Matrix4f tmp
= new Matrix4f();
373 tmp
.loadRotate(rot
, x
, y
, z
);
378 * Modifies the current matrix by post-multiplying it with a
379 * scale matrix of given dimensions
381 * @param x scale component x
382 * @param y scale component y
383 * @param z scale component z
385 public void scale(float x
, float y
, float z
) {
386 Matrix4f tmp
= new Matrix4f();
387 tmp
.loadScale(x
, y
, z
);
392 * Modifies the current matrix by post-multiplying it with a
393 * translation matrix of given dimensions
395 * @param x translation component x
396 * @param y translation component y
397 * @param z translation component z
399 public void translate(float x
, float y
, float z
) {
400 Matrix4f tmp
= new Matrix4f();
401 tmp
.loadTranslate(x
, y
, z
);
404 private float computeCofactor(int i
, int j
) {
412 float minor
= (mMat
[c0
+ 4*r0
] * (mMat
[c1
+ 4*r1
] * mMat
[c2
+ 4*r2
] -
413 mMat
[c1
+ 4*r2
] * mMat
[c2
+ 4*r1
]))
414 - (mMat
[c0
+ 4*r1
] * (mMat
[c1
+ 4*r0
] * mMat
[c2
+ 4*r2
] -
415 mMat
[c1
+ 4*r2
] * mMat
[c2
+ 4*r0
]))
416 + (mMat
[c0
+ 4*r2
] * (mMat
[c1
+ 4*r0
] * mMat
[c2
+ 4*r1
] -
417 mMat
[c1
+ 4*r1
] * mMat
[c2
+ 4*r0
]));
419 float cofactor
= ((i
+j
) & 1) != 0 ?
-minor
: minor
;
424 * Sets the current matrix to its inverse
426 public boolean inverse() {
428 Matrix4f result
= new Matrix4f();
430 for (int i
= 0; i
< 4; ++i
) {
431 for (int j
= 0; j
< 4; ++j
) {
432 result
.mMat
[4*i
+ j
] = computeCofactor(i
, j
);
436 // Dot product of 0th column of source and 0th row of result
437 float det
= mMat
[0]*result
.mMat
[0] + mMat
[4]*result
.mMat
[1] +
438 mMat
[8]*result
.mMat
[2] + mMat
[12]*result
.mMat
[3];
440 if (Math
.abs(det
) < 1e-6) {
445 for (int i
= 0; i
< 16; ++i
) {
446 mMat
[i
] = result
.mMat
[i
] * det
;
453 * Sets the current matrix to its inverse transpose
455 public boolean inverseTranspose() {
457 Matrix4f result
= new Matrix4f();
459 for (int i
= 0; i
< 4; ++i
) {
460 for (int j
= 0; j
< 4; ++j
) {
461 result
.mMat
[4*j
+ i
] = computeCofactor(i
, j
);
465 float det
= mMat
[0]*result
.mMat
[0] + mMat
[4]*result
.mMat
[4] +
466 mMat
[8]*result
.mMat
[8] + mMat
[12]*result
.mMat
[12];
468 if (Math
.abs(det
) < 1e-6) {
473 for (int i
= 0; i
< 16; ++i
) {
474 mMat
[i
] = result
.mMat
[i
] * det
;
481 * Sets the current matrix to its transpose
483 public void transpose() {
484 for(int i
= 0; i
< 3; ++i
) {
485 for(int j
= i
+ 1; j
< 4; ++j
) {
486 float temp
= mMat
[i
*4 + j
];
487 mMat
[i
*4 + j
] = mMat
[j
*4 + i
];
488 mMat
[j
*4 + i
] = temp
;