aboutsummaryrefslogtreecommitdiffstats
path: root/src/ru/olamedia/geom/Frustum2.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ru/olamedia/geom/Frustum2.java')
-rw-r--r--src/ru/olamedia/geom/Frustum2.java282
1 files changed, 282 insertions, 0 deletions
diff --git a/src/ru/olamedia/geom/Frustum2.java b/src/ru/olamedia/geom/Frustum2.java
new file mode 100644
index 0000000..9c382b0
--- /dev/null
+++ b/src/ru/olamedia/geom/Frustum2.java
@@ -0,0 +1,282 @@
+package ru.olamedia.geom;
+
+import java.nio.FloatBuffer;
+
+import org.ode4j.ode.internal.gimpact.GimGeometry.aabb3f;
+import org.openmali.spatial.bodies.Box;
+import org.openmali.spatial.bodies.Classifier;
+import org.openmali.vecmath2.Matrix4f;
+
+import com.jogamp.opengl.math.FloatUtil;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.util.PMVMatrix;
+
+public class Frustum2 {
+ protected Plane[] planes = new Plane[6];
+ protected PMVMatrix pmvMatrix;
+ protected FloatBuffer pmv = FloatBuffer.allocate(16);
+ protected float[] mvp = new float[16];
+ protected int pmvOffset;
+
+ public Frustum2() {
+ for (int i = 0; i < 6; ++i) {
+ planes[i] = new Plane();
+ }
+ }
+
+ public Frustum2(PMVMatrix matrix) {
+ setMatrix(matrix);
+ for (int i = 0; i < 6; ++i) {
+ planes[i] = new Plane();
+ }
+ }
+
+ public void setMatrix(PMVMatrix matrix) {
+ this.pmvMatrix = matrix;
+ // pmv = pmvMatrix.glGetPMvMatrixf();
+ // pmvOffset = pmv.position();
+ makePmvMatrix();
+ }
+
+ protected Matrix4f proj;
+ protected Matrix4f modl;
+
+ private static FloatBuffer b;
+ private static int bOffset;
+
+ private static float f(int offset) {
+ return b.get(bOffset + offset);
+ }
+
+ public static Matrix4f getMatrix4f(FloatBuffer buf) {
+ b = buf;
+ bOffset = b.position();
+ return new Matrix4f(f(0), f(1), f(2), f(3), f(4), f(5), f(6)/* 12 */, f(7), f(8), f(9), f(10), f(11), f(12),
+ f(13), f(14), f(15));
+ }
+
+ public void makePmvMatrix() {
+ FloatUtil.multMatrixf(pmvMatrix.glGetPMatrixf(), pmvMatrix.glGetMvMatrixf(), mvp, 0);
+ getMatrix4f(pmvMatrix.glGetPMatrixf()).mul(getMatrix4f(pmvMatrix.glGetMvMatrixf())).writeToBuffer(pmv, true,
+ false);
+ }
+
+ protected class Vector3f {
+ public float x;
+ public float y;
+ public float z;
+
+ @Override
+ public String toString() {
+ return "{" + x + "," + y + "," + z + "}";
+ }
+ }
+
+ protected class Plane {
+ public Vector3f n = new Vector3f();
+ public float d;
+
+ public final float distanceTo(float x, float y, float z) {
+ return (n.x * x) + (n.y * y) + (n.z * z) + d;
+ }
+
+ @Override
+ public String toString() {
+ return "Plane[" + n + ", " + d + "]";
+ }
+ }
+
+ protected float[] getMatrixFloat(FloatBuffer b) {
+ if (pmvMatrix.usesBackingArray()) {
+ return b.array();
+ } else {
+ int p = b.position();
+ float[] pm = new float[16];
+ b.get(pm, p, 16);
+ b.position(p);
+ return pm;
+ }
+ }
+
+ protected float m(int a) {
+ return mvp[a];
+ // return pmv.get(a);
+ }
+
+ private static final boolean isInside(Plane p, AABBox box) {
+ final float[] low = box.getLow();
+ final float[] high = box.getHigh();
+ if (p.distanceTo(low[0], low[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], low[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(low[0], high[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], high[1], low[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(low[0], low[1], high[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], low[1], high[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(low[0], high[1], high[2]) > 0.0f)
+ return (true);
+ if (p.distanceTo(high[0], high[1], high[2]) > 0.0f)
+ return (true);
+
+ return (false);
+ }
+
+ /**
+ * Quick check to see if an orthogonal bounding box is inside the frustum
+ */
+ public final boolean isOutside(AABBox box) {
+
+ // if all points are behind 1 specific plane, we are out
+ // if we are in with all points, then we are fully in
+ for (int p = 0; p < 6; ++p) {
+ if (!isInside(planes[p], box)) {
+ return true;
+ }
+ }
+
+ // so if iTotalIn is 6, then all are inside the view
+ // if(iTotalIn == 6)
+ // return(IN);
+
+ // we must be partly in then otherwise
+ return false;
+ // for (int i = 0; i < 3; ++i) {
+ // if (!quickClassify(planes[i], box))
+ // return true;
+ // }
+ //
+ // // We make no attempt to determine whether it's fully inside or not.
+ // return false;
+ }
+
+ protected float[] mat = new float[16];
+
+ public void extractFrustumPlanes(boolean normalize) {
+ // Left: [30+00, 31+01, 32+02, 33+03]
+ // comboMatrix.m[12] + comboMatrix.m[0];
+
+ planes[0].n.x = m(12) + m(0);
+ planes[0].n.y = m(13) + m(1);
+ planes[0].n.z = m(14) + m(2);
+ planes[0].d = m(15) + m(3);
+
+ // Right: [30-00, 31-01, 32-02, 33-03]
+
+ planes[1].n.x = m(12) - m(0);
+ planes[1].n.y = m(13) - m(1);
+ planes[1].n.z = m(14) - m(2);
+ planes[1].d = m(15) - m(3);
+
+ // Bottom: [30+10, 31+11, 32+12, 33+13]
+
+ planes[2].n.x = m(12) + m(4);
+ planes[2].n.y = m(13) + m(5);
+ planes[2].n.z = m(14) + m(6);
+ planes[2].d = m(15) + m(7);
+
+ // Top: [30-10, 31-11, 32-12, 33-13]
+
+ planes[3].n.x = m(12) - m(4);
+ planes[3].n.y = m(13) - m(5);
+ planes[3].n.z = m(14) - m(6);
+ planes[3].d = m(15) - m(7);
+
+ // Far: [30-20, 31-21, 32-22, 33-23]
+
+ planes[5].n.x = m(12) - m(8);
+ planes[5].n.y = m(13) - m(9);
+ planes[5].n.z = m(14) - m(10);
+ planes[5].d = m(15) - m(11);
+
+ // Near: [30+20, 31+21, 32+22, 33+23]
+
+ planes[4].n.x = m(12) + m(8);
+ planes[4].n.y = m(13) + m(9);
+ planes[4].n.z = m(14) + m(10);
+ planes[4].d = m(15) + m(11);
+
+ // Normalize
+ if (normalize) {
+ for (int i = 0; i < 6; ++i) {
+ double mag = Math.sqrt(planes[i].n.x * planes[i].n.x + planes[i].n.y * planes[i].n.y + planes[i].n.z
+ * planes[i].n.z);
+
+ planes[i].n.x /= mag;
+ planes[i].n.y /= mag;
+ planes[i].n.z /= mag;
+ planes[i].d /= mag;
+ }
+ }
+ }
+
+ public void extractFrustumPlanes2(boolean normalize) {
+ // Left: [30+00, 31+01, 32+02, 33+03]
+ // comboMatrix.m[12] + comboMatrix.m[0];
+
+ planes[0].n.x = m(3) + m(0);
+ planes[0].n.y = m(7) + m(4);
+ planes[0].n.z = m(11) + m(8);
+ planes[0].d = m(15) + m(12);
+
+ // Right: [30-00, 31-01, 32-02, 33-03]
+
+ planes[1].n.x = m(3) - m(0);
+ planes[1].n.y = m(7) - m(4);
+ planes[1].n.z = m(11) - m(8);
+ planes[1].d = m(15) - m(12);
+
+ // Bottom: [30+10, 31+11, 32+12, 33+13]
+
+ planes[2].n.x = m(3) + m(1);
+ planes[2].n.y = m(7) + m(5);
+ planes[2].n.z = m(11) + m(9);
+ planes[2].d = m(15) + m(13);
+
+ // Top: [30-10, 31-11, 32-12, 33-13]
+
+ planes[3].n.x = m(3) - m(1);
+ planes[3].n.y = m(7) - m(5);
+ planes[3].n.z = m(11) - m(9);
+ planes[3].d = m(15) - m(13);
+
+ // Far: [30-20, 31-21, 32-22, 33-23]
+
+ planes[5].n.x = m(3) - m(2);
+ planes[5].n.y = m(7) - m(6);
+ planes[5].n.z = m(11) - m(10);
+ planes[5].d = m(15) - m(14);
+
+ // Near: [30+20, 31+21, 32+22, 33+23]
+
+ planes[4].n.x = m(3) + m(2);
+ planes[4].n.y = m(7) + m(6);
+ planes[4].n.z = m(11) + m(10);
+ planes[4].d = m(15) + m(14);
+
+ // Normalize
+ if (normalize) {
+ for (int i = 0; i < 6; ++i) {
+ double mag = Math.sqrt(planes[i].n.x * planes[i].n.x + planes[i].n.y * planes[i].n.y + planes[i].n.z
+ * planes[i].n.z);
+
+ planes[i].n.x /= mag;
+ planes[i].n.y /= mag;
+ planes[i].n.z /= mag;
+ planes[i].d /= mag;
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "f2\n" + m(0) + " " + m(1) + " " + m(2) + " " + m(3) + "\n" + m(4) + " " + m(5) + " " + m(6) + " "
+ + m(7) + "\n" + m(8) + " " + m(9) + " " + m(10) + " " + m(11) + "\n" + m(12) + " " + m(13) + " "
+ + m(14) + " " + m(15) + " " + "Frustum2[" + planes[0] + ", " + planes[1] + ", " + planes[2] + ", "
+ + planes[3] + ", " + planes[4] + ", " + planes[5] + "]";
+ }
+}