Fix code so raytrace test now passes.

This commit is contained in:
King_DuckZ 2017-02-10 19:24:44 +00:00
parent 80d0e1c336
commit ff91bbbc71
4 changed files with 66 additions and 54 deletions

View file

@ -79,13 +79,21 @@ namespace curry {
//else
//return INFINITY;
}
vec2f frac (vec2f parVal) {
return parVal - vec2f(std::floor(parVal.x()), std::floor(parVal.y()));
}
template <typename T> int sgn (T val) {
return (T(0) < val) - (val < T(0));
}
#if !defined(BUILD_TESTING)
} //unnamed namespace
#endif
//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(const WorldTileProperty&)> parFunc) {
void for_each_voxel_under_segment (const vec2f& parFrom, const vec2f& parTo, vec2us parObjSize, const WorldGrid& parWorld, std::function<bool(vec2us)> parFunc) {
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));
@ -93,36 +101,51 @@ namespace curry {
assert(parFrom / tile_size <= vector_cast<vec2f>(parWorld.world_size()));
assert(parTo / tile_size <= vector_cast<vec2f>(parWorld.world_size()));
float t = 0.0f;
//float t = 0.0f;
const vec2f& u = parFrom;
const vec2f v = parTo - parFrom;
vec2us start = pixel_to_world_tile(parWorld, u);
vec2f step(fsgn(v.x()), fsgn(v.y()));
//vec2f step(fsgn(v.x()), fsgn(v.y()));
const auto next_tile_boundary = (step + abs(step)) / 2.0f;
const auto intersection = vec2f(
segment_intersection(
u,
v,
vec2f(static_cast<float>(start.x() + next_tile_boundary.x()), 0.0f),
vec2f(0.0f, static_cast<float>(parWorld.world_size().y()) * tile_size.y())
),
segment_intersection(
u,
v,
vec2f(0.0f, static_cast<float>(start.y()) + next_tile_boundary.y()),
vec2f(static_cast<float>(parWorld.world_size().x()) * tile_size.x(), 0.0f)
)
);
const auto delta = tile_size / v;
auto max = delta * (vec2f(1.0f) - frac(u / tile_size));
const auto delta = vec2f(
std::isinf(intersection.x()) ? 0.0f : tile_size.x() / dot(vec2f(1.0f, 0.0f), v * inv_length(v)),
0.0f //std::isinf(intersection.y()) ? 0.0f : tile_size.y() /
);
//vec2us start = pixel_to_world_tile(parWorld, u);
//const auto next_tile_boundary = (step + abs(step)) / 2.0f;
//const auto max = vec2f(
// segment_intersection(
// u,
// v,
// vec2f(static_cast<float>(start.x() + next_tile_boundary.x()), 0.0f),
// vec2f(0.0f, static_cast<float>(parWorld.world_size().y()) * tile_size.y())
// ),
// segment_intersection(
// u,
// v,
// vec2f(0.0f, static_cast<float>(start.y()) + next_tile_boundary.y()),
// vec2f(static_cast<float>(parWorld.world_size().x()) * tile_size.x(), 0.0f)
// )
//);
//if (not std::isinf(intersection_vert)) {
//todo: continuare da qui
//}
//const auto delta = vec2f(
// std::isinf(max.x()) ? 0.0f : tile_size.x() / dot(vec2f(1.0f, 0.0f), v * inv_length(v)),
// 0.0f //std::isinf(max.y()) ? 0.0f : tile_size.y() /
//);
//see:
//http://stackoverflow.com/questions/12367071/how-do-i-initialize-the-t-variables-in-a-fast-voxel-traversal-algorithm-for-ray#12370474
vec2i step(sgn(v.x()), sgn(v.y()));
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) {
if (max.x() < max.y()) {
max.x() += delta.x();
curr_tile.x() = static_cast<uint16_t>(curr_tile.x() + step.x());
}
else {
max.y() += delta.y();
curr_tile.y() = static_cast<uint16_t>(curr_tile.y() + step.y());
}
}
}
} //namespace curry