Add parameter to skip the callback on the first tile.

For example if you are going from tile 1,1 to 1,2 you would get
two notifications if parInclFirst==true, one for 1,1 and one for
1,2. If parInclFirst==false, then you will only get a notification
for 1,2. Note that if the segment passed to to
for_each_voxel_under_segment() is too short and doesn't span over
the initial tile, passing parInclFirst==false will discard the
only callback you would normally get. Effectively this can be used
for a sort of "on tile changed" notification.
This commit is contained in:
King_DuckZ 2017-07-23 16:22:04 +01:00
parent 084c4d64da
commit 40967784a3
4 changed files with 25 additions and 5 deletions

View File

@ -93,7 +93,7 @@ namespace curry {
return true; //wtp.property->walkable;
};
for_each_voxel_under_segment(old_pos, this->position(), width_height(), *m_world, is_walkable);
for_each_voxel_under_segment(old_pos, this->position(), width_height(), *m_world, is_walkable, false);
//for (auto tile_vec : crossed_tiles(old_pos, this->position(), m_world->tile_size())) {
// const TileIndex* const tile = m_world->tile(tile_vec);
// for (uint16_t z = 0; z < m_world->layer_count(); ++z) {

View File

@ -93,7 +93,14 @@ namespace curry {
//see:
//http://stackoverflow.com/questions/24679963/precise-subpixel-line-drawing-algorithm-rasterization-algorithm
void for_each_voxel_under_segment (const vec2f& parFrom, const vec2f& parTo, vec2us parObjSize, const WorldGrid& parWorld, std::function<bool(vec2us)> parFunc) {
void for_each_voxel_under_segment (
const vec2f& parFrom,
const vec2f& parTo,
vec2us parObjSize,
const WorldGrid& parWorld,
std::function<bool(vec2us)> parFunc,
bool parInclFirst
) {
const vec2f tile_size = vector_cast<vec2f>(parWorld.tile_size());
//in this simplified case everything should be part of the world grid
assert(parFrom >= vec2f(0.0f));
@ -129,7 +136,12 @@ namespace curry {
vec2us curr_tile = pixel_to_world_tile(parWorld, u);
const vec2us last_tile = pixel_to_world_tile(parWorld, parTo);
while (parFunc(curr_tile) and last_tile != curr_tile) {
bool& do_callback = parInclFirst;
while (
((do_callback and parFunc(curr_tile)) or not do_callback)
and last_tile != curr_tile
) {
do_callback = true;
if (max.x() < max.y()) {
assert(step.x());
assert(

View File

@ -30,5 +30,12 @@ namespace curry {
float segment_intersection (const vec2f& parA, const vec2f& parDirA, const vec2f& parB, const vec2f& parDirB);
#endif
void for_each_voxel_under_segment ( const vec2f& parFrom, const vec2f& parTo, vec2us parObjSize, const WorldGrid& parWorld, std::function<bool(vec2us)> parFunc );
void for_each_voxel_under_segment (
const vec2f& parFrom,
const vec2f& parTo,
vec2us parObjSize,
const WorldGrid& parWorld,
std::function<bool(vec2us)> parFunc,
bool parInclFirst
);
} //namespace curry

View File

@ -54,7 +54,8 @@ TEST_CASE ("Check that 2D raytracing works", "[raytracing][geometry]") {
vec2f(639.0f, 639.0f), //to
vec2us(1, 1), //objsize
world, //world
[&diagonal](vec2us wtp) mutable {diagonal.push_back(wtp); return true;}
[&diagonal](vec2us wtp) mutable {diagonal.push_back(wtp); return true;},
true
);
const auto* tile_prop = &world.tile_property(world.tile(vec2us(0)));