mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +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()
|
void TestVoxelAlgorithms::testVoxelLineIterator()
|
||||||
{
|
{
|
||||||
// Test some lines
|
// 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;
|
std::vector<core::line3d<f32>> lines;
|
||||||
for (f32 x = -9.1; x < 9; x += 3.124) {
|
for (f32 x = -9.1f; x < 9.0f; x += 3.124f)
|
||||||
for (f32 y = -9.2; y < 9; y += 3.123) {
|
for (f32 y = -9.2f; y < 9.0f; y += 3.123f)
|
||||||
for (f32 z = -9.3; z < 9; z += 3.122) {
|
for (f32 z = -9.3f; z < 9.0f; z += 3.122f) {
|
||||||
lines.emplace_back(-x, -y, -z, x, y, z);
|
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.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
lines.emplace_back(0, 0, 0, 0, 0, 0);
|
|
||||||
// Test every line
|
// Test every line
|
||||||
std::vector<core::line3d<f32> >::iterator it = lines.begin();
|
for (auto l : lines) {
|
||||||
for (; it < lines.end(); it++) {
|
|
||||||
core::line3d<f32> l = *it;
|
|
||||||
|
|
||||||
// Initialize test
|
// Initialize test
|
||||||
voxalgo::VoxelLineIterator iterator(l.start, l.getVector());
|
voxalgo::VoxelLineIterator iterator(l.start, l.getVector());
|
||||||
|
|
||||||
//Test the first voxel
|
//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);
|
UASSERT(iterator.m_current_node_pos == start_voxel);
|
||||||
|
|
||||||
// Values for testing
|
// 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;
|
v3s16 voxel_vector = end_voxel - start_voxel;
|
||||||
int nodecount = abs(voxel_vector.X) + abs(voxel_vector.Y)
|
int nodecount = abs(voxel_vector.X) + abs(voxel_vector.Y)
|
||||||
+ abs(voxel_vector.Z);
|
+ abs(voxel_vector.Z);
|
||||||
@ -88,8 +86,9 @@ void TestVoxelAlgorithms::testVoxelLineIterator()
|
|||||||
UASSERTEQ(f32, (new_voxel - old_voxel).getLengthSQ(), 1);
|
UASSERTEQ(f32, (new_voxel - old_voxel).getLengthSQ(), 1);
|
||||||
// The line must intersect with the voxel
|
// The line must intersect with the voxel
|
||||||
v3f voxel_center = intToFloat(iterator.m_current_node_pos, 1);
|
v3f voxel_center = intToFloat(iterator.m_current_node_pos, 1);
|
||||||
aabb3f box(voxel_center - v3f(0.5, 0.5, 0.5),
|
constexpr f32 eps = 1.0e-5f;
|
||||||
voxel_center + v3f(0.5, 0.5, 0.5));
|
aabb3f box(voxel_center - v3f(0.5f + eps),
|
||||||
|
voxel_center + v3f(0.5f + eps));
|
||||||
UASSERT(box.intersectsWithLine(l));
|
UASSERT(box.intersectsWithLine(l));
|
||||||
// Update old voxel
|
// Update old voxel
|
||||||
old_voxel = new_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));
|
m_last_index = getIndex(floatToInt(start_position + line_vector, 1));
|
||||||
|
|
||||||
if (m_line_vector.X > 0) {
|
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_start_position.X) / m_line_vector.X;
|
||||||
m_intersection_multi_inc.X = 1 / m_line_vector.X;
|
m_intersection_multi_inc.X = 1 / m_line_vector.X;
|
||||||
} else if (m_line_vector.X < 0) {
|
} else if (m_line_vector.X < 0) {
|
||||||
m_next_intersection_multi.X = (floorf(m_start_position.X - 0.5)
|
m_next_intersection_multi.X = (m_current_node_pos.X - 0.5f
|
||||||
- m_start_position.X + 0.5) / m_line_vector.X;
|
- m_start_position.X) / m_line_vector.X;
|
||||||
m_intersection_multi_inc.X = -1 / m_line_vector.X;
|
m_intersection_multi_inc.X = -1 / m_line_vector.X;
|
||||||
m_step_directions.X = -1;
|
m_step_directions.X = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_line_vector.Y > 0) {
|
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_start_position.Y) / m_line_vector.Y;
|
||||||
m_intersection_multi_inc.Y = 1 / m_line_vector.Y;
|
m_intersection_multi_inc.Y = 1 / m_line_vector.Y;
|
||||||
} else if (m_line_vector.Y < 0) {
|
} else if (m_line_vector.Y < 0) {
|
||||||
m_next_intersection_multi.Y = (floorf(m_start_position.Y - 0.5)
|
m_next_intersection_multi.Y = (m_current_node_pos.Y - 0.5f
|
||||||
- m_start_position.Y + 0.5) / m_line_vector.Y;
|
- m_start_position.Y) / m_line_vector.Y;
|
||||||
m_intersection_multi_inc.Y = -1 / m_line_vector.Y;
|
m_intersection_multi_inc.Y = -1 / m_line_vector.Y;
|
||||||
m_step_directions.Y = -1;
|
m_step_directions.Y = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_line_vector.Z > 0) {
|
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_start_position.Z) / m_line_vector.Z;
|
||||||
m_intersection_multi_inc.Z = 1 / m_line_vector.Z;
|
m_intersection_multi_inc.Z = 1 / m_line_vector.Z;
|
||||||
} else if (m_line_vector.Z < 0) {
|
} else if (m_line_vector.Z < 0) {
|
||||||
m_next_intersection_multi.Z = (floorf(m_start_position.Z - 0.5)
|
m_next_intersection_multi.Z = (m_current_node_pos.Z - 0.5f
|
||||||
- m_start_position.Z + 0.5) / m_line_vector.Z;
|
- m_start_position.Z) / m_line_vector.Z;
|
||||||
m_intersection_multi_inc.Z = -1 / m_line_vector.Z;
|
m_intersection_multi_inc.Z = -1 / m_line_vector.Z;
|
||||||
m_step_directions.Z = -1;
|
m_step_directions.Z = -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user