aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubenwardy <rw@rubenwardy.com>2017-12-22 10:00:57 +0000
committerSmallJoker <mk939@ymail.com>2018-06-03 17:32:00 +0200
commitdf0a8574dcef24e5a12a366cb10f7ac5d69a8b79 (patch)
treea9c22c93f6f208ce2d43c667454ce7f8709932ac
parent669806725637a7e97ae884b7983da6e19fcaa6f5 (diff)
downloadminetest-df0a8574dcef24e5a12a366cb10f7ac5d69a8b79.tar.gz
minetest-df0a8574dcef24e5a12a366cb10f7ac5d69a8b79.tar.bz2
minetest-df0a8574dcef24e5a12a366cb10f7ac5d69a8b79.zip
Fix rounding error in g/set_node caused by truncation to float
-rw-r--r--src/irr_v3d.h1
-rw-r--r--src/script/common/c_converter.cpp46
-rw-r--r--src/util/numeric.h11
3 files changed, 54 insertions, 4 deletions
diff --git a/src/irr_v3d.h b/src/irr_v3d.h
index fa6af3661..3a8d1fd30 100644
--- a/src/irr_v3d.h
+++ b/src/irr_v3d.h
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <vector3d.h>
typedef core::vector3df v3f;
+typedef core::vector3d<double> v3d;
typedef core::vector3d<s16> v3s16;
typedef core::vector3d<u16> v3u16;
typedef core::vector3d<s32> v3s32;
diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp
index fc516d56a..d9b926e3e 100644
--- a/src/script/common/c_converter.cpp
+++ b/src/script/common/c_converter.cpp
@@ -196,6 +196,44 @@ v3f check_v3f(lua_State *L, int index)
return pos;
}
+v3d read_v3d(lua_State *L, int index)
+{
+ v3d pos;
+ CHECK_POS_TAB(index);
+ lua_getfield(L, index, "x");
+ pos.X = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, index, "y");
+ pos.Y = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, index, "z");
+ pos.Z = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ return pos;
+}
+
+v3d check_v3d(lua_State *L, int index)
+{
+ v3d pos;
+ CHECK_POS_TAB(index);
+ lua_getfield(L, index, "x");
+ CHECK_POS_COORD("x");
+ pos.X = lua_tonumber(L, -1);
+ CHECK_FLOAT_RANGE(pos.X, "x")
+ lua_pop(L, 1);
+ lua_getfield(L, index, "y");
+ CHECK_POS_COORD("y");
+ pos.Y = lua_tonumber(L, -1);
+ CHECK_FLOAT_RANGE(pos.Y, "y")
+ lua_pop(L, 1);
+ lua_getfield(L, index, "z");
+ CHECK_POS_COORD("z");
+ pos.Z = lua_tonumber(L, -1);
+ CHECK_FLOAT_RANGE(pos.Z, "z")
+ lua_pop(L, 1);
+ return pos;
+}
+
void push_ARGB8(lua_State *L, video::SColor color)
{
lua_newtable(L);
@@ -234,15 +272,15 @@ void push_v3s16(lua_State *L, v3s16 p)
v3s16 read_v3s16(lua_State *L, int index)
{
// Correct rounding at <0
- v3f pf = read_v3f(L, index);
- return floatToInt(pf, 1.0);
+ v3d pf = read_v3d(L, index);
+ return doubleToInt(pf, 1.0);
}
v3s16 check_v3s16(lua_State *L, int index)
{
// Correct rounding at <0
- v3f pf = check_v3f(L, index);
- return floatToInt(pf, 1.0);
+ v3d pf = check_v3d(L, index);
+ return doubleToInt(pf, 1.0);
}
bool read_color(lua_State *L, int index, video::SColor *color)
diff --git a/src/util/numeric.h b/src/util/numeric.h
index 4a27f657d..573f03788 100644
--- a/src/util/numeric.h
+++ b/src/util/numeric.h
@@ -255,6 +255,17 @@ inline v3s16 floatToInt(v3f p, f32 d)
}
/*
+ Returns integer position of node in given double precision position
+ */
+inline v3s16 doubleToInt(v3d p, double d)
+{
+ return v3s16(
+ (p.X + (p.X > 0 ? d / 2 : -d / 2)) / d,
+ (p.Y + (p.Y > 0 ? d / 2 : -d / 2)) / d,
+ (p.Z + (p.Z > 0 ? d / 2 : -d / 2)) / d);
+}
+
+/*
Returns floating point position of node in given integer position
*/
inline v3f intToFloat(v3s16 p, f32 d)