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_matrix3x3 type back to the Android system.
25  *
26  **/
27 public class Matrix3f {
28 
29     /**
30     * Creates a new identity 3x3 matrix
31     */
Matrix3f()32     public Matrix3f() {
33         mMat = new float[9];
34         loadIdentity();
35     }
36 
37     /**
38     * Creates a new matrix and sets its values from the given
39     * parameter
40     *
41     * @param dataArray values to set the matrix to, must be 9
42     *                  floats long
43     */
Matrix3f(float[] dataArray)44     public Matrix3f(float[] dataArray) {
45         mMat = new float[9];
46         System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
47     }
48 
49     /**
50     * Return a reference to the internal array representing matrix
51     * values. Modifying this array will also change the matrix
52     *
53     * @return internal array representing the matrix
54     */
getArray()55     public float[] getArray() {
56         return mMat;
57     }
58 
59     /**
60     * Returns the value for a given row and column
61     *
62     * @param x column of the value to return
63     * @param y row of the value to return
64     *
65     * @return value in the yth row and xth column
66     */
get(int x, int y)67     public float get(int x, int y) {
68         return mMat[x*3 + y];
69     }
70 
71     /**
72     * Sets the value for a given row and column
73     *
74     * @param x column of the value to set
75     * @param y row of the value to set
76     */
set(int x, int y, float v)77     public void set(int x, int y, float v) {
78         mMat[x*3 + y] = v;
79     }
80 
81     /**
82     * Sets the matrix values to identity
83     */
loadIdentity()84     public void loadIdentity() {
85         mMat[0] = 1;
86         mMat[1] = 0;
87         mMat[2] = 0;
88 
89         mMat[3] = 0;
90         mMat[4] = 1;
91         mMat[5] = 0;
92 
93         mMat[6] = 0;
94         mMat[7] = 0;
95         mMat[8] = 1;
96     }
97 
98     /**
99     * Sets the values of the matrix to those of the parameter
100     *
101     * @param src matrix to load the values from
102     */
load(Matrix3f src)103     public void load(Matrix3f src) {
104         System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
105     }
106 
107     /**
108     * Sets current values to be a rotation matrix of certain angle
109     * about a given axis
110     *
111     * @param rot angle of rotation
112     * @param x rotation axis x
113     * @param y rotation axis y
114     * @param z rotation axis z
115     */
loadRotate(float rot, float x, float y, float z)116     public void loadRotate(float rot, float x, float y, float z) {
117         float c, s;
118         rot *= (float)(java.lang.Math.PI / 180.0f);
119         c = (float)java.lang.Math.cos(rot);
120         s = (float)java.lang.Math.sin(rot);
121 
122         float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
123         if (!(len != 1)) {
124             float recipLen = 1.f / len;
125             x *= recipLen;
126             y *= recipLen;
127             z *= recipLen;
128         }
129         float nc = 1.0f - c;
130         float xy = x * y;
131         float yz = y * z;
132         float zx = z * x;
133         float xs = x * s;
134         float ys = y * s;
135         float zs = z * s;
136         mMat[0] = x*x*nc +  c;
137         mMat[3] =  xy*nc - zs;
138         mMat[6] =  zx*nc + ys;
139         mMat[1] =  xy*nc + zs;
140         mMat[4] = y*y*nc +  c;
141         mMat[7] =  yz*nc - xs;
142         mMat[2] =  zx*nc - ys;
143         mMat[5] =  yz*nc + xs;
144         mMat[8] = z*z*nc +  c;
145     }
146 
147     /**
148     * Makes the upper 2x2 a rotation matrix of the given angle
149     *
150     * @param rot rotation angle
151     */
loadRotate(float rot)152     public void loadRotate(float rot) {
153         loadIdentity();
154         float c, s;
155         rot *= (float)(java.lang.Math.PI / 180.0f);
156         c = (float)java.lang.Math.cos(rot);
157         s = (float)java.lang.Math.sin(rot);
158         mMat[0] = c;
159         mMat[1] = -s;
160         mMat[3] = s;
161         mMat[4] = c;
162     }
163 
164     /**
165     * Makes the upper 2x2 a scale matrix of given dimensions
166     *
167     * @param x scale component x
168     * @param y scale component y
169     */
loadScale(float x, float y)170     public void loadScale(float x, float y) {
171         loadIdentity();
172         mMat[0] = x;
173         mMat[4] = y;
174     }
175 
176     /**
177     * Sets current values to be a scale matrix of given dimensions
178     *
179     * @param x scale component x
180     * @param y scale component y
181     * @param z scale component z
182     */
loadScale(float x, float y, float z)183     public void loadScale(float x, float y, float z) {
184         loadIdentity();
185         mMat[0] = x;
186         mMat[4] = y;
187         mMat[8] = z;
188     }
189 
190     /**
191     * Sets current values to be a translation matrix of given
192     * dimensions
193     *
194     * @param x translation component x
195     * @param y translation component y
196     */
loadTranslate(float x, float y)197     public void loadTranslate(float x, float y) {
198         loadIdentity();
199         mMat[6] = x;
200         mMat[7] = y;
201     }
202 
203     /**
204     * Sets current values to be the result of multiplying two given
205     * matrices
206     *
207     * @param lhs left hand side matrix
208     * @param rhs right hand side matrix
209     */
loadMultiply(Matrix3f lhs, Matrix3f rhs)210     public void loadMultiply(Matrix3f lhs, Matrix3f rhs) {
211         for (int i=0 ; i<3 ; i++) {
212             float ri0 = 0;
213             float ri1 = 0;
214             float ri2 = 0;
215             for (int j=0 ; j<3 ; j++) {
216                 float rhs_ij = rhs.get(i,j);
217                 ri0 += lhs.get(j,0) * rhs_ij;
218                 ri1 += lhs.get(j,1) * rhs_ij;
219                 ri2 += lhs.get(j,2) * rhs_ij;
220             }
221             set(i,0, ri0);
222             set(i,1, ri1);
223             set(i,2, ri2);
224         }
225     }
226 
227     /**
228     * Post-multiplies the current matrix by a given parameter
229     *
230     * @param rhs right hand side to multiply by
231     */
multiply(Matrix3f rhs)232     public void multiply(Matrix3f rhs) {
233         Matrix3f tmp = new Matrix3f();
234         tmp.loadMultiply(this, rhs);
235         load(tmp);
236     }
237 
238     /**
239     * Modifies the current matrix by post-multiplying it with a
240     * rotation matrix of certain angle about a given axis
241     *
242     * @param rot angle of rotation
243     * @param x rotation axis x
244     * @param y rotation axis y
245     * @param z rotation axis z
246     */
rotate(float rot, float x, float y, float z)247     public void rotate(float rot, float x, float y, float z) {
248         Matrix3f tmp = new Matrix3f();
249         tmp.loadRotate(rot, x, y, z);
250         multiply(tmp);
251     }
252 
253     /**
254     * Modifies the upper 2x2 of the current matrix by
255     * post-multiplying it with a rotation matrix of given angle
256     *
257     * @param rot angle of rotation
258     */
rotate(float rot)259     public void rotate(float rot) {
260         Matrix3f tmp = new Matrix3f();
261         tmp.loadRotate(rot);
262         multiply(tmp);
263     }
264 
265     /**
266     * Modifies the upper 2x2 of the current matrix by
267     * post-multiplying it with a scale matrix of given dimensions
268     *
269     * @param x scale component x
270     * @param y scale component y
271     */
scale(float x, float y)272     public void scale(float x, float y) {
273         Matrix3f tmp = new Matrix3f();
274         tmp.loadScale(x, y);
275         multiply(tmp);
276     }
277 
278     /**
279     * Modifies the current matrix by post-multiplying it with a
280     * scale matrix of given dimensions
281     *
282     * @param x scale component x
283     * @param y scale component y
284     * @param z scale component z
285     */
scale(float x, float y, float z)286     public void scale(float x, float y, float z) {
287         Matrix3f tmp = new Matrix3f();
288         tmp.loadScale(x, y, z);
289         multiply(tmp);
290     }
291 
292     /**
293     * Modifies the current matrix by post-multiplying it with a
294     * translation matrix of given dimensions
295     *
296     * @param x translation component x
297     * @param y translation component y
298     */
translate(float x, float y)299     public void translate(float x, float y) {
300         Matrix3f tmp = new Matrix3f();
301         tmp.loadTranslate(x, y);
302         multiply(tmp);
303     }
304 
305     /**
306     * Sets the current matrix to its transpose
307     */
transpose()308     public void transpose() {
309         for(int i = 0; i < 2; ++i) {
310             for(int j = i + 1; j < 3; ++j) {
311                 float temp = mMat[i*3 + j];
312                 mMat[i*3 + j] = mMat[j*3 + i];
313                 mMat[j*3 + i] = temp;
314             }
315         }
316     }
317 
318     final float[] mMat;
319 }
320 
321 
322