@Override protected OrientedBoxProbeArea clone() throws CloneNotSupportedException { return new OrientedBoxProbeArea(transform); }
@Override public boolean intersectsFrustum(Camera camera, TempVars vars) { // extract the scaled axis // this allows a small optimization. Vector3f axis1 = getScaledAxis(0, vars.vect1); Vector3f axis2 = getScaledAxis(1, vars.vect2); Vector3f axis3 = getScaledAxis(2, vars.vect3); Vector3f tn = vars.vect4; for (int i = 5; i >= 0; i--) { Plane p = camera.getWorldPlane(i); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; } return true; }
@Override public void simpleUpdate(float tpf) { area.setCenter(ln.getLocalTranslation()); area.setRotation(ln.getLocalRotation()); TempVars vars = TempVars.get(); boolean intersectBox = area.intersectsBox(aabb, vars); boolean intersectFrustum = area.intersectsFrustum(frustumCam, vars); boolean intersectSphere = area.intersectsSphere(sphere, vars); vars.release(); boolean intersect = intersectBox || intersectFrustum || intersectSphere; areaGeom.getMaterial().setColor("Color", intersect ? ColorRGBA.Green : ColorRGBA.White); sphereGeom.getMaterial().setColor("Color", intersectSphere ? ColorRGBA.Cyan : ColorRGBA.White); frustumGeom.getMaterial().setColor("Color", intersectFrustum ? ColorRGBA.Cyan : ColorRGBA.White); aabbGeom.getMaterial().setColor("Color", intersectBox ? ColorRGBA.Cyan : ColorRGBA.White); } }
@Override public boolean intersectsSphere(BoundingSphere sphere, TempVars vars) { Vector3f closestPoint = getClosestPoint(vars, sphere.getCenter()); // check if the point intersects with the sphere bound if (sphere.intersects(closestPoint)) { return true; } return false; }
private Vector3f getClosestPoint(TempVars vars, Vector3f point) { // non normalized direction Vector3f dir = vars.vect2.set(point).subtractLocal(transform.getTranslation()); // initialize the closest point with box center Vector3f closestPoint = vars.vect3.set(transform.getTranslation()); //store extent in an array float[] r = vars.fWdU; r[0] = transform.getScale().x; r[1] = transform.getScale().y; r[2] = transform.getScale().z; // computing closest point to sphere center for (int i = 0; i < 3; i++) { // extract the axis from the 3x3 matrix Vector3f axis = getScaledAxis(i, vars.vect1); // nomalize (here we just divide by the extent axis.divideLocal(r[i]); // distance to the closest point on this axis. float d = FastMath.clamp(dir.dot(axis), -r[i], r[i]); closestPoint.addLocal(vars.vect4.set(axis).multLocal(d)); } return closestPoint; }
@Override public boolean intersectsBox(BoundingBox box, TempVars vars) { Vector3f axis1 = getScaledAxis(0, vars.vect1); Vector3f axis2 = getScaledAxis(1, vars.vect2); Vector3f axis3 = getScaledAxis(2, vars.vect3); Vector3f tn = vars.vect4; Plane p = vars.plane; Vector3f c = box.getCenter(); p.setNormal(0, 0, -1); p.setConstant(-(c.z + box.getZExtent())); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; p.setNormal(0, 0, 1); p.setConstant(c.z - box.getZExtent()); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; p.setNormal(0, -1, 0); p.setConstant(-(c.y + box.getYExtent())); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; p.setNormal(0, 1, 0); p.setConstant(c.y - box.getYExtent()); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; p.setNormal(-1, 0, 0); p.setConstant(-(c.x + box.getXExtent())); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; p.setNormal(1, 0, 0); p.setConstant(c.x - box.getXExtent()); if (!insidePlane(p, axis1, axis2, axis3, tn)) return false; return true; }
public void setAreaType(AreaType type){ switch (type){ case Spherical: area = new SphereProbeArea(Vector3f.ZERO, 1.0f); break; case OrientedBox: area = new OrientedBoxProbeArea(new Transform()); area.setCenter(position); break; } }