Raycast: export exact pointing location (#6304)
* Return intersection point in node coordinates. * Clarify 'intersection_point' documentation
This commit is contained in:
		
							parent
							
								
									798724efea
								
							
						
					
					
						commit
						325bf68041
					
				@ -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`
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
	/*!
 | 
			
		||||
@ -74,9 +75,14 @@ struct PointedThing
 | 
			
		||||
	 * points outside of the box and it's length is 1.
 | 
			
		||||
	 */
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user