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