I have a tiled map which is made of chunks and each chunk is a rectangle of tiles. Now I want to add entities to this(each entity stand on a specific tile), and every loop all the entities should call their update() function, so I wanted to ask for a suggestion: what data structure should I use for saving their locations?
I don't know yet what kind of methods I'll have, but I'll probably need a method that gets all the entities from a specific area(maybe a point) for drawing for example. This is a critic question because there maybe a huge map like 100x100 chunks where each chunk is 30x20 tiles so it will be 3000x2000 tiles, and lots of entities for example 1000, so if I'll save it in a list it will be very slow to search for an entities O(n) and if every entities make a search it will take O(n^2).
Right now I have a couple of solutions but they are all problematic:
kd-tree(for 2d) - since each loop all the entities can change their locations, the complexity of updating them will be the same as rebuilding the whole tree each loop O(nlogn).
each chunk will save the entities that belong to it - my best solution so far, easy updating, but the complexity is higher then in the kd-tree.
So does anybody have a suggestion for this problem?
A dictionary that maps tile (position) towards a list of all entities on that tile. All entities should have a position property and an event notifying when it changes, so that the dictionary can be updated at each movement.
(There should be no list for the tiles without entities. The list should be created when an entitiy moves to that position, and removed when the last entity leaves the position.)
This might be a crude suggestion, and I'm sure it can be improved, but here's a thought:
First, store your positions in such a way that you can access them in constant time given a specific object. For instance, if you want to access them directly through your entities, you can store the position structs in a list/vector and give each entity a pointer/reference to its position.
Second, store an entity pointer/reference or GUID in the same struct as the entity position, so you can identify an entity based on a position object. (There is probably a better way I'm not thinking of right now though.)
Third, utilize some of the principles of sweep and prune/sort and sweep (common in 3D games): Keep two sorted position lists/vectors, one sorted in the x direction and the other sorted in the y direction. One can hold the actual position objects, and the other can hold pointers/references. These lists can take advantage of temporal coherence, so the cost of keeping them sorted shouldn't be too high, unless there's a lot of fast and chaotic movement.
An advantage of this setup is that it's really easy to figure out where every object is relative to each other. Want to know how many objects are within 10 squares of Billy the Elf in either direction? Check Billy's position and iterate forward/backward through both lists until you reach an entity more than 10 squares away in each direction.
If you're interested in the concept, look up sort and sweep (also known as sweep and prune). You'd only be using the first half of the algorithm, but it's used for broad-phase collision detection in practically every major 3D physics engine, so you know that it has to be fast in general. ;) There's a lot of information floating around about it, so you'll probably find much more sophisticated implementation ideas floating around too. (For instance, I don't like the indirection involved in storing a sorted list of pointers/references to position structs; working with the actual structs is more cache-efficient, but then you need to update the position in two places if you want to exploit temporal coherency with persistent arrays. Someone else may have thought of a more clever design that's escaping me right now.)
EDIT: I'd comment on Erik H's idea, but my rep isn't high enough. I just wanted to say that his idea sounds very well suited to your game, especially if you will have a lot of entities tightly packed on the same tile or in a small neighborhood. If I were you, I'd probably try it before the sweep and prune idea. However, it should be accompanied with a well-planned memory management strategy: If you have a dictionary of tile locations that naively map to vectors of entities, you're going to have a lot of memory being allocated and freed when entities move from one tile to another. Instead, you'll want to implement his idea as something more like a dictionary/linked list combo:
The dictionary keys would be tile positions, and the dictionary would return a single pointer to a linked list node. This node would be part of a linked list of all entities on the same tile. Whenever an entity moves from one tile to another, it will be removed from its current linked list and added to the new one. If an entity moves to an empty tile, it will be in a linked list all on its own, and it should be added to the dictionary. When the last entity moves from a tile, the entry for that tile should be removed from the dictionary. This will allow you to move around entities without continual dynamic allocation/deallocation, since you're just updating pointers (and the dictionary will probably be pretty memory efficient).
Note that you don't have to store full-blown entities in the linked lists, either; you can easily create your linked list out of lightweight objects (containing a pointer or GUID to the actual entity).
Related
I am trying to understand the basics of RTree algorithm and I am trying to figure out how it performs the search of e.g. all retaurants within 1 km. We would have all objects stores in rectangles in our database, we would then (prbably) build a query rectangle, based on our current position, and then find all rectangles that overlap with it. WOuld we then scan through the results to find the ones of interest i.e. only objects which are restaurants?
Yes, this is basically how range queries on R-trees work: if a rectangle overlaps with your query region, expand it (look at the contents, rectangles or points). Otherwise, ignore it. Overlap testing is simple for rectangle-to-rectangle, and for spherical queries you need to compute the minimum distance of the sphere center to the rectangle ("minDist").
k nearest neighbor queries are a bit more tricky; here you need priority queues. Always expand the best candidate (by "minDist"), until you have found k objects that are closer than the next rectangles "minDist".
Since you can't really index the "is a restaurant" property, you'll have to either build an r-tree containing restaurants only, or filter the results by the restaurant property.
(This also is how it is done e.g. in SQLite; the spatial part is indexed with an R-tree, while the restaurant property is e.g. obtained via a join or a bitmap index)
The tricky part of an R-tree is not the query, but how to build it. There are very simple but good methods for bulk loading point data (STR), but for an online database you need somewhat tricky methods. R*-trees outperform classic R-trees significantly in my experience; the reinsertions used by R*-trees are in particular tricky to implement in a real DBMS. An interesting tradeoff is to just use insert and split from R*, but not the reinsertions. On the query side, there is no difference between R and R* anyway.
kd-trees: They are related to r-trees, but have some key differences: first of all, they are not designed for disk storage, but in-memory operation only. Secondly, they are not meant to be updated (they are not balanced trees), but if you have changes you will have to rebuild them again every now and then to keep the performance good. So in some cases they will perform very well (and they are fairly simple to implement), but once you get to large data and on-disk they are much more painful. Furthermore, they do not allow for different loading strategies.
I'm trying to use quadtrees for collision detection in a game I'm making, but I'm not sure how to handle objects that might be moving between different quads?
The only way I can think of it is by clearing out the whole tree each frame, and then adding everything back in there, but that seems like that can get cpu intensive and not very efficient. Do you check each object every frame to see if it has moved outside the boundry of it's current quad, and if so then remove it and readd it? That again seems like it can be pretty inefficient because you'd be performing collision checks on every moving object every frame.
Also, regarding quadtrees but unrelated to objects moving around in them, how do you handle multiple objects in the same quad? Most sites that I've read about them on say that you should only have one, maybe two, objects in a quad, and if you get more than that then push them down in the tree. What if you had a situation like this? You have three circles and they are all on the edges of the level below them so they can't go any further down, but there is three all in the same level, which people say you shouldn't have.
I don't think it's particularly inefficient to implement your suggestion: check to see if an object has moved outside its quadtree, and if so then remove and re-add it. Any object which moves from one frame to the next will need to have some collision detection performed on it, surely? And the quadtree operations are only performed if it moves quadtrees, and the CPU time spent there are probably overshadowed by the CPU time doing the more precise "Does object A touch object B?" computations. So I don't know that you can do better.
On your 2nd question: I don't know how other people implement quadtrees, but I allow objects to occupy more than one quadtree, precisely for the reason you've given in your diagram (when an object straddles a boundary). So an object has a "current list of quads" instead of a "current quad".
Removing/re-adding can be optimized by moving up the quad tree instead of removing the item from the tree completely and then re-adding, i.e. move to the "parent" quad, and then have the "parent" add it - if it doesn't fit in the "parent", go to the "grandparent", etc.
As for your second concern, you will need some flexibility - if all 3 are on an edge, then you can't lower them - but that should be (pardon the pun) an edge case.
I am looking to implement a 2D top-down collision system, and was hoping for some input as to the likely performance between a few different ideas. For reference I expect the number of moving collision objects to be in the dozens, and the static collision objects to be in the hundreds.
The first idea is border-line brute force (or maybe not so border-line). I would store two lists of collision objects in a collision system. One list would be dynamic objects, the other would include both dynamic and static objects (each dynamic would be in both lists). Each frame I would loop through the dynamic list and pass each object the larger list, so it could find anything it may run into. This will involve a lot of unnecessary calculations for any reasonably sized loaded area but I am using it as a sort of baseline because it would be very easy to implement.
The second idea is to have a single list of all collision objects, and a 2D array of either ints or floats representing the loaded area. Each element in the array would represent a physical location, and each object would have a size value. Each time an object moved, it would subtract its size value from its old location and add it to its new location. The objects would have to access elements in the array before they moved to make sure there was room in their new location, but that would be fairly simple to do. Besides the fact that I have a very public, very large array, I think it would perform fairly well. I could also implement with a boolean array, simply storing if a location is full or not, but I don't see any advantage to this over the numeric storage.
The third I idea I had was less well formed. A month or two ago I read about a two dimensional, rectangle based data structure (may have been a tree, i don't remember) that would be able to keep elements sorted by position. Then I would only have to pass the dynamic objects their small neighborhood of objects for update. I was wondering if anyone had any idea what this data structure might be, so I could look more into it, and if so, how the per-frame sorting of it would affect performance relative to the other methods.
Really I am just looking for ideas on how these would perform, and any pitfalls I am likely overlooking in any of these. I am not so much worried about the actual detection, as the most efficient way to make the objects talk to one another.
You're not talking about a lot of objects in this case. Honestly, you could probably brute force it and probably be fine for your application, even in mobile game development. With that in mind, I'd recommend you keep it simple but throw a bit of optimization on top for gravy. Spatial hashing with a reasonable cell size is the way I'd go here -- relatively reasonable memory use, decent speedup, and not that bad as far as complexity of implementation goes. More on that in a moment!
You haven't said what the representation of your objects is, but in any case you're likely going to end up with a typical "broad phase" and "narrow phase" (like a physics engine) -- the "broad phase" consisting of a false-positives "what could be intersecting?" query and the "narrow phase" brute forcing out the resulting potential intersections. Unless you're using things like binary space partitioning trees for polygonal shapes, you're not going to end up with a one-phase solution.
As mentioned above, for the broad phase I'd use spatial hashing. Basically, you establish a grid and mark down what's in touch with each grid. (It doesn't have to be perfect -- it could be what axis-aligned bounding boxes are in each grid, even.) Then, later you go through the relevant cells of the grid and check if everything in each relevant cell is actually intersecting with anything else in the cell.
Trick is, instead of having an array, either have a hash table for every cell grid. That way you're only taking up space for grids that actually have something in them. (This is not a substitution for badly sized grids -- you want your grid to be coarse enough to not have an object in a ridiculous amount of cells because that takes memory, but you want it to be fine enough to not have all objects in a few cells because that doesn't save much time.) Chances are by visual inspection, you'll be able to figure out what a good grid size is.
One additional step to spatial hashing... if you want to save memory, throw away the indices that you'd normally verify in a hash table. False positives only cost CPU time, and if you're hashing correctly, it's not going to turn out to be much, but it can save you a lot of memory.
So:
When you update objects, update which grids they're probably in. (Again, it's good enough to just use a bounding box -- e.g. a square or rectangle around the object.) Add the object to the hash table for each cell it's in. (E.g. If you're in cell 5,4, that hashes to the 17th entry of the hash table. Add it to that entry of the hash table and throw away the 5,4 data.) Then, to test collisions, go through the relevant cells in the hash table (e.g. the entire screen's worth of cells if that's what you're interested in) and see what objects inside of each cell collide with other objects inside of each cell.
Compared to the solutions above:
Note brute forcing, takes less time.
This has some commonality with the "2D array" method mentioned because, after all, we're imposing a "grid" (or 2D array) over the represented space, however we're doing it in a way less prone to accuracy errors (since it's only used for a broad-phase that is conservative). Additionally, the memory requirements are lessened by the zealous data reduction in hash tables.
kd, sphere, X, BSP, R, and other "TLA"-trees are almost always quite nontrivial to implement correctly and test and, even after all that effort, can end up being much slower that you'd expect. You don't need that sort of complexity for a few hundreds of objects normally.
Implementation note:
Each node in the spatial hash table will ultimately be a linked list. I recommend writing your own linked list with careful allocations. Each node need take up more than 8 bytes (if you're using C/C++) and should a pooled allocation scheme so you're almost never allocating or freeing memory. Relying on the built-in allocator will likely cripple performance.
First thing, I am but a noob, I am working my way through the 3dbuzz xna extreme 101 videos, and we are just now covering a system that uses static lists of each different type of object, when updating an object you only check against the list/s of things it is supposed to collide with.
So you only check enemy collisions against the player or the players bullets, not other enemys etc.
So there is a static list of each type of game object, then each gamenode has its own collision list(edit:a list of nodes) , that are only the types it can hit.
sorry if its not clear what i mean, i'm still finding my feet
I am making a 2d space game with many moving objects. I have already implemented a camera that can move around and draw the objects within the view. The problem now is that I have to check for every object wether it is within the rectangle of my view before I draw it (O(n) operations where n is the number of objects in my world). I would like a more efficient way to acquire all the objects within the view so I only have to draw them.
I know a bunch of data structures that can achieve a O(log n + k) query time for a two dimensional range query, where k is the amount of objects within the range. The problem is that all the objects are constantly moving. The update time on most of the data structures is O(log n) as well. This is pretty bad because almost all objects are moving so all will have to be updated resulting in O(n log n) operations. With my current implementation (everything is just stored in a list), the update time takes O(n) operations to update everything.
I am thinking that this problem must have been solved already, but I couldn't really find a solution that specifically considers my options. Most 2D camera examples just do it the way I am currently doing.
So my question basically consists out of two things:
Is there a more efficient way to do this than my current one (in general)?
Is there a more efficient way to do this than my current one (in XNA)?
On one hand I am thinking, O(n) + O(n) is better than O(log n) + O(n log n), but on the other hand I know that in many games they use all these data structures like BSPs etc. So I feel like I am missing some piece of the puzzle.
PS: I am a bit confused whether I should post this on Stack Overflow, the Game Developers stack exchange or the Computer Science Theory stack exchange...... So please excuse me if it's a bit out of scope.
My first question would be: are you really going to have a world with a million (or even a billion!) objects?
This is a performance optimisation, so here's what I would do:
First of all: nothing. Just draw everything and update everything every frame, using a big list. Suitable for tens of objects.
If that is too slow, I would do some basic culling as I iterated the list. So for each object - if it is off-screen, don't draw it. If it is "unimportant" (eg: a particle system, other kinds of animation, etc) don't update it while off-screen either. Suitable for hundreds of objects.
(You need to be able to get an object's position and bounding box, and check compare it with the screen's rectangle.)
And finally, if that is too slow, I would implement a bucketed data structure (constant update time, constant query time). In this case a 2D grid of lists that covers your world space. Suitable for thousands of objects.
If that ends up taking up too much memory - if your world is crazy-large and sparse - I would start looking into quadtrees, perhaps. And remember that you don't have to update the space-partitioning structure every time you update an object - only when an object's position changes significantly!
Remember the idiom: Do The Simplest Thing That Could Possibly Work. Implement the simple case, and then actually see if your game is running slowly with a real-world number of objects, before you go implementing something complicated.
You mean to say, you check every object that you wish to put on to screen & take action against whether or not it is inside the specified screen area???
XNA takes care of handling objects which are out of screen (by not drawing of course) automatically, You simply specify the coordinates... Or did I misunderstand you question??
EDIT
Why not use a container sprite, draw everything you want inside it & then draw that single main sprite onto the screen? Calling draw on that single sprite won't really involve drawing of those parts which are outside.
I'm developing a game which features a sizeable square 2d playing area. The gaming area is tileless with bounded sides (no wrapping around). I am trying to figure out how I can best divide up this world to increase the performance of collision detection. Rather than checking each entity for collision with all other entities I want to only check nearby entities for collision and obstacle avoidance.
I have a few special concerns for this game world...
I want to be able to be able to use a large number of entities in the game world at once. However, a % of entities won't collide with entities of the same type. For example projectiles won't collide with other projectiles.
I want to be able to use a large range of entity sizes. I want there to be a very large size difference between the smallest entities and the largest.
There are very few static or non-moving entities in the game world.
I'm interested in using something similar to what's described in the answer here: Quadtree vs Red-Black tree for a game in C++?
My concern is how well will a tree subdivision of the world be able to handle large size differences in entities? To divide the world up enough for the smaller entities the larger ones will need to occupy a large number of regions and I'm concerned about how that will affect the performance of the system.
My other major concern is how to properly keep the list of occupied areas up to date. Since there's a lot of moving entities, and some very large ones, it seems like dividing the world up will create a significant amount of overhead for keeping track of which entities occupy which regions.
I'm mostly looking for any good algorithms or ideas that will help reduce the number collision detection and obstacle avoidance calculations.
If I were you I'd start off by implementing a simple BSP (binary space partition) tree. Since you are working in 2D, bound box checks are really fast. You basically need three classes: CBspTree, CBspNode and CBspCut (not really needed)
CBspTree has one root node instance of class CBspNode
CBspNode has an instance of CBspCut
CBspCut symbolize how you cut a set in two disjoint sets. This can neatly be solved by introducing polymorphism (e.g. CBspCutX or CBspCutY or some other cutting line). CBspCut also has two CBspNode
The interface towards the divided world will be through the tree class and it can be a really good idea to create one more layer on top of that, in case you would like to replace the BSP solution with e.g. a quad tree. Once you're getting the hang of it. But in my experience, a BSP will do just fine.
There are different strategies of how to store your items in the tree. What I mean by that is that you can choose to have e.g. some kind of container in each node that contains references to the objects occuping that area. This means though (as you are asking yourself) that large items will occupy many leaves, i.e. there will be many references to large objects and very small items will show up at single leaves.
In my experience this doesn't have that large impact. Of course it matters, but you'd have to do some testing to check if it's really an issue or not. You would be able to get around this by simply leaving those items at branched nodes in the tree, i.e. you will not store them on "leaf level". This means you will find those objects quick while traversing down the tree.
When it comes to your first question. If you only are going to use this subdivision for collision testing and nothing else, I suggest that things that can never collide never are inserted into the tree. A missile for example as you say, can't collide with another missile. Which would mean that you dont even have to store the missile in the tree.
However, you might want to use the bsp for other things as well, you didn't specify that but keep that in mind (for picking objects with e.g. the mouse). Otherwise I propose that you store everything in the bsp, and resolve the collision later on. Just ask the bsp of a list of objects in a certain area to get a limited set of possible collision candidates and perform the check after that (assuming objects know what they can collide with, or some other external mechanism).
If you want to speed up things, you also need to take care of merge and split, i.e. when things are removed from the tree, a lot of nodes will become empty or the number of items below some node level will decrease below some merge threshold. Then you want to merge two subtrees into one node containing all items. Splitting happens when you insert items into the world. So when the number of items exceed some splitting threshold you introduce a new cut, which splits the world in two. These merge and split thresholds should be two constants that you can use to tune the efficiency of the tree.
Merge and split are mainly used to keep the tree balanced and to make sure that it works as efficient as it can according to its specifications. This is really what you need to worry about. Moving things from one location and thus updating the tree is imo fast. But when it comes to merging and splitting it might become expensive if you do it too often.
This can be avoided by introducing some kind of lazy merge and split system, i.e. you have some kind of dirty flagging or modify count. Batch up all operations that can be batched, i.e. moving 10 objects and inserting 5 might be one batch. Once that batch of operations is finished, you check if the tree is dirty and then you do the needed merge and/or split operations.
Post some comments if you want me to explain further.
Cheers !
Edit
There are many things that can be optimized in the tree. But as you know, premature optimization is the root to all evil. So start off simple. For example, you might create some generic callback system that you can use while traversing the tree. This way you dont have to query the tree to get a list of objects that matched the bound box "question", instead you can just traverse down the tree and execute that call back each time you hit something. "If this bound box I'm providing intersects you, then execute this callback with these parameters"
You most definitely want to check this list of collision detection resources from gamedev.net out. It's full of resources with game development conventions.
For other than collision detection only, check their entire list of articles and resources.
My concern is how well will a tree
subdivision of the world be able to
handle large size differences in
entities? To divide the world up
enough for the smaller entities the
larger ones will need to occupy a
large number of regions and I'm
concerned about how that will affect
the performance of the system.
Use a quad tree. For objects that exist in multiple areas you have a few options:
Store the object in both branches, all the way down. Everything ends up in leaf nodes but you may end up with a significant number of extra pointers. May be appropriate for static things.
Split the object on the zone border and insert each part in their respective locations. Creates a lot of pain and isn't well defined for a lot of objects.
Store the object at the lowest point in the tree you can. Sets of objects now exist in leaf and non-leaf nodes, but each object has one pointer to it in the tree. Probably best for objects that are going to move.
By the way, the reason you're using a quad tree is because it's really really easy to work with. You don't have any heuristic based creation like you might with some BSP implementations. It's simple and it gets the job done.
My other major concern is how to
properly keep the list of occupied
areas up to date. Since there's a lot
of moving entities, and some very
large ones, it seems like dividing the
world up will create a significant
amount of overhead for keeping track
of which entities occupy which
regions.
There will be overhead to keeping your entities in the correct spots in the tree every time they move, yes, and it can be significant. But the whole point is that you're doing much much less work in your collision code. Even though you're adding some overhead with the tree traversal and update it should be much smaller than the overhead you just removed by using the tree at all.
Obviously depending on the number of objects, size of game world, etc etc the trade off might not be worth it. Usually it turns out to be a win, but it's hard to know without doing it.
There are lots of approaches. I'd recommend settings some specific goals (e.g., x collision tests per second with a ratio of y between smallest to largest entities), and do some prototyping to find the simplest approach that achieves those goals. You might be surprised how little work you have to do to get what you need. (Or it might be a ton of work, depending on your particulars.)
Many acceleration structures (e.g., a good BSP) can take a while to set up and thus are generally inappropriate for rapid animation.
There's a lot of literature out there on this topic, so spend some time searching and researching to come up with a list candidate approaches. Mock them up and profile.
I'd be tempted just to overlay a coarse grid over the play area to form a 2D hash. If the grid is at least the size of the largest entity then you only ever have 9 grid squares to check for collisions and it's a lot simpler than managing quad-trees or arbitrary BSP trees. The overhead of determining which coarse grid square you're in is typically just 2 arithmetic operations and when a change is detected the grid just has to remove one reference/ID/pointer from one square's list and add the same to another square.
Further gains can be had from keeping the projectiles out of the grid/tree/etc lookup system - since you can quickly determine where the projectile would be in the grid, you know which grid squares to query for potential collidees. If you check collisions against the environment for each projectile in turn, there's no need for the other entities to then check for collisions against the projectiles in reverse.