diff options
author | rubenwardy <rw@rubenwardy.com> | 2017-12-22 10:00:57 +0000 |
---|---|---|
committer | paramat <mat.gregory@virginmedia.com> | 2017-12-26 21:55:08 +0000 |
commit | 026ad912af0ad147071da79201a335ec84bd6ce9 (patch) | |
tree | 430b97ea4eec13f9a3bc565e231bd38572fd7ebb /src | |
parent | 0bcc2f33ebe382a1dafbe6edaf00f476f2584b74 (diff) | |
download | minetest-026ad912af0ad147071da79201a335ec84bd6ce9.tar.gz minetest-026ad912af0ad147071da79201a335ec84bd6ce9.tar.bz2 minetest-026ad912af0ad147071da79201a335ec84bd6ce9.zip |
Fix rounding error in g/set_node caused by truncation to float
Diffstat (limited to 'src')
-rw-r--r-- | src/irr_v3d.h | 1 | ||||
-rw-r--r-- | src/script/common/c_converter.cpp | 46 | ||||
-rw-r--r-- | src/util/numeric.h | 11 |
3 files changed, 54 insertions, 4 deletions
diff --git a/src/irr_v3d.h b/src/irr_v3d.h index 21438d635..3e95c7913 100644 --- a/src/irr_v3d.h +++ b/src/irr_v3d.h @@ -24,6 +24,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 e81cecac8..ce2548e83 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -225,6 +225,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); @@ -263,15 +301,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 be3e49c56..ff4d89ec4 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) |