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 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     */
     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     */
     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     */
     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     */
     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     */
     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     */
     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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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     */
    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