Home | History | Annotate | Download | only in engine
      1 /*
      2  * Copyright (C) 2015 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 package com.example.android.rs.vr.engine;
     17 
     18 import android.util.Log;
     19 
     20 import java.text.*;
     21 import java.util.*;
     22 
     23 /**
     24  * Generic matrix code
     25  * Written for maximum portability between desktop and Android
     26  * Not in performance critical sections
     27  */
     28 public class Matrix {
     29 
     30     private static final String LOGTAG = "Matrix";
     31     public double[] m;
     32 
     33     public void makeRotation() {
     34         {
     35             double[] v = {m[0], m[4], m[8]};
     36             VectorUtil.normalize(v);
     37             m[0] = v[0];
     38             m[4] = v[1];
     39             m[8] = v[2];
     40         }
     41         {
     42             double[] v = {m[1], m[5], m[9]};
     43             VectorUtil.normalize(v);
     44             m[1] = v[0];
     45             m[5] = v[1];
     46             m[9] = v[2];
     47         }
     48         {
     49             double[] v = {m[2], m[6], m[10]};
     50             VectorUtil.normalize(v);
     51             m[2] = v[0];
     52             m[6] = v[1];
     53             m[10] = v[2];
     54         }
     55 
     56     }
     57 
     58     private static String trim(String s) {
     59         return s.substring(s.length() - 7);
     60     }
     61 
     62     public void print() {
     63         DecimalFormat df = new DecimalFormat("      ##0.000");
     64         for (int i = 0; i < 4; i++) {
     65             String s="";
     66             for (int j = 0; j < 4; j++) {
     67                s+= ((j == 0) ? "[ " : " , ") + trim("       "+df.format(m[i * 4 + j]));
     68             }
     69             Log.v(LOGTAG, s+"]");
     70         }
     71     }
     72 
     73     public Matrix() {
     74         m = new double[4 * 4];
     75         setToUnit();
     76     }
     77 
     78     public Matrix(Matrix matrix) {
     79         this(Arrays.copyOf(matrix.m, matrix.m.length));
     80     }
     81 
     82     protected Matrix(double[] m) {
     83         this.m = m;
     84     }
     85 
     86     public void setToUnit() {
     87         for (int i = 1; i < m.length; i++) {
     88             m[i] = 0;
     89         }
     90         m[0] = 1;
     91         m[5] = 1;
     92         m[10] = 1;
     93         m[15] = 1;
     94     }
     95 
     96     public void mult4(float[] src, float[] dest) {
     97         for (int i = 0; i < 4; i++) {
     98             int col = i * 4;
     99             double sum = 0;
    100             for (int j = 0; j < 4; j++) {
    101                 sum += m[col + j] * src[j];
    102             }
    103             dest[i] = (float) sum;
    104         }
    105     }
    106 
    107     public void mult3(float[] src, float[] dest) {
    108         for (int i = 0; i < 3; i++) {
    109             int col = i * 4;
    110             double sum = m[col + 3];
    111             for (int j = 0; j < 3; j++) {
    112                 sum += m[col + j] * src[j];
    113             }
    114             dest[i] = (float) sum;
    115         }
    116     }
    117 
    118     public void mult3v(float[] src, float[] dest) {
    119         for (int i = 0; i < 3; i++) {
    120             int col = i * 4;
    121             double sum = 0;
    122             for (int j = 0; j < 3; j++) {
    123                 sum += m[col + j] * src[j];
    124             }
    125             dest[i] = (float) sum;
    126         }
    127     }
    128 
    129     public void mult4(double[] src, double[] dest) {
    130         for (int i = 0; i < 4; i++) {
    131             int col = i * 4;
    132             double sum = 0;
    133             for (int j = 0; j < 4; j++) {
    134                 sum += m[col + j] * src[j];
    135             }
    136             dest[i] = (float) sum;
    137         }
    138     }
    139 
    140     public void mult3(double[] src, double[] dest) {
    141         for (int i = 0; i < 3; i++) {
    142             int col = i * 4;
    143             double sum = m[col + 3];
    144             for (int j = 0; j < 3; j++) {
    145                 sum += m[col + j] * src[j];
    146             }
    147             dest[i] = (float) sum;
    148         }
    149     }
    150 
    151     public void mult3v(double[] src, double[] dest) {
    152         for (int i = 0; i < 3; i++) {
    153             int col = i * 4;
    154             double sum = 0;
    155             for (int j = 0; j < 3; j++) {
    156                 sum += m[col + j] * src[j];
    157             }
    158             dest[i] = (float) sum;
    159         }
    160     }
    161 
    162     public double[] vecmult(double[] src) {
    163         double[] ret = new double[3];
    164         mult3v(src, ret);
    165         return ret;
    166     }
    167 
    168     public void mult3(float[] src, int off1, float[] dest, int off2) {
    169 
    170         int col = 0 * 4;
    171         double sum = m[col + 3];
    172         for (int j = 0; j < 3; j++) {
    173             sum += m[col + j] * src[j + off1];
    174         }
    175         float v0 = (float) sum;
    176 
    177 
    178         col = 1 * 4;
    179         sum = m[col + 3];
    180         for (int j = 0; j < 3; j++) {
    181             sum += m[col + j] * src[j + off1];
    182         }
    183 
    184         float v1 = (float) sum;
    185 
    186 
    187         col = 2 * 4;
    188         sum = m[col + 3];
    189         for (int j = 0; j < 3; j++) {
    190             sum += m[col + j] * src[j + off1];
    191         }
    192         float v2 = (float) sum;
    193 
    194         dest[off2] = v0;
    195         dest[1 + off2] = v1;
    196         dest[2 + off2] = v2;
    197 
    198     }
    199 
    200     public Matrix invers() {
    201         double[] inv = new double[16];
    202 
    203         inv[0] = m[5] * m[10] * m[15] -
    204                 m[5] * m[11] * m[14] -
    205                 m[9] * m[6] * m[15] +
    206                 m[9] * m[7] * m[14] +
    207                 m[13] * m[6] * m[11] -
    208                 m[13] * m[7] * m[10];
    209 
    210         inv[4] = -m[4] * m[10] * m[15] +
    211                 m[4] * m[11] * m[14] +
    212                 m[8] * m[6] * m[15] -
    213                 m[8] * m[7] * m[14] -
    214                 m[12] * m[6] * m[11] +
    215                 m[12] * m[7] * m[10];
    216 
    217         inv[8] = m[4] * m[9] * m[15] -
    218                 m[4] * m[11] * m[13] -
    219                 m[8] * m[5] * m[15] +
    220                 m[8] * m[7] * m[13] +
    221                 m[12] * m[5] * m[11] -
    222                 m[12] * m[7] * m[9];
    223 
    224         inv[12] = -m[4] * m[9] * m[14] +
    225                 m[4] * m[10] * m[13] +
    226                 m[8] * m[5] * m[14] -
    227                 m[8] * m[6] * m[13] -
    228                 m[12] * m[5] * m[10] +
    229                 m[12] * m[6] * m[9];
    230 
    231         inv[1] = -m[1] * m[10] * m[15] +
    232                 m[1] * m[11] * m[14] +
    233                 m[9] * m[2] * m[15] -
    234                 m[9] * m[3] * m[14] -
    235                 m[13] * m[2] * m[11] +
    236                 m[13] * m[3] * m[10];
    237 
    238         inv[5] = m[0] * m[10] * m[15] -
    239                 m[0] * m[11] * m[14] -
    240                 m[8] * m[2] * m[15] +
    241                 m[8] * m[3] * m[14] +
    242                 m[12] * m[2] * m[11] -
    243                 m[12] * m[3] * m[10];
    244 
    245         inv[9] = -m[0] * m[9] * m[15] +
    246                 m[0] * m[11] * m[13] +
    247                 m[8] * m[1] * m[15] -
    248                 m[8] * m[3] * m[13] -
    249                 m[12] * m[1] * m[11] +
    250                 m[12] * m[3] * m[9];
    251 
    252         inv[13] = m[0] * m[9] * m[14] -
    253                 m[0] * m[10] * m[13] -
    254                 m[8] * m[1] * m[14] +
    255                 m[8] * m[2] * m[13] +
    256                 m[12] * m[1] * m[10] -
    257                 m[12] * m[2] * m[9];
    258 
    259         inv[2] = m[1] * m[6] * m[15] -
    260                 m[1] * m[7] * m[14] -
    261                 m[5] * m[2] * m[15] +
    262                 m[5] * m[3] * m[14] +
    263                 m[13] * m[2] * m[7] -
    264                 m[13] * m[3] * m[6];
    265 
    266         inv[6] = -m[0] * m[6] * m[15] +
    267                 m[0] * m[7] * m[14] +
    268                 m[4] * m[2] * m[15] -
    269                 m[4] * m[3] * m[14] -
    270                 m[12] * m[2] * m[7] +
    271                 m[12] * m[3] * m[6];
    272 
    273         inv[10] = m[0] * m[5] * m[15] -
    274                 m[0] * m[7] * m[13] -
    275                 m[4] * m[1] * m[15] +
    276                 m[4] * m[3] * m[13] +
    277                 m[12] * m[1] * m[7] -
    278                 m[12] * m[3] * m[5];
    279 
    280         inv[14] = -m[0] * m[5] * m[14] +
    281                 m[0] * m[6] * m[13] +
    282                 m[4] * m[1] * m[14] -
    283                 m[4] * m[2] * m[13] -
    284                 m[12] * m[1] * m[6] +
    285                 m[12] * m[2] * m[5];
    286 
    287         inv[3] = -m[1] * m[6] * m[11] +
    288                 m[1] * m[7] * m[10] +
    289                 m[5] * m[2] * m[11] -
    290                 m[5] * m[3] * m[10] -
    291                 m[9] * m[2] * m[7] +
    292                 m[9] * m[3] * m[6];
    293 
    294         inv[7] = m[0] * m[6] * m[11] -
    295                 m[0] * m[7] * m[10] -
    296                 m[4] * m[2] * m[11] +
    297                 m[4] * m[3] * m[10] +
    298                 m[8] * m[2] * m[7] -
    299                 m[8] * m[3] * m[6];
    300 
    301         inv[11] = -m[0] * m[5] * m[11] +
    302                 m[0] * m[7] * m[9] +
    303                 m[4] * m[1] * m[11] -
    304                 m[4] * m[3] * m[9] -
    305                 m[8] * m[1] * m[7] +
    306                 m[8] * m[3] * m[5];
    307 
    308         inv[15] = m[0] * m[5] * m[10] -
    309                 m[0] * m[6] * m[9] -
    310                 m[4] * m[1] * m[10] +
    311                 m[4] * m[2] * m[9] +
    312                 m[8] * m[1] * m[6] -
    313                 m[8] * m[2] * m[5];
    314 
    315 
    316         double det;
    317         det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
    318 
    319         if (det == 0) {
    320             return null;
    321         }
    322 
    323         det = 1.0 / det;
    324 
    325         double[] out = new double[16];
    326 
    327         for (int i = 0; i < 16; i++) {
    328             out[i] = inv[i] * det;
    329         }
    330 
    331         Matrix ret = new Matrix(out);
    332         return ret;
    333     }
    334 
    335     public void getAsFloats(float[] fm) {
    336         for (int y = 0; y < 4; y++) {
    337             int col = y * 4;
    338 
    339             for (int x = 0; x < 4; x++)
    340                 fm[y + x * 4] = (float) m[x + y * 4];
    341         }
    342     }
    343 
    344     Matrix mult(Matrix b) {
    345         return new Matrix(multiply(this.m, b.m));
    346     }
    347 
    348     Matrix premult(Matrix b) {
    349         return new Matrix(multiply(b.m, this.m));
    350     }
    351 
    352     private static double[] multiply(double a[], double b[]) {
    353         double[] resultant = new double[16];
    354         for (int i = 0; i < 4; i++) {
    355             for (int j = 0; j < 4; j++) {
    356                 for (int k = 0; k < 4; k++) {
    357                     resultant[i + 4 * j] += a[i + 4 * k] * b[k + 4 * j];
    358                 }
    359             }
    360         }
    361 
    362         return resultant;
    363     }
    364 
    365     public void clone(Matrix src) {
    366         System.arraycopy(src.m, 0, m, 0, m.length);
    367     }
    368 }
    369