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 17package android.renderscript; 18 19import java.lang.Math; 20import android.util.Log; 21 22 23/** 24 * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system. 25 * 26 **/ 27public 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