aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt20
-rw-r--r--src/environment.cpp14
-rw-r--r--src/script/common/c_content.cpp11
-rw-r--r--src/script/common/c_content.h8
-rw-r--r--src/script/cpp_api/s_item.cpp4
-rw-r--r--src/script/cpp_api/s_item.h6
-rw-r--r--src/script/lua_api/l_env.cpp2
-rw-r--r--src/util/pointedthing.cpp3
-rw-r--r--src/util/pointedthing.h12
9 files changed, 63 insertions, 17 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 0c331577b..ef70fe6f7 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1317,6 +1317,17 @@ For helper functions see [Spatial Vectors].
* `{type="node", under=pos, above=pos}`
* `{type="object", ref=ObjectRef}`
+Exact pointing location (currently only `Raycast` supports these fields):
+* `pointed_thing.intersection_point`: The absolute world coordinates of the
+ point on the selection box which is pointed at. May be in the selection box
+ if the pointer is in the box too.
+* `pointed_thing.box_id`: The ID of the pointed selection box (counting starts
+ from 1).
+* `pointed_thing.intersection_normal`: Unit vector, points outwards of the
+ selected selection box. This specifies which face is pointed at.
+ Is a null vector `{x = 0, y = 0, z = 0}` when the pointer is inside the
+ selection box.
+
@@ -5323,7 +5334,12 @@ It can be created via `PseudoRandom(seed)`.
---------
A raycast on the map. It works with selection boxes.
-Can be used as an iterator in a for loop.
+Can be used as an iterator in a for loop as:
+
+ local ray = Raycast(...)
+ for pointed_thing in ray do
+ ...
+ end
The map is loaded as the ray advances. If the map is modified after the
`Raycast` is created, the changes may or may not have an effect on the object.
@@ -5338,7 +5354,7 @@ It can be created via `Raycast(pos1, pos2, objects, liquids)` or
### Methods
-* `next()`: returns a `pointed_thing`
+* `next()`: returns a `pointed_thing` with exact pointing location
* Returns the next thing pointed by the ray or nil.
`SecureRandom`
diff --git a/src/environment.cpp b/src/environment.cpp
index c2227601a..ac7b7ce69 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -175,12 +175,12 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result)
bool is_colliding = false;
// Minimal distance of all collisions
float min_distance_sq = 10000000;
+ // ID of the current box (loop counter)
+ u16 id = 0;
v3f npf = intToFloat(np, BS);
- for (std::vector<aabb3f>::const_iterator i = boxes.begin();
- i != boxes.end(); ++i) {
- // Get current collision box
- aabb3f box = *i;
+ // This loop translates the boxes to their in-world place.
+ for (aabb3f &box : boxes) {
box.MinEdge += npf;
box.MaxEdge += npf;
@@ -188,8 +188,10 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result)
v3s16 intersection_normal;
if (!boxLineCollision(box, state->m_shootline.start,
state->m_shootline.getVector(), &intersection_point,
- &intersection_normal))
+ &intersection_normal)) {
+ ++id;
continue;
+ }
f32 distanceSq = (intersection_point
- state->m_shootline.start).getLengthSQ();
@@ -198,9 +200,11 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result)
min_distance_sq = distanceSq;
result.intersection_point = intersection_point;
result.intersection_normal = intersection_normal;
+ result.box_id = id;
found_boxcenter = box.getCenter();
is_colliding = true;
}
+ ++id;
}
// If there wasn't a collision, stop
if (!is_colliding) {
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index 889b94660..1d62ad98a 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -1757,7 +1757,8 @@ void read_json_value(lua_State *L, Json::Value &root, int index, u8 recursion)
lua_pop(L, 1); // Pop value
}
-void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm)
+void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm,
+ bool hitpoint)
{
lua_newtable(L);
if (pointed.type == POINTEDTHING_NODE) {
@@ -1782,6 +1783,14 @@ void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm)
lua_pushstring(L, "nothing");
lua_setfield(L, -2, "type");
}
+ if (hitpoint && (pointed.type != POINTEDTHING_NOTHING)) {
+ push_v3f(L, pointed.intersection_point / BS); // convert to node coords
+ lua_setfield(L, -2, "intersection_point");
+ push_v3s16(L, pointed.intersection_normal);
+ lua_setfield(L, -2, "intersection_normal");
+ lua_pushinteger(L, pointed.box_id + 1); // change to Lua array index
+ lua_setfield(L, -2, "box_id");
+ }
}
void push_objectRef(lua_State *L, const u16 id)
diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h
index 723253559..f3a653682 100644
--- a/src/script/common/c_content.h
+++ b/src/script/common/c_content.h
@@ -178,7 +178,13 @@ bool push_json_value (lua_State *L,
void read_json_value (lua_State *L, Json::Value &root,
int index, u8 recursion = 0);
-void push_pointed_thing (lua_State *L, const PointedThing &pointed, bool csm = false);
+/*!
+ * Pushes a Lua `pointed_thing` to the given Lua stack.
+ * \param csm If true, a client side pointed thing is pushed
+ * \param hitpoint If true, the exact pointing location is also pushed
+ */
+void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm =
+ false, bool hitpoint = false);
void push_objectRef (lua_State *L, const u16 id);
diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp
index 94abe267b..cbdfcf1b1 100644
--- a/src/script/cpp_api/s_item.cpp
+++ b/src/script/cpp_api/s_item.cpp
@@ -255,10 +255,10 @@ bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname,
return false;
}
-void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
+void ScriptApiItem::pushPointedThing(const PointedThing &pointed, bool hitpoint)
{
lua_State* L = getStack();
- push_pointed_thing(L, pointed);
+ push_pointed_thing(L, pointed, false, hitpoint);
}
diff --git a/src/script/cpp_api/s_item.h b/src/script/cpp_api/s_item.h
index d91b5c1d6..6c7f286a9 100644
--- a/src/script/cpp_api/s_item.h
+++ b/src/script/cpp_api/s_item.h
@@ -54,6 +54,10 @@ protected:
friend class LuaRaycast;
bool getItemCallback(const char *name, const char *callbackname, const v3s16 *p = nullptr);
- void pushPointedThing(const PointedThing& pointed);
+ /*!
+ * Pushes a `pointed_thing` tabe to the stack.
+ * \param hitpoint If true, the exact pointing location is also pushed
+ */
+ void pushPointedThing(const PointedThing &pointed, bool hitpoint = false);
};
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 4944968da..1e5149f7a 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -150,7 +150,7 @@ int LuaRaycast::l_next(lua_State *L)
if (pointed.type == POINTEDTHING_NOTHING)
lua_pushnil(L);
else
- script->pushPointedThing(pointed);
+ script->pushPointedThing(pointed, true);
return 1;
}
diff --git a/src/util/pointedthing.cpp b/src/util/pointedthing.cpp
index c5961d56e..b906264d0 100644
--- a/src/util/pointedthing.cpp
+++ b/src/util/pointedthing.cpp
@@ -25,13 +25,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PointedThing::PointedThing(const v3s16 &under, const v3s16 &above,
const v3s16 &real_under, const v3f &point, const v3s16 &normal,
- f32 distSq):
+ u16 box_id, f32 distSq):
type(POINTEDTHING_NODE),
node_undersurface(under),
node_abovesurface(above),
node_real_undersurface(real_under),
intersection_point(point),
intersection_normal(normal),
+ box_id(box_id),
distanceSq(distSq)
{}
diff --git a/src/util/pointedthing.h b/src/util/pointedthing.h
index 4c4c04234..5b30ed031 100644
--- a/src/util/pointedthing.h
+++ b/src/util/pointedthing.h
@@ -64,7 +64,8 @@ struct PointedThing
s16 object_id = -1;
/*!
* Only valid if type isn't POINTEDTHING_NONE.
- * First intersection point of the ray and the nodebox.
+ * First intersection point of the ray and the nodebox in irrlicht
+ * coordinates.
*/
v3f intersection_point;
/*!
@@ -75,8 +76,13 @@ struct PointedThing
*/
v3s16 intersection_normal;
/*!
+ * Only valid if type isn't POINTEDTHING_NONE.
+ * Indicates which selection box is selected, if there are more of them.
+ */
+ u16 box_id = 0;
+ /*!
* Square of the distance between the pointing
- * ray's start point and the intersection point.
+ * ray's start point and the intersection point in irrlicht coordinates.
*/
f32 distanceSq = 0;
@@ -85,7 +91,7 @@ struct PointedThing
//! Constructor for POINTEDTHING_NODE
PointedThing(const v3s16 &under, const v3s16 &above,
const v3s16 &real_under, const v3f &point, const v3s16 &normal,
- f32 distSq);
+ u16 box_id, f32 distSq);
//! Constructor for POINTEDTHING_OBJECT
PointedThing(s16 id, const v3f &point, const v3s16 &normal, f32 distSq);
std::string dump() const;