[solved][libGDX] QuadTree Implementation Malfunction

Hello JGO community,

I followed this tutorial when creating a QuadTree class and made a few modifications based on the feedback on the tutorial. Everything works as expected until I start clearing and inserting entities, as indicated in the tutorial, each frame. Before clearing and inserting, there are multiple quadrants and only 7 entities are marked for collision detection. However, after clearing and inserting, there is only one quadrant and all 33 entities are marked for collision detection. I would post a video, but it seems redundant as all I said is happening in the video.

Here is the QuadTree code:


public class QuadTree {
  private static final int MAX_OBJECTS = 1;
  private static final int MAX_LEVELS = 3;

  private int level;
  private Rectangle bounds;
  private Array<Entity> entities;
  private QuadTree[] nodes;

  public QuadTree(int level, Rectangle bounds) {
    this.level = level;
    this.bounds = bounds;
    this.entities = new Array<Entity>();
    this.nodes = new QuadTree[4];
  }

  public void draw(ShapeRenderer shapes) {
    shapes.setColor(Color.MAGENTA);
    shapes.rect(bounds.x, bounds.y, bounds.width, bounds.height);
    for (int i = 0; i < nodes.length; i++) {
      QuadTree node = nodes[i];
      if (node != null) {
        node.draw(shapes);
      }
    }
  }

  public void clear() {
    entities.clear();
    for (int i = 0; i < nodes.length; i++) {
      if (nodes[i] != null) {
        nodes[i].clear();
        nodes[i] = null;
      }
    }
  }

  private void split() {
    final float x = bounds.x;
    final float y = bounds.y;
    final float w = bounds.width / 2f;
    final float h = bounds.height / 2f;
    final int level = this.level++;

    nodes[0] = new QuadTree(level, new Rectangle(x + w, y, w, h));
    nodes[1] = new QuadTree(level, new Rectangle(x, y, w, h));
    nodes[2] = new QuadTree(level, new Rectangle(x, y + h, w, h));
    nodes[3] = new QuadTree(level, new Rectangle(x + w, y + h, w, h));
  }

  private int getIndex(Rectangle r) {
    int index = -1;

    float verticalMidpoint = bounds.getX() + (bounds.getWidth() / 2f);
    float horizontalMidpoint = bounds.getY() + (bounds.getHeight() / 2f);

    boolean topQuadrant = r.getY() < horizontalMidpoint && r.getY() + r.getHeight() < horizontalMidpoint;
    boolean bottomQuadrant = r.getY() > horizontalMidpoint;

    if (r.getX() < verticalMidpoint && r.getX() + r.getWidth() < verticalMidpoint) {
      if (topQuadrant) {
        index = 1;
      } else if (bottomQuadrant) {
        index = 2;
      }
    } else if (r.getX() > verticalMidpoint) {
      if (topQuadrant) {
        index = 0;
      } else if (bottomQuadrant) {
        index = 3;
      }
    }

    return index;
  }

  public void insert(Entity entity) {
    if (nodes[0] != null) {
      final int index = getIndex(entity.getComponent(BoundsComp.class));
      if (index != -1) {
        nodes[index].insert(entity);
        return;
      }
    }

    entities.add(entity);

    if (entities.size > MAX_OBJECTS && level < MAX_LEVELS) {
      if (nodes[0] == null) {
        split();
      }

      int i = 0;
      while (i < entities.size) {
        final int index = getIndex(entity.getComponent(BoundsComp.class));
        if (index != -1) {
          nodes[index].insert(entities.removeIndex(i));
        } else {
          i++;
        }
      }
    }
  }

  public void retrieve(Array<Entity> entities, Rectangle r) {
    if (nodes[0] != null) {
      final int index = getIndex(r);
      if (index != -1) {
        nodes[index].retrieve(entities, r);
      } else {
        for (int i = 0; i < nodes.length; i++) {
          nodes[i].retrieve(entities, r);
        }
      }
    }
    entities.addAll(this.entities);
  }
}

Here is the clearing and inserting code:


    quadTree.clear();
    ImmutableArray<Entity> entities = getEntities();
    for (int i = 0; i < entities.size(); i++) {
      quadTree.insert(entities.get(i));
    }

I have no idea what I’m doing wrong. Thanks in advance!