/**
* Copyright 2012 Jason Sorensen (sorensenj@smert.net)
*
* 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 net.smert.frameworkgl.math;
import java.nio.FloatBuffer;
import java.util.Objects;
/**
*
* @author Jason Sorensen <sorensenj@smert.net>
*/
public class Transform4f {
final Matrix3f rotation = new Matrix3f();
final Vector3f position = new Vector3f();
// Constructors
public Transform4f() {
rotation.identity();
}
public Transform4f(Matrix3f matrix, Vector3f vector) {
set(matrix, vector);
}
public Transform4f(Transform4f transform) {
set(transform.rotation, transform.position);
}
// Conversion Operations
public void fromColumnArray(float[] in) {
rotation.xAxis.x = in[0];
rotation.xAxis.y = in[1];
rotation.xAxis.z = in[2];
rotation.yAxis.x = in[3];
rotation.yAxis.y = in[4];
rotation.yAxis.z = in[5];
rotation.zAxis.x = in[6];
rotation.zAxis.y = in[7];
rotation.zAxis.z = in[8];
position.x = in[9];
position.y = in[10];
position.z = in[11];
}
public void fromOpenGLArray(float[] in) {
rotation.xAxis.x = in[0];
rotation.xAxis.y = in[1];
rotation.xAxis.z = in[2];
rotation.yAxis.x = in[4];
rotation.yAxis.y = in[5];
rotation.yAxis.z = in[6];
rotation.zAxis.x = in[8];
rotation.zAxis.y = in[9];
rotation.zAxis.z = in[10];
position.x = in[12];
position.y = in[13];
position.z = in[14];
}
public void fromRowArray(float[] in) {
rotation.xAxis.x = in[0];
rotation.yAxis.x = in[1];
rotation.zAxis.x = in[2];
rotation.xAxis.y = in[3];
rotation.yAxis.y = in[4];
rotation.zAxis.y = in[5];
rotation.xAxis.z = in[6];
rotation.yAxis.z = in[7];
rotation.zAxis.z = in[8];
position.x = in[9];
position.y = in[10];
position.z = in[11];
}
public void toFloatBuffer(FloatBuffer fbOut) {
fbOut.put(rotation.xAxis.x);
fbOut.put(rotation.xAxis.y);
fbOut.put(rotation.xAxis.z);
fbOut.put(0f);
fbOut.put(rotation.yAxis.x);
fbOut.put(rotation.yAxis.y);
fbOut.put(rotation.yAxis.z);
fbOut.put(0f);
fbOut.put(rotation.zAxis.x);
fbOut.put(rotation.zAxis.y);
fbOut.put(rotation.zAxis.z);
fbOut.put(0f);
fbOut.put(position.x);
fbOut.put(position.y);
fbOut.put(position.z);
fbOut.put(1f);
}
public void toColumnArray(float[] out) {
out[0] = rotation.xAxis.x;
out[1] = rotation.xAxis.y;
out[2] = rotation.xAxis.z;
out[3] = rotation.yAxis.x;
out[4] = rotation.yAxis.y;
out[5] = rotation.yAxis.z;
out[6] = rotation.zAxis.x;
out[7] = rotation.zAxis.y;
out[8] = rotation.zAxis.z;
out[9] = position.x;
out[10] = position.y;
out[11] = position.z;
}
public void toOpenGLArray(float[] out) {
out[0] = rotation.xAxis.x;
out[1] = rotation.xAxis.y;
out[2] = rotation.xAxis.z;
out[3] = 0f;
out[4] = rotation.yAxis.x;
out[5] = rotation.yAxis.y;
out[6] = rotation.yAxis.z;
out[7] = 0f;
out[8] = rotation.zAxis.x;
out[9] = rotation.zAxis.y;
out[10] = rotation.zAxis.z;
out[11] = 0f;
out[12] = position.x;
out[13] = position.y;
out[14] = position.z;
out[15] = 1f;
}
public void toRowArray(float[] out) {
out[0] = rotation.xAxis.x;
out[1] = rotation.yAxis.x;
out[2] = rotation.zAxis.x;
out[3] = rotation.xAxis.y;
out[4] = rotation.yAxis.y;
out[5] = rotation.zAxis.y;
out[6] = rotation.xAxis.z;
out[7] = rotation.yAxis.z;
out[8] = rotation.zAxis.z;
out[9] = position.x;
out[10] = position.y;
out[11] = position.z;
}
// Matrix Operations
public Matrix3f getRotation() {
return rotation;
}
// Transform Operations
public Transform4f fromAxisAngle(Vector3f vector, float degrees) {
rotation.fromAxisAngle(vector, degrees);
return this;
}
public Transform4f multiply(Transform4f transform) {
position.set(
rotation.dotRow(0, transform.position) + position.x,
rotation.dotRow(1, transform.position) + position.y,
rotation.dotRow(2, transform.position) + position.z);
rotation.multiply(transform.rotation);
return this;
}
public Transform4f multiplyTranspose(Transform4f transform) {
position.set(
transform.position.x - position.x,
transform.position.y - position.y,
transform.position.z - position.z);
rotation.multiplyTransposeOut(position, position);
rotation.multiplyTranspose(transform.rotation);
return this;
}
public Transform4f set(Transform4f transform) {
rotation.set(transform.rotation);
position.set(transform.position);
return this;
}
public final Transform4f set(Matrix3f rotation, Vector3f position) {
this.rotation.set(rotation);
this.position.set(position);
return this;
}
public Transform4f setScale(float radius) {
rotation.setDiagonal(radius);
return this;
}
public Transform4f setScale(float x, float y, float z) {
rotation.setDiagonal(x, y, z);
return this;
}
public Transform4f setPosition(float x, float y, float z) {
this.position.set(x, y, z);
return this;
}
public Transform4f setPosition(Vector3f position) {
this.position.set(position);
return this;
}
public Transform4f setRotation(Matrix3f rotation) {
this.rotation.set(rotation);
return this;
}
public Transform4f setRotation(Quaternion4f quaternion) {
quaternion.toMatrix3(rotation);
return this;
}
// Vector Operations
public Vector3f getAxis(int axis) {
switch (axis) {
case 3:
return position;
default:
return rotation.getAxis(axis);
}
}
public Vector3f getPosition() {
return position;
}
public Vector3f multiplyOut(Vector3f vector, Vector3f out) {
rotation.multiplyOut(vector, out);
out.add(position);
return out;
}
public Vector3f multiplyTransposeOut(Vector3f vector, Vector3f out) {
out.set(vector).subtract(position);
rotation.multiplyTransposeOut(out, out);
return out;
}
@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + Objects.hashCode(this.rotation);
hash = 59 * hash + Objects.hashCode(this.position);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Transform4f other = (Transform4f) obj;
if (!Objects.equals(this.rotation, other.rotation)) {
return false;
}
return Objects.equals(this.position, other.position);
}
@Override
public String toString() {
return "(position: " + position + " rotation: " + rotation + ")";
}
}