Skip to content

Commit 2153965

Browse files
juhdanadparamat
authored andcommittedDec 26, 2017
Line_of_sight: Improve using VoxelLineIterator
This commit rewrites line_of_sight with VoxelLineIterator. Stepsize is no longer needed, the results will be always accurate.
1 parent ca64f56 commit 2153965

File tree

5 files changed

+28
-36
lines changed

5 files changed

+28
-36
lines changed
 

Diff for: ‎doc/lua_api.txt

+3-4
Original file line numberDiff line numberDiff line change
@@ -2876,13 +2876,12 @@ and `minetest.auth_reload` call the authentication handler.
28762876
* parameter was absent)
28772877
* `minetest.delete_area(pos1, pos2)`
28782878
* delete all mapblocks in the area from pos1 to pos2, inclusive
2879-
* `minetest.line_of_sight(pos1, pos2, stepsize)`: returns `boolean, pos`
2880-
* Check if there is a direct line of sight between `pos1` and `pos2`
2879+
* `minetest.line_of_sight(pos1, pos2)`: returns `boolean, pos`
2880+
* Checks if there is anything other than air between pos1 and pos2.
2881+
* Returns false if something is blocking the sight.
28812882
* Returns the position of the blocking node when `false`
28822883
* `pos1`: First position
28832884
* `pos2`: Second position
2884-
* `stepsize`: smaller gives more accurate results but requires more computing
2885-
time. Default is `1`.
28862885
* `minetest.raycast(pos1, pos2, objects, liquids)`: returns `Raycast`
28872886
* Creates a `Raycast` object.
28882887
* `pos1`: start of the ray

Diff for: ‎src/script/lua_api/l_env.cpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -966,24 +966,19 @@ int ModApiEnvMod::l_clear_objects(lua_State *L)
966966
return 0;
967967
}
968968

969-
// line_of_sight(pos1, pos2, stepsize) -> true/false, pos
969+
// line_of_sight(pos1, pos2) -> true/false, pos
970970
int ModApiEnvMod::l_line_of_sight(lua_State *L)
971971
{
972-
float stepsize = 1.0;
973-
974972
GET_ENV_PTR;
975973

976974
// read position 1 from lua
977975
v3f pos1 = checkFloatPos(L, 1);
978976
// read position 2 from lua
979977
v3f pos2 = checkFloatPos(L, 2);
980-
//read step size from lua
981-
if (lua_isnumber(L, 3)) {
982-
stepsize = lua_tonumber(L, 3);
983-
}
984978

985979
v3s16 p;
986-
bool success = env->line_of_sight(pos1, pos2, stepsize, &p);
980+
981+
bool success = env->line_of_sight(pos1, pos2, &p);
987982
lua_pushboolean(L, success);
988983
if (!success) {
989984
push_v3s16(L, p);

Diff for: ‎src/script/lua_api/l_env.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ class ModApiEnvMod : public ModApiBase {
156156
// spawn_tree(pos, treedef)
157157
static int l_spawn_tree(lua_State *L);
158158

159-
// line_of_sight(pos1, pos2, stepsize) -> true/false
159+
// line_of_sight(pos1, pos2) -> true/false
160160
static int l_line_of_sight(lua_State *L);
161161

162162
// raycast(pos1, pos2, objects, liquids) -> Raycast

Diff for: ‎src/serverenvironment.cpp

+12-21
Original file line numberDiff line numberDiff line change
@@ -489,30 +489,21 @@ bool ServerEnvironment::removePlayerFromDatabase(const std::string &name)
489489
return m_player_database->removePlayer(name);
490490
}
491491

492-
bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16 *p)
492+
bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, v3s16 *p)
493493
{
494-
float distance = pos1.getDistanceFrom(pos2);
495-
496-
//calculate normalized direction vector
497-
v3f normalized_vector = v3f((pos2.X - pos1.X)/distance,
498-
(pos2.Y - pos1.Y)/distance,
499-
(pos2.Z - pos1.Z)/distance);
500-
501-
//find out if there's a node on path between pos1 and pos2
502-
for (float i = 1; i < distance; i += stepsize) {
503-
v3s16 pos = floatToInt(v3f(normalized_vector.X * i,
504-
normalized_vector.Y * i,
505-
normalized_vector.Z * i) +pos1,BS);
506-
507-
MapNode n = getMap().getNodeNoEx(pos);
508-
509-
if(n.param0 != CONTENT_AIR) {
510-
if (p) {
511-
*p = pos;
512-
}
494+
// Iterate trough nodes on the line
495+
voxalgo::VoxelLineIterator iterator(pos1 / BS, (pos2 - pos1) / BS);
496+
do {
497+
MapNode n = getMap().getNodeNoEx(iterator.m_current_node_pos);
498+
499+
// Return non-air
500+
if (n.param0 != CONTENT_AIR) {
501+
if (p)
502+
*p = iterator.m_current_node_pos;
513503
return false;
514504
}
515-
}
505+
iterator.next();
506+
} while (iterator.m_current_index <= iterator.m_last_index);
516507
return true;
517508
}
518509

Diff for: ‎src/serverenvironment.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,15 @@ class ServerEnvironment : public Environment
328328
// This makes stuff happen
329329
void step(f32 dtime);
330330

331-
//check if there's a line of sight between two positions
332-
bool line_of_sight(v3f pos1, v3f pos2, float stepsize=1.0, v3s16 *p=NULL);
331+
/*!
332+
* Returns false if the given line intersects with a
333+
* non-air node, true otherwise.
334+
* \param pos1 start of the line
335+
* \param pos2 end of the line
336+
* \param p output, position of the first non-air node
337+
* the line intersects
338+
*/
339+
bool line_of_sight(v3f pos1, v3f pos2, v3s16 *p = NULL);
333340

334341
u32 getGameTime() const { return m_game_time; }
335342

0 commit comments

Comments
 (0)
Please sign in to comment.