package com.jogamp.opengl.util; import java.nio.FloatBuffer; // import org.openmali.spatial.bodies.Box; // import org.openmali.spatial.bodies.Classifier; // import org.openmali.vecmath2.Matrix4f; public class Frustum2 { protected Plane[] planes = new Plane[6]; protected PMVMatrix pmvMatrix; protected FloatBuffer pmv = FloatBuffer.allocate(16); protected int pmvOffset; 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 FloatBuffer b; private int bOffset; private float f(int offset) { return b.get(bOffset + offset); } private Matrix4f getMatrix4f(FloatBuffer b) { this.b = b; 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() { getMatrix4f(pmvMatrix.glGetMvMatrixf()).mul(getMatrix4f(pmvMatrix.glGetPMatrixf())).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 pmv.get(a); } private static final boolean quickClassify(Plane p, Box box) { if (p.distanceTo(box.getLowerX(), box.getLowerY(), box.getLowerZ()) > 0.0f) return (true); if (p.distanceTo(box.getUpperX(), box.getLowerY(), box.getLowerZ()) > 0.0f) return (true); if (p.distanceTo(box.getLowerX(), box.getUpperY(), box.getLowerZ()) > 0.0f) return (true); if (p.distanceTo(box.getUpperX(), box.getUpperY(), box.getLowerZ()) > 0.0f) return (true); if (p.distanceTo(box.getLowerX(), box.getLowerY(), box.getUpperZ()) > 0.0f) return (true); if (p.distanceTo(box.getUpperX(), box.getLowerY(), box.getUpperZ()) > 0.0f) return (true); if (p.distanceTo(box.getLowerX(), box.getUpperY(), box.getUpperZ()) > 0.0f) return (true); if (p.distanceTo(box.getUpperX(), box.getUpperY(), box.getUpperZ()) > 0.0f) return (true); return (false); } /** * Quick check to see if an orthogonal bounding box is inside the frustum */ public final Classifier.Classification quickClassify(Box box) { for (int i = 0; i < 6; ++i) { if (!quickClassify(planes[i], box)) return (Classifier.Classification.OUTSIDE); } // We make no attempt to determine whether it's fully inside or not. return (Classifier.Classification.SPANNING); } protected float[] mat = new float[16]; public void compute() { // 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); for (int i = 0; i < 6; ++i) { double invl = 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 *= invl; planes[i].n.y *= invl; planes[i].n.z *= invl; planes[i].d *= invl; } } @Override public String toString() { return "m[" + m(0) + "|" + m(1) + "|" + m(2) + "|" + m(3) + "|" + m(4) + "|" + m(5) + "|" + m(6) + "|" + m(7) + "|" + m(8) + "|" + m(9) + "|" + m(10) + "|" + m(11) + "|" + m(12) + "|" + m(13) + "|" + m(14) + "|" + m(15) + "]" + "Frustum2[" + planes[0] + ", " + planes[1] + ", " + planes[2] + ", " + planes[3] + ", " + planes[4] + ", " + planes[5] + "]"; } }