From d97f603fba0ff686028da02a9727631d7f3297d4 Mon Sep 17 00:00:00 2001
From: SeH <1s1e1h1@gmail.com>
Date: Sun, 14 Jun 2015 01:02:50 -0400
Subject: [PATCH] octree testing

---
 .../spangraph/spacetime/AbstractOctree.java   | 104 ++++++++++++------
 src/main/java/toxi/geom/AABB.java             |  11 +-
 .../syncleus/spangraph/geom/OctreeTest.java   |  59 ++++++++--
 3 files changed, 120 insertions(+), 54 deletions(-)

diff --git a/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java b/src/main/java/com/syncleus/spangraph/spacetime/AbstractOctree.java
index 7650bc3..b1f725a 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 d0a0017..d8b33c3 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 b86305c..5c18d3c 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();
 
     }
 }
-- 
GitLab