Reputation: 764
Im quite a noob at c++ so I hope this question isn't too obvious.
I'm currently creating a voxel engine. Now I need to get a chunk on a specified XYZ location.
The chunk management class has a vector<Chunk*> loadedChunks
.
I can't use the index location of the vector because once I move the character it will change positions because old chunks will be removed and new chunks will be added.
In Java I would've used an HashMap<Point3D, Chunk>
so I've googled to see if c++ has something like that an I found that there is a class called map.
So I tried to use the map and used a class called Point3D that contains the x,y,z locations of the chunk but this gave me an error because I'm using a chunk* an point3D wasn't a pointer. I can't save the Point3D as a pointer because then I still can't get the location by xyz.
Now the question is, is there a way to use the map like this or is there maybe a better way to get the chunk at x,y,z or do I have to stick with the slowest loop that loops through all the chunks and returns the chunk that has equal x,y,z?
Here is the code I'm using:
ChunkManager.h
...
map<Point3D, Chunk*> loadedChunks;
....
ChunkManager.cpp
void ChunkManager::addChunk(Chunk* chunk){
loadedChunks.insert(make_pair(Point3D(chunk->x, chunk->y, chunk->z), chunk));
Chunk* c = loadedChunks[Point3D(chunk->x, chunk->y, chunk->z)];
}
Chunk* ChunkManager::getChunkAt(int x, int y, int z){
return loadedChunks[Point3D(chunk->x, chunk->y, chunk->z)];
}
void ChunkManager::render(Renderer& renderer){
for(auto iterator = loadedChunks.begin(); iterator != loadedChunks.end(); iterator++){
iterator->second->render(renderer);
}
}
void ChunkManager::update(double delta){
for(auto iterator = loadedChunks.begin(); iterator != loadedChunks.end(); iterator++){
iterator->second->update(delta);
}
}
Point3D:
class Point3D
{
public:
Point3D(int x, int y, int z);
int x, y, z;
bool operator< (const Point3D &rhs) const;
};
bool Point3D::operator< (const Point3D &rhs) const {
return x < rhs.x || ( x == rhs.x && ( y < rhs.y || ( y == rhs.y && z < rhs.z)));
}
I've just added the operator< and now its working.
return x < rhs.x || ( x == rhs.x && ( y < rhs.y || ( y == rhs.y && z < rhs.z)));
Upvotes: 0
Views: 1682
Reputation: 52689
you can use a map like you want. Nothing to do with pointers.... you have other (possibly conceptual) problems there.
but you create a std::map<Point3d, Chunk*> loadedChunks;
add values with loadedChunks.insert(std::make_pair(my_point3d, my_chunk_ptr));
read them using find() or operator[] - they have slightly different behaviour (op[] will return a reference to something, adding a new entry if it didn't already exist, find will return a pair, a bool to say the entry existed or not and an iterator to the entry).
your Point3d class will need to have an operator< at least that the map can use to determine where in the map to put the Point3d.
If you think this will not perform well (a map is implemented as a tree structure) then you can use boost, they have an unordered_map class that uses a hash table instead.
One thing I would potentially recommend is to use unique_ptr<> or shared_ptr<> for your chunk pointers though. These will help prevent leaks if you don't manage the pointer properly.
Upvotes: 1