5

The easiest method is removing and inserting the object, but there are probably faster methods. (If I'm overthinking this and I should just do it the simple way, let me know)

Here are some notes about my QuadTree

  • The objects that are moving are AABBs and may be bigger than the smallest QuadTree node.
  • The objects are not removed when creating children QuadTrees. That means the root QuadTree has a pointer to every object inside the QuadTree.
  • The objects are stored as pointers in a vector outside of the QuadTree.

So far, each time an object moves it calls a function called Update() on the root QuadTree. It includes itself and its past bounding box before it moved in the parameters. I'm not sure how to make the function though.

Posting the entire code to my QuadTree here would make my post quite long, so I've created a GitHub repository for easier reading.

Edit: For anyone looking for an answer this seems to update objects by removing and deleting them and is pretty efficient judging by the test he did in the comments.

epitaque
  • 73
  • 3
  • 9
  • This may be too much to go through & ask for. If you any specific code and it is not working, you may put it here.. – Satish Chalasani Jul 15 '15 at 21:42
  • 1
    The easiest way is to just remove and then re-add the object. If you want a better spatial partitioning scheme for objects that move, take a look at "loose quadtrees" – Buddy Jul 15 '15 at 21:59

2 Answers2

5

It'll be really hard to do better than remove and re-insert, especially in your case, since:

  • Removing seems super cheap (remove the pointer from the corresponding node's vector)
  • When looking for which node to move the object to, you need to traverse the tree the exact same way as when inserting, after which:
  • Insertion is pretty cheap

The only thing I would try if performance is really an issue is some sort of insertion from the leaves. Let's say your tree is pretty large and that objects usually move to immediately adjacent nodes, you could request insertion in the parent node, which would pass it to its parent if needed. Something like:

void insert_from_leaf(object* o) {
  if (!is_in_this_subtree(o)) {
    parent->insert_from_leaf(o);
    return;
  }
  find_child_node_for_object(o)->insert(0);
}

Basically, it might be more efficient to walk the tree from the leaf the object is coming from than always starting from the root since adjacent nodes tend to share a close ancestor.

In the worse case, you'll end up doing twice the work because you'll go back all the way to the root. In the best case, both source and destination share an immediate parent.

How good a gain this would be entirely depends on the layout of your particular tree, its size, and a bunch of other factors so you should measure the performance of your code before and after implementing something like this.

anthonyvd
  • 7,329
  • 4
  • 30
  • 51
1

There are few solutions for that: You can recreate whole tree each update. You can also simple remove and insert object when it moves.

Another solution (in my case it gives me the best performance) is to store only static objects in quad tree. I stored dynamic objcts in list (in my game there is much less dynamic objects than static).

Also you can read about other spatial data structures like grid, it is much simplier to move objects between cells.