/* * Copyright 2016 Nathan Howard * * This file is part of OpenGrave * * OpenGrave is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenGrave is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenGrave. If not, see <http://www.gnu.org/licenses/>. */ package com.opengrave.og.util; import java.nio.FloatBuffer; public class Matrix3f { private float[] matrix = new float[9]; public Matrix3f() { clearToIdentity(); } public Matrix3f(float[] m) { this(); set(m); } public Matrix3f(Matrix3f m) { this(); set(m); } public Matrix3f(Matrix4f mat4) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { put(i, j, mat4.get(i, j)); } } } public Matrix3f clear() { for (int a = 0; a < 9; a++) matrix[a] = 0; return this; } public Matrix3f clearToIdentity() { return clear().put(0, 1).put(4, 1).put(8, 1); } public float get(int index) { return matrix[index]; } public float get(int col, int row) { return matrix[col * 3 + row]; } public Matrix3f put(int index, float f) { matrix[index] = f; return this; } public Matrix3f put(int col, int row, float f) { matrix[col * 3 + row] = f; return this; } public Matrix3f putColumn(int index, Vector3f v) { put(index, 0, v.x()); put(index, 1, v.y()); put(index, 2, v.z()); return this; } public Matrix3f set(float[] m) { if (m.length < 9) { throw new IllegalArgumentException("float array must have at least 9 values."); } for (int a = 0; a < m.length && a < 9; a++) { matrix[a] = m[a]; } return this; } public Matrix3f set(Matrix3f m) { for (int a = 0; a < 9; a++) { matrix[a] = m.matrix[a]; } return this; } public Matrix3f set4x4(Matrix4f m) { for (int a = 0; a < 3; a++) { put(a, 0, m.get(a, 0)); put(a, 1, m.get(a, 1)); put(a, 2, m.get(a, 2)); } return this; } public Matrix3f mult(float f) { for (int a = 0; a < 9; a++) put(a, get(a) * f); return this; } public Matrix3f mult(float[] m) { if (m.length < 9) { throw new IllegalArgumentException("float array must have at least 9 values."); } return mult(new Matrix3f(m)); } public Matrix3f mult(Matrix3f m) { Matrix3f temp = new Matrix3f(); for (int a = 0; a < 3; a++) { temp.put(a, 0, get(0) * m.get(a, 0) + get(3) * m.get(a, 1) + get(6) * m.get(a, 2)); temp.put(a, 1, get(1) * m.get(a, 0) + get(4) * m.get(a, 1) + get(7) * m.get(a, 2)); temp.put(a, 2, get(2) * m.get(a, 0) + get(5) * m.get(a, 1) + get(8) * m.get(a, 2)); } set(temp); return this; } public Vector3f mult3(Vector3f vec, Vector3f result) { if (result == null) { result = new Vector3f(); } return result.set(get(0) * vec.x() + get(3) * vec.y() + get(6) * vec.z(), get(1) * vec.x() + get(4) * vec.y() + get(7) * vec.z(), get(2) * vec.x() + get(5) * vec.y() + get(8) * vec.z()); } public Matrix3f transpose() { float old = get(1); put(1, get(3)); put(3, old); old = get(2); put(2, get(6)); put(6, old); old = get(5); put(5, get(7)); put(7, old); return this; } public float determinant() { return +get(0) * get(4) * get(8) + get(3) * get(7) * get(2) + get(6) * get(1) * get(5) - get(2) * get(4) * get(6) - get(5) * get(7) * get(0) - get(8) * get(1) * get(3); } public Matrix3f inverse() { Matrix3f inv = new Matrix3f(); inv.put(0, +(get(4) * get(8) - get(5) * get(7))); inv.put(1, -(get(3) * get(8) - get(5) * get(6))); inv.put(2, +(get(3) * get(7) - get(4) * get(6))); inv.put(3, -(get(1) * get(8) - get(2) * get(7))); inv.put(4, +(get(0) * get(8) - get(2) * get(6))); inv.put(5, -(get(0) * get(7) - get(1) * get(6))); inv.put(6, +(get(1) * get(5) - get(2) * get(4))); inv.put(7, -(get(0) * get(5) - get(2) * get(3))); inv.put(8, +(get(0) * get(4) - get(1) * get(3))); return set(inv.transpose().mult(1 / determinant())); } public void store(FloatBuffer buf) { for (int a = 0; a < 9; a++) { buf.put(matrix[a]); } } }