diff --git a/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java b/src/main/java/com/syncleus/spangraph/spacetime/OctBox.java similarity index 66% rename from src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java rename to src/main/java/com/syncleus/spangraph/spacetime/OctBox.java index b1f725a3a2eb8f2e01e23aa465d906ac7551a0bf..e5f5f0c6a10f2645f8ddfce9ab6e7c79dc29cc07 100644 --- a/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java +++ b/src/main/java/com/syncleus/spangraph/spacetime/OctBox.java @@ -4,36 +4,28 @@ import toxi.geom.*; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; -public class AbstractOctree<L> extends AABB implements Shape3D { +public class OctBox<V extends XYZ> extends AABB implements Shape3D { /** * alternative tree recursion limit, number of world units when cells are * not subdivided any further */ - protected float minNodeSize = 0.1f; + protected Vec3D resolution; /** * */ - public final AbstractOctree parent; + public final OctBox parent; - protected AbstractOctree[] children; + protected OctBox[] children; - protected byte numChildren; + protected Collection<V> points; - protected Collection<XYZ> points; - - protected float size, halfSize; - - protected Vec3D center; - - private int depth = 0; - - private boolean isAutoReducing = true; /** * Constructs a new AbstractOctree node within the AABB cube volume: {o.x, o.y, @@ -46,18 +38,19 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * @param halfSize * half length of the tree volume along a single axis */ - private AbstractOctree(AbstractOctree p, Vec3D o, float halfSize) { - super(o.add(halfSize, halfSize, halfSize), new Vec3D(halfSize, - halfSize, halfSize)); + private OctBox(OctBox p, Vec3D o, Vec3D halfSize) { + super(o.add(halfSize), new Vec3D(halfSize)); this.parent = p; - this.halfSize = halfSize; - this.size = halfSize * 2; - this.center = o; - this.numChildren = 0; if (parent != null) { - depth = parent.depth + 1; - minNodeSize = parent.minNodeSize; + resolution = parent.resolution; } + + + } + + public int depth() { + if (parent == null) return 0; + return parent.depth() + 1; } /** @@ -66,30 +59,34 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * * @param o * tree origin - * @param size * size of the tree volume along a single axis */ - public AbstractOctree(Vec3D o, float size, float minResolution) { - this(null, o, size / 2); - this.minNodeSize = minResolution; + public OctBox(Vec3D o, Vec3D extents, Vec3D resolution) { + this(null, o, extents); + this.resolution = resolution; } + /** - * Adds all points of the collection to the octree. IMPORTANT: Points need - * be of type Vec3D or have subclassed it. + * Adds all points of the collection to the octree. * * @param points * point collection - * @return true, if all points have been added successfully. + * @return how many points were added */ - public boolean put(Collection<XYZ> points) { - boolean addedAll = true; - for (XYZ p : points) { - addedAll &= put(p); + public int put(final Collection<V> points) { + int count = 0; + for (final V p : points) { + if (put(p)) count++; } - return addedAll; + return count; } + public boolean belowResolution() { + return extent.x <= resolution.x || + extent.y <= resolution.y || + extent.z <= resolution.z; + } /** * Adds a new point/particle to the tree structure. All points are stored * within leaf nodes only. The tree implementation is using lazy @@ -98,15 +95,13 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * @param p * @return true, if point has been added successfully */ - public boolean put(final XYZ p) { - final float halfSize = this.halfSize; - + public boolean put(final V p) { // check if point is inside cube if (containsPoint(p)) { // only add points to leaves for now - if (halfSize <= minNodeSize) { + if (belowResolution()) { if (points == null) { points = newPointsCollection(); } @@ -114,17 +109,16 @@ public class AbstractOctree<L> extends AABB implements Shape3D { return true; } else { if (children == null) { - children = new AbstractOctree[8]; + children = new OctBox[8]; } - int octant = getOctantID(p, center); + int octant = getOctantID(p, min); if (children[octant] == null) { - Vec3D off = center.add(new Vec3D( - (octant & 1) != 0 ? halfSize : 0, - (octant & 2) != 0 ? halfSize : 0, - (octant & 4) != 0 ? halfSize : 0)); - children[octant] = new AbstractOctree(this, off, - halfSize * 0.5f); - numChildren++; + Vec3D off = min.add(new Vec3D( + (octant & 1) != 0 ? extent.x : 0, + (octant & 2) != 0 ? extent.y : 0, + (octant & 4) != 0 ? extent.z : 0)); + children[octant] = new OctBox(this, off, + extent.scale(0.5f)); } return children[octant].put(p); } @@ -132,7 +126,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { return false; } - protected Collection<XYZ> newPointsCollection() { + protected Collection<V> newPointsCollection() { return new ArrayList(); } @@ -141,10 +135,10 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * Applies the given {@link OctreeVisitor} implementation to this node and * all of its children. */ - public void forEachRecursive(Consumer<AbstractOctree> visitor) { + public void forEachRecursive(Consumer<OctBox> visitor) { visitor.accept(this); - if (numChildren > 0) { - for (AbstractOctree c : children) { + if (children!=null) { + for (OctBox c : children) { if (c != null) { c.forEachRecursive(visitor); } @@ -156,8 +150,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { return p.isInAABB(this); } - public AbstractOctree clear() { - numChildren = 0; + public OctBox clear() { children = null; points = null; return this; @@ -166,32 +159,27 @@ public class AbstractOctree<L> extends AABB implements Shape3D { /** * @return a copy of the child nodes array */ - public AbstractOctree[] getChildrenCopy() { + public OctBox[] getChildrenCopy() { if (children != null) { - AbstractOctree[] clones = new AbstractOctree[8]; + OctBox[] clones = new OctBox[8]; System.arraycopy(children, 0, clones, 0, 8); return clones; } return null; } - /** - * @return the depth - */ - public int getDepth() { - return depth; - } + /** * Finds the leaf node which spatially relates to the given point * * @return leaf node or null if point is outside the tree dimensions */ - public AbstractOctree getLeafForPoint(XYZ p) { + public OctBox getLeafForPoint(XYZ p) { // if not a leaf node... if (p.isInAABB(this)) { - if (numChildren > 0) { - int octant = getOctantID(p, center); + if (children!=null) { + int octant = getOctantID(p, this); if (children[octant] != null) { return children[octant].getLeafForPoint(p); } @@ -211,20 +199,10 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * * @return the minimum size of tree nodes */ - public float getMinNodeSize() { - return minNodeSize; + public Vec3D getResolution() { + return resolution; } - public float getNodeSize() { - return size; - } - - /** - * @return the number of child nodes (max. 8) - */ - public int getNumChildren() { - return numChildren; - } /** * Computes the local child octant/cube index for the given point @@ -234,10 +212,10 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * @return octant index */ protected final int getOctantID(final Vec3D plocal) { - float halfSize = this.halfSize; + final Vec3D h = this.extent; - return (plocal.x >= halfSize ? 1 : 0) + (plocal.y >= halfSize ? 2 : 0) - + (plocal.z >= halfSize ? 4 : 0); + return (plocal.x >= h.x ? 1 : 0) + (plocal.y >= h.y ? 2 : 0) + + (plocal.z >= h.z ? 4 : 0); } /** computes getOctantID for the point subtracted by another point, @@ -245,25 +223,22 @@ public class AbstractOctree<L> extends AABB implements Shape3D { */ private int getOctantID(final XYZ p, final Vec3D s) { - return ((p.x() - s.x) >= halfSize ? 1 : 0) + ((p.y() - s.y) >= halfSize ? 2 : 0) - + ((p.z() - s.z) >= halfSize ? 4 : 0); + final Vec3D h = this.extent; + return ((p.x() - s.x) >= h.x ? 1 : 0) + ((p.y() - s.y) >= h.y? 2 : 0) + + ((p.z() - s.z) >= h.z ? 4 : 0); } - /** - * @return the offset - */ - public roVec3D getCenter() { - return center; - } + /** * @return the parent */ - public AbstractOctree getParent() { + public OctBox getParent() { return parent; } - public Collection<XYZ> getPoints() { + public Collection<V> getPoints() { + if (points == null) return Collections.EMPTY_LIST; return points; } @@ -278,17 +253,17 @@ public class AbstractOctree<L> extends AABB implements Shape3D { return points.size(); } - public List<XYZ> getPointsRecursively() { + public List<V> getPointsRecursively() { return getPointsRecursively(new ArrayList()); } /** * @return the points */ - public List<XYZ> getPointsRecursively(List<XYZ> results) { + public List<V> getPointsRecursively(List<V> results) { if (points != null) { results.addAll(points); - } else if (numChildren > 0) { + } else if (children!=null) { for (int i = 0; i < 8; i++) { if (children[i] != null) { children[i].getPointsRecursively(results); @@ -305,7 +280,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * AABB * @return all points with the box volume */ - @Deprecated public List<XYZ> getPointsWithinBox(AABB b) { + @Deprecated public List<XYZ> getPointsWithinBox(BB b) { ArrayList<XYZ> results = null; if (this.intersectsBox(b)) { if (points != null) { @@ -317,7 +292,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { results.add(q); } } - } else if (numChildren > 0) { + } else if (children!=null) { for (int i = 0; i < 8; i++) { if (children[i] != null) { List<XYZ> points = children[i].getPointsWithinBox(b); @@ -334,7 +309,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { return results; } - public void forEachInBox(AABB b, Consumer<XYZ> c) { + public void forEachInBox(BB b, Consumer<XYZ> c) { if (this.intersectsBox(b)) { if (points != null) { for (XYZ q : points) { @@ -342,7 +317,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { c.accept(q); } } - } else if (numChildren > 0) { + } else if (children!=null) { for (int i = 0; i < 8; i++) { if (children[i] != null) { children[i].forEachInBox(b, c); @@ -360,9 +335,9 @@ public class AbstractOctree<L> extends AABB implements Shape3D { c.accept(q); } } - } else if (numChildren > 0) { + } else if (children!=null) { for (int i = 0; i < 8; i++) { - AbstractOctree cc = children[i]; + OctBox cc = children[i]; if (cc != null) { cc.forEachInSphere(s, c); } @@ -389,7 +364,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D { results.add(q); } } - } else if (numChildren > 0) { + } else if (children!=null) { for (int i = 0; i < 8; i++) { if (children[i] != null) { List<XYZ> points = children[i].getPointsWithinSphere(s); @@ -419,18 +394,13 @@ public class AbstractOctree<L> extends AABB implements Shape3D { forEachInSphere(new Sphere(sphereOrigin, clipRadius), c); } - /** - * @return the size - */ - public float getScale() { - return size; - } + private void reduceBranch() { if (points != null && points.size() == 0) { points = null; } - if (numChildren > 0) { + if (children!=null) { for (int i = 0; i < 8; i++) { if (children[i] != null && children[i].points == null) { children[i] = null; @@ -450,13 +420,13 @@ public class AbstractOctree<L> extends AABB implements Shape3D { * point to delete * @return true, if the point was found & removed */ - public boolean remove(XYZ p) { + public boolean remove(V p) { boolean found = false; - AbstractOctree leaf = getLeafForPoint(p); + OctBox leaf = getLeafForPoint(p); if (leaf != null) { if (leaf.points.remove(p)) { found = true; - if (isAutoReducing && leaf.points.size() == 0) { + if (leaf.points.size() == 0) { leaf.reduceBranch(); } } @@ -464,36 +434,18 @@ public class AbstractOctree<L> extends AABB implements Shape3D { return found; } - public void removeAll(Collection<XYZ> points) { - for (XYZ p : points) { + public void removeAll(Collection<V> points) { + for (V p : points) { remove(p); } } - /** - * @param minNodeSize - */ - public void setMinNodeSize(float minNodeSize) { - this.minNodeSize = minNodeSize * 0.5f; - } - - /** - * Enables/disables auto reduction of branches after points have been - * deleted from the tree. Turned off by default. - * - * @param state - * true, to enable feature - */ - public void setTreeAutoReduction(boolean state) { - isAutoReducing = state; - } - /* * (non-Javadoc) * * @see toxi.geom.AABB#toString() */ public String toString() { - return "<octree> offset: " + super.toString() + " size: " + size; + return "<OctBox @" + super.toString() + '>'; } } diff --git a/src/main/java/toxi/geom/AABB.java b/src/main/java/toxi/geom/AABB.java index d8b33c30ffe37f880d12f3d140ab3d821bea13fa..a7468fe318b09cc333da0b06930e20c480223a31 100644 --- a/src/main/java/toxi/geom/AABB.java +++ b/src/main/java/toxi/geom/AABB.java @@ -31,61 +31,14 @@ import toxi.math.MathUtils; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; -import java.util.List; /** * Axis-aligned bounding box with basic intersection features for Ray, AABB and * Sphere classes. */ @XmlAccessorType(XmlAccessType.FIELD) -public class AABB extends Vec3D implements Shape3D { - - /** - * Creates a new instance from two vectors specifying opposite corners of - * the box - * - * @param min - * first corner point - * @param max - * second corner point - * @return new AABB with centre at the half point between the 2 input - * vectors - */ - public static final AABB fromMinMax(Vec3D min, Vec3D max) { - Vec3D a = Vec3D.min(min, max); - Vec3D b = Vec3D.max(min, max); - return new AABB(a.interpolateTo(b, 0.5f), b.sub(a).scaleSelf(0.5f)); - } - - /** - * Factory method, computes & returns the bounding box for the given list of - * points. - * - * @param points - * @return bounding rect - */ - public static final AABB getBoundingBox(List<? extends XYZ> points) { - if (points == null || points.size() == 0) { - return null; - } - XYZ first = points.get(0); - Vec3D min = new Vec3D(first); - Vec3D max = new Vec3D(first); - int n = points.size(); - if (n > 1) { - for (int i = 1; i < n; i++) { - XYZ p = points.get(i); - min.minSelf(p); - max.maxSelf(p); - } - } - return fromMinMax(min, max); - } - - @XmlElement(required = true) - protected Vec3D extent; +public class AABB extends BB implements Shape3D { @XmlTransient protected Vec3D min, max; @@ -100,7 +53,7 @@ public class AABB extends Vec3D implements Shape3D { * * @param box */ - public AABB(AABB box) { + public AABB(BB box) { this(box, box.getExtent()); } @@ -138,29 +91,10 @@ public class AABB extends Vec3D implements Shape3D { setExtent(extent); } - public boolean containsPoint(XYZ p) { - return p.isInAABB(this); - } - - public AABB copy() { + public BB copy() { return new AABB(this); } - public Sphere getBoundingSphere() { - return new Sphere(this, extent.magnitude()); - } - - /** - * Returns the current box size as new Vec3D instance (updating this vector - * will NOT update the box size! Use {@link #setExtent(roVec3D)} for - * those purposes) - * - * @return box size - */ - public final Vec3D getExtent() { - return extent.copy(); - } - public final Vec3D getMax() { // return this.add(extent); return max.copy(); @@ -193,7 +127,7 @@ public class AABB extends Vec3D implements Shape3D { * point to include * @return itself */ - public AABB growToContainPoint(roVec3D p) { + public BB growToContainPoint(roVec3D p) { min.minSelf(p); max.maxSelf(p); set(min.interpolateTo(max, 0.5f)); @@ -201,30 +135,17 @@ public class AABB extends Vec3D implements Shape3D { return this; } - /** - * Checks if the box intersects the passed in one. - * - * @param box - * box to check - * @return true, if boxes overlap - */ - public boolean intersectsBox(final AABB box) { - return MathUtils.abs(box.x - x) <= (extent.x + box.extent.x) - && MathUtils.abs(box.y - y) <= (extent.y + box.extent.y) - && MathUtils.abs(box.z - z) <= (extent.z + box.extent.z); - } - /** * Calculates intersection with the given ray between a certain distance * interval. - * + * * Ray-box intersection is using IEEE numerical properties to ensure the * test is both robust and efficient, as described in: - * + * * Amy Williams, Steve Barrus, R. Keith Morley, and Peter Shirley: "An * Efficient and Robust Ray-Box Intersection Algorithm" Journal of graphics * tools, 10(1):49-54, 2005 - * + * * @param ray * incident ray * @param minDist @@ -273,48 +194,6 @@ public class AABB extends Vec3D implements Shape3D { return null; } - public boolean intersectsSphere(Sphere s) { - return intersectsSphere(s, s.radius); - } - - /** - * @param c - * sphere centre - * @param r - * sphere radius - * @return true, if AABB intersects with sphere - */ - public boolean intersectsSphere(Vec3D c, float r) { - float s, d = 0; - // find the square of the distance - // from the sphere to the box - if (c.x < min.x) { - s = c.x - min.x; - d = s * s; - } else if (c.x > max.x) { - s = c.x - max.x; - d += s * s; - } - - if (c.y < min.y) { - s = c.y - min.y; - d += s * s; - } else if (c.y > max.y) { - s = c.y - max.y; - d += s * s; - } - - if (c.z < min.z) { - s = c.z - min.z; - d += s * s; - } else if (c.z > max.z) { - s = c.z - max.z; - d += s * s; - } - - return d <= r * r; - } - public boolean intersectsTriangle(Triangle3D tri) { // use separating axis theorem to test overlap between triangle and box // need to test for overlap in these directions: @@ -450,7 +329,7 @@ public class AABB extends Vec3D implements Shape3D { return false; } - public AABB set(AABB box) { + public BB set(BB box) { extent.set(box.extent); return set((XYZ) box); } @@ -474,7 +353,7 @@ public class AABB extends Vec3D implements Shape3D { * {@link #updateBounds()} immediately * */ - public AABB set(XYZ v) { + public BB set(XYZ v) { x = v.x(); y = v.y(); z = v.z(); @@ -489,7 +368,7 @@ public class AABB extends Vec3D implements Shape3D { * new box size * @return itself, for method chaining */ - public AABB setExtent(roVec3D extent) { + public BB setExtent(roVec3D extent) { this.extent = extent.copy(); return updateBounds(); } @@ -558,12 +437,12 @@ public class AABB extends Vec3D implements Shape3D { */ public String toString() { StringBuffer sb = new StringBuffer(); - sb.append("<aabb> pos: ").append(super.toString()).append(" ext: ") + sb.append("<aabb @").append(super.toString()).append("x") .append(extent); return sb.toString(); } - public AABB union(AABB box) { + public BB union(AABB box) { min.minSelf(box.getMin()); max.maxSelf(box.getMax()); set(min.interpolateTo(max, 0.5f)); @@ -577,7 +456,7 @@ public class AABB extends Vec3D implements Shape3D { * * @return itself */ - public final AABB updateBounds() { + public final BB updateBounds() { // this is check is necessary for the constructor if (extent != null) { this.min = this.sub(extent); @@ -586,25 +465,4 @@ public class AABB extends Vec3D implements Shape3D { return this; } - public boolean contains(final XYZ v) { - final Vec3D min = this.min; - final Vec3D max = this.max; - - final float x = v.x(); - if (x < min.x || x > max.x) { - return false; - } - - final float y = v.y(); - if (y < min.y || y > max.y) { - return false; - } - - final float z = v.z(); - if (z < min.z || z > max.z) { - return false; - } - - return true; - } } \ No newline at end of file diff --git a/src/main/java/toxi/geom/BB.java b/src/main/java/toxi/geom/BB.java new file mode 100644 index 0000000000000000000000000000000000000000..231b467987ae33d3672d229078a298ca747093f4 --- /dev/null +++ b/src/main/java/toxi/geom/BB.java @@ -0,0 +1,169 @@ +package toxi.geom; + +import toxi.math.MathUtils; + +import javax.xml.bind.annotation.XmlElement; +import java.util.List; + +/** + * Created by me on 6/14/15. + */ +public abstract class BB extends Vec3D { + + + protected Vec3D extent; + + public BB() { + super(); + } + + public BB(XYZ v) { + super(v); + } + + /** + * Creates a new instance from two vectors specifying opposite corners of + * the box + * + * @param min + * first corner point + * @param max + * second corner point + * @return new AABB with centre at the half point between the 2 input + * vectors + */ + public static final BB fromMinMax(Vec3D min, Vec3D max) { + Vec3D a = Vec3D.min(min, max); + Vec3D b = Vec3D.max(min, max); + return new AABB(a.interpolateTo(b, 0.5f), b.sub(a).scaleSelf(0.5f)); + } + + /** + * Factory method, computes & returns the bounding box for the given list of + * points. + * + * @param points + * @return bounding rect + */ + public static final BB getBoundingBox(List<? extends XYZ> points) { + if (points == null || points.size() == 0) { + return null; + } + XYZ first = points.get(0); + Vec3D min = new Vec3D(first); + Vec3D max = new Vec3D(first); + int n = points.size(); + if (n > 1) { + for (int i = 1; i < n; i++) { + XYZ p = points.get(i); + min.minSelf(p); + max.maxSelf(p); + } + } + return fromMinMax(min, max); + } + + public boolean containsPoint(XYZ p) { + return p.isInAABB(this); + } + + public Sphere getBoundingSphere() { + return new Sphere(this, extent.magnitude()); + } + + /** + * Returns the current box size as new Vec3D instance (updating this vector + * will NOT update the box size! Use {@link #setExtent(roVec3D)} for + * those purposes) + * + * @return box size + */ + public final Vec3D getExtent() { + return extent.copy(); + } + + /** + * Checks if the box intersects the passed in one. + * + * @param box + * box to check + * @return true, if boxes overlap + */ + public boolean intersectsBox(final BB box) { + return MathUtils.abs(box.x - x) <= (extent.x + box.extent.x) + && MathUtils.abs(box.y - y) <= (extent.y + box.extent.y) + && MathUtils.abs(box.z - z) <= (extent.z + box.extent.z); + } + + + + public boolean intersectsSphere(Sphere s) { + return intersectsSphere(s, s.radius); + } + + /** + * @param c + * sphere centre + * @param r + * sphere radius + * @return true, if AABB intersects with sphere + */ + public boolean intersectsSphere(Vec3D c, float r) { + float s, d = 0; + // find the square of the distance + // from the sphere to the box + if (c.x < minX()) { + s = c.x - minX(); + d = s * s; + } else if (c.x > maxX()) { + s = c.x - maxX(); + d += s * s; + } + + if (c.y < minY()) { + s = c.y - minY(); + d += s * s; + } else if (c.y > maxY()) { + s = c.y - maxY(); + d += s * s; + } + + if (c.z < minZ()) { + s = c.z - minZ(); + d += s * s; + } else if (c.z > maxZ()) { + s = c.z - maxZ(); + d += s * s; + } + + return d <= r * r; + } + + public boolean contains(final XYZ v) { + final float x = v.x(); + if (x < minX() || x > maxX()) { + return false; + } + + final float y = v.y(); + if (y < minY() || y > maxY()) { + return false; + } + + final float z = v.z(); + if (z < minZ() || z > maxZ()) { + return false; + } + + return true; + } + + + float minX() { return x - extent.x; } + float maxX() { return x + extent.x; } + float minY() { return y - extent.y; } + float maxY() { return y + extent.y; } + float minZ() { return z - extent.z; } + float maxZ() { return z + extent.z; } + +} diff --git a/src/main/java/toxi/geom/BoxIntersector.java b/src/main/java/toxi/geom/BoxIntersector.java index 3b02acd3fe074bea6a447eed771055f25334d2a1..6f481c5236c56323c5de8928deb0d29c36e2b6fd 100644 --- a/src/main/java/toxi/geom/BoxIntersector.java +++ b/src/main/java/toxi/geom/BoxIntersector.java @@ -13,7 +13,7 @@ public class BoxIntersector implements Intersector3D { /** * @return the box */ - public AABB getBox() { + public BB getBox() { return box; } diff --git a/src/main/java/toxi/geom/Line3D.java b/src/main/java/toxi/geom/Line3D.java index 45af97ad73c1829bf9355f26fa607996d58429b0..49e37349e880b6f01fb90c3cc42cc1b97087d088 100644 --- a/src/main/java/toxi/geom/Line3D.java +++ b/src/main/java/toxi/geom/Line3D.java @@ -241,8 +241,8 @@ public class Line3D { * @return aabb * @see AABB */ - public AABB getBounds() { - return AABB.fromMinMax(a, b); + public BB getBounds() { + return BB.fromMinMax(a, b); } public Vec3D getDirection() { diff --git a/src/main/java/toxi/geom/PointCloud3D.java b/src/main/java/toxi/geom/PointCloud3D.java index dbe8a46cf502ebd44a527319f7dc6dc942623bec..376a5c3303423479be650fe9ce45091ce2e1ca75 100644 --- a/src/main/java/toxi/geom/PointCloud3D.java +++ b/src/main/java/toxi/geom/PointCloud3D.java @@ -140,8 +140,8 @@ public class PointCloud3D implements Iterable<Vec3D> { return c; } - public AABB getBoundingBox() { - return AABB.fromMinMax(min, max); + public BB getBoundingBox() { + return BB.fromMinMax(min, max); } public Sphere getBoundingSphere() { diff --git a/src/main/java/toxi/geom/PointOctree.java b/src/main/java/toxi/geom/PointOctree.java index c5de07f5e8e46e846a0b7c8a8a32e3baa825a55f..675162a22b269e41707bdb63b162e09bab86c8c7 100644 --- a/src/main/java/toxi/geom/PointOctree.java +++ b/src/main/java/toxi/geom/PointOctree.java @@ -304,7 +304,7 @@ public class PointOctree extends AABB implements Shape3D { * AABB * @return all points with the box volume */ - public List<XYZ> getPointsWithinBox(AABB b) { + public List<XYZ> getPointsWithinBox(BB b) { ArrayList<XYZ> results = null; if (this.intersectsBox(b)) { if (points != null) { diff --git a/src/main/java/toxi/geom/Triangle3D.java b/src/main/java/toxi/geom/Triangle3D.java index 44c787bd10e4108892cd3f5056fee5bcce56929a..162d21c010d70be64214ecdde4a230a3b17106e8 100644 --- a/src/main/java/toxi/geom/Triangle3D.java +++ b/src/main/java/toxi/geom/Triangle3D.java @@ -217,10 +217,10 @@ public class Triangle3D implements Shape3D { * p.z()); } - public AABB getBoundingBox() { + public BB getBoundingBox() { Vec3D min = Vec3D.min(Vec3D.min(a, b), c); Vec3D max = Vec3D.max(Vec3D.max(a, b), c); - return AABB.fromMinMax(min, max); + return BB.fromMinMax(min, max); } /** diff --git a/src/main/java/toxi/geom/XYZ.java b/src/main/java/toxi/geom/XYZ.java index 91c52c8e878251798adbcf349544122ac964c75f..7e61b40b646b7bb3b2b8503a182facc8015d4d34 100644 --- a/src/main/java/toxi/geom/XYZ.java +++ b/src/main/java/toxi/geom/XYZ.java @@ -81,7 +81,7 @@ public interface XYZ { * * @see toxi.geom.ReadonlyVec3D#isInAABB(toxi.geom.AABB) */ - default public boolean isInAABB(final AABB box) { + default public boolean isInAABB(final BB box) { return box.contains(this); } diff --git a/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java b/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java index 5c18d3caab84d86a1175e68f622acd97ba2ecb21..4b2aeedd0260fc984f07a7e7551d39eaec7d6418 100644 --- a/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java +++ b/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java @@ -1,13 +1,15 @@ package com.syncleus.spangraph.geom; -import com.syncleus.spangraph.spacetime.AbstractOctree; +import com.syncleus.spangraph.spacetime.OctBox; import org.junit.Test; import toxi.geom.AABB; +import toxi.geom.BB; import toxi.geom.Vec3D; import java.util.List; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Created by me on 6/13/15. @@ -15,10 +17,18 @@ import static org.junit.Assert.assertEquals; public class OctreeTest { @Test public void test1() { - AbstractOctree o = new AbstractOctree( - new Vec3D(-2f, -2f, -2f), 4f, 0.05f); - - o.put(new Vec3D(1, 1, 0)); + OctBox o = new OctBox( + new Vec3D(-2f, -2f, -2f), + new Vec3D(4f, 4f, 4f), + new Vec3D(0.05f, 0.05f, 0.05f)); + + assertEquals(0, o.countPointsRecursively()); + + boolean b = o.put(new Vec3D(3,3,3)); + assertTrue(b); + assertEquals(1, o.countPointsRecursively()); + + o.put(new Vec3D(0, 1, 0)); o.put(new Vec3D(0, 1, 0)); o.put(new Vec3D(0, 0, 1)); o.put(new Vec3D(0, 0, 1.25f)); @@ -31,14 +41,14 @@ public class OctreeTest { o.forEachRecursive(x -> { - List p = (((AbstractOctree) x).getPointsRecursively()); + List p = (((OctBox) x).getPointsRecursively()); //if (!p.isEmpty()) //System.out.println(x + " " + p); }); //System.out.println("size: " + o.getNumChildren()); - assertEquals(o.countPointsRecursively(), 10); + assertEquals(o.countPointsRecursively(), 11); int[] sphereCount = new int[1]; o.forEachInSphere(new Vec3D(0, 0, -0.75f), 0.5f, x -> { @@ -48,8 +58,8 @@ public class OctreeTest { int[] boxCount = new int[1]; - AABB aabb = new AABB(new Vec3D(0f, -0.5f, -2.0f), new Vec3D(0.5f, 0.5f, 0.5f)); - o.forEachInBox(aabb, x -> { + BB BB = new AABB(new Vec3D(0f, -0.5f, -2.0f), new Vec3D(0.5f, 0.5f, 0.5f)); + o.forEachInBox(BB, x -> { boxCount[0]++; }); assertEquals(3, boxCount[0]);