diff options
author | Sven Gothel <[email protected]> | 2014-03-17 09:22:51 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-03-17 09:22:51 +0100 |
commit | 3595f18c35676ed5e420174acd8f2f8dd75ca3be (patch) | |
tree | 6d37fa18c5cbaa51e2f3a0874efa0056c9af48b2 /src/jogl/classes/com/jogamp/opengl/math | |
parent | 5e728baa72517865d602580b920d9bdfdfb26c65 (diff) |
Quaternion: Add rotateByEuler(..); AABBox: Add translate(..); Minor edits ..
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/math')
4 files changed, 110 insertions, 36 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java index bb40fed33..9d3ee412b 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java @@ -199,6 +199,7 @@ public class FloatUtil { } /** + * Multiply matrix: [d] = [a] x [b] * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order * @param d result a*b in column-major order @@ -215,6 +216,7 @@ public class FloatUtil { } /** + * Multiply matrix: [a] = [a] x [b] * @param a 4x4 matrix in column-major order (also result) * @param b 4x4 matrix in column-major order */ @@ -231,6 +233,7 @@ public class FloatUtil { } /** + * Multiply matrix: [d] = [a] x [b] * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order * @param d result a*b in column-major order @@ -248,6 +251,7 @@ public class FloatUtil { } /** + * Multiply matrix: [d] = [a] x [b] * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order * @param d result a*b in column-major order @@ -266,6 +270,7 @@ public class FloatUtil { } /** + * Multiply matrix: [a] = [a] x [b] * @param a 4x4 matrix in column-major order (also result) * @param b 4x4 matrix in column-major order */ @@ -283,6 +288,7 @@ public class FloatUtil { } /** + * Multiply matrix: [d] = [a] x [b] * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order * @param d result a*b in column-major order @@ -302,6 +308,7 @@ public class FloatUtil { } /** + * Multiply matrix: [a] = [a] x [b] * @param a 4x4 matrix in column-major order (also result) * @param b 4x4 matrix in column-major order */ @@ -320,6 +327,7 @@ public class FloatUtil { } /** + * Multiply matrix: [d] = [a] x [b] * @param a 4x4 matrix in column-major order * @param b 4x4 matrix in column-major order * @param d result a*b in column-major order diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java index e2b23544a..cc2a3a1cc 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java +++ b/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java @@ -185,10 +185,11 @@ public class Quaternion { if ( FloatUtil.isZero(norm, FloatUtil.EPSILON) ) { setIdentity(); } else { - w /= norm; - x /= norm; - y /= norm; - z /= norm; + final float invNorm = 1f/norm; + w *= invNorm; + x *= invNorm; + y *= invNorm; + z *= invNorm; } return this; } @@ -221,10 +222,11 @@ public class Quaternion { if ( FloatUtil.isEqual(1.0f, magnitudeSQ, FloatUtil.EPSILON) ) { conjugate(); } else { - w /= magnitudeSQ; - x = -x / magnitudeSQ; - y = -y / magnitudeSQ; - z = -z / magnitudeSQ; + final float invmsq = 1f/magnitudeSQ; + w *= invmsq; + x = -x * invmsq; + y = -y * invmsq; + z = -z * invmsq; } return this; } @@ -393,6 +395,61 @@ public class Quaternion { -z * sin + w * cos); } + /** + * Rotates this quaternion from the given Euler rotation array <code>angradXYZ</code> in radians. + * <p> + * The <code>angradXYZ</code> array is laid out in natural order: + * <ul> + * <li>x - bank</li> + * <li>y - heading</li> + * <li>z - attitude</li> + * </ul> + * </p> + * For details see {@link #rotateByEuler(float, float, float)}. + * @param angradXYZ euler angel array in radians + * @return this quaternion for chaining. + * @see #rotateByEuler(float, float, float) + */ + public final Quaternion rotateByEuler(final float[] angradXYZ) { + return rotateByEuler(angradXYZ[0], angradXYZ[1], angradXYZ[2]); + } + + /** + * Rotates this quaternion from the given Euler rotation angles in radians. + * <p> + * The rotations are applied in the given order and using chained rotation per axis: + * <ul> + * <li>y - heading - {@link #rotateByAngleY(float)}</li> + * <li>z - attitude - {@link #rotateByAngleZ(float)}</li> + * <li>x - bank - {@link #rotateByAngleX(float)}</li> + * </ul> + * </p> + * <p> + * Implementation Details: + * <ul> + * <li> {@link #setIdentity()} if all angles are {@link FloatUtil#isZero(float, float) is zero} using {@link FloatUtil#EPSILON epsilon}</li> + * <li> result is {@link #normalize()}ed</li> + * </ul> + * </p> + * @param bankX the Euler pitch angle in radians. (rotation about the X axis) + * @param headingY the Euler yaw angle in radians. (rotation about the Y axis) + * @param attitudeZ the Euler roll angle in radians. (rotation about the Z axis) + * @return this quaternion for chaining. + * @see #rotateByAngleY(float) + * @see #rotateByAngleZ(float) + * @see #rotateByAngleX(float) + * @see #setFromEuler(float, float, float) + */ + public final Quaternion rotateByEuler(final float bankX, final float headingY, float attitudeZ) { + if ( VectorUtil.isZero(bankX, headingY, attitudeZ, FloatUtil.EPSILON) ) { + return setIdentity(); + } else { + // setFromEuler muls: ( 8 + 4 ) , + quat muls 24 = 36 + // this: 8 + 8 + 8 + 4 = 28 muls + return rotateByAngleY(headingY).rotateByAngleZ(attitudeZ).rotateByAngleX(bankX).normalize(); + } + } + /*** * Rotate the given vector by this quaternion * @@ -525,7 +582,11 @@ public class Quaternion { * Implementation generates a 3x3 matrix * and is equal with ProjectFloat's lookAt(..).<br/> * </p> - * + * Implementation Details: + * <ul> + * <li> result is {@link #normalize()}ed</li> + * </ul> + * </p> * @param directionIn where to <i>look</i> at * @param upIn a vector indicating the local <i>up</i> direction. * @param xAxisOut vector storing the <i>orthogonal</i> x-axis of the coordinate system. @@ -764,27 +825,10 @@ public class Quaternion { * <li>z - attitude</li> * </ul> * </p> - * <p> - * The rotations are applied in the given order: - * <ul> - * <li>y - heading</li> - * <li>z - attitude</li> - * <li>x - bank</li> - * </ul> - * </p> - * <p> - * Implementation Details: - * <ul> - * <li> {@link #setIdentity()} if all angles are {@link FloatUtil#isZero(float, float) is zero} using {@link FloatUtil#EPSILON epsilon}</li> - * </ul> - * </p> + * For details see {@link #setFromEuler(float, float, float)}. * @param angradXYZ euler angel array in radians * @return this quaternion for chaining. - * @see <a href="http://web.archive.org/web/20041029003853/http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q60">Matrix-FAQ Q60</a> - * @see <a href="http://vered.rose.utoronto.ca/people/david_dir/GEMS/GEMS.html">Gems</a> - * @see <a href="http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm">euclideanspace.com-eulerToQuaternion</a> * @see #setFromEuler(float, float, float) - * @see #toEuler(float[]) */ public final Quaternion setFromEuler(final float[] angradXYZ) { return setFromEuler(angradXYZ[0], angradXYZ[1], angradXYZ[2]); @@ -804,6 +848,7 @@ public class Quaternion { * Implementation Details: * <ul> * <li> {@link #setIdentity()} if all angles are {@link FloatUtil#isZero(float, float) is zero} using {@link FloatUtil#EPSILON epsilon}</li> + * <li> result is {@link #normalize()}ed</li> * </ul> * </p> * @param bankX the Euler pitch angle in radians. (rotation about the X axis) @@ -1113,14 +1158,22 @@ public class Quaternion { * @return the result column-vector for chaining. */ public float[] copyMatrixColumn(final int index, final float[] result, final int resultOffset) { + // pre-multipliy scaled-reciprocal-magnitude to reduce multiplications final float norm = magnitudeSquared(); - final float s = norm == 1.0f ? 2.0f : norm > 0.0f ? 2.0f / norm : 0f; + final float srecip; + if ( FloatUtil.isZero(norm, FloatUtil.EPSILON) ) { + srecip= 0f; + } else if ( FloatUtil.isEqual(1f, norm, FloatUtil.EPSILON) ) { + srecip= 2f; + } else { + srecip= 2.0f / norm; + } // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs // will be used 2-4 times each. - final float xs = x * s; - final float ys = y * s; - final float zs = z * s; + final float xs = x * srecip; + final float ys = y * srecip; + final float zs = z * srecip; final float xx = x * xs; final float xy = x * ys; final float xz = x * zs; @@ -1207,10 +1260,10 @@ public class Quaternion { return false; if (FloatUtil.abs(m[2] * m[2] + m[5] * m[5] + m[8] * m[8] - 1) > epsilon) return false; - return (FloatUtil.abs(determinant4f(m) - 1) < epsilon); + return (FloatUtil.abs(determinant3f(m) - 1) < epsilon); } - private final float determinant4f(float[] m) { + private final float determinant3f(float[] m) { return m[0] * m[4] * m[8] + m[3] * m[7] * m[2] + m[6] * m[1] * m[5] - m[0] * m[7] * m[5] - m[3] * m[1] * m[8] - m[6] * m[4] * m[2]; } diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java index 3aaed2032..9c6da7e24 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java @@ -31,6 +31,9 @@ import java.util.ArrayList; public class VectorUtil { + public static final float[] VEC3_ONE = { 1f, 1f, 1f }; + public static final float[] VEC3_ZERO = { 0f, 0f, 0f }; + public enum Winding { CW(-1), CCW(1); diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java index 8a18ea4c4..7ab02ba64 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java +++ b/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java @@ -121,9 +121,9 @@ public class AABBox implements Cloneable { } private final void computeCenter() { - center[0] = (high[0] + low[0])/2; - center[1] = (high[1] + low[1])/2; - center[2] = (high[2] + low[2])/2; + center[0] = (high[0] + low[0])/2f; + center[1] = (high[1] + low[1])/2f; + center[2] = (high[2] + low[2])/2f; } /** @@ -410,6 +410,16 @@ public class AABBox implements Cloneable { VectorUtil.addVec3(low, center, tmpV3); } + /** + * Translate the AABBox by a float[3] vector + * @param t the float[3] translation vector + */ + public final void translate(final float[] t) { + VectorUtil.addVec3(low, low, t); // in-place translate + VectorUtil.addVec3(high, high, t); // in-place translate + computeCenter(); + } + public final float getMinX() { return low[0]; } |