# HG changeset patch # User postspectacular # Date 1326688496 0 # Node ID 9ba0a16897f18de93e232d249e3934a5cf09bad6 # Parent 6012bfd45a1437fa52e7cd5b01546d9d03fd4a23 adding Box/Plane/MeshIntersector implementations of Intersector3D diff -r 6012bfd45a1437fa52e7cd5b01546d9d03fd4a23 -r 9ba0a16897f18de93e232d249e3934a5cf09bad6 src.core/toxi/geom/BoxIntersector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src.core/toxi/geom/BoxIntersector.java Mon Jan 16 04:34:56 2012 +0000 @@ -0,0 +1,42 @@ +package toxi.geom; + +public class BoxIntersector implements Intersector3D { + + private AABB box; + private final IsectData3D isec; + + public BoxIntersector(AABB box) { + this.box = box; + this.isec = new IsectData3D(); + } + + /** + * @return the box + */ + public AABB getBox() { + return box; + } + + public IsectData3D getIntersectionData() { + return isec; + } + + public boolean intersectsRay(Ray3D ray) { + final Vec3D pos = box.intersectsRay(ray, 0, Float.MAX_VALUE); + isec.pos = pos; + isec.isIntersection = pos != null; + if (isec.isIntersection) { + isec.normal = box.getNormalForPoint(pos); + isec.dist = ray.distanceTo(pos); + } + return isec.isIntersection; + } + + /** + * @param box + * the box to set + */ + public void setBox(AABB box) { + this.box = box; + } +} diff -r 6012bfd45a1437fa52e7cd5b01546d9d03fd4a23 -r 9ba0a16897f18de93e232d249e3934a5cf09bad6 src.core/toxi/geom/PlaneIntersector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src.core/toxi/geom/PlaneIntersector.java Mon Jan 16 04:34:56 2012 +0000 @@ -0,0 +1,47 @@ +package toxi.geom; + +import toxi.math.MathUtils; + +public class PlaneIntersector implements Intersector3D { + + private Plane plane; + private final IsectData3D isec; + + public PlaneIntersector(Plane p) { + this.plane = p; + this.isec = new IsectData3D(); + } + + public IsectData3D getIntersectionData() { + return isec; + } + + /** + * @return the box + */ + public Plane getPlane() { + return plane; + } + + public boolean intersectsRay(Ray3D ray) { + float d = -plane.normal.dot(plane); + float numer = plane.normal.dot(ray) + d; + float denom = plane.normal.dot(ray.dir); + + // normal is orthogonal to vector, can't intersect + if (isec.isIntersection = (MathUtils.abs(denom) >= MathUtils.EPS)) { + isec.dist = -(numer / denom); + isec.pos = ray.getPointAtDistance(isec.dist); + isec.normal = plane.normal; + } + return isec.isIntersection; + } + + /** + * @param box + * the box to set + */ + public void setPlane(Plane p) { + this.plane = p; + } +} diff -r 6012bfd45a1437fa52e7cd5b01546d9d03fd4a23 -r 9ba0a16897f18de93e232d249e3934a5cf09bad6 src.core/toxi/geom/mesh/MeshIntersector.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src.core/toxi/geom/mesh/MeshIntersector.java Mon Jan 16 04:34:56 2012 +0000 @@ -0,0 +1,77 @@ +package toxi.geom.mesh; + +import toxi.geom.AABB; +import toxi.geom.Intersector3D; +import toxi.geom.IsectData3D; +import toxi.geom.Ray3D; +import toxi.geom.Vec3D; + +public class MeshIntersector implements Intersector3D { + + private static final float EPS = 0.00001f; + + private TriangleMesh mesh; + private AABB bounds; + + private final IsectData3D isec; + + public MeshIntersector(TriangleMesh mesh) { + setMesh(mesh); + this.isec = new IsectData3D(); + } + + public IsectData3D getIntersectionData() { + return isec; + } + + public boolean intersectsRay(Ray3D ray) { + isec.isIntersection = false; + if (bounds.intersectsRay(ray, 0, Float.MAX_VALUE) != null) { + Vec3D dir = ray.getDirection(); + float minD = Float.MAX_VALUE; + for (Face f : mesh.getFaces()) { + float d = intersectTriangle(f.a, f.b, f.c, ray, dir); + if (d >= 0.0 && d < minD) { + isec.isIntersection = true; + isec.normal = f.normal; + minD = d; + } + } + if (isec.isIntersection) { + isec.pos = ray.getPointAtDistance(minD); + isec.dist = minD; + isec.dir = dir.getInverted(); + } + } + return isec.isIntersection; + } + + private float intersectTriangle(Vec3D a, Vec3D b, Vec3D c, Vec3D ro, + Vec3D dir) { + Vec3D e1 = b.sub(a); + Vec3D e2 = c.sub(a); + Vec3D pvec = dir.cross(e2); + float det = e1.dot(pvec); + if (det > -EPS && det < EPS) { + return -1; + } + float invDet = 1f / det; + Vec3D tvec = ro.sub(a); + float u = tvec.dot(pvec) * invDet; + if (u < 0.0 || u > 1.0) { + return -1; + } + Vec3D qvec = tvec.cross(e1); + float v = dir.dot(qvec) * invDet; + if (v < 0.0 || u + v > 1.0) { + return -1; + } + float t = e2.dot(qvec) * invDet; + return t; + } + + public void setMesh(TriangleMesh mesh) { + this.mesh = mesh; + this.bounds = mesh.getBoundingBox(); + } +}