/*
* 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);
}
}