mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Fix inconsistent rounding in VoxelLineIterator::VoxelLineIterator (#14555)
floatToInt rounds 0.5 differently depending on sign.
This commit is contained in:
parent
d767ab0890
commit
5a07f5a652
@ -49,31 +49,29 @@ void TestVoxelAlgorithms::runTests(IGameDef *gamedef)
|
||||
void TestVoxelAlgorithms::testVoxelLineIterator()
|
||||
{
|
||||
// Test some lines
|
||||
// Do not test lines that start or end on the border of
|
||||
// two voxels as rounding errors can make the test fail!
|
||||
std::vector<core::line3d<f32> > lines;
|
||||
for (f32 x = -9.1; x < 9; x += 3.124) {
|
||||
for (f32 y = -9.2; y < 9; y += 3.123) {
|
||||
for (f32 z = -9.3; z < 9; z += 3.122) {
|
||||
std::vector<core::line3d<f32>> lines;
|
||||
for (f32 x = -9.1f; x < 9.0f; x += 3.124f)
|
||||
for (f32 y = -9.2f; y < 9.0f; y += 3.123f)
|
||||
for (f32 z = -9.3f; z < 9.0f; z += 3.122f) {
|
||||
lines.emplace_back(-x, -y, -z, x, y, z);
|
||||
}
|
||||
for (f32 x = -3.0f; x < 3.1f; x += 0.5f)
|
||||
for (f32 y = -3.0f; y < 3.1f; y += 0.5f)
|
||||
for (f32 z = -3.0f; z < 3.1f; z += 0.5f) {
|
||||
lines.emplace_back(-x, -y, -z, x, y, z);
|
||||
}
|
||||
}
|
||||
lines.emplace_back(0, 0, 0, 0, 0, 0);
|
||||
lines.emplace_back(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
// Test every line
|
||||
std::vector<core::line3d<f32> >::iterator it = lines.begin();
|
||||
for (; it < lines.end(); it++) {
|
||||
core::line3d<f32> l = *it;
|
||||
|
||||
for (auto l : lines) {
|
||||
// Initialize test
|
||||
voxalgo::VoxelLineIterator iterator(l.start, l.getVector());
|
||||
|
||||
//Test the first voxel
|
||||
v3s16 start_voxel = floatToInt(l.start, 1);
|
||||
v3s16 start_voxel = floatToInt(l.start, 1.0f);
|
||||
UASSERT(iterator.m_current_node_pos == start_voxel);
|
||||
|
||||
// Values for testing
|
||||
v3s16 end_voxel = floatToInt(l.end, 1);
|
||||
v3s16 end_voxel = floatToInt(l.end, 1.0f);
|
||||
v3s16 voxel_vector = end_voxel - start_voxel;
|
||||
int nodecount = abs(voxel_vector.X) + abs(voxel_vector.Y)
|
||||
+ abs(voxel_vector.Z);
|
||||
@ -88,8 +86,9 @@ void TestVoxelAlgorithms::testVoxelLineIterator()
|
||||
UASSERTEQ(f32, (new_voxel - old_voxel).getLengthSQ(), 1);
|
||||
// The line must intersect with the voxel
|
||||
v3f voxel_center = intToFloat(iterator.m_current_node_pos, 1);
|
||||
aabb3f box(voxel_center - v3f(0.5, 0.5, 0.5),
|
||||
voxel_center + v3f(0.5, 0.5, 0.5));
|
||||
constexpr f32 eps = 1.0e-5f;
|
||||
aabb3f box(voxel_center - v3f(0.5f + eps),
|
||||
voxel_center + v3f(0.5f + eps));
|
||||
UASSERT(box.intersectsWithLine(l));
|
||||
// Update old voxel
|
||||
old_voxel = new_voxel;
|
||||
|
@ -1246,34 +1246,34 @@ VoxelLineIterator::VoxelLineIterator(const v3f &start_position, const v3f &line_
|
||||
m_last_index = getIndex(floatToInt(start_position + line_vector, 1));
|
||||
|
||||
if (m_line_vector.X > 0) {
|
||||
m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5) + 1.5
|
||||
m_next_intersection_multi.X = (m_current_node_pos.X + 0.5f
|
||||
- m_start_position.X) / m_line_vector.X;
|
||||
m_intersection_multi_inc.X = 1 / m_line_vector.X;
|
||||
} else if (m_line_vector.X < 0) {
|
||||
m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5)
|
||||
- m_start_position.X + 0.5) / m_line_vector.X;
|
||||
m_next_intersection_multi.X = (m_current_node_pos.X - 0.5f
|
||||
- m_start_position.X) / m_line_vector.X;
|
||||
m_intersection_multi_inc.X = -1 / m_line_vector.X;
|
||||
m_step_directions.X = -1;
|
||||
}
|
||||
|
||||
if (m_line_vector.Y > 0) {
|
||||
m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5) + 1.5
|
||||
m_next_intersection_multi.Y = (m_current_node_pos.Y + 0.5f
|
||||
- m_start_position.Y) / m_line_vector.Y;
|
||||
m_intersection_multi_inc.Y = 1 / m_line_vector.Y;
|
||||
} else if (m_line_vector.Y < 0) {
|
||||
m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5)
|
||||
- m_start_position.Y + 0.5) / m_line_vector.Y;
|
||||
m_next_intersection_multi.Y = (m_current_node_pos.Y - 0.5f
|
||||
- m_start_position.Y) / m_line_vector.Y;
|
||||
m_intersection_multi_inc.Y = -1 / m_line_vector.Y;
|
||||
m_step_directions.Y = -1;
|
||||
}
|
||||
|
||||
if (m_line_vector.Z > 0) {
|
||||
m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5) + 1.5
|
||||
m_next_intersection_multi.Z = (m_current_node_pos.Z + 0.5f
|
||||
- m_start_position.Z) / m_line_vector.Z;
|
||||
m_intersection_multi_inc.Z = 1 / m_line_vector.Z;
|
||||
} else if (m_line_vector.Z < 0) {
|
||||
m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5)
|
||||
- m_start_position.Z + 0.5) / m_line_vector.Z;
|
||||
m_next_intersection_multi.Z = (m_current_node_pos.Z - 0.5f
|
||||
- m_start_position.Z) / m_line_vector.Z;
|
||||
m_intersection_multi_inc.Z = -1 / m_line_vector.Z;
|
||||
m_step_directions.Z = -1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user