1d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams/* 2d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Copyright (C) 2009 The Android Open Source Project 3d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * 4d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * you may not use this file except in compliance with the License. 6d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * You may obtain a copy of the License at 7d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * 8d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 9d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * 10d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Unless required by applicable law or agreed to in writing, software 11d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * See the License for the specific language governing permissions and 14d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * limitations under the License. 15d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams */ 16d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 17d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "rsMatrix.h" 18d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 19d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "stdlib.h" 2081d0a9a70ad68c836f89c5fcbebda95efe0048abJack Palevich#include "string.h" 21d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "math.h" 22d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 23d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsusing namespace android; 24d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsusing namespace android::renderscript; 25d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 26d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 27d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 28d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::loadIdentity() 29d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 30d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(0, 0, 1); 31d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(1, 0, 0); 32d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(2, 0, 0); 33d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(3, 0, 0); 34d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 35d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(0, 1, 0); 36d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(1, 1, 1); 37d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(2, 1, 0); 38d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(3, 1, 0); 39d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 40d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(0, 2, 0); 41d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(1, 2, 0); 42d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(2, 2, 1); 43d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(3, 2, 0); 44d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 45d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(0, 3, 0); 46d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(1, 3, 0); 47d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(2, 3, 0); 48d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(3, 3, 1); 49d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 50d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 51d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::load(const float *v) 52d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 53d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams memcpy(m, v, sizeof(m)); 54d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 55d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 56d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::load(const Matrix *v) 57d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 58d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams memcpy(m, v->m, sizeof(m)); 59d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 60d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 61d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::loadRotate(float rot, float x, float y, float z) 62d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 63d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams float c, s; 64d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[3] = 0; 65d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[7] = 0; 66d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[11]= 0; 67d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[12]= 0; 68d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[13]= 0; 69d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[14]= 0; 70d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[15]= 1; 71d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams rot *= float(M_PI / 180.0f); 72d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams c = cosf(rot); 73d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams s = sinf(rot); 74d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 75d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float len = sqrtf(x*x + y*y + z*z); 76d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams if (!(len != 1)) { 77d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float recipLen = 1.f / len; 78d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams x *= recipLen; 79d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams y *= recipLen; 80d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams z *= recipLen; 81d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams } 82d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float nc = 1.0f - c; 83d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float xy = x * y; 84d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float yz = y * z; 85d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float zx = z * x; 86d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float xs = x * s; 87d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float ys = y * s; 88e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Sams const float zs = z * s; 89d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 0] = x*x*nc + c; 90d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 4] = xy*nc - zs; 91d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 8] = zx*nc + ys; 92d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 1] = xy*nc + zs; 93d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 5] = y*y*nc + c; 94d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 9] = yz*nc - xs; 95d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 2] = zx*nc - ys; 96d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[ 6] = yz*nc + xs; 97d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[10] = z*z*nc + c; 98d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 99d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 100d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::loadScale(float x, float y, float z) 101d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 102d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams loadIdentity(); 103d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[0] = x; 104d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[5] = y; 105d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[10] = z; 106d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 107d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 108d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::loadTranslate(float x, float y, float z) 109d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 110d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams loadIdentity(); 111d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[12] = x; 112d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[13] = y; 113d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams m[14] = z; 114d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 115d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 116d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsvoid Matrix::loadMultiply(const Matrix *lhs, const Matrix *rhs) 117d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{ 118d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams for (int i=0 ; i<4 ; i++) { 119d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams float ri0 = 0; 120d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams float ri1 = 0; 121d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams float ri2 = 0; 122d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams float ri3 = 0; 123d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams for (int j=0 ; j<4 ; j++) { 124d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams const float rhs_ij = rhs->get(i,j); 125d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams ri0 += lhs->get(j,0) * rhs_ij; 126d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams ri1 += lhs->get(j,1) * rhs_ij; 127d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams ri2 += lhs->get(j,2) * rhs_ij; 128d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams ri3 += lhs->get(j,3) * rhs_ij; 129d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams } 130d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(i,0, ri0); 131d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(i,1, ri1); 132d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(i,2, ri2); 133d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams set(i,3, ri3); 134d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams } 135d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams} 136d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams 1379c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Samsvoid Matrix::loadOrtho(float l, float r, float b, float t, float n, float f) { 1389c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams loadIdentity(); 1399c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[0] = 2 / (r - l); 1409c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[5] = 2 / (t - b); 1419c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[10]= -2 / (f - n); 1429c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[12]= -(r + l) / (r - l); 1439c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[13]= -(t + b) / (t - b); 1449c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[14]= -(f + n) / (f - n); 1459c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams} 1469c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams 1479c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Samsvoid Matrix::loadFrustum(float l, float r, float b, float t, float n, float f) { 1489c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams loadIdentity(); 1499c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[0] = 2 * n / (r - l); 1509c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[5] = 2 * n / (t - b); 1519c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[8] = (r + l) / (r - l); 1529c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[9] = (t + b) / (t - b); 1539c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[10]= -(f + n) / (f - n); 1549c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[11]= -1; 1559c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[14]= -2*f*n / (f - n); 1569c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams m[15]= 0; 1579c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams} 1589c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams 159e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Samsvoid Matrix::vectorMultiply(float *out, const float *in) const { 160e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Sams out[0] = (m[0] * in[0]) + (m[4] * in[1]) + (m[8] * in[2]) + m[12]; 161e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Sams out[1] = (m[1] * in[0]) + (m[5] * in[1]) + (m[9] * in[2]) + m[13]; 162e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Sams out[2] = (m[2] * in[0]) + (m[6] * in[1]) + (m[10] * in[2]) + m[14]; 163e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Sams out[3] = (m[3] * in[0]) + (m[7] * in[1]) + (m[11] * in[2]) + m[15]; 164e9ad9a719dc66437ddf021d13e6ca736a23b5413Jason Sams} 165