I have been looking for a quadtree/quadtree node implementation on the net for ages. There is some basic stuff but nothing that I would be able to really use it a game.
My purpose is to store objects in a game for processing things such as collision detection.
I am not 100% certain that a quadtree is the best data structure to use, but from what I have read it is. I have already coded a Red-Black tree, but I don't really know if the performance would be good enough for my game (which will be an adventure 3rd person game like Ankh).
How would I write a basic but complete quadtree class (or octree) in C++?
How would you use the quad tree for collisions?
Quadtrees are used when you only need to store things that are effectively on a plane. Like units in a classic RTS where they are all on the ground or just a little bit above it. Essentially each node has links to 4 children that divide the node's space up into evenly distributed quarters.
Octrees do the same but in all three dimensions rather than just two, and thus they have 8 child nodes and partition the space up into eights. They should be used when the game entities are distributed more evenly among all three dimensions.
If you are looking for a binary tree - like a red-black tree - then you want to use a data structure called a binary space partitioning tree (BSP tree) or a version of it called the KD Tree. These partition space into halves using a plane, in the KD tree the planes are orthogonal (on the XZ, XY, ZY axes) so sometimes it works better in a 3D scene. BSP trees divide the scene up using planes in any orientation, but they can be quite useful, and they were used as far back as Doom.
Now because you've partitioned the game space you now don't have to test every game entity against every other game entity to see if they collide, which is an O(n^2) algorithm at best. Instead you query the data structure to return the game entities within a sub-region of the game space, and only perform collision detection for those nodes against each other.
This means that collision detection for all game entities should be n O(nlogn) operation (at worst).
A couple of extra things to watch out for:
Make sure you test game entities from adjacent nodes, not just the ones in the current node, since they could still collide.
Rebalance the data structure after the entities have moved since you may have empty nodes in the data structure now, or ones that contain too many entities for good performance (also the degenerate case of all entities being in the same node).
A red-black tree is not a spatial index; it can only sort on a single ordinal key. A quadtree is (for two dimensions) a spatial index that allows fast lookup and elimination of points. An Octree does the same thing for three dimensions.
The reason to use a quadtree is because you can then split on x- and y-coordinates, an octree on x, y and z, making collision detection trivial.
Quadtree: if an element is not in the topleft, it wont collide with one in topright, bottomleft or bottomright.
It is a very basic class, so I don't understand what you are missing in implementations you found.
I would not write such a class, I'd just borrow it from a project with a suitable license.
I warmly suggest you to use a rendering engine, Ogre3D for instance. As far as I know it supports Octrees for scene management. But you can extend the Octree-based class as you wish. I used to code the stuff I needed by myself, but for complex projects, it's just not the right way.
Trees in general are problematic for this in that any item inserted can lie on a boundary, and all the methods of dealing with that situation are fairly unsatisfactory.
You'll most likely want to sort your objects into moveable and static, and check anything that moved on a given frame against the static objects.
BSP Trees are the accepted solution for static geometry (boundary cases handled by splitting the object into two pieces), for dynamic try something like Sort and Sweep (also known as Sweep and Prune).
Right now STANN is the best open source implementation.
http://sites.google.com/a/compgeom.com/stann/
Related
I would like to apply Data-Oriented Design (based on e.g. this article) to my simple physics engine. And I'm focused on optimizing the collision testing as it is the most expensive part of it.
I've organized the bounding spheres that may collide with player into single vector:
struct Sphere{ //I don't split sphere into parts,
//as I usually access both position and radius in my calculations
Point3D position;
float radius;
};
std::vector<BoudingSphere> spheres;
and I test collisions with them inside single function/method. Everything looks clear to me to that point.
The problem is, I also have some more general structures like:
struct Polygon{ //it may e.g. represents the area or be used for more precise tests
std::vector<Point2D> points;
};
I guess it won't be a good practise to just create std::vector<Polygon> the same way, as nested vector (points) will take a lot of place in memory (reserving it).
On the other hand, I cannot assume that there are always 2,3,4 or 10 points (it differs a lot, with the maximum of about 20, but it's usually much less).
And I do not want to switch from Polygon general structure to e.g. series of triangles (as it is faster then separated triangles in many calculations).
What should I do then? I want to go with the spirit of Data-Oriented Design and use the memory/cache efficiently with my Polygon.
Do I have to get rid of the inner vector (points)? How if so?
There can't be a definitive answer to this question as it would require knowledge about the way you access the data in terms of when is it initialized, can it be changed after the initialization stage and many others. However, if your data is relatively stable and you are accessing your polygons in a consistent manner just iterating over all polygons or polygons belonging to one particular object, one approach may be to put the points of your polygons into a separate vector and just have the polygons store the beginning and the end indices to that array.
This way, there are a couple of things that needs to be accessed during traversal. First, the indices stored in the polygons. Second, the points themselves. Both of these accesses are likely to be cache-friendly if the polygons are also laid out in a vector. Similar approach can be applied to polygon sets - just store the polygons in a vector and have a (begin, end) pair in your game objects.
I'm trying to create a quad tree for my 3D environment (all elements are on a flat terrain, so they can be represented with 2D data), but I'm a little lost on the implementation of the finer parts of it.
I will first begin by describing my current quad tree, than move on to its flaws, and than ask the questions.
What I currently have is a quad tree that takes in a very specific rectangle in which I define the x,z,width, and forward. Here is an overview of my operations.
Insert an object into the quadtree:
Check if the current node has any child. If it does, check if the object is able to completely fit into any of the four nodes. If Possible, recurse and repeat. If the object does not completely fit into the four nodes or there are no nodes at all, it will add it to a std vector, than check if it should split. If it splits, split it and split the current objects into their respective nodes.
Delete an object from the quadtree:
Check if the object is inside the current node. Than move onto children. If found, pop the object out of the vector.
Update the quadtree:
Moving and static objects are stored in different quad trees. Moving quad tree will always delete whatever has moved and reinsert. Static quad tree just chills.
Retrieving an object
First find which of the four nodes it belongs to, than move recursively, taking all of the node's current objects and adding it to a vector that is returned at the end.
So here are my flaws: Not all of my rects are located in the leaf. I have no idea what I should do with those that intersect between the nodes. This also makes collision detection checking kinda stupid in a quad tree; why do I need to put rects inside parent nodes? I am thoroughly unhappy about the Retrieve object function.
My second flaw is that I can only take a rect in. While this was useful in making the quad tree and debugging it, I would like to move on and be able to directly put my Objects in my game inside.
So here are my questions
I've read Quadtree for 2D collision detection. Everything seems good enough, until "Objects can belong to several collections inside the quadtree. You're going to need an extra linear collection outside the quadtree to enumerate every object without duplicates."
I have no idea what that means, or how to do that. The operations for collision detection also seems much better than what I currently have. I want to know what he means and how its done.
My second question is regarding the insertion of objects into the tree. All my objects in the game would be part of a base class. Should I just make them add the base class directly? Or should I cast the objects into rects and than add a pointer to the object? I am loading some models for my game as well, and they are stretched around and played with by glScalef(). Thus it seems really hard (but possible) to get the scaling of and the position of the models after scaling.
On a side note, the main reason I am scaling the models is because I am basically making walls for a maze game. So I need them to fit perfectly around, and I can't mathematics on maya.
How do you use quad tree for 3d? Maybe you mean 2d? Because usually octree is used for 3d.
About you first question. Your objects may belong to several quads in quadtree. When you retrieve objects you need to check collision with you just check if you already detected collision between two objects and if you did you dont do the detection again to bypass duplicates. For example you have 2 objects in one quad. You check collision between 1st and second and then between 2nd and 1st. You need to check that you already detected this collision before.
Try reading this link for details.
You can try a morton curve to find overlapping area I also think you need an octree:http://dmytry.com/texts/collision_detection_using_z_order_curve_aka_Morton_order.html. Here are example of overlapping objects:https://books.google.fr/books?id=1mu099DN9UwC&pg=PA29&lpg=PA22&ots=pzvPDLu5qi&focus=viewport&dq=hilbert+curve+overlapping+objects&hl=de&output=html_text
Efficient way of threading an octree such that the pointers contained by each octcell in an oct make it easy in the traversal through the tree at the same level.
We have to make use of fully threaded trees here so that i can use openmp to parallelize the code at the same level.
I have some experience with oct-trees and coded several myself. The basic problem is that the tree has (at least) two directions of traversal: horizontal (between daughter cells) and vertical (between mother and daughter cells), which cannot be mapped to linear memory. Thus, traversing the tree (for example for neighbour search) will inevitably result in cache misses.
For a most efficient implementations, you should have all (up to 8) daughter cells of a non-final cell to be in one contiguous block of memory, avoiding both cache misses when traversing over them and the need to link them up with pointers. Each cell then only need one pointer/index for their first daughter cell and, possibly (depending on the needs of your applications), a pointer to their mother cell.
Similarly, any particles/positions sorted by the tree should be ordered such that all contained within a cell are contiguous in memory, at all tree levels. Then each cell only has to store the first and number of particles, allowing access to all them at at every level of the tree (not just final cells).
In practice, such an ordering can be achieved by first building a fully linked tree and then mapping it to the form described above. The overhead of this mapping is minor but the gain in a applications substantial.
Finally, when re-building the tree with only slightly changed particle positions, it makes for a significant speed up (depending on your algorithm) to feed the particles in the previous tree order to the tree building algorithm.
I'm building a game engine and I was wondering: are there any algorithms out there for Collision Detection that have time complexity of O(N^log N)?
I haven't written any coding yet, but I can only think of a O(N^2) algorithm (ie: 2 for-loops looping through a list of object to see if there's collision).
Any advice and help will be appreciated.
Thanks
Spatial partitioning can create O(n log(n)) solutions. Depending on the exact structure and nature of your objects, you'll want a different spatial partitioning algorithm, but the most common are octrees and BSP.
Basically, the idea of spatial partitioning is to group objects by the space they occupy. An object in node Y can never collide with an object in node X (unless X is a subnode of Y or vice versa). Then you partition the objects by which go in which nodes. I implemented an octree myself.
You can minimize the number of checks by sorting the objects into areas of space.
( There is no point in checking for a collision between an object near 0,0 and one near 1000,1000 )
The obvious solution would be to succesively divide your space in half and use a tree (BSP) structure. Although this works best for sparse clouds of objects, otherwise you spend all the time checking if an object near a boundary hits an object just on the other side of the boundary
I assume you have a restricted interaction length, i.e. when two objects are a certain distance, there is no more interaction.
If that is so, you normally would divide your space into domains of appropriate size (e.g. interaction length in each direction). Now, for applying the interaction to a particle, all you need to do is go through its own domain and the nearest neighbor domains, because all other particles are guaranteed further away than the interaction length is. Of course, you must check at particle updates whether any domain boundary is crossed, and adjust the domain membership accordingly. This extra bookkeeping is no problem, considering the enormous performance improvement due to the lowered interacting pair count.
For more tricks I suggest a scientific book about numerical N-Body-Simulation.
Of course each domain has its own list of particles that are in that domain. There's no use having a central list of particles in the simulation and going through all entries to check on each one whether it's in the current or the neighboring domains.
I'm using oct-tree for positions in 3D, which can be quite in-homogeneously distributed. The tree (re-)build is usually quite fast, bot O(N log(N)). Then finding all collisions for a given particle can be done in O(K) with K the number of collisions per particle, in particular there is no factor log(N). So, to find all collisions then need O(K*N), after the tree build.
So, I was thinking about making a simple random world generator. This generator would create a starting "cell" that would have between one and four random exits (in the cardinal directions, something like a maze). After deciding those exits, I would generate a new random "cell" at each of those exits, and repeat whenever a player would get near a part of the world that had not yet been generated. This concept would allow a "infinite" world of sorts, all randomly generated; however, I am unsure of how to best represent this internally.
I am using C++ (which doesn't really matter, I could implement any sort of data structure necessary). At first I thought of using a sort of directed graph in which each node would have directed edges to each cell surrounding it, but this probably won't work well if a user finds a spot in the world, backtracks, and comes back to that spot from another direction. The world might do some weird things, such as generate two cells at one location.
Any ideas on what kind of data structure might be the most effective for such a situation? Or am I doing something really dumb with my random world generation?
Any help would be greatly appreciated.
Thanks,
Chris
I recommend you read about graphs. This is exactly an application of random graph generation. Instead of 'cell' and 'exit' you are describing 'node' and 'edge'.
Plus, then you can do things like shortest path analysis, cycle detection and all sorts of other useful graph theory application.
This will help you understand about the nodes and edges:
and here is a finished application of these concepts. I implemented this in a OOP way - each node knew about it's edges to other nodes. A popular alternative is to implement this using an adjacency list. I think the adjacency list concept is basically what user470379 described with his answer. However, his map solution allows for infinite graphs, while a traditional adjacency list does not. I love graph theory, and this is a perfect application of it.
Good luck!
-Brian J. Stianr-
A map< pair<int,int>, cell> would probably work well; the pair would represent the x,y coordinates. If there's not a cell in the map at those coordinates, create a new cell. If you wanted to make it truly infinite, you could replace the ints with an arbitrary length integer class that you would have to provide (such as a bigint)
If the world's cells are arranged in a grid, you can easily give them cartesian coordinates. If you keep a big list of existing cells, then before determining exits from a given cell, you can check that list to see if any of its neighbors already exist. If they do, and you don't want to have 1-way doors (directed graph?) then you'll have to take their exits into account. If you don't mind having chutes in your game, you can still choose exits randomly, just make sure that you link to existing cells if they're there.
Optimization note: checking a hash table to see if it contains a particular key is O(1).
Couldn't you have a hash (or STL set) that stored a collection of all grid coordinates that contain occupied cells?
Then when you are looking at creating a new cell, you can quickly check to see if the candidate cell location is already occupied.
(if you had finite space, you could use a 2d array - I think I saw this in a Byte magazine article back in ~1980-ish, but if I understand correctly, you want a world that could extend indefinitely)