/* * Copyright (C) 2013 Google Inc. * * 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 interactivespaces.util.geometry; import java.util.List; /** * A 3D transform. * * @author Keith M. Hughes */ public class Transform3 { /** * The X axis. */ private static final Vector3 X_AXIS = Vector3.newXAxis(); /** * The Y axis. */ private static final Vector3 Y_AXIS = Vector3.newYAxis(); /** * The Z axis. */ private static final Vector3 Z_AXIS = Vector3.newZAxis(); /** * The transform matrix. */ private final Matrix4 transform; /** * A temporary matrix for composing transforms. */ private final Matrix4 temp; /** * Construct the transform currently as an identity transform. */ public Transform3() { transform = new Matrix4().identity(); temp = new Matrix4(); } /** * Transform the given vector according to the current transform. * * @param v * the given vector * * @return a newly constructed vector transformed */ public Vector3 transform(Vector3 v) { return v.multiply(transform); } /** * Transform the given vector according to the current transform. * * @param v * the given vector * * @return the given vector with its coordinates transformed */ public Vector3 transformSelf(Vector3 v) { return v.multiplySelf(transform); } /** * Transform the given list of vectors according to the current transform. * * <p> * The original list of the original vectors is returned with just a new set * of coordinates in the vectors. * * @param vectors * the given vectors * * @return this transform */ public Transform3 transformSelf(List<Vector3> vectors) { for (Vector3 v : vectors) { transformSelf(v); } return this; } /** * Reset the transform to an identify transform. * * @return this transform */ public Transform3 reset() { identity(); return this; } /** * Multiply the transform by the supplied matrix. * * @param m * the supplied matrix * * @return this transform */ public Transform3 multiply(Matrix4 m) { transform.multiplySelf(m); return this; } /** * Set the transform to the supplied matrix. * * @param m * the supplied matrix * * @return this transform */ public Transform3 set(Matrix4 m) { transform.set(m); return this; } /** * Get the current transform matrix. * * @return the current transform matrix */ public Matrix4 get() { return transform; } /** * Make the current transform the identity transform. * * @return this transform */ public Transform3 identity() { transform.identity(); return this; } /** * Translate by a given set of coordinates. * * @param tx * the amount along the x axis * @param ty * the amount along the y axis * @param tz * the amount along the z axis * * @return this transform */ public Transform3 translate(double tx, double ty, double tz) { temp.identity().setEntry(0, 3, tx).setEntry(1, 3, ty).setEntry(2, 3, tz); return multiply(temp); } /** * Scale the current transform by each of the following scales. * * @param sx * the scale in x * @param sy * the scale in y * @param sz * the scale in z * * @return this transform */ public Transform3 scale(double sx, double sy, double sz) { temp.identity().setEntry(0, 0, sx).setEntry(1, 1, sy).setEntry(2, 2, sz); return multiply(temp); } /** * Scale the transform by the corresponding components of the vector. * * @param s * the scaling vector * * @return this transform */ public Transform3 scale(Vector3 s) { return scale(s.getV0(), s.getV1(), s.getV2()); } /** * Translate the current transform by the scaled vector. * * @param v * the base vector for the translation * @param scale * the factor by which the vector will be scaled * * @return this transform */ public Transform3 translate(Vector3 v, double scale) { return translate(scale * v.getV0(), scale * v.getV1(), scale * v.getV2()); } /** * Translate the transform by the supplied vector. * * @param v * the vector by which to translate * * @return this transform */ public Transform3 translate(Vector3 v) { return translate(v.getV0(), v.getV1(), v.getV2()); } /** * Rotate the transform around a given axis by a given angle. * * @param axis * the rotation axis * @param angle * the angle in radians * * @return this transform */ public Transform3 rotate(Vector3 axis, double angle) { Vector3 rotationAxis = axis.normalize(); Quaternion q = new Quaternion(rotationAxis, angle); temp.set(q); return multiply(temp); } /** * Rotate the transform by the given quaternion. * * @param q * the quaternion * * @return this transform */ public Transform3 rotate(Quaternion q) { temp.set(q); return multiply(temp); } /** * Rotate the transformation around the X axis by a given angle. * * @param angle * the rotation angle in radians * * @return the current transform */ public Transform3 rotateX(double angle) { return rotate(X_AXIS, angle); } /** * Rotate the transformation around the Y axis by a given angle. * * @param angle * the rotation angle in radians * * @return the current transform */ public Transform3 rotateY(double angle) { return rotate(Y_AXIS, angle); } /** * Rotate the transformation around the Z axis by a given angle. * * @param angle * the rotation angle in radians * * @return the current transform */ public Transform3 rotateZ(double angle) { return rotate(Z_AXIS, angle); } }