summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/math
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-07-05 08:27:03 +0200
committerSven Gothel <[email protected]>2014-07-05 08:27:03 +0200
commitbda482e4eee76a5ba2139645682ae64dadacbc6b (patch)
tree51f67d3734276114754bff02bbde2217fc0fb797 /src/jogl/classes/com/jogamp/opengl/math
parentf8f0f051604721bceaee214b8e5218fd47d2eb9e (diff)
Fix FloatUtil.makePerspective(..): The tan(fovy/2) shall be used, not tan(fovy), fix callers; Simplify FloatUtil.makePerspective(..FovHVHalves..)
Fix FloatUtil.makePerspective(..): The tan(fovy/2) shall be used, not tan(fovy), fix callers - This bug didn't hit (yet), since callers already performed the division (degree -> radian) by falsly claiming the passed value is in radian - where it was actually fov/2 in radians. Simplify FloatUtil.makePerspective(..FovHVHalves..) - Due to the fix above, it became pretty clear that the makeFrustum(..) method can be utilized. Simply apply all our tan-half-fov values on zNear.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/math')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java65
-rw-r--r--src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java39
2 files changed, 47 insertions, 57 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
index 3c6a867e6..d2e535eaf 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java
@@ -558,18 +558,18 @@ public final class FloatUtil {
* @param m_offset offset in given array <i>m</i>, i.e. start of the 4x4 matrix
* @param initM if true, given matrix will be initialized w/ identity matrix,
* otherwise only the frustum fields are set.
- * @param fovy angle in radians
+ * @param fovy_rad angle in radians
* @param aspect
* @param zNear
* @param zFar
* @return given matrix for chaining
*/
public static float[] makePerspective(final float[] m, final int m_off, final boolean initM,
- final float fovy, final float aspect, final float zNear, final float zFar) {
- final float top=(float)Math.tan(fovy)*zNear;
- final float bottom=-1.0f*top;
- final float left=aspect*bottom;
- final float right=aspect*top;
+ final float fovy_rad, final float aspect, final float zNear, final float zFar) {
+ final float top = tan(fovy_rad/2f) * zNear; // use tangent of half-fov !
+ final float bottom = -1.0f * top;
+ final float left = aspect * bottom;
+ final float right = aspect * top;
return makeFrustum(m, m_off, initM, left, right, bottom, top, zNear, zFar);
}
@@ -591,53 +591,12 @@ public final class FloatUtil {
*/
public static float[] makePerspective(final float[] m, final int m_offset, final boolean initM,
final FovHVHalves fovhv, final float zNear, final float zFar) {
- if( initM ) {
- // m[m_offset+0+4*0] = 1f;
- m[m_offset+1+4*0] = 0f;
- m[m_offset+2+4*0] = 0f;
- m[m_offset+3+4*0] = 0f;
-
- m[m_offset+0+4*1] = 0f;
- // m[m_offset+1+4*1] = 1f;
- m[m_offset+2+4*1] = 0f;
- m[m_offset+3+4*1] = 0f;
-
- // m[m_offset+0+4*2] = 0f;
- // m[m_offset+1+4*2] = 0f;
- // m[m_offset+2+4*2] = 1f;
- // m[m_offset+3+4*2] = 0f;
-
- m[m_offset+0+4*3] = 0f;
- m[m_offset+1+4*3] = 0f;
- // m[m_offset+2+4*3] = 0f;
- // m[m_offset+3+4*3] = 1f;
- }
-
- final float projScaleX = 2.0f / ( fovhv.left + fovhv.right );
- final float projScaleY = 2.0f / ( fovhv.top + fovhv.bottom );
- final float projOffsetX = ( fovhv.left - fovhv.right ) * projScaleX * 0.5f;
- final float projOffsetY = -1f * ( fovhv.top - fovhv.bottom ) * projScaleY * 0.5f;
-
- // Produces X result, mapping clip edges to [-w,+w]
- m[m_offset+0+4*0] = projScaleX;
- m[m_offset+0+4*2] = -1f * projOffsetX;
-
- // Produces Y result, mapping clip edges to [-w,+w] (Y=up)
- m[m_offset+1+4*1] = projScaleY;
- m[m_offset+1+4*2] = -1f * projOffsetY;
-
- // Custom Z-buffer result .. same as frustum matrix!
- m[m_offset+2+4*2] = -1.0f*(zFar+zNear)/(zFar-zNear);
- m[m_offset+2+4*3] = -2.0f*(zFar*zNear)/(zFar-zNear);
- // alternative:
- // m[m_offset+2+4*2] = -1.0f * zFar / (zNear - zFar);
- // m[m_offset+2+4*3] = (zFar * zNear) / (zNear - zFar);
-
- // Produces W result (= Z in)
- m[m_offset+3+4*2] = -1.0f;
- m[m_offset+3+4*3] = 0f;
-
- return m;
+ final FovHVHalves fovhvTan = fovhv.getInTangents(); // use tangent of half-fov !
+ final float top = fovhvTan.top * zNear;
+ final float bottom = -1.0f * fovhvTan.bottom * zNear;
+ final float left = -1.0f * fovhvTan.left * zNear;
+ final float right = fovhvTan.right * zNear;
+ return makeFrustum(m, m_offset, initM, left, right, bottom, top, zNear, zFar);
}
/**
diff --git a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java b/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java
index 18bba8c45..786d146e6 100644
--- a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java
+++ b/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java
@@ -48,7 +48,10 @@ public final class FovHVHalves {
/**
* Constructor for one {@link FovHVHalves} instance.
- *
+ * <p>
+ * It is recommended to pass and store values in tangent
+ * if used for perspective FOV calculations, since it will avoid conversion to tangent later on.
+ * </p>
* @param left half horizontal FOV, left side, in tangent or radians
* @param right half horizontal FOV, right side, in tangent or radians
* @param top half vertical FOV, top side, in tangent or radians
@@ -73,11 +76,26 @@ public final class FovHVHalves {
* @param verticalFov whole vertical FOV in radians
*/
public static FovHVHalves createByRadians(final float horizontalFov, final float verticalFov) {
- final float halfHorizFovTan = (float)Math.tan(horizontalFov/2f);
- final float halfVertFovTan = (float)Math.tan(verticalFov/2f);
+ final float halfHorizFovTan = FloatUtil.tan(horizontalFov/2f);
+ final float halfVertFovTan = FloatUtil.tan(verticalFov/2f);
return new FovHVHalves(halfHorizFovTan, halfHorizFovTan, halfVertFovTan, halfVertFovTan, true);
}
+ /**
+ * Returns this instance values <i>in tangent</i> values.
+ * <p>
+ * If this instance is {@link #inTangents} already, method returns this instance,
+ * otherwise a newly created instance w/ converted values to tangent.
+ * </p>
+ */
+ public final FovHVHalves getInTangents() {
+ if( inTangents ) {
+ return this;
+ } else {
+ return new FovHVHalves(FloatUtil.tan(left), FloatUtil.tan(right), FloatUtil.tan(top), FloatUtil.tan(bottom), true);
+ }
+ }
+
/** Returns the full horizontal FOV, i.e. {@link #left} + {@link #right}. */
public final float horzFov() { return left+right; }
@@ -85,6 +103,19 @@ public final class FovHVHalves {
public final float vertFov() { return top+bottom; }
public final String toString() {
- return "FovHVHalves["+(inTangents?"tangents":"radians")+": "+left+" l, "+right+" r, "+top+" t, "+bottom+" b]";
+ return "FovHVH["+(inTangents?"tangents":"radians")+": "+left+" l, "+right+" r, "+top+" t, "+bottom+" b]";
+ }
+ public final String toStringInDegrees() {
+ final float f = 180.0f / FloatUtil.PI;
+ final String storedAs = inTangents?"tangents":"radians";
+ if( inTangents ) {
+ final float aleft = FloatUtil.atan(left);
+ final float aright = FloatUtil.atan(right);
+ final float atop = FloatUtil.atan(top);
+ final float abottom = FloatUtil.atan(bottom);
+ return "FovHVH[degrees: "+aleft*f+" l, "+aright*f+" r, "+atop*f+" t, "+abottom*f+" b, stored-as: "+storedAs+"]";
+ } else {
+ return "FovHVH[degrees: "+left*f+" l, "+right*f+" r, "+top*f+" t, "+bottom*f+" b, stored-as: "+storedAs+"]";
+ }
}
}