aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-19 06:11:46 +0100
committerSven Göthel <[email protected]>2024-01-19 06:11:46 +0100
commit1040bed4ecc6f4598ea459f1073a9240583fc3c3 (patch)
tree4d940115be7b5967553b9b93480abb7321da51ea /src/jogl/classes
parent7e582cbe21084e2b4b624761a411259da270ce26 (diff)
Add Cube to Frustum Plane mapping, supporting transformation of object-space AABBox into model-view Cube to Frustum.Plane for culling (cpu) and clipping (gpu)
Diffstat (limited to 'src/jogl/classes')
-rw-r--r--src/jogl/classes/com/jogamp/math/geom/Cube.java228
-rw-r--r--src/jogl/classes/com/jogamp/math/geom/Frustum.java24
2 files changed, 251 insertions, 1 deletions
diff --git a/src/jogl/classes/com/jogamp/math/geom/Cube.java b/src/jogl/classes/com/jogamp/math/geom/Cube.java
new file mode 100644
index 000000000..ded963a04
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/math/geom/Cube.java
@@ -0,0 +1,228 @@
+/**
+ * Copyright 2024 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.geom;
+
+import com.jogamp.math.Matrix4f;
+import com.jogamp.math.Vec3f;
+
+/**
+ * Simple 8-point {@link Vec3f} cube compound having {@code z-far <= z-near}
+ * <p>
+ * 8-points from far to near (z), left to right (x) and bottom to top (y) in AABB case, otherwise arbitrary
+ * <ul>
+ * <li>lbf, rbf, rtf, ltf</li>
+ * <li>lbn, rbn, rtn, ltn</li>
+ * </ul>
+ * </p>
+ * <p>
+ * A cube can be used to transform an {@link AABBox}
+ * from object-space to e.g. model-view (Mv) space via {@link #Cube(AABBox)} and {@link #transform(Matrix4f)}
+ * as required for an Mv {@link Frustum} presentation, see {@link #updateFrustumPlanes(Frustum)}.
+ * </p>
+ */
+public class Cube {
+ /** left -bottom-far (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f lbf;
+ /** right-bottom-far (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f rbf;
+ /** right-top -far (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f rtf;
+ /** left -top -far (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f ltf;
+
+ /** left -bottom-near (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f lbn;
+ /** right-bottom-near (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f rbn;
+ /** right-top -near (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f rtn;
+ /** left -top -near (xyz) in AABB case, otherwise arbitrary */
+ public final Vec3f ltn;
+
+ @Override
+ public final String toString() {
+ return "[lbf "+lbf+", rbf "+rbf+", rtf "+rtf+", lbn "+lbn+", rbn "+rbn+", rtn "+rtn+", ltn "+ltn+"]";
+ }
+
+ /**
+ * Construct a {@link Cube} with all points set to zero.
+ */
+ public Cube() {
+ lbf = new Vec3f();
+ rbf = new Vec3f();
+ rtf = new Vec3f();
+ ltf = new Vec3f();
+
+ lbn = new Vec3f();
+ rbn = new Vec3f();
+ rtn = new Vec3f();
+ ltn = new Vec3f();
+ }
+
+ /** Copy construct for a {@link Cube}. */
+ public Cube(final Cube o) {
+ lbf = new Vec3f(o.lbf);
+ rbf = new Vec3f(o.rbf);
+ rtf = new Vec3f(o.rtf);
+ ltf = new Vec3f(o.ltf);
+
+ lbn = new Vec3f(o.lbn);
+ rbn = new Vec3f(o.rbn);
+ rtn = new Vec3f(o.rtn);
+ ltn = new Vec3f(o.ltn);
+ }
+
+ /** Construct a {@link Cube} with given {@link AABBox}. */
+ public Cube(final AABBox box) {
+ this( box.getLow(), box.getHigh());
+ }
+
+ /**
+ * Construct a {@link Cube} with given {@link AABBox} minimum and maximum.
+ * @param lo_lbf minimum left -bottom-far (xyz)
+ * @param hi_rtn maximum right-top -near (xyz)
+ */
+ public Cube(final Vec3f lo_lbf, final Vec3f hi_rtn) {
+ lbf = new Vec3f(lo_lbf);
+ rtn = new Vec3f(hi_rtn);
+
+ rbf = new Vec3f(rtn.x(), lbf.y(), lbf.z());
+ rtf = new Vec3f(rtn.x(), rtn.y(), lbf.z());
+ ltf = new Vec3f(lbf.x(), rtn.y(), lbf.z());
+
+ lbn = new Vec3f(lbf.x(), lbf.y(), rtn.z());
+ rbn = new Vec3f(rtn.x(), lbf.y(), rtn.z());
+ ltn = new Vec3f(lbf.x(), rtn.y(), rtn.z());
+ }
+
+ /**
+ * Setting this cube to given {@link AABBox} minimum and maximum.
+ */
+ public Cube set(final AABBox box) {
+ return set( box.getLow(), box.getHigh());
+ }
+
+ /**
+ * Setting this cube to given {@link AABBox} minimum and maximum.
+ * @param lo_lbf minimum left -bottom-far (xyz)
+ * @param hi_rtn maximum right-top -near (xyz)
+ */
+ public Cube set(final Vec3f lo_lbf, final Vec3f hi_rtn) {
+ lbf.set(lo_lbf);
+ rtn.set(hi_rtn);
+
+ rbf.set(rtn.x(), lbf.y(), lbf.z());
+ rtf.set(rtn.x(), rtn.y(), lbf.z());
+ ltf.set(lbf.x(), rtn.y(), lbf.z());
+
+ lbn.set(lbf.x(), lbf.y(), rtn.z());
+ rbn.set(rtn.x(), lbf.y(), rtn.z());
+ ltn.set(lbf.x(), rtn.y(), rtn.z());
+ return this;
+ }
+
+ public Cube set(final Cube o) {
+ lbf.set(o.lbf);
+ rbf.set(o.rbf);
+ rtf.set(o.rtf);
+ ltf.set(o.ltf);
+
+ lbn.set(o.lbn);
+ rbn.set(o.rbn);
+ rtn.set(o.rtn);
+ ltn.set(o.ltn);
+ return this;
+ }
+
+ /** Affine 3f-vector transformation of all 8-points with given matrix, {@link Matrix4f#mulVec3f(Vec3f)}. */
+ public Cube transform(final Matrix4f mat) {
+ mat.mulVec3f(lbf);
+ mat.mulVec3f(rbf);
+ mat.mulVec3f(rtf);
+ mat.mulVec3f(ltf);
+
+ mat.mulVec3f(lbn);
+ mat.mulVec3f(rbn);
+ mat.mulVec3f(rtn);
+ mat.mulVec3f(ltn);
+ return this;
+ }
+
+ /**
+ * Calculate the frustum planes using this {@link Cube}.
+ * <p>
+ * One useful application is to {@link Cube#transform(Matrix4f) transform}
+ * an {@link AABBox}, see {@link Cube#Cube(AABBox)} from its object-space
+ * into model-view (Mv) and produce the {@link Frustum} planes using this method
+ * for CPU side object culling and GPU shader side fragment clipping.
+ * </p>
+ * <p>
+ * Frustum plane's normals will point to the inside of the viewing frustum,
+ * as required by the {@link Frustum} class.
+ * </p>
+ * @param frustum the output frustum
+ * @return the output frustum for chaining
+ * @see Frustum#updateFrustumPlanes(Cube)
+ * @see Cube#Cube(AABBox)
+ * @see Cube#transform(Matrix4f)
+ */
+ public Frustum updateFrustumPlanes(final Frustum frustum) {
+ // n [ 0.0 / 0.0 / -1.0 ]
+ frustum.getPlanes()[Frustum.NEAR].set(
+ (lbf).minus(lbn).normalize(), // | lbf - lbn |, inwards
+ lbn ); // closest AABB point to origin on plane
+
+ // n [ 0.0 / 0.0 / 1.0 ]
+ frustum.getPlanes()[Frustum.FAR].set(
+ (lbn).minus(lbf).normalize(), // | lbn - lbf |, inwards
+ lbf ); // closest AABB point to origin on plane
+
+ // n [ 1.0 / 0.0 / 0.0 ]
+ frustum.getPlanes()[Frustum.LEFT].set(
+ (rbf).minus(lbf).normalize(), // | rbf - lbf |, inwards
+ lbn ); // closest AABB point to origin on plane
+
+ // n [ -1.0 / 0.0 / 0.0 ]
+ frustum.getPlanes()[Frustum.RIGHT].set(
+ (lbf).minus(rbf).normalize(), // | lbf - rbf |, inwards
+ rbn ); // closest AABB point to origin on plane
+
+ // n [ 0.0 / 1.0 / 0.0 ]
+ frustum.getPlanes()[Frustum.BOTTOM].set(
+ (ltf).minus(lbf).normalize(), // | ltf - lbf |, inwards
+ lbn ); // closest AABB point to origin on plane
+
+ // n [ 0.0 / -1.0 / 0.0 ]
+ frustum.getPlanes()[Frustum.TOP].set(
+ (lbf).minus(ltf).normalize(), // | lbf - ltf |, inwards
+ ltn ); // closest AABB point to origin on plane
+
+ return frustum;
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/math/geom/Frustum.java b/src/jogl/classes/com/jogamp/math/geom/Frustum.java
index 9e9f65c31..991e70aac 100644
--- a/src/jogl/classes/com/jogamp/math/geom/Frustum.java
+++ b/src/jogl/classes/com/jogamp/math/geom/Frustum.java
@@ -255,7 +255,29 @@ public class Frustum {
pmv.updateFrustumPlanes(this);
}
- private static final boolean isOutsideImpl(final Plane p, final AABBox box) {
+ /**
+ * Calculate the frustum planes using the given {@link Cube}.
+ * <p>
+ * One useful application is to {@link Cube#transform(Matrix4f) transform}
+ * an {@link AABBox}, see {@link Cube#Cube(AABBox)} from its object-space
+ * into model-view (Mv) and produce the {@link Frustum} planes using this method
+ * for CPU side object culling and GPU shader side fragment clipping.
+ * </p>
+ * <p>
+ * Frustum plane's normals will point to the inside of the viewing frustum,
+ * as required by this class.
+ * </p>
+ * @param c the {@link Cube} source
+ * @return this frustum for chaining
+ * @see Cube#updateFrustumPlanes(Frustum)
+ * @see Cube#Cube(AABBox)
+ * @see Cube#transform(Matrix4f)
+ */
+ public Frustum updateFrustumPlanes(final Cube c) {
+ return c.updateFrustumPlanes(this);
+ }
+
+ private static final boolean isOutsideImpl(final Plane p, final AABBox box) {
final Vec3f lo = box.getLow();
final Vec3f hi = box.getHigh();