diff options
Diffstat (limited to 'src/jogl/classes/com/jogamp')
57 files changed, 2506 insertions, 1365 deletions
diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java index 644f428cd..2da0f6850 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java @@ -36,14 +36,14 @@ import com.jogamp.graph.curve.tess.Triangulator; import com.jogamp.graph.geom.Outline; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.plane.AffineTransform; -import com.jogamp.graph.geom.plane.Path2F; -import com.jogamp.graph.geom.plane.Winding; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.math.VectorUtil; -import com.jogamp.opengl.math.Vert2fImmutable; -import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.Vec3f; +import com.jogamp.math.VectorUtil; +import com.jogamp.math.Vert2fImmutable; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.plane.AffineTransform; +import com.jogamp.math.geom.plane.Path2F; +import com.jogamp.math.geom.plane.Winding; /** * A Generic shape objects which is defined by a list of Outlines. @@ -671,7 +671,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @param y point (P1) * @param z point (P1) * @see Path2F#moveTo(float, float) - * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean) + * @see #addPath(com.jogamp.math.geom.plane.Path2F.Iterator, boolean) * @see <a href="#windingrules">see winding rules</a> */ public final void moveTo(final float x, final float y, final float z) { @@ -691,7 +691,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @param y final point (P1) * @param z final point (P1) * @see Path2F#lineTo(float, float) - * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean) + * @see #addPath(com.jogamp.math.geom.plane.Path2F.Iterator, boolean) * @see <a href="#windingrules">see winding rules</a> */ public final void lineTo(final float x, final float y, final float z) { @@ -708,7 +708,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @param y2 final interpolated control point (P2) * @param z2 quadratic parametric control point (P2) * @see Path2F#quadTo(float, float, float, float) - * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean) + * @see #addPath(com.jogamp.math.geom.plane.Path2F.Iterator, boolean) * @see <a href="#windingrules">see winding rules</a> */ public final void quadTo(final float x1, final float y1, final float z1, final float x2, final float y2, final float z2) { @@ -729,7 +729,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { * @param y3 final interpolated control point (P3) * @param z3 final interpolated control point (P3) * @see Path2F#cubicTo(float, float, float, float, float, float) - * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean) + * @see #addPath(com.jogamp.math.geom.plane.Path2F.Iterator, boolean) * @see <a href="#windingrules">see winding rules</a> */ public final void cubicTo(final float x1, final float y1, final float z1, final float x2, final float y2, final float z2, final float x3, final float y3, final float z3) { @@ -741,7 +741,7 @@ public final class OutlineShape implements Comparable<OutlineShape> { /** * Closes the current sub-path segment by drawing a straight line back to the coordinates of the last moveTo. If the path is already closed then this method has no effect. * @see Path2F#closePath() - * @see #addPath(com.jogamp.graph.geom.plane.Path2F.Iterator, boolean) + * @see #addPath(com.jogamp.math.geom.plane.Path2F.Iterator, boolean) */ public final void closePath() { if ( 0 < getLastOutline().getVertexCount() ) { diff --git a/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java b/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java index 1a21ea74f..c8d9223af 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java +++ b/src/jogl/classes/com/jogamp/graph/curve/OutlineShapeXForm.java @@ -1,6 +1,6 @@ package com.jogamp.graph.curve; -import com.jogamp.graph.geom.plane.AffineTransform; +import com.jogamp.math.geom.plane.AffineTransform; public class OutlineShapeXForm { public final OutlineShape shape; diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java index 66ef3da6e..93b05aefa 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/Region.java +++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java @@ -40,17 +40,17 @@ import jogamp.opengl.Debug; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; -import com.jogamp.graph.geom.plane.AffineTransform; +import com.jogamp.math.Vec3f; +import com.jogamp.math.Vec4f; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.Frustum; +import com.jogamp.math.geom.plane.AffineTransform; import com.jogamp.common.nio.Buffers; import com.jogamp.common.os.Clock; import com.jogamp.common.util.PerfCounterCtrl; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.opengl.GLCapabilitiesImmutable; import com.jogamp.opengl.GLProfile; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.math.Vec4f; -import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.math.geom.Frustum; import com.jogamp.opengl.util.texture.TextureSequence; /** diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java index d25ab4311..47f8e1b2a 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java @@ -35,8 +35,6 @@ import com.jogamp.opengl.util.GLArrayDataEditable; import com.jogamp.opengl.util.GLArrayDataServer;
import com.jogamp.opengl.util.GLArrayDataWrapper;
import com.jogamp.opengl.GLProfile;
-import com.jogamp.opengl.math.Vec3f;
-import com.jogamp.opengl.math.Vec4f;
import jogamp.graph.curve.opengl.VBORegion2PMSAAES2;
import jogamp.graph.curve.opengl.VBORegion2PVBAAES2;
@@ -44,11 +42,12 @@ import jogamp.graph.curve.opengl.VBORegionSPES2; import jogamp.graph.curve.opengl.shader.AttributeNames;
import jogamp.opengl.Debug;
-import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.texture.TextureSequence;
import com.jogamp.graph.curve.Region;
import com.jogamp.graph.font.Font;
+import com.jogamp.math.Vec3f;
+import com.jogamp.math.Vec4f;
import java.io.PrintStream;
import java.nio.FloatBuffer;
@@ -508,7 +507,7 @@ public abstract class GLRegion extends Region { * {@link RegionRenderer#create(Vertex.Factory<? extends Vertex>, RenderState, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback, com.jogamp.graph.curve.opengl.RegionRenderer.GLCallback) created}
* with the appropriate {@link RegionRenderer.GLCallback callbacks}.
* </p>
- * @param matrix current {@link PMVMatrix}.
+ * @param gl current {@link GL2ES2}.
* @param renderer the {@link RegionRenderer} to be used
* @param sampleCount desired multisampling sample count for vbaa- or msaa-rendering.
* Use -1 for glSelect mode, pass1 w/o any color texture nor channel, use static select color only.
diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java index 6fbedf809..7e3a7ff30 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java @@ -34,9 +34,6 @@ import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLES2; import com.jogamp.opengl.GLException; -import com.jogamp.opengl.fixedfunc.GLMatrixFunc; -import com.jogamp.opengl.math.Recti; -import com.jogamp.opengl.math.Vec4f; import jogamp.graph.curve.opengl.shader.AttributeNames; import jogamp.graph.curve.opengl.shader.UniformNames; @@ -46,10 +43,12 @@ import com.jogamp.opengl.GLRendererQuirks; import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; import com.jogamp.opengl.util.texture.TextureSequence; -import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.common.os.Platform; import com.jogamp.common.util.IntObjectHashMap; import com.jogamp.graph.curve.Region; +import com.jogamp.math.Recti; +import com.jogamp.math.Vec4f; +import com.jogamp.math.util.PMVMatrix4f; /** * OpenGL {@link Region} renderer @@ -177,7 +176,7 @@ public final class RegionRenderer { * For example, instances {@link #defaultBlendEnable} and {@link #defaultBlendDisable} * can be utilized to enable and disable {@link GL#GL_BLEND}. * </p> - * @param sharedPMVMatrix optional shared {@link PMVMatrix} to be used for the {@link RenderState} composition. + * @param sharedPMVMatrix optional shared {@link PMVMatrix4f} to be used for the {@link RenderState} composition. * @param enableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at * {@link #init(GL2ES2) init(gl)} and {@link #enable(GL2ES2, boolean) enable(gl, true)}. * @param disableCallback optional {@link GLCallback}, if not <code>null</code> will be issued at @@ -185,7 +184,7 @@ public final class RegionRenderer { * @return an instance of Region Renderer * @see #enable(GL2ES2, boolean) */ - public static RegionRenderer create(final PMVMatrix sharedPMVMatrix, + public static RegionRenderer create(final PMVMatrix4f sharedPMVMatrix, final GLCallback enableCallback, final GLCallback disableCallback) { return new RegionRenderer(sharedPMVMatrix, enableCallback, disableCallback); } @@ -221,7 +220,7 @@ public final class RegionRenderer { this(null, enableCallback, disableCallback); } - protected RegionRenderer(final PMVMatrix sharedPMVMatrix, + protected RegionRenderer(final PMVMatrix4f sharedPMVMatrix, final GLCallback enableCallback, final GLCallback disableCallback) { this.rs = new RenderState(sharedPMVMatrix); @@ -290,8 +289,8 @@ public final class RegionRenderer { // RenderState forwards // - /** Borrow the current {@link PMVMatrix}. */ - public final PMVMatrix getMatrix() { return rs.getMatrix(); } + /** Borrow the current {@link PMVMatrix4f}. */ + public final PMVMatrix4f getMatrix() { return rs.getMatrix(); } public final float getWeight() { return rs.getWeight(); } @@ -357,7 +356,7 @@ public final class RegionRenderer { } /** - * No PMVMatrix operation is performed here. + * No PMVMatrix4f operation is performed here. */ public final void reshapeNotify(final int x, final int y, final int width, final int height) { viewport.set(x, y, width, height); @@ -374,10 +373,9 @@ public final class RegionRenderer { public final void reshapePerspective(final float angle_rad, final int width, final int height, final float near, final float far) { reshapeNotify(0, 0, width, height); final float ratio = (float)width/(float)height; - final PMVMatrix p = getMatrix(); - p.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - p.glLoadIdentity(); - p.gluPerspective(angle_rad, ratio, near, far); + final PMVMatrix4f p = getMatrix(); + p.loadPIdentity(); + p.perspectiveP(angle_rad, ratio, near, far); } /** @@ -389,10 +387,9 @@ public final class RegionRenderer { */ public final void reshapeOrtho(final int width, final int height, final float near, final float far) { reshapeNotify(0, 0, width, height); - final PMVMatrix p = getMatrix(); - p.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - p.glLoadIdentity(); - p.glOrthof(0, width, 0, height, near, far); + final PMVMatrix4f p = getMatrix(); + p.loadPIdentity(); + p.orthoP(0, width, 0, height, near, far); } // diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java index f2e1c8066..b1bbdde91 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/RenderState.java @@ -33,20 +33,20 @@ import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLUniformData; -import com.jogamp.opengl.math.Vec4f; import jogamp.common.os.PlatformPropsImpl; import jogamp.graph.curve.opengl.shader.UniformNames; import com.jogamp.graph.curve.Region; +import com.jogamp.math.Vec4f; +import com.jogamp.math.util.PMVMatrix4f; import com.jogamp.opengl.util.GLArrayDataWrapper; -import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.glsl.ShaderProgram; /** * The RenderState is owned by {@link RegionRenderer}. * - * It holds rendering state data like {@link PMVMatrix}, viewport, + * It holds rendering state data like {@link PMVMatrix4f}, viewport, * but also the current {@link #getColorStatic(float[]) static color}. */ public class RenderState { @@ -91,7 +91,7 @@ public class RenderState { return (RenderState) gl.getContext().getAttachedObject(thisKey); } - private final PMVMatrix pmvMatrix; + private final PMVMatrix4f pmvMatrix; private final float[] weight; private final FloatBuffer weightBuffer; private final float[] colorStatic; @@ -140,7 +140,7 @@ public class RenderState { public final boolean update(final GL2ES2 gl, final RenderState rs, final boolean updateLocation, final int renderModes, final boolean pass1, final boolean throwOnError) { if( rs.id() != rsId ) { // Assignment of Renderstate buffers to uniforms (no copy, direct reference) - gcu_PMVMatrix01.setData(rs.pmvMatrix.getSyncPMvMat()); + gcu_PMVMatrix01.setData(rs.pmvMatrix.getSyncPMv()); gcu_Weight.setData(rs.weightBuffer); gcu_ColorStatic.setData(rs.colorStaticBuffer); rsId = rs.id(); @@ -185,12 +185,12 @@ public class RenderState { /** * Create a RenderState, a composition of RegionRenderer - * @param sharedPMVMatrix optional shared PMVMatrix, if null using a local instance + * @param sharedPMVMatrix optional shared PMVMatrix4f, if null using a local instance */ - /* pp */ RenderState(final PMVMatrix sharedPMVMatrix) { + /* pp */ RenderState(final PMVMatrix4f sharedPMVMatrix) { this.id = getNextID(); this.sp = null; - this.pmvMatrix = null != sharedPMVMatrix ? sharedPMVMatrix : new PMVMatrix(); + this.pmvMatrix = null != sharedPMVMatrix ? sharedPMVMatrix : new PMVMatrix4f(); this.weight = new float[1]; this.weightBuffer = FloatBuffer.wrap(weight); this.colorStatic = new float[] { 1, 1, 1, 1 }; @@ -229,7 +229,8 @@ public class RenderState { return true; } - public final PMVMatrix getMatrix() { return pmvMatrix; } + /** Borrow the current {@link PMVMatrix4f}. */ + public final PMVMatrix4f getMatrix() { return pmvMatrix; } public static boolean isWeightValid(final float v) { return 0.0f <= v && v <= 1.9f ; diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index 0090480bb..782615c3e 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -33,13 +33,13 @@ import java.util.Iterator; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GLException; -import com.jogamp.opengl.math.Vec4f; -import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; import com.jogamp.graph.font.Font; import com.jogamp.graph.font.Font.Glyph; -import com.jogamp.graph.geom.plane.AffineTransform; +import com.jogamp.math.Vec4f; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.plane.AffineTransform; /** * Text Type Rendering Utility Class adding the {@link Font.Glyph}s {@link OutlineShape} to a {@link GLRegion}. diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java index c3c997135..997eacbb8 100644 --- a/src/jogl/classes/com/jogamp/graph/font/Font.java +++ b/src/jogl/classes/com/jogamp/graph/font/Font.java @@ -28,8 +28,8 @@ package com.jogamp.graph.font; import com.jogamp.graph.curve.OutlineShape; -import com.jogamp.graph.geom.plane.AffineTransform; -import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.plane.AffineTransform; /** * Interface wrapper for font implementation. diff --git a/src/jogl/classes/com/jogamp/graph/geom/Outline.java b/src/jogl/classes/com/jogamp/graph/geom/Outline.java index 654bd2636..272f92f37 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Outline.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Outline.java @@ -29,13 +29,13 @@ package com.jogamp.graph.geom; import java.util.ArrayList; -import com.jogamp.graph.geom.plane.AffineTransform; -import com.jogamp.graph.geom.plane.Winding; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.VectorUtil; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.plane.AffineTransform; +import com.jogamp.math.geom.plane.Winding; import com.jogamp.graph.curve.OutlineShape; import com.jogamp.graph.curve.Region; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.VectorUtil; -import com.jogamp.opengl.math.geom.AABBox; diff --git a/src/jogl/classes/com/jogamp/graph/geom/Triangle.java b/src/jogl/classes/com/jogamp/graph/geom/Triangle.java index 6b07501a6..e26d2aaf1 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Triangle.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Triangle.java @@ -27,8 +27,8 @@ */ package com.jogamp.graph.geom; -import com.jogamp.graph.geom.plane.AffineTransform; -import com.jogamp.opengl.math.VectorUtil; +import com.jogamp.math.VectorUtil; +import com.jogamp.math.geom.plane.AffineTransform; public class Triangle { private final Vertex[] vertices = new Vertex[3]; diff --git a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java index e5fe76c28..8744474d9 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/Vertex.java +++ b/src/jogl/classes/com/jogamp/graph/geom/Vertex.java @@ -27,9 +27,9 @@ */ package com.jogamp.graph.geom; -import com.jogamp.opengl.math.Vec2f; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.math.Vert3fImmutable; +import com.jogamp.math.Vec2f; +import com.jogamp.math.Vec3f; +import com.jogamp.math.Vert3fImmutable; /** * A Vertex exposing Vec3f vertex- and texture-coordinates. diff --git a/src/jogl/classes/com/jogamp/opengl/math/Binary16.java b/src/jogl/classes/com/jogamp/math/Binary16.java index 8e4aa9176..725c608c6 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Binary16.java +++ b/src/jogl/classes/com/jogamp/math/Binary16.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * <p> diff --git a/src/jogl/classes/com/jogamp/opengl/math/Binary32.java b/src/jogl/classes/com/jogamp/math/Binary32.java index 599b1ff68..398f97c3a 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Binary32.java +++ b/src/jogl/classes/com/jogamp/math/Binary32.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * Functions for interrogating <code>binary32</code> (float) values. diff --git a/src/jogl/classes/com/jogamp/opengl/math/Binary64.java b/src/jogl/classes/com/jogamp/math/Binary64.java index d4ec636a5..8561cfa8d 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Binary64.java +++ b/src/jogl/classes/com/jogamp/math/Binary64.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * Functions for interrogating <code>binary64</code> (double) values. diff --git a/src/jogl/classes/com/jogamp/math/DoubleUtil.java b/src/jogl/classes/com/jogamp/math/DoubleUtil.java new file mode 100644 index 000000000..e9ccceb10 --- /dev/null +++ b/src/jogl/classes/com/jogamp/math/DoubleUtil.java @@ -0,0 +1,274 @@ +/** + * Copyright 2010-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.math; + +/** + * Basic Double math utility functions. + */ +public final class DoubleUtil { + // + // Scalar Ops + // + + @SuppressWarnings("unused") + private static void calculateMachineEpsilonDouble() { + final long t0; + double machEps = 1.0; + int i=0; + do { + machEps /= 2.0; + i++; + } while (1.0 + (machEps / 2.0) != 1.0); + machEpsilon = machEps; + } + private static volatile boolean machEpsilonAvail = false; + private static double machEpsilon = 0f; + + /** + * Return computed machine Epsilon value. + * <p> + * The machine Epsilon value is computed once. + * </p> + * @see #EPSILON + */ + public static double getMachineEpsilon() { + if( !machEpsilonAvail ) { + synchronized(DoubleUtil.class) { + if( !machEpsilonAvail ) { + machEpsilonAvail = true; + calculateMachineEpsilonDouble(); + } + } + } + return machEpsilon; + } + + public static final double E = 2.7182818284590452354; + + /** The value PI, i.e. 180 degrees in radians. */ + public static final double PI = 3.14159265358979323846; + + /** The value 2PI, i.e. 360 degrees in radians. */ + public static final double TWO_PI = 2.0 * PI; + + /** The value PI/2, i.e. 90 degrees in radians. */ + public static final double HALF_PI = PI / 2.0; + + /** The value PI/4, i.e. 45 degrees in radians. */ + public static final double QUARTER_PI = PI / 4.0; + + /** The value PI^2. */ + public final static double SQUARED_PI = PI * PI; + + /** Converts arc-degree to radians */ + public static double adegToRad(final double arc_degree) { + return arc_degree * PI / 180.0; + } + + /** Converts radians to arc-degree */ + public static double radToADeg(final double rad) { + return rad * 180.0 / PI; + } + + /** + * Epsilon for floating point {@value}, as once computed via {@link #getMachineEpsilon()} on an AMD-64 CPU. + * <p> + * Definition of machine epsilon guarantees that: + * <pre> + * 1.0 + EPSILON != 1.0 + * </pre> + * In other words: <i>machEps</i> is the maximum relative error of the chosen rounding procedure. + * </p> + * <p> + * A number can be considered zero if it is in the range (or in the set): + * <pre> + * <b>MaybeZeroSet</b> e ]-<i>machEps</i> .. <i>machEps</i>[ <i>(exclusive)</i> + * </pre> + * While comparing floating point values, <i>machEps</i> allows to clip the relative error: + * <pre> + * boolean isZero = afloat < EPSILON; + * boolean isNotZero = afloat >= EPSILON; + * + * boolean isEqual = abs(bfloat - afloat) < EPSILON; + * boolean isNotEqual = abs(bfloat - afloat) >= EPSILON; + * </pre> + * </p> + * @see #isEqual(float, float, float) + * @see #isZero(float, float) + */ + public static final double EPSILON = 2.220446049250313E-16; + + /** + * Inversion Epsilon, used with equals method to determine if two inverted matrices are close enough to be considered equal. + * <p> + * Using {@value}, which is ~100 times {@link DoubleUtil#EPSILON}. + * </p> + */ + public static final double INV_DEVIANCE = 1.0E-8f; // EPSILON == 1.1920929E-7f; double ALLOWED_DEVIANCE: 1.0E-8f + + /** + * Return true if both values are equal w/o regarding an epsilon. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * </ul> + * </p> + * @see #isEqual(float, float, float) + */ + public static boolean isEqualRaw(final double a, final double b) { + // Values are equal (Inf, Nan .. ) + return Double.doubleToLongBits(a) == Double.doubleToLongBits(b); + } + + /** + * Return true if both values are equal, i.e. their absolute delta < <code>epsilon</code>. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * </ul> + * </p> + * @see #EPSILON + */ + public static boolean isEqual(final double a, final double b, final double epsilon) { + if ( Math.abs(a - b) < epsilon ) { + return true; + } else { + // Values are equal (Inf, Nan .. ) + return Double.doubleToLongBits(a) == Double.doubleToLongBits(b); + } + } + + /** + * Return true if both values are equal, i.e. their absolute delta < {@link #EPSILON}. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * </ul> + * </p> + * @see #EPSILON + */ + public static boolean isEqual(final double a, final double b) { + if ( Math.abs(a - b) < EPSILON ) { + return true; + } else { + // Values are equal (Inf, Nan .. ) + return Double.doubleToLongBits(a) == Double.doubleToLongBits(b); + } + } + + /** + * Return true if both values are equal, i.e. their absolute delta < {@link #EPSILON}. + * <p> + * Implementation does not consider corner cases like {@link #isEqual(float, float, float)}. + * </p> + * @see #EPSILON + */ + public static boolean isEqual2(final double a, final double b) { + return Math.abs(a - b) < EPSILON; + } + + /** + * Return true if both values are equal w/o regarding an epsilon. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * <li>NaN > 0</li> + * <li>+Inf > -Inf</li> + * </ul> + * </p> + * @see #compare(float, float, float) + */ + public static int compare(final double a, final double b) { + if (a < b) { + return -1; // Neither is NaN, a is smaller + } + if (a > b) { + return 1; // Neither is NaN, a is larger + } + final long aBits = Double.doubleToLongBits(a); + final long bBits = Double.doubleToLongBits(b); + if( aBits == bBits ) { + return 0; // Values are equal (Inf, Nan .. ) + } else if( aBits < bBits ) { + return -1; // (-0.0, 0.0) or (!NaN, NaN) + } else { + return 1; // ( 0.0, -0.0) or ( NaN, !NaN) + } + } + + /** + * Return true if both values are equal, i.e. their absolute delta < <code>epsilon</code>. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * <li>NaN > 0</li> + * <li>+Inf > -Inf</li> + * </ul> + * </p> + * @see #EPSILON + */ + public static int compare(final double a, final double b, final double epsilon) { + if ( Math.abs(a - b) < epsilon ) { + return 0; + } else { + return compare(a, b); + } + } + + /** + * Return true if value is zero, i.e. it's absolute value < <code>epsilon</code>. + * @see #EPSILON + */ + public static boolean isZero(final double a, final double epsilon) { + return Math.abs(a) < epsilon; + } + + /** + * Return true if value is zero, i.e. it's absolute value < {@link #EPSILON}. + * @see #EPSILON + */ + public static boolean isZero(final double a) { + return Math.abs(a) < EPSILON; + } + +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/math/FixedPoint.java b/src/jogl/classes/com/jogamp/math/FixedPoint.java index 31408b079..d40bd6dac 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FixedPoint.java +++ b/src/jogl/classes/com/jogamp/math/FixedPoint.java @@ -31,7 +31,7 @@ * */ -package com.jogamp.opengl.math; +package com.jogamp.math; public class FixedPoint { public static final int toFixed(int value) { diff --git a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java b/src/jogl/classes/com/jogamp/math/FloatUtil.java index 25b5a8ad7..e75e86b7f 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FloatUtil.java +++ b/src/jogl/classes/com/jogamp/math/FloatUtil.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; import java.nio.FloatBuffer; import java.util.Locale; diff --git a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java b/src/jogl/classes/com/jogamp/math/FovHVHalves.java index 5d7907f2f..cc7bcee3d 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/FovHVHalves.java +++ b/src/jogl/classes/com/jogamp/math/FovHVHalves.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * Horizontal and vertical field of view (FOV) halves, diff --git a/src/jogl/classes/com/jogamp/opengl/math/Matrix4f.java b/src/jogl/classes/com/jogamp/math/Matrix4f.java index 5d1d8e968..ee505a95d 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Matrix4f.java +++ b/src/jogl/classes/com/jogamp/math/Matrix4f.java @@ -26,13 +26,13 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; import java.nio.FloatBuffer; -import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.math.geom.Frustum; -import com.jogamp.opengl.math.geom.Frustum.Plane; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.Frustum; +import com.jogamp.math.geom.Frustum.Plane; /** * Basic 4x4 float matrix implementation using fields for intensive use-cases (host operations). @@ -40,8 +40,7 @@ import com.jogamp.opengl.math.geom.Frustum.Plane; * Implementation covers {@link FloatUtil} matrix functionality, exposed in an object oriented manner. * </p> * <p> - * Unlike {@link com.jogamp.opengl.util.PMVMatrix PMVMatrix}, this class only represents one single matrix - * without a complete {@link com.jogamp.opengl.fixedfunc.GLMatrixFunc GLMatrixFunc} implementation. + * Unlike {@link com.jogamp.math.util.PMVMatrix4f PMVMatrix4f}, this class only represents one single matrix. * </p> * <p> * For array operations the layout is expected in column-major order @@ -84,7 +83,7 @@ import com.jogamp.opengl.math.geom.Frustum.Plane; * <li><a href="https://github.com/lessthanoptimal/ejml">EJML Efficient Java Matrix Library</a></li> * </ul> * </p> - * @see com.jogamp.opengl.util.PMVMatrix + * @see com.jogamp.math.util.PMVMatrix4f * @see FloatUtil */ public class Matrix4f { @@ -1319,7 +1318,7 @@ public class Matrix4f { * @return this matrix for chaining * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear} * @see #setToFrustum(float, float, float, float, float, float) - * @see Frustum#updateByFovDesc(Matrix4f, com.jogamp.opengl.math.geom.Frustum.FovDesc) + * @see Frustum#updateByFovDesc(Matrix4f, com.jogamp.math.geom.Frustum.FovDesc) */ public Matrix4f setToPerspective(final FovHVHalves fovhv, final float zNear, final float zFar) throws IllegalArgumentException { final FovHVHalves fovhvTan = fovhv.toTangents(); // use tangent of half-fov ! diff --git a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java b/src/jogl/classes/com/jogamp/math/Quaternion.java index 0d04c69cc..690c1b8dc 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Quaternion.java +++ b/src/jogl/classes/com/jogamp/math/Quaternion.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * Quaternion implementation supporting diff --git a/src/jogl/classes/com/jogamp/opengl/math/Ray.java b/src/jogl/classes/com/jogamp/math/Ray.java index 25a7d9a70..0189b9ce2 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Ray.java +++ b/src/jogl/classes/com/jogamp/math/Ray.java @@ -25,9 +25,9 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; -import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.math.geom.AABBox; /** * Simple compound denoting a ray. diff --git a/src/jogl/classes/com/jogamp/opengl/math/Recti.java b/src/jogl/classes/com/jogamp/math/Recti.java index 58f5e5e77..68e0cfd0b 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Recti.java +++ b/src/jogl/classes/com/jogamp/math/Recti.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * Rectangle with x, y, width and height integer components. diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java b/src/jogl/classes/com/jogamp/math/Vec2f.java index f504b960b..27371401a 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec2f.java +++ b/src/jogl/classes/com/jogamp/math/Vec2f.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * 2D Vector based upon two float components. diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec2i.java b/src/jogl/classes/com/jogamp/math/Vec2i.java index 9e70a502f..73906120d 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec2i.java +++ b/src/jogl/classes/com/jogamp/math/Vec2i.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * 2D Vector based upon two integer components. diff --git a/src/jogl/classes/com/jogamp/math/Vec3d.java b/src/jogl/classes/com/jogamp/math/Vec3d.java new file mode 100644 index 000000000..14408f714 --- /dev/null +++ b/src/jogl/classes/com/jogamp/math/Vec3d.java @@ -0,0 +1,397 @@ +/** + * Copyright 2022-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.math; + + +/** + * 3D Vector based upon three double components. + * + * Implementation borrowed from [gfxbox2](https://jausoft.com/cgit/cs_class/gfxbox2.git/tree/include/pixel/pixel3f.hpp#n29) + * and its data layout from JOAL's Vec3f. + */ +public final class Vec3d { + private double x; + private double y; + private double z; + + public Vec3d() {} + + public Vec3d(final Vec3d o) { + set(o); + } + + /** Creating new Vec3f using Vec4f, dropping w. */ + public Vec3d(final Vec4f o) { + set(o); + } + + /** Creating new Vec3f using { Vec2f, z}. */ + public Vec3d(final Vec2f o, final double z) { + set(o, z); + } + + public Vec3d copy() { + return new Vec3d(this); + } + + public Vec3d(final double[/*3*/] xyz) { + set(xyz); + } + + public Vec3d(final double x, final double y, final double z) { + set(x, y, z); + } + + /** this = o, returns this. */ + public Vec3d set(final Vec3d o) { + this.x = o.x; + this.y = o.y; + this.z = o.z; + return this; + } + + /** this = { o, z }, returns this. */ + public Vec3d set(final Vec2f o, final double z) { + this.x = o.x(); + this.y = o.y(); + this.z = z; + return this; + } + + /** this = o while dropping w, returns this. */ + public Vec3d set(final Vec4f o) { + this.x = o.x(); + this.y = o.y(); + this.z = o.z(); + return this; + } + + /** this = { x, y, z }, returns this. */ + public Vec3d set(final double x, final double y, final double z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + + /** this = xyz, returns this. */ + public Vec3d set(final double[/*3*/] xyz) { + this.x = xyz[0]; + this.y = xyz[1]; + this.z = xyz[2]; + return this; + } + + /** Sets the ith component, 0 <= i < 3 */ + public void set(final int i, final double val) { + switch (i) { + case 0: x = val; break; + case 1: y = val; break; + case 2: z = val; break; + default: throw new IndexOutOfBoundsException(); + } + } + + /** xyz = this, returns xyz. */ + public double[] get(final double[/*3*/] xyz) { + xyz[0] = this.x; + xyz[1] = this.y; + xyz[2] = this.z; + return xyz; + } + + /** Gets the ith component, 0 <= i < 3 */ + public double get(final int i) { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + default: throw new IndexOutOfBoundsException(); + } + } + + public double x() { return x; } + public double y() { return y; } + public double z() { return z; } + + public void setX(final double x) { this.x = x; } + public void setY(final double y) { this.y = y; } + public void setZ(final double z) { this.z = z; } + + /** this = max(this, m), returns this. */ + public Vec3d max(final Vec3d m) { + this.x = Math.max(this.x, m.x); + this.y = Math.max(this.y, m.y); + this.z = Math.max(this.z, m.z); + return this; + } + /** this = min(this, m), returns this. */ + public Vec3d min(final Vec3d m) { + this.x = Math.min(this.x, m.x); + this.y = Math.min(this.y, m.y); + this.z = Math.min(this.z, m.z); + return this; + } + + /** Returns this * val; creates new vector */ + public Vec3d mul(final double val) { + return new Vec3d(this).scale(val); + } + + /** this = a * b, returns this. */ + public Vec3d mul(final Vec3d a, final Vec3d b) { + x = a.x * b.x; + y = a.y * b.y; + z = a.z * b.z; + return this; + } + + /** this = this * s, returns this. */ + public Vec3d scale(final double s) { + x *= s; + y *= s; + z *= s; + return this; + } + + /** this = this * { sx, sy, sz }, returns this. */ + public Vec3d scale(final double sx, final double sy, final double sz) { + x *= sx; + y *= sy; + z *= sz; + return this; + } + + /** this = this * { s.x, s.y, s.z }, returns this. */ + public Vec3d scale(final Vec3d s) { return scale(s.x, s.y, s.z); } + + /** Returns this + arg; creates new vector */ + public Vec3d plus(final Vec3d arg) { + return new Vec3d(this).add(arg); + } + + /** this = a + b, returns this. */ + public Vec3d plus(final Vec3d a, final Vec3d b) { + x = a.x + b.x; + y = a.y + b.y; + z = a.z + b.z; + return this; + } + + /** this = this + { dx, dy, dz }, returns this. */ + public Vec3d add(final double dx, final double dy, final double dz) { + x += dx; + y += dy; + z += dz; + return this; + } + + /** this = this + b, returns this. */ + public Vec3d add(final Vec3d b) { + x += b.x; + y += b.y; + z += b.z; + return this; + } + + /** Returns this - arg; creates new vector */ + public Vec3d minus(final Vec3d arg) { + return new Vec3d(this).sub(arg); + } + + /** this = a - b, returns this. */ + public Vec3d minus(final Vec3d a, final Vec3d b) { + x = a.x - b.x; + y = a.y - b.y; + z = a.z - b.z; + return this; + } + + /** this = this - b, returns this. */ + public Vec3d sub(final Vec3d b) { + x -= b.x; + y -= b.y; + z -= b.z; + return this; + } + + /** Return true if all components are zero, i.e. it's absolute value < {@link #EPSILON}. */ + public boolean isZero() { + return DoubleUtil.isZero(x) && DoubleUtil.isZero(y) && DoubleUtil.isZero(z); + } + + /** + * Return the length of this vector, a.k.a the <i>norm</i> or <i>magnitude</i> + */ + public double length() { + return Math.sqrt(lengthSq()); + } + + /** + * Return the squared length of this vector, a.k.a the squared <i>norm</i> or squared <i>magnitude</i> + */ + public double lengthSq() { + return x*x + y*y + z*z; + } + + /** + * Normalize this vector in place + */ + public Vec3d normalize() { + final double lengthSq = lengthSq(); + if ( DoubleUtil.isZero( lengthSq ) ) { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } else { + final double invSqr = 1.0f / Math.sqrt(lengthSq); + x *= invSqr; + y *= invSqr; + z *= invSqr; + } + return this; + } + + /** + * Return the squared distance between this vector and the given one. + * <p> + * When comparing the relative distance between two points it is usually sufficient to compare the squared + * distances, thus avoiding an expensive square root operation. + * </p> + */ + public double distSq(final Vec3d o) { + final double dx = x - o.x; + final double dy = y - o.y; + final double dz = z - o.z; + return dx*dx + dy*dy + dz*dz; + } + + /** + * Return the distance between this vector and the given one. + */ + public double dist(final Vec3d o) { + return Math.sqrt(distSq(o)); + } + + + /** + * Return the dot product of this vector and the given one + * @return the dot product as double + */ + public double dot(final Vec3d o) { + return x*o.x + y*o.y + z*o.z; + } + + /** Returns this cross arg; creates new vector */ + public Vec3d cross(final Vec3d arg) { + return new Vec3d().cross(this, arg); + } + + /** this = a cross b. NOTE: "this" must be a different vector than + both a and b. */ + public Vec3d cross(final Vec3d a, final Vec3d b) { + x = a.y * b.z - a.z * b.y; + y = a.z * b.x - a.x * b.z; + z = a.x * b.y - a.y * b.x; + return this; + } + + /** + * Return the cosine of the angle between two vectors using {@link #dot(Vec3d)} + */ + public double cosAngle(final Vec3d o) { + return dot(o) / ( length() * o.length() ) ; + } + + /** + * Return the angle between two vectors in radians using {@link Math#acos(double)} on {@link #cosAngle(Vec3d)}. + */ + public double angle(final Vec3d o) { + return Math.acos( cosAngle(o) ); + } + + /** + * Equals check using a given {@link DoubleUtil#EPSILON} value and {@link DoubleUtil#isEqual(double, double, double)}. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * </ul> + * @param o comparison value + * @param epsilon consider using {@link DoubleUtil#EPSILON} + * @return true if all components differ less than {@code epsilon}, otherwise false. + */ + public boolean isEqual(final Vec3d o, final double epsilon) { + if( this == o ) { + return true; + } else { + return DoubleUtil.isEqual(x, o.x, epsilon) && + DoubleUtil.isEqual(y, o.y, epsilon) && + DoubleUtil.isEqual(z, o.z, epsilon); + } + } + + /** + * Equals check using {@link DoubleUtil#EPSILON} in {@link DoubleUtil#isEqual(double, double)}. + * <p> + * Implementation considers following corner cases: + * <ul> + * <li>NaN == NaN</li> + * <li>+Inf == +Inf</li> + * <li>-Inf == -Inf</li> + * </ul> + * @param o comparison value + * @return true if all components differ less than {@link DoubleUtil#EPSILON}, otherwise false. + */ + public boolean isEqual(final Vec3d o) { + if( this == o ) { + return true; + } else { + return DoubleUtil.isEqual(x, o.x) && + DoubleUtil.isEqual(y, o.y) && + DoubleUtil.isEqual(z, o.z); + } + } + + @Override + public boolean equals(final Object o) { + if( o instanceof Vec3d ) { + return isEqual((Vec3d)o); + } else { + return false; + } + } + + @Override + public String toString() { + return x + " / " + y + " / " + z; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java b/src/jogl/classes/com/jogamp/math/Vec3f.java index 7012edd74..1ad27463e 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec3f.java +++ b/src/jogl/classes/com/jogamp/math/Vec3f.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * 3D Vector based upon three float components. diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vec4f.java b/src/jogl/classes/com/jogamp/math/Vec4f.java index 914450bf1..45afea7f8 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vec4f.java +++ b/src/jogl/classes/com/jogamp/math/Vec4f.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; /** * 4D Vector based upon four float components. diff --git a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java b/src/jogl/classes/com/jogamp/math/VectorUtil.java index e38501c73..6cea0be0b 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java +++ b/src/jogl/classes/com/jogamp/math/VectorUtil.java @@ -25,11 +25,11 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; import java.util.ArrayList; -import com.jogamp.graph.geom.plane.Winding; +import com.jogamp.math.geom.plane.Winding; public final class VectorUtil { /** diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vert2fImmutable.java b/src/jogl/classes/com/jogamp/math/Vert2fImmutable.java index 66bf078f3..5fc5de7ef 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vert2fImmutable.java +++ b/src/jogl/classes/com/jogamp/math/Vert2fImmutable.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; public interface Vert2fImmutable { float x(); diff --git a/src/jogl/classes/com/jogamp/opengl/math/Vert3fImmutable.java b/src/jogl/classes/com/jogamp/math/Vert3fImmutable.java index 6f63a746c..03e26e840 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/Vert3fImmutable.java +++ b/src/jogl/classes/com/jogamp/math/Vert3fImmutable.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math; +package com.jogamp.math; public interface Vert3fImmutable extends Vert2fImmutable { float z(); diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java b/src/jogl/classes/com/jogamp/math/geom/AABBox.java index 1720caf0e..926f55aec 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/AABBox.java +++ b/src/jogl/classes/com/jogamp/math/geom/AABBox.java @@ -25,16 +25,15 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math.geom; +package com.jogamp.math.geom; -import com.jogamp.graph.geom.plane.AffineTransform; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.Ray; -import com.jogamp.opengl.math.Recti; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.util.PMVMatrix; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.Matrix4f; +import com.jogamp.math.Quaternion; +import com.jogamp.math.Ray; +import com.jogamp.math.Recti; +import com.jogamp.math.Vec3f; +import com.jogamp.math.geom.plane.AffineTransform; /** @@ -836,21 +835,6 @@ public class AABBox { } /** - * Transform this box using the {@link PMVMatrix#getMvMat() modelview} of the given {@link PMVMatrix} into {@code out} - * @param pmv transformation {@link PMVMatrix} - * @param out the resulting {@link AABBox} - * @return the resulting {@link AABBox} for chaining - */ - public AABBox transformMv(final PMVMatrix pmv, final AABBox out) { - final Vec3f tmp = new Vec3f(); - out.reset(); - out.resize( pmv.mulMvMatVec3f(low, tmp) ); - out.resize( pmv.mulMvMatVec3f(high, tmp) ); - out.computeCenter(); - return out; - } - - /** * Assume this bounding box as being in object space and * compute the window bounding box. * <p> diff --git a/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java b/src/jogl/classes/com/jogamp/math/geom/Frustum.java index 73079959b..9e9f65c31 100644 --- a/src/jogl/classes/com/jogamp/opengl/math/geom/Frustum.java +++ b/src/jogl/classes/com/jogamp/math/geom/Frustum.java @@ -25,11 +25,11 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.math.geom; +package com.jogamp.math.geom; -import com.jogamp.opengl.math.FovHVHalves; -import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.Vec3f; +import com.jogamp.math.FovHVHalves; +import com.jogamp.math.Matrix4f; +import com.jogamp.math.Vec3f; /** * Providing frustum {@link #getPlanes() planes} derived by different inputs diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java b/src/jogl/classes/com/jogamp/math/geom/plane/AffineTransform.java index 66d661990..05d7e201e 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/AffineTransform.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/AffineTransform.java @@ -18,15 +18,15 @@ * @author Denis M. Kishenko * @author Sven Gothel, (c) 2010-2023 */ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; // import jogamp.opengl.util.HashCode; import com.jogamp.graph.geom.Vertex; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.Vec2f; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.Vec2f; +import com.jogamp.math.Vec3f; +import com.jogamp.math.geom.AABBox; public class AffineTransform implements Cloneable { diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Crossing2F.java b/src/jogl/classes/com/jogamp/math/geom/plane/Crossing2F.java index 7eb1d0bf0..09476238f 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/Crossing2F.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/Crossing2F.java @@ -17,9 +17,9 @@ /** * @author Denis M. Kishenko */ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; -import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.math.FloatUtil; /* pp */ class Crossing2F { diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/IllegalPathStateException.java b/src/jogl/classes/com/jogamp/math/geom/plane/IllegalPathStateException.java index be0a14a76..95e47fe5b 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/IllegalPathStateException.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/IllegalPathStateException.java @@ -17,7 +17,7 @@ /** * @author Denis M. Kishenko */ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; public class IllegalPathStateException extends RuntimeException { diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/NoninvertibleTransformException.java b/src/jogl/classes/com/jogamp/math/geom/plane/NoninvertibleTransformException.java index fb90cedfc..f82195944 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/NoninvertibleTransformException.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/NoninvertibleTransformException.java @@ -17,7 +17,7 @@ /** * @author Denis M. Kishenko */ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; public class NoninvertibleTransformException extends java.lang.Exception { diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Path2F.java b/src/jogl/classes/com/jogamp/math/geom/plane/Path2F.java index 588232d9a..9e0dda286 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/Path2F.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/Path2F.java @@ -18,12 +18,12 @@ * @author Denis M. Kishenko * @author Sven Gothel */ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; import java.io.PrintStream; import java.util.NoSuchElementException; -import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.math.geom.AABBox; /** * Path2F represents and provides construction method for a 2D shape using float[2] points. diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/Winding.java b/src/jogl/classes/com/jogamp/math/geom/plane/Winding.java index bfa214c22..0b3c8dc21 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/Winding.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/Winding.java @@ -1,4 +1,4 @@ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; /** * Winding direction, either clockwise (CW) or counter-clockwise (CCW). diff --git a/src/jogl/classes/com/jogamp/graph/geom/plane/WindingRule.java b/src/jogl/classes/com/jogamp/math/geom/plane/WindingRule.java index 46ef167a3..d7881b6db 100644 --- a/src/jogl/classes/com/jogamp/graph/geom/plane/WindingRule.java +++ b/src/jogl/classes/com/jogamp/math/geom/plane/WindingRule.java @@ -1,4 +1,4 @@ -package com.jogamp.graph.geom.plane; +package com.jogamp.math.geom.plane; /** * Winding rule, either EVEN_ODD or NON_ZERO (like for TrueType fonts). diff --git a/src/jogl/classes/com/jogamp/math/util/PMVMatrix4f.java b/src/jogl/classes/com/jogamp/math/util/PMVMatrix4f.java new file mode 100644 index 000000000..826ca82f6 --- /dev/null +++ b/src/jogl/classes/com/jogamp/math/util/PMVMatrix4f.java @@ -0,0 +1,1610 @@ +/** + * Copyright 2009-2023 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.math.util; + +import java.nio.Buffer; +import java.nio.FloatBuffer; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.Matrix4f; +import com.jogamp.math.Quaternion; +import com.jogamp.math.Ray; +import com.jogamp.math.Recti; +import com.jogamp.math.Vec3f; +import com.jogamp.math.Vec4f; +import com.jogamp.math.geom.AABBox; +import com.jogamp.math.geom.Frustum; + +/** + * PMVMatrix4f implements the basic computer graphics {@link Matrix4f} pack using + * projection (P), modelview (Mv) and texture (T) {@link Matrix4f} operations. + * <p> + * Unlike {@link com.jogamp.opengl.util.PMVMatrix PMVMatrix}, this class doesn't implement + * {@link com.jogamp.opengl.fixedfunc.GLMatrixFunc GLMatrixFunc} and is OpenGL agnostic. + * </p> + * <p> + * This is the second implementation of `PMVMatrix4f` using + * direct {@link Matrix4f}, {@link Vec4f} and {@link Vec3f} math operations instead of `float[]` + * via {@link com.jogamp.math.FloatUtil FloatUtil}. + * </p> + * <p> + * PMVMatrix4f provides the {@link #getMvi() inverse modelview matrix (Mvi)} and + * {@link #getMvit() inverse transposed modelview matrix (Mvit)}. + * {@link Frustum} is also provided by {@link #getFrustum()}. + * + * To keep these derived values synchronized after mutable Mv operations like {@link #rotateMv(Quaternion)} + * users have to call {@link #update()} before using Mvi and Mvit. + * </p> + * <p> + * All matrices are provided in column-major order, + * as specified in the OpenGL fixed function pipeline, i.e. compatibility profile. + * See {@link Matrix4f}. + * </p> + * <p> + * PMVMatrix4f can supplement {@link com.jogamp.opengl.GL2ES2 GL2ES2} applications w/ the + * lack of the described matrix functionality. + * </p> + * <a name="storageDetails"><h5>Matrix storage details</h5></a> + * <p> + * The {@link SyncBuffer} abstraction is provided, e.g. {@link #getSyncPMvMvi()}, + * to synchronize the respective {@link Matrix4f matrices} with the `float[]` backing store. + * The latter is represents the data to {@link com.jogamp.opengl.GLUniformData} via its {@link FloatBuffer}s, see {@link SyncBuffer#getBuffer()}, + * and is pushed to the GPU eventually. + * </p> + * <p> + * {@link SyncBuffer}'s {@link SyncAction} is called by {@link com.jogamp.opengl.GLUniformData#getBuffer()}, + * i.e. before the data is pushed to the GPU. + * </p> + * <p> + * The provided {@link SyncAction} ensures that the {@link Matrix4f matrices data} + * gets copied into the `float[]` backing store. + * </p> + * <p> + * PMVMatrix4f provides two specializations of {@link SyncBuffer}, {@link SyncMatrix4f} for single {@link Matrix4f} mappings + * and {@link SyncMatrices4f} for multiple {@link Matrix4f} mappings. + * </p> + * <p> + * They can be feed directly to instantiate a {@link com.jogamp.opengl.GLUniformData} object via e.g. {@link com.jogamp.opengl.GLUniformData#GLUniformData(String, int, int, SyncBuffer)}. + * </p> + * <p> + * All {@link Matrix4f matrix} {@link SyncBuffer}'s backing store are backed up by a common primitive float-array for performance considerations + * and are a {@link Buffers#slice2Float(float[], int, int) sliced} representation of it. + * </p> + * <p> + * <b>{@link Matrix4f} {@link SyncBuffer}'s Backing-Store Notes:</b> + * <ul> + * <li>The {@link Matrix4f matrix} {@link SyncBuffer}'s backing store is a {@link Buffers#slice2Float(float[], int, int) sliced part } of a host matrix and it's start position has been {@link FloatBuffer#mark() marked}.</li> + * <li>Use {@link FloatBuffer#reset() reset()} to rewind it to it's start position after relative operations, like {@link FloatBuffer#get() get()}.</li> + * <li>If using absolute operations like {@link FloatBuffer#get(int) get(int)}, use it's {@link FloatBuffer#reset() reset} {@link FloatBuffer#position() position} as it's offset.</li> + * </ul> + * </p> + */ +public class PMVMatrix4f { + + /** Bit value stating a modified {@link #getP() projection matrix (P)}, since last {@link #update()} call. */ + public static final int MODIFIED_PROJECTION = 1 << 0; + /** Bit value stating a modified {@link #getMv() modelview matrix (Mv)}, since last {@link #update()} call. */ + public static final int MODIFIED_MODELVIEW = 1 << 1; + /** Bit value stating a modified {@link #getT() texture matrix (T)}, since last {@link #update()} call. */ + public static final int MODIFIED_TEXTURE = 1 << 2; + /** Bit value stating all is modified */ + public static final int MODIFIED_ALL = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE; + /** Bit value for {@link #getMvi() inverse modelview matrix (Mvi)}, updated via {@link #update()}. */ + public static final int INVERSE_MODELVIEW = 1 << 1; + /** Bit value for {@link #getMvit() inverse transposed modelview matrix (Mvit)}, updated via {@link #update()}. */ + public static final int INVERSE_TRANSPOSED_MODELVIEW = 1 << 2; + /** Bit value for {@link #getFrustum() frustum} and updated by {@link #getFrustum()}. */ + public static final int FRUSTUM = 1 << 3; + /** Bit value for {@link #getPMv() pre-multiplied P * Mv}, updated by {@link #getPMv()}. */ + public static final int PREMUL_PMV = 1 << 4; + /** Bit value for {@link #getPMvi() pre-multiplied invert(P * Mv)}, updated by {@link #getPMvi()}. */ + public static final int PREMUL_PMVI = 1 << 5; + /** Manual bits not covered by {@link #update()} but {@link #getFrustum()}, {@link #FRUSTUM}, {@link #getPMv()}, {@link #PREMUL_PMV}, {@link #getPMvi()}, {@link #PREMUL_PMVI}, etc. */ + public static final int MANUAL_BITS = FRUSTUM | PREMUL_PMV | PREMUL_PMVI; + + /** + * Creates an instance of PMVMatrix4f. + * <p> + * This constructor only sets up an instance w/o additional {@link #INVERSE_MODELVIEW} or {@link #INVERSE_TRANSPOSED_MODELVIEW}. + * </p> + * <p> + * Implementation uses non-direct non-NIO Buffers with guaranteed backing array, + * which are synchronized to the actual Matrix4f instances. + * This allows faster access in Java computation. + * </p> + * @see #PMVMatrix4f(int) + */ + public PMVMatrix4f() { + this(0); + } + + /** + * Creates an instance of PMVMatrix4f. + * <p> + * Additional derived matrices can be requested via `derivedMatrices`, i.e. + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} + * </p> + * <p> + * Implementation uses non-direct non-NIO Buffers with guaranteed backing array, + * which are synchronized to the actual Matrix4f instances. + * This allows faster access in Java computation. + * </p> + * @param derivedMatrices additional matrices can be requested by passing bits {@link #INVERSE_MODELVIEW} and {@link #INVERSE_TRANSPOSED_MODELVIEW}. + * @see #getReqBits() + * @see #isReqDirty() + * @see #getDirtyBits() + * @see #update() + */ + public PMVMatrix4f(final int derivedMatrices) { + // I Identity + // T Texture + // P Projection + // Mv ModelView + // Mvi Modelview-Inverse + // Mvit Modelview-Inverse-Transpose + { + int mask = 0; + if( 0 != ( derivedMatrices & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) { + mask |= INVERSE_MODELVIEW; + } + if( 0 != ( derivedMatrices & INVERSE_TRANSPOSED_MODELVIEW ) ) { + mask |= INVERSE_TRANSPOSED_MODELVIEW; + } + requestBits = mask; + } + + // actual underlying Matrix4f count + int mcount = 3; + + // actual underlying Matrix4f data + matP = new Matrix4f(); + matMv = new Matrix4f(); + matTex = new Matrix4f(); + + if( 0 != ( requestBits & INVERSE_MODELVIEW ) ) { + matMvi = new Matrix4f(); + mMvi_offset = 2*16; + ++mcount; + } else { + matMvi = null; + mMvi_offset = -1; + } + if( 0 != ( requestBits & INVERSE_TRANSPOSED_MODELVIEW ) ) { + matMvit = new Matrix4f(); + mMvit_offset = 3*16; + ++mcount; + } else { + matMvit = null; + mMvit_offset = -1; + } + mTex_offset = (mcount-1)*16; // last one + + // float back buffer for GPU, Matrix4f -> matrixStore via SyncedBuffer + matrixStore = new float[mcount*16]; + + // FloatBuffer for single Matrix4f back-buffer + final FloatBuffer bufP = Buffers.slice2Float(matrixStore, mP_offset, 1*16); // P + syncP = new SyncBuffer0(matP, bufP); // mP_offset + + final FloatBuffer bufMv = Buffers.slice2Float(matrixStore, mMv_offset, 1*16); // Mv + syncMv = new SyncBuffer1(matMv, bufMv, mMv_offset); + + final FloatBuffer bufP_Mv = Buffers.slice2Float(matrixStore, mP_offset, 2*16); // P + Mv + syncP_Mv = new SyncBufferN(new Matrix4f[] { matP, matMv }, bufP_Mv, mP_offset); + + final FloatBuffer bufTex = Buffers.slice2Float(matrixStore, mTex_offset, 1*16); // T + syncT = new SyncBuffer1(matTex, bufTex, mTex_offset); + + if( null != matMvi ) { + final FloatBuffer bufMvi = Buffers.slice2Float(matrixStore, mMvi_offset, 1*16); // Mvi + final FloatBuffer bufP_Mv_Mvi = Buffers.slice2Float(matrixStore, mP_offset, 3*16); // P + Mv + Mvi + syncMvi = new SyncBuffer1U(matMvi, bufMvi, mMvi_offset); + syncP_Mv_Mvi = new SyncBufferNU(new Matrix4f[] { matP, matMv, matMvi }, bufP_Mv_Mvi, mP_offset); + } else { + syncMvi = null; + syncP_Mv_Mvi = null; + } + if( null != matMvit ) { + final FloatBuffer bufMvit = Buffers.slice2Float(matrixStore, mMvit_offset, 1*16); // Mvit + final FloatBuffer bufP_Mv_Mvi_Mvit = Buffers.slice2Float(matrixStore, mP_offset, 4*16); // P + Mv + Mvi + Mvit + syncMvit = new SyncBuffer1U(matMvit, bufMvit, mMvit_offset); + syncP_Mv_Mvi_Mvit = new SyncBufferNU(new Matrix4f[] { matP, matMv, matMvi, matMvit }, bufP_Mv_Mvi_Mvit, mP_offset); + } else { + syncMvit = null; + syncP_Mv_Mvi_Mvit = null; + } + + mat4Tmp1 = new Matrix4f(); + + mat4Tmp2 = null; // on demand + matPMv = null; // on demand + matPMvi = null; // on demand + matPMviOK = false; + frustum = null; // on demand + + reset(); + } + + /** + * Issues {@link Matrix4f#loadIdentity()} on all matrices and resets all internal states. + */ + public void reset() { + matP.loadIdentity(); + matMv.loadIdentity(); + matTex.loadIdentity(); + + modifiedBits = MODIFIED_ALL; + dirtyBits = requestBits | MANUAL_BITS; + } + + // + // Temporary storage access for efficiency + // + + + /** + * Return the second temporary Matrix4f exposed to be reused for efficiency. + * <p> + * Temporary storage is only used by this class within single method calls, + * hence has no side-effects. + * </p> + */ + protected final Matrix4f getTmp2Mat() { + if( null == mat4Tmp2 ) { + mat4Tmp2 = new Matrix4f(); + } + return mat4Tmp2; + } + + // + // Regular Matrix4f access as well as their SyncedBuffer counterpart SyncedMatrix and SyncedMatrices + // + + /** + * Returns the {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T). + * <p> + * Consider using {@link #setTextureDirty()} if modifying the returned {@link Matrix4f}. + * </p> + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final Matrix4f getT() { + return matTex; + } + + /** + * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T). + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final SyncMatrix4f getSyncT() { + return syncT; + } + + /** + * Returns the {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P). + * <p> + * Consider using {@link #setProjectionDirty()} if modifying the returned {@link Matrix4f}. + * </p> + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final Matrix4f getP() { + return matP; + } + + /** + * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P). + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final SyncMatrix4f getSyncP() { + return syncP; + } + + /** + * Returns the {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv). + * <p> + * Consider using {@link #setModelviewDirty()} if modifying the returned {@link Matrix4f}. + * </p> + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final Matrix4f getMv() { + return matMv; + } + + /** + * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv). + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final SyncMatrix4f getSyncMv() { + return syncMv; + } + + /** + * Returns {@link SyncMatrices4f} of 2 matrices within one FloatBuffer: {@link #getP() P} and {@link #getMv() Mv}. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + */ + public final SyncMatrices4f getSyncPMv() { + return syncP_Mv; + } + + /** + * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4f(int)}. + */ + public final Matrix4f getMvi() { + if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + updateImpl(false); + return matMvi; + } + + /** + * Returns the {@link SyncMatrix} of inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4f(int)}. + */ + public final SyncMatrix4f getSyncMvi() { + if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncMvi; + } + + /** + * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4f(int)}. + */ + public final Matrix4f getMvit() { + if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + updateImpl(false); + return matMvit; + } + + /** + * Returns the {@link SyncMatrix} of inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4f(int)}. + */ + public final SyncMatrix4f getSyncMvit() { + if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncMvit; + } + + /** + * Returns {@link SyncMatrices4f} of 3 matrices within one FloatBuffer: {@link #getP() P}, {@link #getMv() Mv} and {@link #getMvi() Mvi} if requested. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4f(int)}. + */ + public final SyncMatrices4f getSyncPMvMvi() { + if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncP_Mv_Mvi; + } + + /** + * Returns {@link SyncMatrices4f} of 4 matrices within one FloatBuffer: {@link #getP() P}, {@link #getMv() Mv}, {@link #getMvi() Mvi} and {@link #getMvit() Mvit} if requested. + * <p> + * See <a href="#storageDetails"> matrix storage details</a>. + * </p> + * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4f(int)}. + */ + public final SyncMatrices4f getSyncPMvMviMvit() { + if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { + throw new IllegalArgumentException("Not requested in ctor"); + } + return syncP_Mv_Mvi_Mvit; + } + + // + // Basic Matrix4f, Vec3f and Vec4f operations similar to GLMatrixFunc + // + + /** + * Returns multiplication result of {@link #getP() P} and {@link #getMv() Mv} matrix, i.e. + * <pre> + * result = P x Mv + * </pre> + * @param result 4x4 matrix storage for result + * @return given result matrix for chaining + */ + public final Matrix4f getMulPMv(final Matrix4f result) { + return result.mul(matP, matMv); + } + + /** + * Returns multiplication result of {@link #getMv() Mv} and {@link #getP() P} matrix, i.e. + * <pre> + * result = Mv x P + * </pre> + * @param result 4x4 matrix storage for result + * @return given result matrix for chaining + */ + public final Matrix4f getMulMvP(final Matrix4f result) { + return result.mul(matMv, matP); + } + + /** + * v_out = Mv * v_in + * @param v_in input vector, can be v_out for in-place transformation + * @param v_out output vector + * @returns v_out for chaining + */ + public final Vec4f mulWithMv(final Vec4f v_in, final Vec4f v_out) { + return matMv.mulVec4f(v_in, v_out); + } + + /** + * v_inout = Mv * v_inout + * @param v_inout input and output vector, i.e. in-place transformation + * @returns v_inout for chaining + */ + public final Vec4f mulWithMv(final Vec4f v_inout) { + return matMv.mulVec4f(v_inout); + } + + /** + * v_out = Mv * v_in + * + * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. + * + * @param v_in input vector, can be v_out for in-place transformation + * @param v_out output vector + * @returns v_out for chaining + */ + public final Vec3f mulWithMv(final Vec3f v_in, final Vec3f v_out) { + return matMv.mulVec3f(v_in, v_out); + } + + /** + * v_inout = Mv * v_inout + * + * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. + * + * @param v_inout input and output vector, i.e. in-place transformation + * @returns v_inout for chaining + */ + public final Vec3f mulWithMv(final Vec3f v_inout) { + return matMv.mulVec3f(v_inout); + } + + /** + * v_out = P * v_in + * @param v_in input vector, can be v_out for in-place transformation + * @param v_out output vector + * @return given result vector for chaining + * @returns v_out for chaining + */ + public final Vec4f mulWithP(final Vec4f v_in, final Vec4f v_out) { + return matP.mulVec4f(v_in, v_out); + } + + /** + * v_inout = P * v_inout + * @param v_inout input and output vector, i.e. in-place transformation + * @return given result vector for chaining + * @returns v_inout for chaining + */ + public final Vec4f mulWithP(final Vec4f v_inout) { + return matP.mulVec4f(v_inout); + } + + /** + * v_out = P * v_in + * + * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. + * + * @param v_in float[3] input vector, can be v_out for in-place transformation + * @param v_out float[3] output vector + * @returns v_out for chaining + */ + public final Vec3f mulWithP(final Vec3f v_in, final Vec3f v_out) { + return matP.mulVec3f(v_in, v_out); + } + + /** + * v_inout = P * v_inout + * + * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. + * + * @param v_inout input and output vector, i.e. in-place transformation + * @returns v_inout for chaining + */ + public final Vec3f mulWithP(final Vec3f v_inout) { + return matP.mulVec3f(v_inout); + } + + /** + * v_out = P * Mv * v_in + * @param v_in float[4] input vector, can be v_out for in-place transformation + * @param v_out float[4] output vector + * @returns v_out for chaining + */ + public final Vec4f mulWithPMv(final Vec4f v_in, final Vec4f v_out) { + return matP.mulVec4f( matMv.mulVec4f( v_in, v_out ) ); + } + + /** + * v_inout = P * Mv * v_inout + * @param v_inout input and output vector, i.e. in-place transformation + * @returns v_inout for chaining + */ + public final Vec4f mulWithPMv(final Vec4f v_inout) { + return matP.mulVec4f( matMv.mulVec4f( v_inout ) ); + } + + /** + * v_out = P * Mv * v_in + * + * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. + * + * @param v_in float[3] input vector, can be v_out for in-place transformation + * @param v_out float[3] output vector + * @returns v_out for chaining + */ + public final Vec3f mulWithPMv(final Vec3f v_in, final Vec3f v_out) { + return matP.mulVec3f( matMv.mulVec3f( v_in, v_out ) ); + } + + /** + * v_inout = P * Mv * v_inout + * + * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. + * + * @param v_inout float[3] input and output vector, i.e. in-place transformation + * @returns v_inout for chaining + */ + public final Vec3f mulWithPMv(final Vec3f v_inout) { + return matP.mulVec3f( matMv.mulVec3f( v_inout ) ); + } + + // + // GLMatrixFunc alike functionality + // + + /** + * Load the {@link #getMv() modelview matrix} with the provided values. + */ + public final PMVMatrix4f loadMv(final float[] values, final int offset) { + matMv.load(values, offset); + setModelviewDirty(); + return this; + } + /** + * Load the {@link #getMv() modelview matrix} with the provided values. + */ + public final PMVMatrix4f loadMv(final java.nio.FloatBuffer m) { + final int spos = m.position(); + matMv.load(m); + setModelviewDirty(); + m.position(spos); + return this; + } + /** + * Load the {@link #getMv() modelview matrix} with the values of the given {@link Matrix4f}. + */ + public final PMVMatrix4f loadMv(final Matrix4f m) { + matMv.load(m); + setModelviewDirty(); + return this; + } + /** + * Load the {@link #getMv() modelview matrix} with the values of the given {@link Quaternion}'s rotation {@link Matrix4f#setToRotation(Quaternion) matrix representation}. + */ + public final PMVMatrix4f loadMv(final Quaternion quat) { + matMv.setToRotation(quat); + setModelviewDirty(); + return this; + } + + /** + * Load the {@link #getP() projection matrix} with the provided values. + */ + public final PMVMatrix4f loadP(final float[] values, final int offset) { + matP.load(values, offset); + setProjectionDirty(); + return this; + } + /** + * Load the {@link #getP() projection matrix} with the provided values. + */ + public final PMVMatrix4f loadP(final java.nio.FloatBuffer m) { + final int spos = m.position(); + matP.load(m); + setProjectionDirty(); + m.position(spos); + return this; + } + /** + * Load the {@link #getP() projection matrix} with the values of the given {@link Matrix4f}. + */ + public final PMVMatrix4f loadP(final Matrix4f m) { + matP.load(m); + setProjectionDirty(); + return this; + } + /** + * Load the {@link #getP() projection matrix} with the values of the given {@link Quaternion}'s rotation {@link Matrix4f#setToRotation(Quaternion) matrix representation}. + */ + public final PMVMatrix4f loadP(final Quaternion quat) { + matP.setToRotation(quat); + setProjectionDirty(); + return this; + } + + /** + * Load the {@link #getT() texture matrix} with the provided values. + */ + public final PMVMatrix4f loadT(final float[] values, final int offset) { + matTex.load(values, offset); + setTextureDirty(); + return this; + } + /** + * Load the {@link #getT() texture matrix} with the provided values. + */ + public final PMVMatrix4f loadT(final java.nio.FloatBuffer m) { + final int spos = m.position(); + matTex.load(m); + setTextureDirty(); + m.position(spos); + return this; + } + /** + * Load the {@link #getT() texture matrix} with the values of the given {@link Matrix4f}. + */ + public final PMVMatrix4f loadT(final Matrix4f m) { + matTex.load(m); + setTextureDirty(); + return this; + } + /** + * Load the {@link #getT() texture matrix} with the values of the given {@link Quaternion}'s rotation {@link Matrix4f#setToRotation(Quaternion) matrix representation}. + */ + public final PMVMatrix4f loadT(final Quaternion quat) { + matTex.setToRotation(quat); + setTextureDirty(); + return this; + } + + /** + * Load the {@link #getMv() modelview matrix} with the values of the given {@link Matrix4f}. + */ + public final PMVMatrix4f loadMvIdentity() { + matMv.loadIdentity(); + setModelviewDirty(); + return this; + } + + /** + * Load the {@link #getP() projection matrix} with the values of the given {@link Matrix4f}. + */ + public final PMVMatrix4f loadPIdentity() { + matP.loadIdentity(); + setProjectionDirty(); + return this; + } + + /** + * Load the {@link #getT() texture matrix} with the values of the given {@link Matrix4f}. + */ + public final PMVMatrix4f loadTIdentity() { + matTex.loadIdentity(); + setTextureDirty(); + return this; + } + + /** + * Multiply the {@link #getMv() modelview matrix}: [c] = [c] x [m] + * @param m the right hand Matrix4f + * @return this instance of chaining + */ + public final PMVMatrix4f mulMv(final Matrix4f m) { + matMv.mul( m ); + setModelviewDirty(); + return this; + } + + /** + * Multiply the {@link #getP() projection matrix}: [c] = [c] x [m] + * @param m the right hand Matrix4f + * @return this instance of chaining + */ + public final PMVMatrix4f mulP(final Matrix4f m) { + matP.mul( m ); + setProjectionDirty(); + return this; + } + + /** + * Multiply the {@link #getT() texture matrix}: [c] = [c] x [m] + * @param m the right hand Matrix4f + * @return this instance of chaining + */ + public final PMVMatrix4f mulT(final Matrix4f m) { + matTex.mul( m ); + setTextureDirty(); + return this; + } + + /** + * Translate the {@link #getMv() modelview matrix}. + * @param x + * @param y + * @param z + * @return this instance of chaining + */ + public final PMVMatrix4f translateMv(final float x, final float y, final float z) { + return mulMv( mat4Tmp1.setToTranslation(x, y, z) ); + } + /** + * Translate the {@link #getMv() modelview matrix}. + * @param t translation vec3 + * @return this instance of chaining + */ + public final PMVMatrix4f translateMv(final Vec3f t) { + return mulMv( mat4Tmp1.setToTranslation(t) ); + } + + /** + * Translate the {@link #getP() projection matrix}. + * @param x + * @param y + * @param z + * @return this instance of chaining + */ + public final PMVMatrix4f translateP(final float x, final float y, final float z) { + return mulP( mat4Tmp1.setToTranslation(x, y, z) ); + } + /** + * Translate the {@link #getP() projection matrix}. + * @param t translation vec3 + * @return this instance of chaining + */ + public final PMVMatrix4f translateP(final Vec3f t) { + return mulP( mat4Tmp1.setToTranslation(t) ); + } + + /** + * Scale the {@link #getMv() modelview matrix}. + * @param x + * @param y + * @param z + * @return this instance of chaining + */ + public final PMVMatrix4f scaleMv(final float x, final float y, final float z) { + return mulMv( mat4Tmp1.setToScale(x, y, z) ); + } + /** + * Scale the {@link #getMv() modelview matrix}. + * @param s scale vec4f + * @return this instance of chaining + */ + public final PMVMatrix4f scaleMv(final Vec3f s) { + return mulMv( mat4Tmp1.setToScale(s) ); + } + + /** + * Scale the {@link #getP() projection matrix}. + * @param x + * @param y + * @param z + * @return this instance of chaining + */ + public final PMVMatrix4f scaleP(final float x, final float y, final float z) { + return mulP( mat4Tmp1.setToScale(x, y, z) ); + } + /** + * Scale the {@link #getP() projection matrix}. + * @param s scale vec4f + * @return this instance of chaining + */ + public final PMVMatrix4f scaleP(final Vec3f s) { + return mulP( mat4Tmp1.setToScale(s) ); + } + + /** + * Rotate the {@link #getMv() modelview matrix} by the given axis and angle in radians. + * <p> + * Consider using {@link #rotateMv(Quaternion)} + * </p> + * @param ang_rad angle in radians + * @param axis rotation axis + * @return this instance of chaining + * @see #rotateMv(Quaternion) + */ + public final PMVMatrix4f rotateMv(final float ang_rad, final float x, final float y, final float z) { + return mulMv( mat4Tmp1.setToRotationAxis(ang_rad, x, y, z) ); + } + /** + * Rotate the {@link #getMv() modelview matrix} by the given axis and angle in radians. + * <p> + * Consider using {@link #rotateMv(Quaternion)} + * </p> + * @param ang_rad angle in radians + * @param axis rotation axis + * @return this instance of chaining + * @see #rotateMv(Quaternion) + */ + public final PMVMatrix4f rotateMv(final float ang_rad, final Vec3f axis) { + return mulMv( mat4Tmp1.setToRotationAxis(ang_rad, axis) ); + } + /** + * Rotate the {@link #getMv() modelview matrix} with the given {@link Quaternion}'s rotation {@link Matrix4f#setToRotation(Quaternion) matrix representation}. + * @param quat the {@link Quaternion} + * @return this instance of chaining + */ + public final PMVMatrix4f rotateMv(final Quaternion quat) { + return mulMv( mat4Tmp1.setToRotation(quat) ); + } + + /** + * Rotate the {@link #getP() projection matrix} by the given axis and angle in radians. + * <p> + * Consider using {@link #rotateP(Quaternion)} + * </p> + * @param ang_rad angle in radians + * @param axis rotation axis + * @return this instance of chaining + * @see #rotateP(Quaternion) + */ + public final PMVMatrix4f rotateP(final float ang_rad, final float x, final float y, final float z) { + return mulP( mat4Tmp1.setToRotationAxis(ang_rad, x, y, z) ); + } + /** + * Rotate the {@link #getP() projection matrix} by the given axis and angle in radians. + * <p> + * Consider using {@link #rotateP(Quaternion)} + * </p> + * @param ang_rad angle in radians + * @param axis rotation axis + * @return this instance of chaining + * @see #rotateP(Quaternion) + */ + public final PMVMatrix4f rotateP(final float ang_rad, final Vec3f axis) { + return mulP( mat4Tmp1.setToRotationAxis(ang_rad, axis) ); + } + /** + * Rotate the {@link #getP() projection matrix} with the given {@link Quaternion}'s rotation {@link Matrix4f#setToRotation(Quaternion) matrix representation}. + * @param quat the {@link Quaternion} + * @return this instance of chaining + */ + public final PMVMatrix4f rotateP(final Quaternion quat) { + return mulP( mat4Tmp1.setToRotation(quat) ); + } + + /** Pop the {@link #getMv() modelview matrix} from its stack. */ + public final PMVMatrix4f popMv() { + matMv.pop(); + setModelviewDirty(); + return this; + } + /** Pop the {@link #getP() projection matrix} from its stack. */ + public final PMVMatrix4f popP() { + matP.pop(); + setProjectionDirty(); + return this; + } + /** Pop the {@link #getT() texture matrix} from its stack. */ + public final PMVMatrix4f popT() { + matTex.pop(); + setTextureDirty(); + return this; + } + /** Push the {@link #getMv() modelview matrix} to its stack, while preserving its values. */ + public final PMVMatrix4f pushMv() { + matMv.push(); + return this; + } + /** Push the {@link #getP() projection matrix} to its stack, while preserving its values. */ + public final PMVMatrix4f pushP() { + matP.push(); + return this; + } + /** Push the {@link #getT() texture matrix} to its stack, while preserving its values. */ + public final PMVMatrix4f pushT() { + matTex.push(); + return this; + } + + /** + * {@link #mulP(Matrix4f) Multiply} the {@link #getP() projection matrix} with the orthogonal matrix. + * @param left + * @param right + * @param bottom + * @param top + * @param zNear + * @param zFar + * @see Matrix4f#setToOrtho(float, float, float, float, float, float) + */ + public final void orthoP(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) { + mulP( mat4Tmp1.setToOrtho(left, right, bottom, top, zNear, zFar) ); + } + + /** + * {@link #mulP(Matrix4f) Multiply} the {@link #getP() projection matrix} with the frustum matrix. + * + * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear} + * or {@code left == right}, or {@code bottom == top}. + * @see Matrix4f#setToFrustum(float, float, float, float, float, float) + */ + public final void frustumP(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) throws IllegalArgumentException { + mulP( mat4Tmp1.setToFrustum(left, right, bottom, top, zNear, zFar) ); + } + + // + // Extra functionality + // + + /** + * {@link #mulP(Matrix4f) Multiply} the {@link #getP() projection matrix} with the perspective/frustum matrix. + * + * @param fovy_rad fov angle in radians + * @param aspect aspect ratio width / height + * @param zNear + * @param zFar + * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear} + * @see Matrix4f#setToPerspective(float, float, float, float) + */ + public final PMVMatrix4f perspectiveP(final float fovy_rad, final float aspect, final float zNear, final float zFar) throws IllegalArgumentException { + mulP( mat4Tmp1.setToPerspective(fovy_rad, aspect, zNear, zFar) ); + return this; + } + + /** + * {@link #mulP(Matrix4f) Multiply} the {@link #getP() projection matrix} + * with the eye, object and orientation, i.e. {@link Matrix4f#setToLookAt(Vec3f, Vec3f, Vec3f, Matrix4f)}. + */ + public final PMVMatrix4f lookAtP(final Vec3f eye, final Vec3f center, final Vec3f up) { + mulP( mat4Tmp1.setToLookAt(eye, center, up, getTmp2Mat()) ); + return this; + } + + /** + * Map object coordinates to window coordinates. + * <p> + * Traditional <code>gluProject</code> implementation. + * </p> + * + * @param objPos 3 component object coordinate + * @param viewport Rect4i viewport + * @param winPos 3 component window coordinate, the result + * @return true if successful, otherwise false (z is 1) + */ + public final boolean mapObjToWin(final Vec3f objPos, final Recti viewport, final Vec3f winPos) { + return Matrix4f.mapObjToWin(objPos, matMv, matP, viewport, winPos); + } + + /** + * Map window coordinates to object coordinates. + * <p> + * Traditional <code>gluUnProject</code> implementation. + * </p> + * + * @param winx + * @param winy + * @param winz + * @param viewport Rect4i viewport + * @param objPos 3 component object coordinate, the result + * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) + */ + public final boolean mapWinToObj(final float winx, final float winy, final float winz, + final Recti viewport, final Vec3f objPos) { + if( Matrix4f.mapWinToObj(winx, winy, winz, getPMvi(), viewport, objPos) ) { + return true; + } else { + return false; + } + } + + /** + * Map window coordinates to object coordinates. + * <p> + * Traditional <code>gluUnProject4</code> implementation. + * </p> + * + * @param winx + * @param winy + * @param winz + * @param clipw + * @param viewport Rect4i viewport + * @param near + * @param far + * @param objPos 4 component object coordinate, the result + * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) + */ + public boolean mapWinToObj4(final float winx, final float winy, final float winz, final float clipw, + final Recti viewport, final float near, final float far, final Vec4f objPos) { + if( Matrix4f.mapWinToObj4(winx, winy, winz, clipw, getPMvi(), viewport, near, far, objPos) ) { + return true; + } else { + return false; + } + } + + /** + * Map two window coordinates w/ shared X/Y and distinctive Z + * to a {@link Ray}. The resulting {@link Ray} maybe used for <i>picking</i> + * using a {@link AABBox#getRayIntersection(Vec3f, Ray, float, boolean) bounding box}. + * <p> + * Notes for picking <i>winz0</i> and <i>winz1</i>: + * <ul> + * <li>see {@link FloatUtil#getZBufferEpsilon(int, float, float)}</li> + * <li>see {@link FloatUtil#getZBufferValue(int, float, float, float)}</li> + * <li>see {@link FloatUtil#getOrthoWinZ(float, float, float)}</li> + * </ul> + * </p> + * @param winx + * @param winy + * @param winz0 + * @param winz1 + * @param viewport + * @param ray storage for the resulting {@link Ray} + * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) + */ + public final boolean mapWinToRay(final float winx, final float winy, final float winz0, final float winz1, + final Recti viewport, final Ray ray) { + return Matrix4f.mapWinToRay(winx, winy, winz0, winz1, getPMvi(), viewport, ray); + } + + public StringBuilder toString(StringBuilder sb, final String f) { + if(null == sb) { + sb = new StringBuilder(); + } + final boolean pmvDirty = 0 != (PREMUL_PMV & dirtyBits); + final boolean pmvUsed = null != matPMv; + + final boolean pmviDirty = 0 != (PREMUL_PMVI & dirtyBits); + final boolean pmviUsed = null != matPMvi; + + final boolean frustumDirty = 0 != (FRUSTUM & dirtyBits); + final boolean frustumUsed = null != frustum; + + final boolean mviDirty = 0 != (INVERSE_MODELVIEW & dirtyBits); + final boolean mviReq = 0 != (INVERSE_MODELVIEW & requestBits); + + final boolean mvitDirty = 0 != (INVERSE_TRANSPOSED_MODELVIEW & dirtyBits); + final boolean mvitReq = 0 != (INVERSE_TRANSPOSED_MODELVIEW & requestBits); + + final boolean modP = 0 != ( MODIFIED_PROJECTION & modifiedBits ); + final boolean modMv = 0 != ( MODIFIED_MODELVIEW & modifiedBits ); + final boolean modT = 0 != ( MODIFIED_TEXTURE & modifiedBits ); + int count = 3; // P, Mv, T + + sb.append("PMVMatrix4f[modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT); + sb.append("], dirty/used[PMv ").append(pmvDirty).append("/").append(pmvUsed).append(", Pmvi ").append(pmviDirty).append("/").append(pmviUsed).append(", Frustum ").append(frustumDirty).append("/").append(frustumUsed); + sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq).append("]").append(System.lineSeparator()); + sb.append(", Projection").append(System.lineSeparator()); + matP.toString(sb, null, f); + sb.append(", Modelview").append(System.lineSeparator()); + matMv.toString(sb, null, f); + sb.append(", Texture").append(System.lineSeparator()); + matTex.toString(sb, null, f); + if( null != matPMv ) { + sb.append(", P * Mv").append(System.lineSeparator()); + matPMv.toString(sb, null, f); + ++count; + } + if( null != matPMvi ) { + sb.append(", P * Mv").append(System.lineSeparator()); + matPMvi.toString(sb, null, f); + ++count; + } + if( mviReq ) { + sb.append(", Inverse Modelview").append(System.lineSeparator()); + matMvi.toString(sb, null, f); + ++count; + } + if( mvitReq ) { + sb.append(", Inverse Transposed Modelview").append(System.lineSeparator()); + matMvit.toString(sb, null, f); + ++count; + } + int tmpCount = 1; + if( null != mat4Tmp2 ) { + ++tmpCount; + } + sb.append(", matrices "+count+" + "+tmpCount+" temp = "+(count+tmpCount)+"]"); + return sb; + } + + @Override + public String toString() { + return toString(null, "%10.5f").toString(); + } + + /** + * Returns the modified bits due to mutable operations.. + * <p> + * A modified bit is set, if the corresponding matrix had been modified by a mutable operation + * since last {@link #update()} or {@link #getModifiedBits(boolean) getModifiedBits(true)} call. + * </p> + * @param clear if true, clears the modified bits, otherwise leaves them untouched. + * + * @see #MODIFIED_PROJECTION + * @see #MODIFIED_MODELVIEW + * @see #MODIFIED_TEXTURE + * @see #getDirtyBits() + * @see #isReqDirty() + */ + public final int getModifiedBits(final boolean clear) { + final int r = modifiedBits; + if(clear) { + modifiedBits = 0; + } + return r; + } + + /** + * Returns the dirty bits due to mutable operations, + * i.e. + * - {@link #INVERSE_MODELVIEW} (if requested) + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} (if requested) + * - {@link #FRUSTUM} (always, cleared via {@link #getFrustum()} + * <p> + * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation + * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix4f(int)}. + * </p> + * <p> + * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}. + * </p> + * + * @see #isReqDirty() + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #FRUSTUM + * @see #PMVMatrix4f(int) + * @see #getMvi() + * @see #getMvit() + * @see #getSyncPMvMvi() + * @see #getSyncPMvMviMvit() + * @see #getFrustum() + */ + public final int getDirtyBits() { + return dirtyBits; + } + + /** + * Returns true if the one of the {@link #getReqBits() requested bits} are are set dirty due to mutable operations, + * i.e. at least one of + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} + * <p> + * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation + * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix4f(int)}. + * </p> + * <p> + * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}. + * </p> + * + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #PMVMatrix4f(int) + * @see #getMvi() + * @see #getMvit() + * @see #getSyncPMvMvi() + * @see #getSyncPMvMviMvit() + */ + public final boolean isReqDirty() { + return 0 != ( requestBits & dirtyBits ); + } + + /** + * Sets the {@link #getMv() Modelview (Mv)} matrix dirty and modified, + * i.e. adds {@link #getReqBits() requested bits} and {@link #MANUAL_BITS} to {@link #getDirtyBits() dirty bits}. + * @see #isReqDirty() + */ + public final void setModelviewDirty() { + dirtyBits |= requestBits | MANUAL_BITS ; + modifiedBits |= MODIFIED_MODELVIEW; + } + + /** + * Sets the {@link #getP() Projection (P)} matrix dirty and modified, + * i.e. adds {@link #MANUAL_BITS} to {@link #getDirtyBits() dirty bits}. + */ + public final void setProjectionDirty() { + dirtyBits |= MANUAL_BITS ; + modifiedBits |= MODIFIED_PROJECTION; + } + + /** + * Sets the {@link #getT() Texture (T)} matrix modified. + */ + public final void setTextureDirty() { + modifiedBits |= MODIFIED_TEXTURE; + } + + /** + * Returns the request bit mask, which uses bit values equal to the dirty mask + * and may contain + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} + * <p> + * The request bit mask is set by in the constructor {@link #PMVMatrix4f(int)}. + * </p> + * + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #PMVMatrix4f(int) + * @see #getMvi() + * @see #getMvit() + * @see #getSyncPMvMvi() + * @see #getSyncPMvMviMvit() + * @see #getFrustum() + */ + public final int getReqBits() { + return requestBits; + } + + /** + * Returns the pre-multiplied projection x modelview, P x Mv. + * <p> + * This {@link Matrix4f} instance should be re-fetched via this method and not locally stored + * to have it updated from a potential modification of underlying projection and/or modelview matrix. + * {@link #update()} has no effect on this {@link Matrix4f}. + * </p> + * <p> + * This pre-multipled P x Mv is considered dirty, if its corresponding + * {@link #getP() P matrix} or {@link #getMv() Mv matrix} has been modified since its last update. + * </p> + * @see #update() + */ + public final Matrix4f getPMv() { + if( 0 != ( dirtyBits & PREMUL_PMV ) ) { + if( null == matPMv ) { + matPMv = new Matrix4f(); + } + matPMv.mul(matP, matMv); + dirtyBits &= ~PREMUL_PMV; + } + return matPMv; + } + + /** + * Returns the pre-multiplied inverse projection x modelview, + * if {@link Matrix4f#invert(Matrix4f)} succeeded, otherwise `null`. + * <p> + * This {@link Matrix4f} instance should be re-fetched via this method and not locally stored + * to have it updated from a potential modification of underlying projection and/or modelview matrix. + * {@link #update()} has no effect on this {@link Matrix4f}. + * </p> + * <p> + * This pre-multipled invert(P x Mv) is considered dirty, if its corresponding + * {@link #getP() P matrix} or {@link #getMv() Mv matrix} has been modified since its last update. + * </p> + * @see #update() + */ + public final Matrix4f getPMvi() { + if( 0 != ( dirtyBits & PREMUL_PMVI ) ) { + if( null == matPMvi ) { + matPMvi = new Matrix4f(); + } + final Matrix4f mPMv = getPMv(); + matPMviOK = matPMvi.invert(mPMv); + dirtyBits &= ~PREMUL_PMVI; + } + return matPMviOK ? matPMvi : null; + } + + /** + * Returns the frustum, derived from projection x modelview. + * <p> + * This {@link Frustum} instance should be re-fetched via this method and not locally stored + * to have it updated from a potential modification of underlying projection and/or modelview matrix. + * {@link #update()} has no effect on this {@link Frustum}. + * </p> + * <p> + * The {@link Frustum} is considered dirty, if its corresponding + * {@link #getP() P matrix} or {@link #getMv() Mv matrix} has been modified since its last update. + * </p> + * @see #update() + */ + public final Frustum getFrustum() { + if( 0 != ( dirtyBits & FRUSTUM ) ) { + if( null == frustum ) { + frustum = new Frustum(); + } + final Matrix4f mPMv = getPMv(); + frustum.updateFrustumPlanes(mPMv); + dirtyBits &= ~FRUSTUM; + } + return frustum; + } + + /** + * Update the derived {@link #getMvi() inverse modelview (Mvi)}, + * {@link #getMvit() inverse transposed modelview (Mvit)} matrices + * <b>if</b> they {@link #isReqDirty() are dirty} <b>and</b> + * requested via the constructor {@link #PMVMatrix4f(int)}.<br/> + * Hence updates the following dirty bits. + * - {@link #INVERSE_MODELVIEW} + * - {@link #INVERSE_TRANSPOSED_MODELVIEW} + * <p> + * The {@link Frustum} is updated only via {@link #getFrustum()} separately. + * </p> + * <p> + * The Mvi and Mvit matrices are considered dirty, if their corresponding + * {@link #getMv() Mv matrix} has been modified since their last update. + * </p> + * <p> + * Method is automatically called by {@link SyncMatrix4f} and {@link SyncMatrices4f} + * instances {@link SyncAction} as retrieved by e.g. {@link #getSyncMvit()}. + * This ensures an automatic update cycle if used with {@link com.jogamp.opengl.GLUniformData}. + * </p> + * <p> + * Method may be called manually in case mutable operations has been called + * and caller operates on already fetched references, i.e. not calling + * {@link #getMvi()}, {@link #getMvit()} anymore. + * </p> + * <p> + * Method clears the modified bits like {@link #getModifiedBits(boolean) getModifiedBits(true)}, + * which are set by any mutable operation. The modified bits have no impact + * on this method, but the return value. + * </p> + * + * @return true if any matrix has been modified since last update call or + * if the derived matrices Mvi and Mvit were updated, otherwise false. + * In other words, method returns true if any matrix used by the caller must be updated, + * e.g. uniforms in a shader program. + * + * @see #getModifiedBits(boolean) + * @see #isReqDirty() + * @see #INVERSE_MODELVIEW + * @see #INVERSE_TRANSPOSED_MODELVIEW + * @see #PMVMatrix4f(int) + * @see #getMvi() + * @see #getMvit() + * @see #getSyncPMvMvi() + * @see #getSyncPMvMviMvit() + */ + public final boolean update() { + return updateImpl(true); + } + + // + // private + // + + private final boolean updateImpl(final boolean clearModBits) { + boolean mod = 0 != modifiedBits; + if( clearModBits ) { + modifiedBits = 0; + } + if( 0 != ( requestBits & ( ( dirtyBits & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) ) ) { // only if dirt requested & dirty + if( !matMvi.invert(matMv) ) { + throw new RuntimeException("Invalid source Mv matrix, can't compute inverse"); + } + dirtyBits &= ~INVERSE_MODELVIEW; + mod = true; + } + if( 0 != ( requestBits & ( dirtyBits & INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty + matMvit.transpose(matMvi); + dirtyBits &= ~INVERSE_TRANSPOSED_MODELVIEW; + mod = true; + } + return mod; + } + + protected final Matrix4f matP; + protected final Matrix4f matMv; + protected final Matrix4f matTex; + + private final Matrix4f matMvi; + private final Matrix4f matMvit; + + private static final int mP_offset = 0*16; + private static final int mMv_offset = 1*16; + private final int mMvi_offset; + private final int mMvit_offset; + private final int mTex_offset; + + private final float[] matrixStore; + + private final SyncMatrix4f syncP, syncMv, syncT; + private final SyncMatrix4f syncMvi, syncMvit; + private final SyncMatrices4f syncP_Mv, syncP_Mv_Mvi, syncP_Mv_Mvi_Mvit; + + protected final Matrix4f mat4Tmp1; + private Matrix4f mat4Tmp2; + + private int modifiedBits = MODIFIED_ALL; + private int dirtyBits = 0; // contains the dirty bits, i.e. hinting for update operation + private final int requestBits; // may contain the requested bits: INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW + private Matrix4f matPMv; + private Matrix4f matPMvi; + private boolean matPMviOK; + private Frustum frustum; + + private abstract class PMVSyncBuffer implements SyncMatrix4f { + protected final Matrix4f mat; + private final FloatBuffer fbuf; + + public PMVSyncBuffer(final Matrix4f m, final FloatBuffer fbuf) { + this.mat = m; + this.fbuf = fbuf; + } + + @Override + public final Buffer getBuffer() { return fbuf; } + + @Override + public final SyncBuffer sync() { getAction().sync(); return this; } + + @Override + public final Buffer getSyncBuffer() { getAction().sync(); return fbuf; } + + @Override + public final Matrix4f getMatrix() { return mat; } + + @Override + public final FloatBuffer getSyncFloats() { getAction().sync(); return fbuf; } + } + private final class SyncBuffer0 extends PMVSyncBuffer { + private final SyncAction action = new SyncAction() { + @Override + public void sync() { mat.get(matrixStore); } + }; + + public SyncBuffer0(final Matrix4f m, final FloatBuffer fbuf) { super(m, fbuf); } + + @Override + public SyncAction getAction() { return action; } + + } + private final class SyncBuffer1 extends PMVSyncBuffer { + private final int offset; + private final SyncAction action = new SyncAction() { + @Override + public void sync() { mat.get(matrixStore, offset); } + }; + + public SyncBuffer1(final Matrix4f m, final FloatBuffer fbuf, final int offset) { + super(m, fbuf); + this.offset = offset; + } + + @Override + public SyncAction getAction() { return action; } + } + private final class SyncBuffer1U extends PMVSyncBuffer { + private final int offset; + private final SyncAction action = new SyncAction() { + @Override + public void sync() { + updateImpl(true); + mat.get(matrixStore, offset); + } + }; + + public SyncBuffer1U(final Matrix4f m, final FloatBuffer fbuf, final int offset) { + super(m, fbuf); + this.offset = offset; + } + + @Override + public SyncAction getAction() { return action; } + } + + private abstract class PMVSyncBufferN implements SyncMatrices4f { + protected final Matrix4f[] mats; + private final FloatBuffer fbuf; + + public PMVSyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf) { + this.mats = ms; + this.fbuf = fbuf; + } + + @Override + public final Buffer getBuffer() { return fbuf; } + + @Override + public final SyncBuffer sync() { getAction().sync(); return this; } + + @Override + public final Buffer getSyncBuffer() { getAction().sync(); return fbuf; } + + @Override + public Matrix4f[] getMatrices() { return mats; } + + @Override + public final FloatBuffer getSyncFloats() { getAction().sync(); return fbuf; } + } + private final class SyncBufferN extends PMVSyncBufferN { + private final int offset; + private final SyncAction action = new SyncAction() { + @Override + public void sync() { + int ioff = offset; + for(int i=0; i<mats.length; ++i, ioff+=16) { + mats[i].get(matrixStore, ioff); + } + } + }; + + public SyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { + super(ms, fbuf); + this.offset = offset; + } + + @Override + public SyncAction getAction() { return action; } + } + private final class SyncBufferNU extends PMVSyncBufferN { + private final int offset; + private final SyncAction action = new SyncAction() { + @Override + public void sync() { + updateImpl(true); + int ioff = offset; + for(int i=0; i<mats.length; ++i, ioff+=16) { + mats[i].get(matrixStore, ioff); + } + } + }; + + public SyncBufferNU(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { + super(ms, fbuf); + this.offset = offset; + } + + @Override + public SyncAction getAction() { return action; } + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/util/SyncAction.java b/src/jogl/classes/com/jogamp/math/util/SyncAction.java index fbf55e683..08be2d2ac 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/SyncAction.java +++ b/src/jogl/classes/com/jogamp/math/util/SyncAction.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.util; +package com.jogamp.math.util; /** * Specific data synchronization action implemented by the data provider diff --git a/src/jogl/classes/com/jogamp/opengl/util/SyncBuffer.java b/src/jogl/classes/com/jogamp/math/util/SyncBuffer.java index 27bdb5dfb..368a69b14 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/SyncBuffer.java +++ b/src/jogl/classes/com/jogamp/math/util/SyncBuffer.java @@ -25,7 +25,7 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.util; +package com.jogamp.math.util; import java.nio.Buffer; diff --git a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrices4f.java b/src/jogl/classes/com/jogamp/math/util/SyncMatrices4f.java index 055345d65..cc2ae36b6 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrices4f.java +++ b/src/jogl/classes/com/jogamp/math/util/SyncMatrices4f.java @@ -25,13 +25,13 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.util; +package com.jogamp.math.util; import java.nio.FloatBuffer; -import com.jogamp.opengl.math.Matrix4f; +import com.jogamp.math.Matrix4f; -/** {@link SyncBuffer} with a multiple underlying {@link Matrix4f}, used in {@link SyncMatrices4f16} and {@link PMVMatrix} */ +/** {@link SyncBuffer} with a multiple underlying {@link Matrix4f}, used in {@link SyncMatrices4f16} and {@link com.jogamp.math.util.PMVMatrix4f PMVMatrix4f} */ public interface SyncMatrices4f extends SyncBuffer { /** Return the underlying multiple {@link Matrix4f}, used to {@link SyncAction#sync() synchronize} to the {@link #getBuffer()}. */ Matrix4f[] getMatrices(); diff --git a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrices4f16.java b/src/jogl/classes/com/jogamp/math/util/SyncMatrices4f16.java index bca827b9f..6faba38ee 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrices4f16.java +++ b/src/jogl/classes/com/jogamp/math/util/SyncMatrices4f16.java @@ -25,12 +25,12 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.util; +package com.jogamp.math.util; import java.nio.Buffer; import java.nio.FloatBuffer; -import com.jogamp.opengl.math.Matrix4f; +import com.jogamp.math.Matrix4f; /** {@link SyncBuffer} {@link SyncMatrices4f16} implementation for multiple underlying {@link Matrix4f} instances using one {@code float[16*n]} backing array. */ public final class SyncMatrices4f16 implements SyncMatrices4f { diff --git a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrix4f.java b/src/jogl/classes/com/jogamp/math/util/SyncMatrix4f.java index 6ab473771..9ca6857c5 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrix4f.java +++ b/src/jogl/classes/com/jogamp/math/util/SyncMatrix4f.java @@ -25,13 +25,13 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.util; +package com.jogamp.math.util; import java.nio.FloatBuffer; -import com.jogamp.opengl.math.Matrix4f; +import com.jogamp.math.Matrix4f; -/** {@link SyncBuffer} interface with a single underlying {@link Matrix4f}, used in {@link SyncMatrix4f16} and {@link PMVMatrix}. */ +/** {@link SyncBuffer} interface with a single underlying {@link Matrix4f}, used in {@link SyncMatrix4f16} and {@link com.jogamp.math.util.PMVMatrix4f PMVMatrix4f}. */ public interface SyncMatrix4f extends SyncBuffer { /** Return the underlying {@link Matrix4f}, used to {@link SyncAction#sync() synchronize} to the {@link #getBuffer()}. */ Matrix4f getMatrix(); diff --git a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrix4f16.java b/src/jogl/classes/com/jogamp/math/util/SyncMatrix4f16.java index 03a4b64fa..e6b7e8742 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/SyncMatrix4f16.java +++ b/src/jogl/classes/com/jogamp/math/util/SyncMatrix4f16.java @@ -25,12 +25,12 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ -package com.jogamp.opengl.util; +package com.jogamp.math.util; import java.nio.Buffer; import java.nio.FloatBuffer; -import com.jogamp.opengl.math.Matrix4f; +import com.jogamp.math.Matrix4f; /** {@link SyncBuffer} {@link SyncMatrix4f} implementation for a single underlying {@link Matrix4f} using one {@code float[16]} backing array. */ public final class SyncMatrix4f16 implements SyncMatrix4f { diff --git a/src/jogl/classes/com/jogamp/opengl/GLUniformData.java b/src/jogl/classes/com/jogamp/opengl/GLUniformData.java index c4cc3fe8f..63eb2658d 100644 --- a/src/jogl/classes/com/jogamp/opengl/GLUniformData.java +++ b/src/jogl/classes/com/jogamp/opengl/GLUniformData.java @@ -32,9 +32,9 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import com.jogamp.common.nio.Buffers; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.util.SyncAction; -import com.jogamp.opengl.util.SyncBuffer; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.util.SyncAction; +import com.jogamp.math.util.SyncBuffer; /** * GLSL uniform data wrapper encapsulating data to be uploaded to the GPU as a uniform. diff --git a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java index ebb164912..3350b30a7 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java +++ b/src/jogl/classes/com/jogamp/opengl/util/PMVMatrix.java @@ -27,38 +27,27 @@ */ package com.jogamp.opengl.util; -import java.nio.Buffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import com.jogamp.opengl.GL; import com.jogamp.opengl.GLException; import com.jogamp.opengl.fixedfunc.GLMatrixFunc; -import com.jogamp.opengl.GLUniformData; -import com.jogamp.common.nio.Buffers; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.Ray; -import com.jogamp.opengl.math.Recti; -import com.jogamp.opengl.math.Vec3f; -import com.jogamp.opengl.math.Vec4f; -import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.math.geom.Frustum; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.Matrix4f; +import com.jogamp.math.Quaternion; +import com.jogamp.math.Recti; +import com.jogamp.math.Vec3f; +import com.jogamp.math.geom.Frustum; +import com.jogamp.math.util.PMVMatrix4f; /** - * PMVMatrix implements a subset of the fixed function pipeline - * regarding the projection (P), modelview (Mv) and texture (T) matrix operations, - * which is specified in {@link GLMatrixFunc}. + * PMVMatrix implements a subset of the fixed function pipeline {@link GLMatrixFunc} + * using {@link PMVMatrix4f}. * <p> - * This is the second implementation of `PMVMatrix` using - * direct {@link Matrix4f}, {@link Vec4f} and {@link Vec3f} math operations instead of `float[]` - * via {@link com.jogamp.opengl.math.FloatUtil FloatUtil}. - * </p> - * <p> - * PMVMatrix provides the {@link #getMviMat() inverse modelview matrix (Mvi)} and - * {@link #getMvitMat() inverse transposed modelview matrix (Mvit)}. + * PMVMatrix provides the {@link #getMvi() inverse modelview matrix (Mvi)} and + * {@link #getMvit() inverse transposed modelview matrix (Mvit)}. * {@link Frustum} is also provided by {@link #getFrustum()}. * * To keep these derived values synchronized after mutable Mv operations like {@link #glRotatef(float, float, float, float) glRotatef(..)} @@ -66,68 +55,11 @@ import com.jogamp.opengl.math.geom.Frustum; * users have to call {@link #update()} before using Mvi and Mvit. * </p> * <p> - * All matrices are provided in column-major order, - * as specified in the OpenGL fixed function pipeline, i.e. compatibility profile. - * See {@link Matrix4f}. - * </p> - * <p> - * PMVMatrix can supplement {@link GL2ES2} applications w/ the + * PMVMatrix can supplement {@link com.jogamp.opengl.GL2ES2 GL2ES2} applications w/ the * lack of the described matrix functionality. * </p> - * <a name="storageDetails"><h5>Matrix storage details</h5></a> - * <p> - * The {@link SyncBuffer} abstraction is provided, e.g. {@link #getSyncPMvMviMat()}, - * to synchronize the respective {@link Matrix4f matrices} with the `float[]` backing store. - * The latter is represents the data to {@link GLUniformData} via its {@link FloatBuffer}s, see {@link SyncBuffer#getBuffer()}, - * and is pushed to the GPU eventually. - * - * {@link SyncBuffer}'s {@link SyncAction} is called by {@link GLUniformData#getBuffer()}, - * i.e. before the data is pushed to the GPU. - * - * The provided {@link SyncAction} ensures that the {@link Matrix4f matrices data} - * gets copied into the `float[]` backing store. - * - * PMVMatrix provides two specializations of {@link SyncBuffer}, {@link SyncMatrix4f} for single {@link Matrix4f} mappings - * and {@link SyncMatrices4f} for multiple {@link Matrix4f} mappings. - * - * They can be feed directly to instantiate a {@link GLUniformData} object via e.g. {@link GLUniformData#GLUniformData(String, int, int, SyncBuffer)}. - * </p> - * <p> - * All matrices are backed up by a common primitive float-array for performance considerations - * and are a {@link Buffers#slice2Float(float[], int, int) sliced} representation of it. - * </p> - * <p> - * <b>Note:</b> - * <ul> - * <li>The matrix is a {@link Buffers#slice2Float(float[], int, int) sliced part } of a host matrix and it's start position has been {@link FloatBuffer#mark() marked}.</li> - * <li>Use {@link FloatBuffer#reset() reset()} to rewind it to it's start position after relative operations, like {@link FloatBuffer#get() get()}.</li> - * <li>If using absolute operations like {@link FloatBuffer#get(int) get(int)}, use it's {@link FloatBuffer#reset() reset} {@link FloatBuffer#position() position} as it's offset.</li> - * </ul> - * </p> */ -public final class PMVMatrix implements GLMatrixFunc { - - /** Bit value stating a modified {@link #getPMat() projection matrix (P)}, since last {@link #update()} call. */ - public static final int MODIFIED_PROJECTION = 1 << 0; - /** Bit value stating a modified {@link #getMvMat() modelview matrix (Mv)}, since last {@link #update()} call. */ - public static final int MODIFIED_MODELVIEW = 1 << 1; - /** Bit value stating a modified {@link #getTMat() texture matrix (T)}, since last {@link #update()} call. */ - public static final int MODIFIED_TEXTURE = 1 << 2; - /** Bit value stating all is modified */ - public static final int MODIFIED_ALL = MODIFIED_PROJECTION | MODIFIED_MODELVIEW | MODIFIED_TEXTURE ; - - /** Bit value for {@link #getMviMat() inverse modelview matrix (Mvi)}, updated via {@link #update()}. */ - public static final int INVERSE_MODELVIEW = 1 << 1; - /** Bit value for {@link #getMvitMat() inverse transposed modelview matrix (Mvit)}, updated via {@link #update()}. */ - public static final int INVERSE_TRANSPOSED_MODELVIEW = 1 << 2; - /** Bit value for {@link #getFrustum() frustum} and updated by {@link #getFrustum()}. */ - public static final int FRUSTUM = 1 << 3; - /** Bit value for {@link #getPMvMat() pre-multiplied P * Mv}, updated by {@link #getPMvMat()}. */ - public static final int PREMUL_PMV = 1 << 4; - /** Bit value for {@link #getPMviMat() pre-multiplied invert(P * Mv)}, updated by {@link #getPMviMat()}. */ - public static final int PREMUL_PMVI = 1 << 5; - /** Manual bits not covered by {@link #update()} but {@link #getFrustum()}, {@link #FRUSTUM}, {@link #getPMvMat()}, {@link #PREMUL_PMV}, {@link #getPMviMat()}, {@link #PREMUL_PMVI}, etc. */ - public static final int MANUAL_BITS = FRUSTUM | PREMUL_PMV | PREMUL_PMVI; +public final class PMVMatrix extends PMVMatrix4f implements GLMatrixFunc { /** * @param matrixModeName One of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE} @@ -227,297 +159,29 @@ public final class PMVMatrix implements GLMatrixFunc { * @see #update() */ public PMVMatrix(final int derivedMatrices) { - // I Identity - // T Texture - // P Projection - // Mv ModelView - // Mvi Modelview-Inverse - // Mvit Modelview-Inverse-Transpose - { - int mask = 0; - if( 0 != ( derivedMatrices & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) { - mask |= INVERSE_MODELVIEW; - } - if( 0 != ( derivedMatrices & INVERSE_TRANSPOSED_MODELVIEW ) ) { - mask |= INVERSE_TRANSPOSED_MODELVIEW; - } - requestBits = mask; - } - - // actual underlying Matrix4f count - int mcount = 3; - - // actual underlying Matrix4f data - matP = new Matrix4f(); - matMv = new Matrix4f(); - matTex = new Matrix4f(); - - if( 0 != ( requestBits & INVERSE_MODELVIEW ) ) { - matMvi = new Matrix4f(); - mMvi_offset = 2*16; - ++mcount; - } else { - matMvi = null; - mMvi_offset = -1; - } - if( 0 != ( requestBits & INVERSE_TRANSPOSED_MODELVIEW ) ) { - matMvit = new Matrix4f(); - mMvit_offset = 3*16; - ++mcount; - } else { - matMvit = null; - mMvit_offset = -1; - } - mTex_offset = (mcount-1)*16; // last one - - // float back buffer for GPU, Matrix4f -> matrixStore via SyncedBuffer - matrixStore = new float[mcount*16]; - - // FloatBuffer for single Matrix4f back-buffer - bufP = Buffers.slice2Float(matrixStore, mP_offset, 1*16); // P - syncP = new SyncBuffer0(matP, bufP); // mP_offset - - bufMv = Buffers.slice2Float(matrixStore, mMv_offset, 1*16); // Mv - syncMv = new SyncBuffer1(matMv, bufMv, mMv_offset); - - bufP_Mv = Buffers.slice2Float(matrixStore, mP_offset, 2*16); // P + Mv - syncP_Mv = new SyncBufferN(new Matrix4f[] { matP, matMv }, bufP_Mv, mP_offset); - - bufTex = Buffers.slice2Float(matrixStore, mTex_offset, 1*16); // T - syncT = new SyncBuffer1(matTex, bufTex, mTex_offset); - - if( null != matMvi ) { - bufMvi = Buffers.slice2Float(matrixStore, mMvi_offset, 1*16); // Mvi - bufP_Mv_Mvi = Buffers.slice2Float(matrixStore, mP_offset, 3*16); // P + Mv + Mvi - syncMvi = new SyncBuffer1U(matMvi, bufMvi, mMvi_offset); - syncP_Mv_Mvi = new SyncBufferNU(new Matrix4f[] { matP, matMv, matMvi }, bufP_Mv_Mvi, mP_offset); - } else { - bufMvi = null; - bufP_Mv_Mvi = null; - syncMvi = null; - syncP_Mv_Mvi = null; - } - if( null != matMvit ) { - bufMvit = Buffers.slice2Float(matrixStore, mMvit_offset, 1*16); // Mvit - bufP_Mv_Mvi_Mvit = Buffers.slice2Float(matrixStore, mP_offset, 4*16); // P + Mv + Mvi + Mvit - syncMvit = new SyncBuffer1U(matMvit, bufMvit, mMvit_offset); - syncP_Mv_Mvi_Mvit = new SyncBufferNU(new Matrix4f[] { matP, matMv, matMvi, matMvit }, bufP_Mv_Mvi_Mvit, mP_offset); - } else { - bufMvit = null; - bufP_Mv_Mvi_Mvit = null; - syncMvit = null; - syncP_Mv_Mvi_Mvit = null; - } - - mat4Tmp1 = new Matrix4f(); - - mat4Tmp2 = null; // on demand - matPMv = null; // on demand - matPMvi = null; // on demand - matPMviOK = false; - frustum = null; // on demand - - reset(); - } - - /** - * Issues {@link #glLoadIdentity()} on all matrices, - * i.e. {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE} - * and resets all internal states. - * - * Leaves {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW} the active matrix mode. - */ - public final void reset() { - matP.loadIdentity(); - matMv.loadIdentity(); - matTex.loadIdentity(); - - modifiedBits = MODIFIED_ALL; - dirtyBits = requestBits | MANUAL_BITS; - matrixMode = GL_MODELVIEW; - } - - /** Returns the current matrix-mode, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}. */ - public final int glGetMatrixMode() { - return matrixMode; + super(derivedMatrices); } - // - // Temporary storage access for efficiency - // /** - * Return the second temporary Matrix4f exposed to be reused for efficiency. + * {@inheritDoc} * <p> - * Temporary storage is only used by this class within single method calls, - * hence has no side-effects. + * Leaves {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW} the active matrix mode. * </p> */ - private final Matrix4f getTmp2Mat() { - if( null == mat4Tmp2 ) { - mat4Tmp2 = new Matrix4f(); - } - return mat4Tmp2; + @Override + public void reset() { + super.reset(); + matrixMode = GL_MODELVIEW; } // - // Regular Matrix4f access as well as their SyncedBuffer counterpart SyncedMatrix and SyncedMatrices + // GLMatrixFunc implementation // - /** - * Returns the {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T). - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final Matrix4f getTMat() { - return matTex; - } - - /** - * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T). - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final SyncMatrix4f getSyncTMat() { - return syncT; - } - - /** - * Returns the {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P). - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final Matrix4f getPMat() { - return matP; - } - - /** - * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P). - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final SyncMatrix4f getSyncPMat() { - return syncP; - } - - /** - * Returns the {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv). - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final Matrix4f getMvMat() { - return matMv; - } - - /** - * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv). - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final SyncMatrix4f getSyncMvMat() { - return syncMv; - } - - /** - * Returns {@link SyncMatrices4f} of 2 matrices within one FloatBuffer: {@link #getPMat() P} and {@link #getMvMat() Mv}. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - */ - public final SyncMatrices4f getSyncPMvMat() { - return syncP_Mv; - } - - /** - * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. - */ - public final Matrix4f getMviMat() { - if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { - throw new IllegalArgumentException("Not requested in ctor"); - } - updateImpl(false); - return matMvi; - } - - /** - * Returns the {@link SyncMatrix} of inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. - */ - public final SyncMatrix4f getSyncMviMat() { - if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { - throw new IllegalArgumentException("Not requested in ctor"); - } - return syncMvi; - } - - /** - * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. - */ - public final Matrix4f getMvitMat() { - if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { - throw new IllegalArgumentException("Not requested in ctor"); - } - updateImpl(false); - return matMvit; - } - - /** - * Returns the {@link SyncMatrix} of inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. - */ - public final SyncMatrix4f getSyncMvitMat() { - if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { - throw new IllegalArgumentException("Not requested in ctor"); - } - return syncMvit; - } - - /** - * Returns {@link SyncMatrices4f} of 3 matrices within one FloatBuffer: {@link #getPMat() P}, {@link #getMvMat() Mv} and {@link #getMviMat() Mvi} if requested. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. - */ - public final SyncMatrices4f getSyncPMvMviMat() { - if( 0 == ( INVERSE_MODELVIEW & requestBits ) ) { - throw new IllegalArgumentException("Not requested in ctor"); - } - return syncP_Mv_Mvi; - } - - /** - * Returns {@link SyncMatrices4f} of 4 matrices within one FloatBuffer: {@link #getPMat() P}, {@link #getMvMat() Mv}, {@link #getMviMat() Mvi} and {@link #getMvitMat() Mvit} if requested. - * <p> - * See <a href="#storageDetails"> matrix storage details</a>. - * </p> - * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix(int)}. - */ - public final SyncMatrices4f getSyncPMvMviMvitMat() { - if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & requestBits ) ) { - throw new IllegalArgumentException("Not requested in ctor"); - } - return syncP_Mv_Mvi_Mvit; + /** Returns the current matrix-mode, one of {@link GLMatrixFunc#GL_MODELVIEW GL_MODELVIEW}, {@link GLMatrixFunc#GL_PROJECTION GL_PROJECTION} or {@link GL#GL_TEXTURE GL_TEXTURE}. */ + public final int glGetMatrixMode() { + return matrixMode; } /** @@ -550,172 +214,6 @@ public final class PMVMatrix implements GLMatrixFunc { } } - // - // Basic Matrix4f, Vec3f and Vec4f operations similar to GLMatrixFunc - // - - /** - * Multiplies the {@link #getPMat() P} and {@link #getMvMat() Mv} matrix, i.e. - * <pre> - * result = P x Mv - * </pre> - * @param result 4x4 matrix storage for result - * @return given result matrix for chaining - */ - public final Matrix4f mulPMvMat(final Matrix4f result) { - return result.mul(matP, matMv); - } - - /** - * Multiplies the {@link #getMvMat() Mv} and {@link #getPMat() P} matrix, i.e. - * <pre> - * result = Mv x P - * </pre> - * @param result 4x4 matrix storage for result - * @return given result matrix for chaining - */ - public final Matrix4f mulMvPMat(final Matrix4f result) { - return result.mul(matMv, matP); - } - - /** - * v_out = Mv * v_in - * @param v_in input vector, can be v_out for in-place transformation - * @param v_out output vector - * @returns v_out for chaining - */ - public final Vec4f mulMvMatVec4f(final Vec4f v_in, final Vec4f v_out) { - return matMv.mulVec4f(v_in, v_out); - } - - /** - * v_inout = Mv * v_inout - * @param v_inout input and output vector, i.e. in-place transformation - * @returns v_inout for chaining - */ - public final Vec4f mulMvMatVec4f(final Vec4f v_inout) { - return matMv.mulVec4f(v_inout); - } - - /** - * v_out = Mv * v_in - * - * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. - * - * @param v_in input vector, can be v_out for in-place transformation - * @param v_out output vector - * @returns v_out for chaining - */ - public final Vec3f mulMvMatVec3f(final Vec3f v_in, final Vec3f v_out) { - return matMv.mulVec3f(v_in, v_out); - } - - /** - * v_inout = Mv * v_inout - * - * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. - * - * @param v_inout input and output vector, i.e. in-place transformation - * @returns v_inout for chaining - */ - public final Vec3f mulMvMatVec3f(final Vec3f v_inout) { - return matMv.mulVec3f(v_inout); - } - - /** - * v_out = P * v_in - * @param v_in input vector, can be v_out for in-place transformation - * @param v_out output vector - * @return given result vector for chaining - * @returns v_out for chaining - */ - public final Vec4f mulPMatVec4f(final Vec4f v_in, final Vec4f v_out) { - return matP.mulVec4f(v_in, v_out); - } - - /** - * v_inout = P * v_inout - * @param v_inout input and output vector, i.e. in-place transformation - * @return given result vector for chaining - * @returns v_inout for chaining - */ - public final Vec4f mulPMatVec4f(final Vec4f v_inout) { - return matP.mulVec4f(v_inout); - } - - /** - * v_out = P * v_in - * - * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. - * - * @param v_in float[3] input vector, can be v_out for in-place transformation - * @param v_out float[3] output vector - * @returns v_out for chaining - */ - public final Vec3f mulPMatVec3f(final Vec3f v_in, final Vec3f v_out) { - return matP.mulVec3f(v_in, v_out); - } - - /** - * v_inout = P * v_inout - * - * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. - * - * @param v_inout input and output vector, i.e. in-place transformation - * @returns v_inout for chaining - */ - public final Vec3f mulPMatVec3f(final Vec3f v_inout) { - return matP.mulVec3f(v_inout); - } - - /** - * v_out = P * Mv * v_in - * @param v_in float[4] input vector, can be v_out for in-place transformation - * @param v_out float[4] output vector - * @returns v_out for chaining - */ - public final Vec4f mulPMvMatVec4f(final Vec4f v_in, final Vec4f v_out) { - return matP.mulVec4f( matMv.mulVec4f( v_in, v_out ) ); - } - - /** - * v_inout = P * Mv * v_inout - * @param v_inout input and output vector, i.e. in-place transformation - * @returns v_inout for chaining - */ - public final Vec4f mulPMvMatVec4f(final Vec4f v_inout) { - return matP.mulVec4f( matMv.mulVec4f( v_inout ) ); - } - - /** - * v_out = P * Mv * v_in - * - * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. - * - * @param v_in float[3] input vector, can be v_out for in-place transformation - * @param v_out float[3] output vector - * @returns v_out for chaining - */ - public final Vec3f mulPMvMatVec3f(final Vec3f v_in, final Vec3f v_out) { - return matP.mulVec3f( matMv.mulVec3f( v_in, v_out ) ); - } - - /** - * v_inout = P * Mv * v_inout - * - * Affine 3f-vector transformation by 4x4 matrix, see {@link Matrix4f#mulVec3f(Vec3f, Vec3f)}. - * - * @param v_inout float[3] input and output vector, i.e. in-place transformation - * @returns v_inout for chaining - */ - public final Vec3f mulPMvMatVec3f(final Vec3f v_inout) { - return matP.mulVec3f( matMv.mulVec3f( v_inout ) ); - } - - // - // GLMatrixFunc implementation - // - @Override public final void glMatrixMode(final int matrixName) { switch(matrixName) { @@ -772,35 +270,23 @@ public final class PMVMatrix implements GLMatrixFunc { @Override public final void glLoadMatrixf(final float[] values, final int offset) { if(matrixMode==GL_MODELVIEW) { - matMv.load(values, offset); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + loadMv(values, offset); } else if(matrixMode==GL_PROJECTION) { - matP.load(values, offset); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + loadP(values, offset); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.load(values, offset); - modifiedBits |= MODIFIED_TEXTURE; + loadT(values, offset); } } @Override public final void glLoadMatrixf(final java.nio.FloatBuffer m) { - final int spos = m.position(); if(matrixMode==GL_MODELVIEW) { - matMv.load(m); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + loadMv(m); } else if(matrixMode==GL_PROJECTION) { - matP.load(m); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + loadP(m); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.load(m); - modifiedBits |= MODIFIED_TEXTURE; + loadT(m); } - m.position(spos); } /** @@ -811,16 +297,11 @@ public final class PMVMatrix implements GLMatrixFunc { */ public final void glLoadMatrixf(final Matrix4f m) { if(matrixMode==GL_MODELVIEW) { - matMv.load(m); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + loadMv(m); } else if(matrixMode==GL_PROJECTION) { - matP.load(m); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + loadP(m); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.load(m); - modifiedBits |= MODIFIED_TEXTURE; + loadT(m); } } @@ -832,59 +313,22 @@ public final class PMVMatrix implements GLMatrixFunc { */ public final void glLoadMatrix(final Quaternion quat) { if(matrixMode==GL_MODELVIEW) { - matMv.setToRotation(quat); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + loadMv(quat); } else if(matrixMode==GL_PROJECTION) { - matP.setToRotation(quat); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + loadP(quat); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.setToRotation(quat); - modifiedBits |= MODIFIED_TEXTURE; - } - } - - @Override - public final void glPopMatrix() { - if(matrixMode==GL_MODELVIEW) { - matMv.pop(); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; - } else if(matrixMode==GL_PROJECTION) { - matP.pop(); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; - } else if(matrixMode==GL.GL_TEXTURE) { - matTex.pop(); - modifiedBits |= MODIFIED_TEXTURE; - } - } - - @Override - public final void glPushMatrix() { - if(matrixMode==GL_MODELVIEW) { - matMv.push(); - } else if(matrixMode==GL_PROJECTION) { - matP.push(); - } else if(matrixMode==GL.GL_TEXTURE) { - matTex.push(); + loadT(quat); } } @Override public final void glLoadIdentity() { if(matrixMode==GL_MODELVIEW) { - matMv.loadIdentity(); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + loadMvIdentity(); } else if(matrixMode==GL_PROJECTION) { - matP.loadIdentity(); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + loadPIdentity(); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.loadIdentity(); - modifiedBits |= MODIFIED_TEXTURE; + loadTIdentity(); } } @@ -892,16 +336,11 @@ public final class PMVMatrix implements GLMatrixFunc { public final void glMultMatrixf(final FloatBuffer m) { final int spos = m.position(); if(matrixMode==GL_MODELVIEW) { - matMv.mul( mat4Tmp1.load( m ) ); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + mulMv( mat4Tmp1.load( m ) ); } else if(matrixMode==GL_PROJECTION) { - matP.mul( mat4Tmp1.load( m ) ); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + mulP( mat4Tmp1.load( m ) ); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.mul( mat4Tmp1.load( m ) ); - modifiedBits |= MODIFIED_TEXTURE; + mulT( mat4Tmp1.load( m ) ); } m.position(spos); } @@ -909,16 +348,11 @@ public final class PMVMatrix implements GLMatrixFunc { @Override public final void glMultMatrixf(final float[] m, final int m_offset) { if(matrixMode==GL_MODELVIEW) { - matMv.mul( mat4Tmp1.load( m, m_offset ) ); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + mulMv( mat4Tmp1.load( m, m_offset ) ); } else if(matrixMode==GL_PROJECTION) { - matP.mul( mat4Tmp1.load( m, m_offset ) ); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + mulP( mat4Tmp1.load( m, m_offset ) ); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.mul( mat4Tmp1.load( m, m_offset ) ); - modifiedBits |= MODIFIED_TEXTURE; + mulT( mat4Tmp1.load( m, m_offset ) ); } } @@ -932,16 +366,11 @@ public final class PMVMatrix implements GLMatrixFunc { */ public final PMVMatrix glMultMatrixf(final Matrix4f m) { if(matrixMode==GL_MODELVIEW) { - matMv.mul( m ); - dirtyBits |= requestBits | MANUAL_BITS ; - modifiedBits |= MODIFIED_MODELVIEW; + mulMv(m); } else if(matrixMode==GL_PROJECTION) { - matP.mul( m ); - dirtyBits |= MANUAL_BITS ; - modifiedBits |= MODIFIED_PROJECTION; + mulP(m); } else if(matrixMode==GL.GL_TEXTURE) { - matTex.mul( m ); - modifiedBits |= MODIFIED_TEXTURE; + mulT(m); } return this; } @@ -1015,6 +444,28 @@ public final class PMVMatrix implements GLMatrixFunc { } @Override + public final void glPopMatrix() { + if(matrixMode==GL_MODELVIEW) { + popMv(); + } else if(matrixMode==GL_PROJECTION) { + popP(); + } else if(matrixMode==GL.GL_TEXTURE) { + popT(); + } + } + + @Override + public final void glPushMatrix() { + if(matrixMode==GL_MODELVIEW) { + pushMv(); + } else if(matrixMode==GL_PROJECTION) { + pushP(); + } else if(matrixMode==GL.GL_TEXTURE) { + pushT(); + } + } + + @Override public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) { glMultMatrixf( mat4Tmp1.setToOrtho(left, right, bottom, top, zNear, zFar) ); } @@ -1022,12 +473,12 @@ public final class PMVMatrix implements GLMatrixFunc { /** * {@inheritDoc} * - * @throws GLException if {@code zNear <= 0} or {@code zFar <= zNear} - * or {@code left == right}, or {@code bottom == top}. + * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear} + * or {@code left == right}, or {@code bottom == top}. * @see Matrix4f#setToFrustum(float, float, float, float, float, float) */ @Override - public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) throws GLException { + public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) throws IllegalArgumentException { glMultMatrixf( mat4Tmp1.setToFrustum(left, right, bottom, top, zNear, zFar) ); } @@ -1042,111 +493,22 @@ public final class PMVMatrix implements GLMatrixFunc { * @param aspect aspect ratio width / height * @param zNear * @param zFar - * @throws GLException if {@code zNear <= 0} or {@code zFar <= zNear} + * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear} * @see Matrix4f#setToPerspective(float, float, float, float) */ - public final void gluPerspective(final float fovy_rad, final float aspect, final float zNear, final float zFar) throws GLException { + public final void gluPerspective(final float fovy_rad, final float aspect, final float zNear, final float zFar) throws IllegalArgumentException { glMultMatrixf( mat4Tmp1.setToPerspective(fovy_rad, aspect, zNear, zFar) ); } /** - * {@link #glMultMatrixf(FloatBuffer) Multiply} and {@link #glTranslatef(float, float, float) translate} the {@link #glGetMatrixMode() current matrix} - * with the eye, object and orientation. + * {@link #glMultMatrixf(FloatBuffer) Multiply} the {@link #glGetMatrixMode() current matrix} + * with the eye, object and orientation, i.e. {@link Matrix4f#setToLookAt(Vec3f, Vec3f, Vec3f, Matrix4f)}. */ public final void gluLookAt(final Vec3f eye, final Vec3f center, final Vec3f up) { glMultMatrixf( mat4Tmp1.setToLookAt(eye, center, up, getTmp2Mat()) ); } /** - * Map object coordinates to window coordinates. - * <p> - * Traditional <code>gluProject</code> implementation. - * </p> - * - * @param objPos 3 component object coordinate - * @param viewport Rect4i viewport - * @param winPos 3 component window coordinate, the result - * @return true if successful, otherwise false (z is 1) - */ - public final boolean gluProject(final Vec3f objPos, final Recti viewport, final Vec3f winPos ) { - return Matrix4f.mapObjToWin(objPos, matMv, matP, viewport, winPos); - } - - /** - * Map window coordinates to object coordinates. - * <p> - * Traditional <code>gluUnProject</code> implementation. - * </p> - * - * @param winx - * @param winy - * @param winz - * @param viewport Rect4i viewport - * @param objPos 3 component object coordinate, the result - * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) - */ - public final boolean gluUnProject(final float winx, final float winy, final float winz, - final Recti viewport, final Vec3f objPos) { - if( Matrix4f.mapWinToObj(winx, winy, winz, getPMviMat(), viewport, objPos) ) { - return true; - } else { - return false; - } - } - - /** - * Map window coordinates to object coordinates. - * <p> - * Traditional <code>gluUnProject4</code> implementation. - * </p> - * - * @param winx - * @param winy - * @param winz - * @param clipw - * @param viewport Rect4i viewport - * @param near - * @param far - * @param objPos 4 component object coordinate, the result - * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z) - */ - public boolean gluUnProject4(final float winx, final float winy, final float winz, final float clipw, - final Recti viewport, - final float near, final float far, - final Vec4f objPos) { - if( Matrix4f.mapWinToObj4(winx, winy, winz, clipw, getPMviMat(), viewport, near, far, objPos) ) { - return true; - } else { - return false; - } - } - - /** - * Map two window coordinates w/ shared X/Y and distinctive Z - * to a {@link Ray}. The resulting {@link Ray} maybe used for <i>picking</i> - * using a {@link AABBox#getRayIntersection(Vec3f, Ray, float, boolean) bounding box}. - * <p> - * Notes for picking <i>winz0</i> and <i>winz1</i>: - * <ul> - * <li>see {@link FloatUtil#getZBufferEpsilon(int, float, float)}</li> - * <li>see {@link FloatUtil#getZBufferValue(int, float, float, float)}</li> - * <li>see {@link FloatUtil#getOrthoWinZ(float, float, float)}</li> - * </ul> - * </p> - * @param winx - * @param winy - * @param winz0 - * @param winz1 - * @param viewport - * @param ray storage for the resulting {@link Ray} - * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity) - */ - public final boolean gluUnProjectRay(final float winx, final float winy, final float winz0, final float winz1, - final Recti viewport, final Ray ray) { - return Matrix4f.mapWinToRay(winx, winy, winz0, winz1, getPMviMat(), viewport, ray); - } - - /** * Make given matrix the <i>pick</i> matrix based on given parameters. * <p> * Traditional <code>gluPickMatrix</code> implementation. @@ -1160,495 +522,15 @@ public final class PMVMatrix implements GLMatrixFunc { * @param deltaY the height of the picking region in window coordinates. * @param viewport Rect4i viewport vector */ - public final void gluPickMatrix(final float x, final float y, - final float deltaX, final float deltaY, final Recti viewport) { + public final void gluPickMatrix(final float x, final float y, final float deltaX, final float deltaY, final Recti viewport) { if( null != mat4Tmp1.setToPick(x, y, deltaX, deltaY, viewport, getTmp2Mat()) ) { glMultMatrixf( mat4Tmp1 ); } } - public StringBuilder toString(StringBuilder sb, final String f) { - if(null == sb) { - sb = new StringBuilder(); - } - final boolean pmvDirty = 0 != (PREMUL_PMV & dirtyBits); - final boolean pmvUsed = null != matPMv; - - final boolean pmviDirty = 0 != (PREMUL_PMVI & dirtyBits); - final boolean pmviUsed = null != matPMvi; - - final boolean frustumDirty = 0 != (FRUSTUM & dirtyBits); - final boolean frustumUsed = null != frustum; - - final boolean mviDirty = 0 != (INVERSE_MODELVIEW & dirtyBits); - final boolean mviReq = 0 != (INVERSE_MODELVIEW & requestBits); - - final boolean mvitDirty = 0 != (INVERSE_TRANSPOSED_MODELVIEW & dirtyBits); - final boolean mvitReq = 0 != (INVERSE_TRANSPOSED_MODELVIEW & requestBits); - - final boolean modP = 0 != ( MODIFIED_PROJECTION & modifiedBits ); - final boolean modMv = 0 != ( MODIFIED_MODELVIEW & modifiedBits ); - final boolean modT = 0 != ( MODIFIED_TEXTURE & modifiedBits ); - int count = 3; // P, Mv, T - - sb.append("PMVMatrix[modified[P ").append(modP).append(", Mv ").append(modMv).append(", T ").append(modT); - sb.append("], dirty/used[PMv ").append(pmvDirty).append("/").append(pmvUsed).append(", Pmvi ").append(pmviDirty).append("/").append(pmviUsed).append(", Frustum ").append(frustumDirty).append("/").append(frustumUsed); - sb.append("], dirty/req[Mvi ").append(mviDirty).append("/").append(mviReq).append(", Mvit ").append(mvitDirty).append("/").append(mvitReq).append("]").append(System.lineSeparator()); - sb.append(", Projection").append(System.lineSeparator()); - matP.toString(sb, null, f); - sb.append(", Modelview").append(System.lineSeparator()); - matMv.toString(sb, null, f); - sb.append(", Texture").append(System.lineSeparator()); - matTex.toString(sb, null, f); - if( null != matPMv ) { - sb.append(", P * Mv").append(System.lineSeparator()); - matPMv.toString(sb, null, f); - ++count; - } - if( null != matPMvi ) { - sb.append(", P * Mv").append(System.lineSeparator()); - matPMvi.toString(sb, null, f); - ++count; - } - if( mviReq ) { - sb.append(", Inverse Modelview").append(System.lineSeparator()); - matMvi.toString(sb, null, f); - ++count; - } - if( mvitReq ) { - sb.append(", Inverse Transposed Modelview").append(System.lineSeparator()); - matMvit.toString(sb, null, f); - ++count; - } - int tmpCount = 1; - if( null != mat4Tmp2 ) { - ++tmpCount; - } - sb.append(", matrices "+count+" + "+tmpCount+" temp = "+(count+tmpCount)+"]"); - return sb; - } - - @Override - public String toString() { - return toString(null, "%10.5f").toString(); - } - - /** - * Returns the modified bits due to mutable operations.. - * <p> - * A modified bit is set, if the corresponding matrix had been modified by a mutable operation - * since last {@link #update()} or {@link #getModifiedBits(boolean) getModifiedBits(true)} call. - * </p> - * @param clear if true, clears the modified bits, otherwise leaves them untouched. - * - * @see #MODIFIED_PROJECTION - * @see #MODIFIED_MODELVIEW - * @see #MODIFIED_TEXTURE - * @see #getDirtyBits() - * @see #isReqDirty() - */ - public final int getModifiedBits(final boolean clear) { - final int r = modifiedBits; - if(clear) { - modifiedBits = 0; - } - return r; - } - - /** - * Returns the dirty bits due to mutable operations, - * i.e. - * - {@link #INVERSE_MODELVIEW} (if requested) - * - {@link #INVERSE_TRANSPOSED_MODELVIEW} (if requested) - * - {@link #FRUSTUM} (always, cleared via {@link #getFrustum()} - * <p> - * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation - * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix(int)}. - * </p> - * <p> - * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}. - * </p> - * - * @see #isReqDirty() - * @see #INVERSE_MODELVIEW - * @see #INVERSE_TRANSPOSED_MODELVIEW - * @see #FRUSTUM - * @see #PMVMatrix(int) - * @see #getMviMat() - * @see #getMvitMat() - * @see #getSyncPMvMviMat() - * @see #getSyncPMvMviMvitMat() - * @see #getFrustum() - */ - public final int getDirtyBits() { - return dirtyBits; - } - - /** - * Returns true if the one of the {@link #getReqBits() requested bits} are are set dirty due to mutable operations, - * i.e. at least one of - * - {@link #INVERSE_MODELVIEW} - * - {@link #INVERSE_TRANSPOSED_MODELVIEW} - * <p> - * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation - * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix(int)}. - * </p> - * <p> - * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}. - * </p> - * - * @see #INVERSE_MODELVIEW - * @see #INVERSE_TRANSPOSED_MODELVIEW - * @see #PMVMatrix(int) - * @see #getMviMat() - * @see #getMvitMat() - * @see #getSyncPMvMviMat() - * @see #getSyncPMvMviMvitMat() - */ - public final boolean isReqDirty() { - return 0 != ( requestBits & dirtyBits ); - } - - /** - * Returns the request bit mask, which uses bit values equal to the dirty mask - * and may contain - * - {@link #INVERSE_MODELVIEW} - * - {@link #INVERSE_TRANSPOSED_MODELVIEW} - * <p> - * The request bit mask is set by in the constructor {@link #PMVMatrix(int)}. - * </p> - * - * @see #INVERSE_MODELVIEW - * @see #INVERSE_TRANSPOSED_MODELVIEW - * @see #PMVMatrix(int) - * @see #getMviMat() - * @see #getMvitMat() - * @see #getSyncPMvMviMat() - * @see #getSyncPMvMviMvitMat() - * @see #getFrustum() - */ - public final int getReqBits() { - return requestBits; - } - - /** - * Returns the pre-multiplied projection x modelview, P x Mv. - * <p> - * This {@link Matrix4f} instance should be re-fetched via this method and not locally stored - * to have it updated from a potential modification of underlying projection and/or modelview matrix. - * {@link #update()} has no effect on this {@link Matrix4f}. - * </p> - * <p> - * This pre-multipled P x Mv is considered dirty, if its corresponding - * {@link #getPMat() P matrix} or {@link #getMvMat() Mv matrix} has been modified since its last update. - * </p> - * @see #update() - */ - public final Matrix4f getPMvMat() { - if( 0 != ( dirtyBits & PREMUL_PMV ) ) { - if( null == matPMv ) { - matPMv = new Matrix4f(); - } - matPMv.mul(matP, matMv); - dirtyBits &= ~PREMUL_PMV; - } - return matPMv; - } - - /** - * Returns the pre-multiplied inverse projection x modelview, - * if {@link Matrix4f#invert(Matrix4f)} succeeded, otherwise `null`. - * <p> - * This {@link Matrix4f} instance should be re-fetched via this method and not locally stored - * to have it updated from a potential modification of underlying projection and/or modelview matrix. - * {@link #update()} has no effect on this {@link Matrix4f}. - * </p> - * <p> - * This pre-multipled invert(P x Mv) is considered dirty, if its corresponding - * {@link #getPMat() P matrix} or {@link #getMvMat() Mv matrix} has been modified since its last update. - * </p> - * @see #update() - */ - public final Matrix4f getPMviMat() { - if( 0 != ( dirtyBits & PREMUL_PMVI ) ) { - if( null == matPMvi ) { - matPMvi = new Matrix4f(); - } - final Matrix4f mPMv = getPMvMat(); - matPMviOK = matPMvi.invert(mPMv); - dirtyBits &= ~PREMUL_PMVI; - } - return matPMviOK ? matPMvi : null; - } - - /** - * Returns the frustum, derived from projection x modelview. - * <p> - * This {@link Frustum} instance should be re-fetched via this method and not locally stored - * to have it updated from a potential modification of underlying projection and/or modelview matrix. - * {@link #update()} has no effect on this {@link Frustum}. - * </p> - * <p> - * The {@link Frustum} is considered dirty, if its corresponding - * {@link #getPMat() P matrix} or {@link #getMvMat() Mv matrix} has been modified since its last update. - * </p> - * @see #update() - */ - public final Frustum getFrustum() { - if( 0 != ( dirtyBits & FRUSTUM ) ) { - if( null == frustum ) { - frustum = new Frustum(); - } - final Matrix4f mPMv = getPMvMat(); - frustum.updateFrustumPlanes(mPMv); - dirtyBits &= ~FRUSTUM; - } - return frustum; - } - - /** - * Update the derived {@link #getMviMat() inverse modelview (Mvi)}, - * {@link #getMvitMat() inverse transposed modelview (Mvit)} matrices - * <b>if</b> they {@link #isReqDirty() are dirty} <b>and</b> - * requested via the constructor {@link #PMVMatrix(int)}.<br/> - * Hence updates the following dirty bits. - * - {@link #INVERSE_MODELVIEW} - * - {@link #INVERSE_TRANSPOSED_MODELVIEW} - * <p> - * The {@link Frustum} is updated only via {@link #getFrustum()} separately. - * </p> - * <p> - * The Mvi and Mvit matrices are considered dirty, if their corresponding - * {@link #getMvMat() Mv matrix} has been modified since their last update. - * </p> - * <p> - * Method is automatically called by {@link SyncMatrix4f} and {@link SyncMatrices4f} - * instances {@link SyncAction} as retrieved by e.g. {@link #getSyncMvitMat()}. - * This ensures an automatic update cycle if used with {@link GLUniformData}. - * </p> - * <p> - * Method may be called manually in case mutable operations has been called - * and caller operates on already fetched references, i.e. not calling - * {@link #getMviMat()}, {@link #getMvitMat()} anymore. - * </p> - * <p> - * Method clears the modified bits like {@link #getModifiedBits(boolean) getModifiedBits(true)}, - * which are set by any mutable operation. The modified bits have no impact - * on this method, but the return value. - * </p> - * - * @return true if any matrix has been modified since last update call or - * if the derived matrices Mvi and Mvit were updated, otherwise false. - * In other words, method returns true if any matrix used by the caller must be updated, - * e.g. uniforms in a shader program. - * - * @see #getModifiedBits(boolean) - * @see #isReqDirty() - * @see #INVERSE_MODELVIEW - * @see #INVERSE_TRANSPOSED_MODELVIEW - * @see #PMVMatrix(int) - * @see #getMviMat() - * @see #getMvitMat() - * @see #getSyncPMvMviMat() - * @see #getSyncPMvMviMvitMat() - */ - public final boolean update() { - return updateImpl(true); - } - // // private // - private final boolean updateImpl(final boolean clearModBits) { - boolean mod = 0 != modifiedBits; - if( clearModBits ) { - modifiedBits = 0; - } - if( 0 != ( requestBits & ( ( dirtyBits & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) ) ) { // only if dirt requested & dirty - if( !matMvi.invert(matMv) ) { - throw new GLException(msgCantComputeInverse); - } - dirtyBits &= ~INVERSE_MODELVIEW; - mod = true; - } - if( 0 != ( requestBits & ( dirtyBits & INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty - matMvit.transpose(matMvi); - dirtyBits &= ~INVERSE_TRANSPOSED_MODELVIEW; - mod = true; - } - return mod; - } - private static final String msgCantComputeInverse = "Invalid source Mv matrix, can't compute inverse"; - - private final Matrix4f matP; - private final Matrix4f matMv; - private final Matrix4f matTex; - - private final Matrix4f matMvi; - private final Matrix4f matMvit; - - private static final int mP_offset = 0*16; - private static final int mMv_offset = 1*16; - private final int mMvi_offset; - private final int mMvit_offset; - private final int mTex_offset; - - private final float[] matrixStore; - - private final FloatBuffer bufP, bufMv, bufTex; - private final FloatBuffer bufMvi, bufMvit; - private final FloatBuffer bufP_Mv, bufP_Mv_Mvi, bufP_Mv_Mvi_Mvit; - - private final SyncMatrix4f syncP, syncMv, syncT; - private final SyncMatrix4f syncMvi, syncMvit; - private final SyncMatrices4f syncP_Mv, syncP_Mv_Mvi, syncP_Mv_Mvi_Mvit; - - private final Matrix4f mat4Tmp1; - private int matrixMode = GL_MODELVIEW; - private int modifiedBits = MODIFIED_ALL; - private int dirtyBits = 0; // contains the dirty bits, i.e. hinting for update operation - private final int requestBits; // may contain the requested bits: INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW - private Matrix4f mat4Tmp2; - private Matrix4f matPMv; - private Matrix4f matPMvi; - private boolean matPMviOK; - private Frustum frustum; - - private abstract class PMVSyncBuffer implements SyncMatrix4f { - protected final Matrix4f mat; - private final FloatBuffer fbuf; - - public PMVSyncBuffer(final Matrix4f m, final FloatBuffer fbuf) { - this.mat = m; - this.fbuf = fbuf; - } - - @Override - public final Buffer getBuffer() { return fbuf; } - - @Override - public final SyncBuffer sync() { getAction().sync(); return this; } - - @Override - public final Buffer getSyncBuffer() { getAction().sync(); return fbuf; } - - @Override - public final Matrix4f getMatrix() { return mat; } - - @Override - public final FloatBuffer getSyncFloats() { getAction().sync(); return fbuf; } - } - private final class SyncBuffer0 extends PMVSyncBuffer { - private final SyncAction action = new SyncAction() { - @Override - public void sync() { mat.get(matrixStore); } - }; - - public SyncBuffer0(final Matrix4f m, final FloatBuffer fbuf) { super(m, fbuf); } - - @Override - public SyncAction getAction() { return action; } - - } - private final class SyncBuffer1 extends PMVSyncBuffer { - private final int offset; - private final SyncAction action = new SyncAction() { - @Override - public void sync() { mat.get(matrixStore, offset); } - }; - - public SyncBuffer1(final Matrix4f m, final FloatBuffer fbuf, final int offset) { - super(m, fbuf); - this.offset = offset; - } - - @Override - public SyncAction getAction() { return action; } - } - private final class SyncBuffer1U extends PMVSyncBuffer { - private final int offset; - private final SyncAction action = new SyncAction() { - @Override - public void sync() { - updateImpl(true); - mat.get(matrixStore, offset); - } - }; - - public SyncBuffer1U(final Matrix4f m, final FloatBuffer fbuf, final int offset) { - super(m, fbuf); - this.offset = offset; - } - - @Override - public SyncAction getAction() { return action; } - } - - private abstract class PMVSyncBufferN implements SyncMatrices4f { - protected final Matrix4f[] mats; - private final FloatBuffer fbuf; - - public PMVSyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf) { - this.mats = ms; - this.fbuf = fbuf; - } - - @Override - public final Buffer getBuffer() { return fbuf; } - - @Override - public final SyncBuffer sync() { getAction().sync(); return this; } - - @Override - public final Buffer getSyncBuffer() { getAction().sync(); return fbuf; } - - @Override - public Matrix4f[] getMatrices() { return mats; } - - @Override - public final FloatBuffer getSyncFloats() { getAction().sync(); return fbuf; } - } - private final class SyncBufferN extends PMVSyncBufferN { - private final int offset; - private final SyncAction action = new SyncAction() { - @Override - public void sync() { - int ioff = offset; - for(int i=0; i<mats.length; ++i, ioff+=16) { - mats[i].get(matrixStore, ioff); - } - } - }; - - public SyncBufferN(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { - super(ms, fbuf); - this.offset = offset; - } - - @Override - public SyncAction getAction() { return action; } - } - private final class SyncBufferNU extends PMVSyncBufferN { - private final int offset; - private final SyncAction action = new SyncAction() { - @Override - public void sync() { - updateImpl(true); - int ioff = offset; - for(int i=0; i<mats.length; ++i, ioff+=16) { - mats[i].get(matrixStore, ioff); - } - } - }; - - public SyncBufferNU(final Matrix4f[] ms, final FloatBuffer fbuf, final int offset) { - super(ms, fbuf); - this.offset = offset; - } - - @Override - public SyncAction getAction() { return action; } - } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java index 37bca895a..e6549baba 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/glsl/fixedfunc/FixedFuncUtil.java @@ -4,6 +4,7 @@ package com.jogamp.opengl.util.glsl.fixedfunc; +import com.jogamp.math.util.PMVMatrix4f; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES1; import com.jogamp.opengl.GL2ES2; @@ -66,7 +67,7 @@ public class FixedFuncUtil { * @see ShaderSelectionMode#COLOR_TEXTURE * @see ShaderSelectionMode#COLOR_TEXTURE_LIGHT_PER_VERTEX */ - public static final GL2ES1 wrapFixedFuncEmul(final GL gl, final ShaderSelectionMode mode, final PMVMatrix pmvMatrix) { + public static final GL2ES1 wrapFixedFuncEmul(final GL gl, final ShaderSelectionMode mode, final PMVMatrix4f pmvMatrix) { return wrapFixedFuncEmul(gl, mode, null, false, false); } diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java index e0f465da7..c6c968415 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/EyeParameter.java @@ -27,8 +27,8 @@ */ package com.jogamp.opengl.util.stereo; -import com.jogamp.opengl.math.FovHVHalves; -import com.jogamp.opengl.math.Vec3f; +import com.jogamp.math.FovHVHalves; +import com.jogamp.math.Vec3f; /** * Constant single eye parameter of the viewer, relative to its {@link ViewerPose}. diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/LocationSensorParameter.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/LocationSensorParameter.java index 6294adee1..2634535aa 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/LocationSensorParameter.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/LocationSensorParameter.java @@ -27,8 +27,8 @@ */ package com.jogamp.opengl.util.stereo; -import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.geom.Frustum; +import com.jogamp.math.Matrix4f; +import com.jogamp.math.geom.Frustum; /** * Constant parameter of the positioning sensor to locate the {@link ViewerPose}. diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java index 85e752302..538152f7a 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java @@ -27,14 +27,13 @@ */ package com.jogamp.opengl.util.stereo; +import com.jogamp.math.FovHVHalves; +import com.jogamp.math.Vec3f; import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.PointImmutable; import jogamp.opengl.Debug; -import com.jogamp.opengl.math.FovHVHalves; -import com.jogamp.opengl.math.Vec3f; - /** * Interface describing a native stereoscopic device */ diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceRenderer.java index 0d6539634..624a1984c 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceRenderer.java @@ -27,12 +27,11 @@ */ package com.jogamp.opengl.util.stereo; +import com.jogamp.math.FovHVHalves; import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.RectangleImmutable; import com.jogamp.opengl.GL; -import com.jogamp.opengl.math.FovHVHalves; - /** * Stereoscopic device rendering interface. * <p> @@ -175,7 +174,7 @@ public interface StereoDeviceRenderer { * <p> * In case the renderer does not support multiple textures for post-processing, * or no post-processing at all, method returns zero despite the request - * from {@link StereoDevice#createRenderer(int, int, float[], com.jogamp.opengl.math.FovHVHalves[], float)}. + * from {@link StereoDevice#createRenderer(int, int, float[], com.jogamp.math.FovHVHalves[], float)}. * </p> */ public int getTextureCount(); diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoGLEventListener.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoGLEventListener.java index 59f38f2af..9108a0723 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoGLEventListener.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoGLEventListener.java @@ -27,10 +27,9 @@ */ package com.jogamp.opengl.util.stereo; +import com.jogamp.math.FloatUtil; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLEventListener; - -import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.util.CustomGLEventListener; /** @@ -65,7 +64,7 @@ public interface StereoGLEventListener extends CustomGLEventListener { * @param height viewport height in pixel units * @param eyeParam constant eye parameter, i.e. FOV and IPD * @param viewerPose current viewer position and orientation - * @see FloatUtil#makePerspective(float[], int, boolean, com.jogamp.opengl.math.FloatUtil.FovHVHalves, float, float) + * @see FloatUtil#makePerspective(float[], int, boolean, com.jogamp.math.FloatUtil.FovHVHalves, float, float) */ public void reshapeForEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height, final EyeParameter eyeParam, final ViewerPose viewerPose); diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoUtil.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoUtil.java index 63cb3e1e7..404c80d23 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoUtil.java @@ -27,9 +27,9 @@ */ package com.jogamp.opengl.util.stereo; -import com.jogamp.opengl.math.Matrix4f; -import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.Vec3f; +import com.jogamp.math.Matrix4f; +import com.jogamp.math.Quaternion; +import com.jogamp.math.Vec3f; import com.jogamp.opengl.util.CustomGLEventListener; import com.jogamp.opengl.util.stereo.StereoDeviceRenderer.Eye; diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/ViewerPose.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/ViewerPose.java index 5d2cf925c..7c116a019 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/ViewerPose.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/ViewerPose.java @@ -27,8 +27,8 @@ */ package com.jogamp.opengl.util.stereo; -import com.jogamp.opengl.math.Quaternion; -import com.jogamp.opengl.math.Vec3f; +import com.jogamp.math.Quaternion; +import com.jogamp.math.Vec3f; /** * {@link #position} and {@link #orientation} of viewer. diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java index 0cdef8770..a25e923dc 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/generic/GenericStereoDeviceFactory.java @@ -31,11 +31,11 @@ import jogamp.opengl.util.stereo.DistortionMesh; import jogamp.opengl.util.stereo.GenericStereoDevice; import com.jogamp.common.util.ReflectionUtil; +import com.jogamp.math.FloatUtil; +import com.jogamp.math.FovHVHalves; +import com.jogamp.math.Vec3f; import com.jogamp.nativewindow.util.Dimension; import com.jogamp.nativewindow.util.DimensionImmutable; -import com.jogamp.opengl.math.FloatUtil; -import com.jogamp.opengl.math.FovHVHalves; -import com.jogamp.opengl.math.Vec3f; import com.jogamp.opengl.util.stereo.EyeParameter; import com.jogamp.opengl.util.stereo.StereoDevice; import com.jogamp.opengl.util.stereo.StereoDeviceConfig; |