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