1 package org.simantics.g3d.datastructures;
3 import java.util.HashSet;
6 import javax.vecmath.Point3d;
8 public class OcTree<T> {
20 * @param center center of the octree area
21 * @param dx size of the area along x-axis.
22 * @param dy size of the area along y-axis.
23 * @param dz size of the area along z-axis.
24 * @param depth depth of the tree structure.
26 public OcTree(Point3d center, double dx, double dy, double dz, int depth) {
35 private OcTree(Point3d center, double dx, double dy, double dz) {
44 * Insets an object into the tree
48 public void insert(T object, Box bounds) {
53 boolean ins[] = getAccessArr(bounds);
54 for (int i = 0; i < 8; i++) {
56 children[i].insert(object, bounds);
61 private boolean[] getAccessArr(Box bounds) {
62 boolean pX = bounds.getMin().getX() > center.getX();
63 boolean nX = bounds.getMax().getX() < center.getX();
64 boolean pY = bounds.getMin().getY() > center.getY();
65 boolean nY = bounds.getMax().getY() < center.getY();
66 boolean pZ = bounds.getMin().getZ() > center.getZ();
67 boolean nZ = bounds.getMax().getZ() < center.getZ();
69 boolean ins[] = new boolean[8];
70 for (int i = 0; i < 8; i++)
74 for (int i = 1; i < 8; i+=2) {
78 for (int i = 0; i < 8; i+=2) {
84 for (int i = 2; i < 8; ) {
90 for (int i = 0; i < 8; ) {
98 for (int i = 4; i < 8; i++) {
102 for (int i = 0; i < 4; i++) {
110 * Removes an object from the tree
113 public void remove(T object) {
115 contains.remove(object);
117 for (OcTree<T> n : children) {
124 * Returns objects within the given area.
128 public void get(Box bounds, Set<T> set) {
130 set.addAll(contains);
133 boolean ins[] = getAccessArr(bounds);
134 for (int i = 0; i < 8; i++) {
136 children[i].get(bounds, set);
141 public void clear() {
145 for (OcTree<T> n : children)
150 private void split(int depth) {
152 throw new IllegalStateException("Node is already split");
155 this.contains = new HashSet<>();
160 for (OcTree<T> n : children) {
166 private void split() {
167 double _dx = dx * 0.5;
168 double _dy = dy * 0.5;
169 double _dz = dz * 0.5;
170 double xd2 = _dx * 0.5;
171 double yd2 = _dy * 0.5;
172 double zd2 = _dz * 0.5;
173 children = new OcTree[8];
174 children[0] = new OcTree<T>(new Point3d(center.x+xd2, center.y+yd2, center.z+zd2),_dx,_dy,_dz);
175 children[1] = new OcTree<T>(new Point3d(center.x-xd2, center.y+yd2, center.z+zd2),_dx,_dy,_dz);
176 children[2] = new OcTree<T>(new Point3d(center.x+xd2, center.y-yd2, center.z+zd2),_dx,_dy,_dz);
177 children[3] = new OcTree<T>(new Point3d(center.x-xd2, center.y-yd2, center.z+zd2),_dx,_dy,_dz);
178 children[4] = new OcTree<T>(new Point3d(center.x+xd2, center.y+yd2, center.z-zd2),_dx,_dy,_dz);
179 children[5] = new OcTree<T>(new Point3d(center.x-xd2, center.y+yd2, center.z-zd2),_dx,_dy,_dz);
180 children[6] = new OcTree<T>(new Point3d(center.x+xd2, center.y-yd2, center.z-zd2),_dx,_dy,_dz);
181 children[7] = new OcTree<T>(new Point3d(center.x-xd2, center.y-yd2, center.z-zd2),_dx,_dy,_dz);
186 public void dispose() {
188 this.contains = null;
190 for (OcTree<T> n : children) {