Skip to content

Added Compass Class#63

Open
scrasmussen wants to merge 5 commits intoksundberg:masterfrom
scrasmussen:master
Open

Added Compass Class#63
scrasmussen wants to merge 5 commits intoksundberg:masterfrom
scrasmussen:master

Conversation

@scrasmussen
Copy link
Contributor

David and I (Soren) have added a Compass class to the project. It has not been added to the GUI but when you implement it will give the distance from your current position to the closest material of your choosing. Unlike our original proposal the algorithm does not calculate the shortest walking distance.

We check the area around a person for a certain material, starting at distance one. If that area does not contain the material then increase the distance of our search area by one. We continue this until we have found the material or have searched the entire world and failed to find the material. We have found three places in our algorithm where we have obtained speedup by using tbb::parallel_for. We populate the queue of points to check in parallel. After which we check each point is the material we want in parallel. We then have to check the Boolean array to see if the material was found at the current distance. This gives us O(n * q) where n is the number of blocks in the world and q is the size of the queue. Having to access each element of the concurrent_queue one at a time slowed down the function more then we would have liked.

@GriffinHatchery
Copy link

Hey this is David can we talk about this? You can access each element of the concurrent_queue in parallel. you just need to use the unsafe_begin(), and unsafe_end() functions. As long as we are just accessing them and not changing them this is just fine. Also I though we were going return a vector3 with the direction of the closest element. I can make these changes quickly if you like. Just tell me what you want.

@GriffinHatchery
Copy link

We need to use 'chunkmanager' not 'world' so that we dont need to go though every block.
The whole point of my code was to find the positions that where a certan distance from a starting point.
I think the following code should work right (For Compass.cpp. Compass.h would also have to change some) I have access to a windows machine right now and have never gotten the project to build on windows. so I dont know if the following code builds (that why I'm not making pull for it yet) But it should be something like this.

#include "Compass.h"
#include "tbb/tbb.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"
#include "tbb/concurrent_queue.h"
//#include "../world.h"

#include
#include
#include
#include "chunkmanager.h"

int modx(int s){
return (s>0?s%ChunkManager::BOUNDX :(s+ChunkManager::BOUNDX)%ChunkManager::BOUNDX );
}

int mody(int s){
return (s>0?s%ChunkManager::BOUNDY :(s+ChunkManager::BOUNDY)%ChunkManager::BOUNDY );
}

int modz(int s){
return s;
}

Compass::Compass(chunkmanager input, glm::vec3 pos)
{
world = input;
currentPos = pos;
};

struct CheckType
{
std::vectorstd::shared_ptr* blocks;
glm::vec3 position;
BlockType type;
bool* found;
ChunkManager* chunk
volatile glm::vec3 distance;
void operator()( const tbb::blocked_range& range ) const
{
for (auto i=range.begin(); found==false, i!=auto.end(); ++i)
{
if(type==chunk->get(i->x,i->y,i->z)
{
(*found)=true;
distance=glm::vec3 (i->x-position.x,i->y-position.y,i->z-position.z);
}
}
}
};

glm::vec3 Compass::find(BlockType type)
{
auto found = false;
auto distance = 1;

while (distance<=worldSize/2)
{
auto q = getQueue(currentPos, distance,worldSize);
CheckType check;
check.chunk =& world;
check.position = e;
check.type = type;
check.found=&found;
tbb::parallel_for( tbb::blocked_range(q.unsafe_begin(), q.unsafe_end() ), check);
if(found){
return check.distance();
}
}
return glm::vec3(0,0,0);
}

struct populatej {
tbb::concurrent_queueglm::vec3* queue;
glm::vec3* start;
int distance;
int i;
int worldSize;
void operator()( tbb::blocked_range& range ) const {
for( int j=range.begin(); j!=range.end(); ++j ){
int k=i>0?distance-j:distance+j;
queue->push(glm::vec3(mod(start->x+i),mod(start->y+j),(mod start->z+k)));
if(k!=0)queue->push(glm::vec3(modx(start->x+i),mody(start->y+j),modz(start->z-k)));
}
}

};

struct populateQueue {
tbb::concurrent_queueglm::vec3* queue;
glm::vec3* start;
int distance;
int worldSize;
void operator()( tbb::blocked_range& range ) const {
for( int i=range.begin(); i!=range.end(); ++i ){
populatej jloop;
int jdistance=i>0?distance-i:distance+i;
jloop.distance=jdistance;
jloop.queue=queue;
jloop.start=start;
jloop.i=i;
jloop.worldSize=worldSize;
tbb::parallel_for( tbb::blocked_range(-jdistance,jdistance),jloop);
}
}
};

tbb::concurrent_queueglm::vec3 Compass::getQueue( glm::vec3& start,int dis,int worldSize) {
tbb::concurrent_queueglm::vec3 queue;
populateQueue pq;
pq.queue=&queue;
pq.distance=dis;
pq.worldSize=worldSize;
pq.start=&start;
tbb::parallel_for( tbb::blocked_range( -dis, +dis ), pq );
return queue;
}

@scrasmussen
Copy link
Contributor Author

Thanks for making those changes, sorry for not responding sooner. I've been studying all day for Koebbe's final tomorrow... Sorry, we had made changes from our original plan and I thought we had just wanted to return the distance from a certain point, not the vector, but I was wrong. I've been building the code on my linux box so I'll be able to test everything.

@GriffinHatchery
Copy link

cool thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants