diff --git a/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java b/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java
index 7650bc3839c2116687d4705dc7cfb8861c1b9ed8..b1f725a3a2eb8f2e01e23aa465d906ac7551a0bf 100644
--- a/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java
+++ b/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java
@@ -14,7 +14,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
* alternative tree recursion limit, number of world units when cells are
* not subdivided any further
*/
- protected float minNodeSize = 4;
+ protected float minNodeSize = 0.1f;
/**
*
@@ -69,8 +69,9 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
* @param size
* size of the tree volume along a single axis
*/
- public AbstractOctree(Vec3D o, float size) {
+ public AbstractOctree(Vec3D o, float size, float minResolution) {
this(null, o, size / 2);
+ this.minNodeSize = minResolution;
}
/**
@@ -81,10 +82,10 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
* point collection
* @return true, if all points have been added successfully.
*/
- public boolean addAll(Collection<XYZ> points) {
+ public boolean put(Collection<XYZ> points) {
boolean addedAll = true;
for (XYZ p : points) {
- addedAll &= addPoint(p);
+ addedAll &= put(p);
}
return addedAll;
}
@@ -97,10 +98,10 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
* @param p
* @return true, if point has been added successfully
*/
- public boolean addPoint(final XYZ p) {
+ public boolean put(final XYZ p) {
final float halfSize = this.halfSize;
- AbstractOctree[] children = this.children;
+
// check if point is inside cube
if (containsPoint(p)) {
@@ -125,7 +126,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
halfSize * 0.5f);
numChildren++;
}
- return children[octant].addPoint(p);
+ return children[octant].put(p);
}
}
return false;
@@ -140,12 +141,12 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
* Applies the given {@link OctreeVisitor} implementation to this node and
* all of its children.
*/
- public void forEach(Consumer<AbstractOctree> visitor) {
+ public void forEachRecursive(Consumer<AbstractOctree> visitor) {
visitor.accept(this);
if (numChildren > 0) {
for (AbstractOctree c : children) {
if (c != null) {
- c.forEach(visitor);
+ c.forEachRecursive(visitor);
}
}
}
@@ -262,22 +263,35 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
return parent;
}
- public List<XYZ> getPoints() {
- return getPoints(new ArrayList());
+ public Collection<XYZ> getPoints() {
+ return points;
+ }
+
+ public int countPointsRecursively() {
+ final int[] x = {0};
+ forEachRecursive(n -> x[0] += n.countPoints());
+ return x[0];
+ }
+
+ public int countPoints() {
+ if (points == null) return 0;
+ return points.size();
+ }
+
+ public List<XYZ> getPointsRecursively() {
+ return getPointsRecursively(new ArrayList());
}
/**
* @return the points
*/
- public List<XYZ> getPoints(List<XYZ> results) {
+ public List<XYZ> getPointsRecursively(List<XYZ> results) {
if (points != null) {
+ results.addAll(points);
} else if (numChildren > 0) {
for (int i = 0; i < 8; i++) {
if (children[i] != null) {
- List<XYZ> childPoints = children[i].getPoints();
- if (childPoints != null) {
- results.addAll(childPoints);
- }
+ children[i].getPointsRecursively(results);
}
}
}
@@ -291,7 +305,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
* AABB
* @return all points with the box volume
*/
- public List<XYZ> getPointsWithinBox(AABB b) {
+ @Deprecated public List<XYZ> getPointsWithinBox(AABB b) {
ArrayList<XYZ> results = null;
if (this.intersectsBox(b)) {
if (points != null) {
@@ -320,6 +334,42 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
return results;
}
+ public void forEachInBox(AABB b, Consumer<XYZ> c) {
+ if (this.intersectsBox(b)) {
+ if (points != null) {
+ for (XYZ q : points) {
+ if (q.isInAABB(b)) {
+ c.accept(q);
+ }
+ }
+ } else if (numChildren > 0) {
+ for (int i = 0; i < 8; i++) {
+ if (children[i] != null) {
+ children[i].forEachInBox(b, c);
+ }
+ }
+ }
+ }
+ }
+ public void forEachInSphere(Sphere s, Consumer<XYZ> c) {
+
+ if (this.intersectsSphere(s)) {
+ if (points != null) {
+ for (XYZ q : points) {
+ if (s.containsPoint(q)) {
+ c.accept(q);
+ }
+ }
+ } else if (numChildren > 0) {
+ for (int i = 0; i < 8; i++) {
+ AbstractOctree cc = children[i];
+ if (cc != null) {
+ cc.forEachInSphere(s, c);
+ }
+ }
+ }
+ }
+ }
/**
* Selects all stored points within the given sphere volume
*
@@ -356,25 +406,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
return results;
}
- public void forEachInSphere(Sphere s, Consumer<XYZ> c) {
- if (this.intersectsSphere(s)) {
- if (points != null) {
- for (XYZ q : points) {
- if (s.containsPoint(q)) {
- c.accept(q);
- }
- }
- } else if (numChildren > 0) {
- for (int i = 0; i < 8; i++) {
- AbstractOctree cc = children[i];
- if (cc != null) {
- cc.forEachInSphere(s, c);
- }
- }
- }
- }
- }
/**
* Selects all stored points within the given sphere volume
@@ -390,7 +422,7 @@ public class AbstractOctree<L> extends AABB implements Shape3D {
/**
* @return the size
*/
- public float getSize() {
+ public float getScale() {
return size;
}
diff --git a/src/main/java/toxi/geom/AABB.java b/src/main/java/toxi/geom/AABB.java
index d0a0017f045988cee102bccd5fef2fe1cde23157..d8b33c30ffe37f880d12f3d140ab3d821bea13fa 100644
--- a/src/main/java/toxi/geom/AABB.java
+++ b/src/main/java/toxi/geom/AABB.java
@@ -133,7 +133,7 @@ public class AABB extends Vec3D implements Shape3D {
* box dimensions (the box will be double the size in each
* direction)
*/
- public AABB(roVec3D pos, roVec3D extent) {
+ public AABB(XYZ pos, roVec3D extent) {
super(pos);
setExtent(extent);
}
@@ -208,11 +208,10 @@ public class AABB extends Vec3D implements Shape3D {
* box to check
* @return true, if boxes overlap
*/
- public boolean intersectsBox(AABB box) {
- Vec3D t = box.sub(this);
- return MathUtils.abs(t.x) <= (extent.x + box.extent.x)
- && MathUtils.abs(t.y) <= (extent.y + box.extent.y)
- && MathUtils.abs(t.z) <= (extent.z + box.extent.z);
+ 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);
}
/**
diff --git a/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java b/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java
index b86305ccfb0cca232f8b3ada0fa9996bbd19e562..5c18d3caab84d86a1175e68f622acd97ba2ecb21 100644
--- a/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java
+++ b/src/test/java/com/syncleus/spangraph/geom/OctreeTest.java
@@ -1,6 +1,13 @@
package com.syncleus.spangraph.geom;
+import com.syncleus.spangraph.spacetime.AbstractOctree;
import org.junit.Test;
+import toxi.geom.AABB;
+import toxi.geom.Vec3D;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
/**
* Created by me on 6/13/15.
@@ -8,18 +15,46 @@ import org.junit.Test;
public class OctreeTest {
@Test
public void test1() {
- Octree o = new Octree(2, new Point(0,0,0));
- o.add(1, 1, 0);
- o.add(0, 1, 0);
- o.add(0, 0, 1);
- o.add(0, 0, 1.25);
- o.add(0, 0, 1.5);
- o.add(0, 0, -1);
- o.add(0, 0, -1.25);
- o.add(0, 0, -1.50);
- o.add(0, 0, -1.55);
- o.add(0, 0, -1.575);
- o.print_tree();
+ AbstractOctree o = new AbstractOctree(
+ new Vec3D(-2f, -2f, -2f), 4f, 0.05f);
+
+ o.put(new Vec3D(1, 1, 0));
+ o.put(new Vec3D(0, 1, 0));
+ o.put(new Vec3D(0, 0, 1));
+ o.put(new Vec3D(0, 0, 1.25f));
+ o.put(new Vec3D(0, 0, 1.5f));
+ o.put(new Vec3D(0, 0, -1));
+ o.put(new Vec3D(0, 0, -1.25f));
+ o.put(new Vec3D(0, 0, -1.50f));
+ o.put(new Vec3D(0, 0, -1.55f));
+ o.put(new Vec3D(0, 0, -1.575f));
+
+ o.forEachRecursive(x -> {
+
+ List p = (((AbstractOctree) x).getPointsRecursively());
+ //if (!p.isEmpty())
+ //System.out.println(x + " " + p);
+ });
+
+ //System.out.println("size: " + o.getNumChildren());
+
+ assertEquals(o.countPointsRecursively(), 10);
+
+ int[] sphereCount = new int[1];
+ o.forEachInSphere(new Vec3D(0, 0, -0.75f), 0.5f, x -> {
+ sphereCount[0]++;
+ });
+ assertEquals(2, sphereCount[0]);
+
+ 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 -> {
+ boxCount[0]++;
+ });
+ assertEquals(3, boxCount[0]);
+
+ //o.print_tree();
}
}