/* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.rs.vr.engine; import android.util.Log; import java.text.*; import java.util.*; /** * Generic matrix code * Written for maximum portability between desktop and Android * Not in performance critical sections */ public class Matrix { private static final String LOGTAG = "Matrix"; public double[] m; public void makeRotation() { { double[] v = {m[0], m[4], m[8]}; VectorUtil.normalize(v); m[0] = v[0]; m[4] = v[1]; m[8] = v[2]; } { double[] v = {m[1], m[5], m[9]}; VectorUtil.normalize(v); m[1] = v[0]; m[5] = v[1]; m[9] = v[2]; } { double[] v = {m[2], m[6], m[10]}; VectorUtil.normalize(v); m[2] = v[0]; m[6] = v[1]; m[10] = v[2]; } } private static String trim(String s) { return s.substring(s.length() - 7); } public void print() { DecimalFormat df = new DecimalFormat(" ##0.000"); for (int i = 0; i < 4; i++) { String s=""; for (int j = 0; j < 4; j++) { s+= ((j == 0) ? "[ " : " , ") + trim(" "+df.format(m[i * 4 + j])); } Log.v(LOGTAG, s+"]"); } } public Matrix() { m = new double[4 * 4]; setToUnit(); } public Matrix(Matrix matrix) { this(Arrays.copyOf(matrix.m, matrix.m.length)); } protected Matrix(double[] m) { this.m = m; } public void setToUnit() { for (int i = 1; i < m.length; i++) { m[i] = 0; } m[0] = 1; m[5] = 1; m[10] = 1; m[15] = 1; } public void mult4(float[] src, float[] dest) { for (int i = 0; i < 4; i++) { int col = i * 4; double sum = 0; for (int j = 0; j < 4; j++) { sum += m[col + j] * src[j]; } dest[i] = (float) sum; } } public void mult3(float[] src, float[] dest) { for (int i = 0; i < 3; i++) { int col = i * 4; double sum = m[col + 3]; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j]; } dest[i] = (float) sum; } } public void mult3v(float[] src, float[] dest) { for (int i = 0; i < 3; i++) { int col = i * 4; double sum = 0; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j]; } dest[i] = (float) sum; } } public void mult4(double[] src, double[] dest) { for (int i = 0; i < 4; i++) { int col = i * 4; double sum = 0; for (int j = 0; j < 4; j++) { sum += m[col + j] * src[j]; } dest[i] = (float) sum; } } public void mult3(double[] src, double[] dest) { for (int i = 0; i < 3; i++) { int col = i * 4; double sum = m[col + 3]; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j]; } dest[i] = (float) sum; } } public void mult3v(double[] src, double[] dest) { for (int i = 0; i < 3; i++) { int col = i * 4; double sum = 0; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j]; } dest[i] = (float) sum; } } public double[] vecmult(double[] src) { double[] ret = new double[3]; mult3v(src, ret); return ret; } public void mult3(float[] src, int off1, float[] dest, int off2) { int col = 0 * 4; double sum = m[col + 3]; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j + off1]; } float v0 = (float) sum; col = 1 * 4; sum = m[col + 3]; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j + off1]; } float v1 = (float) sum; col = 2 * 4; sum = m[col + 3]; for (int j = 0; j < 3; j++) { sum += m[col + j] * src[j + off1]; } float v2 = (float) sum; dest[off2] = v0; dest[1 + off2] = v1; dest[2 + off2] = v2; } public Matrix invers() { double[] inv = new double[16]; inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10]; inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10]; inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9]; inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9]; inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10]; inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10]; inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9]; inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9]; inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6]; inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6]; inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5]; inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5]; inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6]; inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6]; inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] - m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5]; inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] + m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5]; double det; det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; if (det == 0) { return null; } det = 1.0 / det; double[] out = new double[16]; for (int i = 0; i < 16; i++) { out[i] = inv[i] * det; } Matrix ret = new Matrix(out); return ret; } public void getAsFloats(float[] fm) { for (int y = 0; y < 4; y++) { int col = y * 4; for (int x = 0; x < 4; x++) fm[y + x * 4] = (float) m[x + y * 4]; } } Matrix mult(Matrix b) { return new Matrix(multiply(this.m, b.m)); } Matrix premult(Matrix b) { return new Matrix(multiply(b.m, this.m)); } private static double[] multiply(double a[], double b[]) { double[] resultant = new double[16]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 4; k++) { resultant[i + 4 * j] += a[i + 4 * k] * b[k + 4 * j]; } } } return resultant; } public void clone(Matrix src) { System.arraycopy(src.m, 0, m, 0, m.length); } }