libgdx best approach for big list with game objects - list

I am planning a game, where I will have hundreds of game objects that should be drawn in certain order, and everyone of them will be able to spawn objects that should remain in the position of their parent (if the parent objects is drawn at the middle, they also should be drawn there).
So I need list that can perform the following operations fast:
add(), insertAt(pos), remove(pos), get(pos)
I have analyzed some data and have come to the following:
I will be using the Unordered Array of libgdx for storing the objects, with:
add() - O(1)
remove(pos) - O(2), because it uses swaping technique and at the end removes the last element
insert(pos) - O(2) for the same reason
get() - O(1)
I will also be using a LinkedList for keeping the order with references to the unordered array, so I can add objects in the middle fast.
I want to ask is this the best approach or am I missing something?

Related

Is there any way to move the cursor position of a linked list in constant time?

I have a linked list like this:
Head->A->B->C->D->Tail.
There can be N (1<N<10^5) items in the list.
The current cursor position is, cursor->B which is 2 if we think like an array.
I have to perform the following operation on my list:
insert x characters in the list at the cursor position and update the
cursor.
delete y (y < N) characters starting from the
cursor position and update the cursor.
move the cursor to a specific position within in the list.
I want all this operation in constant time.
Can anyone kindly help by suggesting any data structure model?
There isn't. Searching / iterating is linear in complexity - O(n). If you want a constant complexity, you need to use the different data structure. Since you are using C++, you should utilize one from the Containers library.
If the data can be sorted then by using "skip lists" a speed up can be achieved.
The principle is that extra pointers are used to skip ahead.
skip list is a data structure that allows fast search within an ordered sequence of elements. Fast search is made possible by maintaining a linked hierarchy of subsequences, with each successive subsequence skipping over fewer elements than the previous one ...
wikipedia
Therefore, with O(√n) extra space, we are able to reduce the time complexity to O(√n).
Skip-list
Of course it is not possible to use the linked list for that. As said before a linked list has a linear complexity.
You can try to use a more complex data structure like a hash as a lookup-container for the items in your list, which has a complexity of - O(n). Instead of storing the items itself the stored item can contain a pointer / index showing to the next item. But you have to keep in mind that the deletion will be still expensive because when removing one item you have to refresh the links showing to this item as well, So the item itself will need to know, if any other items are pointing to it.

How do you update a QuadTree after an object has moved in C++?

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.
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.
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.

Quadtree for collision detection implementaion

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

What type of Container should I use to hold a 2D Tile Based World's Tile Objects?

I have a 2D tile based world, which is created using a simple array: World[100][100].
I plan on making the game multiplayer, so I figure it would be good to have the SERVER send the CLIENT all the tiles surrounding the player, and only the information that the CLIENT needs: What texture/sprite to render, and what position to render it.
To do this, I am assuming it would be good to make my own TILE class, which has a tileType (Grass, Sand, Water, etc.) and holds an array of 10 TileObjects.
TileObject is a class that holds three variables: objectType (Is it a Character? An Item? A tree? A rock?), an int objectID (which is linked to whatever the object actually is, so it knows the Character is "Leeroy Jenkins" and can then send Leeroy's animation & direction to the CLIENT for rendering.) and an objectPosition (X & Y from the Tile. This can extend beyond the Tile if needed.)
Although with this I am not sure how I would handle objects or characters that are larger than a single tile (such as a Dragon whose collision consumes many tiles) but it sounds like the best design.
What type of container should I use to store the TileObjects in the TILE class? Right now I have an array, but I doubt that is good for performance right? Some tiles may have 0 TileObjects, while others may have 5+. I used 10 because I severely doubt anything will ever exceed <10.
class Tile
{
private:
TileObject TileObjects[10]; //up to 10 objects on a single tile
TileTerrainType tileTerrainType; //GFX to display Grass, Sand, Water, Swamp, etc.
}
I have read many different tutorials and books, who argue completely different container types: Vectors, Maps, Linked Lists, Arrays. I just do not know what is best to store TileObjects (some of which may move constantly, can be destroyed or added like dropping/picking up items, and some which may remain stationary like a tree or rock).
I think you should have a map from co-ordinates on the world to a vector of what things are contained at those co-ordinates in the world.
As in, if I have a class Thing that represents any thing that can be on a space in the game, and a class Position with x and y parameters, I would have this:
map<Position, vector<Thing>>
initialized with one vector<Thing>, initially empty, for every position in the game (all 10000 of them).
This gives you a useful property:
Spatial partitioning. If I want to figure out what things are around me, I just have to check in the map at nine different positions. If I were to go the other way, and have one big list of Things unpartitioned by where they are, I would have to look at every single Thing in the game to make sure I'd see every single Thing that might be near me.
This provides huge speedups 1) the larger the map gets 2) the more Things exist 3) the more and more complex kinds of local interactions you demand.
What if you have a ThingID and need to get the Thing associated with it, not knowing where it is? To solve this, you can have a big map<int, Thing> of ThingIDs to Things and look in there. Of course, we see some redundancy here - we could either store the Thing in the flat map, or in the by-Position map, and have the other one just be a reference to the other (in the former case, containing just current position - in the latter case, containing just ThingID) and they must be kept in sync.
This could even lead to the 'dragon' problem being solved - if Things are in the flat map and merely references are stored in the by-position map, your Dragon could have one entry in the flat map and four references (one for each of the positions it occupies) in the by-position map, all pointing to the same thing. Then you just have to write code that is careful to not interact with an object twice, just because it happened to find it in two positions it was considering!

Bidirectional data structure for this situation

I'm studying a little part of a my game engine and wondering how to optimize some parts.
The situation is quite simple and it is the following:
I have a map of Tiles (stored in a bi-dimensional array) (~260k tiles, but assume many more)
I have a list of Items which always are in at least and at most a tile
A Tile can logically contain infinite amount of Items
During game execution many Items are continuously created and they start from their own Tile
Every Item continuously changes its Tile to one of the neighbors (up, right, down, left)
Up to now every Item has a reference to its actual Tile, and I just keep a list of items.
Every time an Item moves to an adjacent tile I just update item->tile = .. and I'm fine. This works fine but it's unidirectional.
While extending the engine I realized that I have to find all items contained in a tile many times and this is effectively degrading the performance (especially for some situations, in which I have to find all items for a range of tiles, one by one).
This means I would like to find a data structure suitable to find all the items of a specific Tile better than in O(n), but I would like to avoid much overhead in the "moving from one tile to another" phase (now it's just assigning a pointer, I would like to avoid doing many operations there, since it's quite frequent).
I'm thinking about a custom data structure to exploit the fact that items always move to neighbor cell but I'm currently groping in the dark! Any advice would be appreciated, even tricky or cryptic approaches. Unfortunately I can't just waste memory so a good trade-off is needed to.
I'm developing it in C++ with STL but without Boost. (Yes, I do know about multimap, it doesn't satisfy me, but I'll try if I don't find anything better)
struct Coordinate { int x, y; };
map<Coordinate, set<Item*>> tile_items;
This maps coordinates on the tile map to sets of Item pointers indicating which items are on that tile. You wouldn't need an entry for every coordinate, only the ones that actually have items on them. Now, I know you said this:
but I would like to avoid much overhead in the "moving from one tile
to another" phase
And this method would involve adding more overhead in that phase. But have you actually tried something like this yet and determined that it is a problem?
To me I would wrap a std::vector into a matrix type (IE impose 2d access on a 1d array) this give you fast random access to any of your tiles (implementing the matrix is trivial).
use
vector_index=y_pos*y_size+x_pos;
to index a vector of size
vector_size=y_size*x_size;
Then each item can have a std::vector of items (if the amount of items a tile has is very dynamic maybe a deque) again these are random access contains with very minimal overhead.
I would stay away from indirect containers for your use case.
PS: if you want you can have my matrix template.
If you really think having each tile store it's items will cost you too much space, consider using a quadtree to store items then. This allows you to efficiently get all the items on a tile, but leaves your Tile grid in place for item movement.