mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Optimize code patterns around raycasting
This commit is contained in:
		@@ -129,9 +129,8 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
		if (state->m_objects_pointable) {
 | 
			
		||||
			std::vector<PointedThing> found;
 | 
			
		||||
			getSelectedActiveObjects(state->m_shootline, found, state->m_pointabilities);
 | 
			
		||||
			for (const PointedThing &pointed : found) {
 | 
			
		||||
				state->m_found.push(pointed);
 | 
			
		||||
			}
 | 
			
		||||
			for (auto &pointed : found)
 | 
			
		||||
				state->m_found.push(std::move(pointed));
 | 
			
		||||
		}
 | 
			
		||||
		// Set search range
 | 
			
		||||
		core::aabbox3d<s16> maximal_exceed = nodedef->getSelectionBoxIntUnion();
 | 
			
		||||
@@ -150,14 +149,10 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Map &map = getMap();
 | 
			
		||||
	// If a node is found, this is the center of the
 | 
			
		||||
	// first nodebox the shootline meets.
 | 
			
		||||
	v3f found_boxcenter(0, 0, 0);
 | 
			
		||||
	// The untested nodes are in this range.
 | 
			
		||||
	core::aabbox3d<s16> new_nodes;
 | 
			
		||||
	std::vector<aabb3f> boxes;
 | 
			
		||||
	while (state->m_iterator.m_current_index <= lastIndex) {
 | 
			
		||||
		// Test the nodes around the current node in search_range.
 | 
			
		||||
		new_nodes = state->m_search_range;
 | 
			
		||||
		core::aabbox3d<s16> new_nodes = state->m_search_range;
 | 
			
		||||
		new_nodes.MinEdge += state->m_iterator.m_current_node_pos;
 | 
			
		||||
		new_nodes.MaxEdge += state->m_iterator.m_current_node_pos;
 | 
			
		||||
 | 
			
		||||
@@ -205,7 +200,7 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
 | 
			
		||||
			PointedThing result;
 | 
			
		||||
 | 
			
		||||
			std::vector<aabb3f> boxes;
 | 
			
		||||
			boxes.clear();
 | 
			
		||||
			n.getSelectionBoxes(nodedef, &boxes,
 | 
			
		||||
				n.getNeighbors(np, &map));
 | 
			
		||||
 | 
			
		||||
@@ -215,6 +210,9 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
			float min_distance_sq = 10000000;
 | 
			
		||||
			// ID of the current box (loop counter)
 | 
			
		||||
			u16 id = 0;
 | 
			
		||||
			// If a node is found, this is the center of the
 | 
			
		||||
			// first nodebox the shootline meets.
 | 
			
		||||
			v3f found_boxcenter(0, 0, 0);
 | 
			
		||||
 | 
			
		||||
			// Do calculations relative to the node center
 | 
			
		||||
			// to translate the ray rather than the boxes
 | 
			
		||||
@@ -253,7 +251,7 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
			result.node_undersurface = np;
 | 
			
		||||
			result.distanceSq = min_distance_sq;
 | 
			
		||||
			// Set undersurface and abovesurface nodes
 | 
			
		||||
			f32 d = 0.002 * BS;
 | 
			
		||||
			const f32 d = 0.002 * BS;
 | 
			
		||||
			v3f fake_intersection = result.intersection_point;
 | 
			
		||||
			found_boxcenter += npf; // translate back to world coords
 | 
			
		||||
			// Move intersection towards its source block.
 | 
			
		||||
@@ -276,8 +274,9 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
				fake_intersection, BS);
 | 
			
		||||
			result.node_abovesurface = result.node_real_undersurface
 | 
			
		||||
				+ floatToInt(result.intersection_normal, 1.0f);
 | 
			
		||||
 | 
			
		||||
			// Push found PointedThing
 | 
			
		||||
			state->m_found.push(result);
 | 
			
		||||
			state->m_found.push(std::move(result));
 | 
			
		||||
			// If this is nearer than the old nearest object,
 | 
			
		||||
			// the search can be shorter
 | 
			
		||||
			s16 newIndex = state->m_iterator.getIndex(
 | 
			
		||||
@@ -297,9 +296,8 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result_p)
 | 
			
		||||
	} else {
 | 
			
		||||
		*result_p = state->m_found.top();
 | 
			
		||||
		state->m_found.pop();
 | 
			
		||||
		if (result_p->pointability == PointabilityType::POINTABLE_BLOCKING) {
 | 
			
		||||
		if (result_p->pointability == PointabilityType::POINTABLE_BLOCKING)
 | 
			
		||||
			result_p->type = POINTEDTHING_NOTHING;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1817,17 +1817,14 @@ void ServerEnvironment::getSelectedActiveObjects(
 | 
			
		||||
	std::vector<PointedThing> &objects,
 | 
			
		||||
	const std::optional<Pointabilities> &pointabilities)
 | 
			
		||||
{
 | 
			
		||||
	std::vector<ServerActiveObject *> objs;
 | 
			
		||||
	getObjectsInsideRadius(objs, shootline_on_map.getMiddle(),
 | 
			
		||||
		0.5 * shootline_on_map.getLength() + 5 * BS, nullptr);
 | 
			
		||||
	const v3f line_vector = shootline_on_map.getVector();
 | 
			
		||||
 | 
			
		||||
	for (auto obj : objs) {
 | 
			
		||||
	auto process = [&] (ServerActiveObject *obj) -> bool {
 | 
			
		||||
		if (obj->isGone())
 | 
			
		||||
			continue;
 | 
			
		||||
			return false;
 | 
			
		||||
		aabb3f selection_box;
 | 
			
		||||
		if (!obj->getSelectionBox(&selection_box))
 | 
			
		||||
			continue;
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		v3f pos = obj->getBasePosition();
 | 
			
		||||
		v3f rel_pos = shootline_on_map.start - pos;
 | 
			
		||||
@@ -1847,29 +1844,37 @@ void ServerEnvironment::getSelectedActiveObjects(
 | 
			
		||||
				¤t_intersection, ¤t_normal);
 | 
			
		||||
			current_raw_normal = current_normal;
 | 
			
		||||
		}
 | 
			
		||||
		if (collision) {
 | 
			
		||||
			PointabilityType pointable;
 | 
			
		||||
			if (pointabilities) {
 | 
			
		||||
				if (LuaEntitySAO* lsao = dynamic_cast<LuaEntitySAO*>(obj)) {
 | 
			
		||||
					pointable = pointabilities->matchObject(lsao->getName(),
 | 
			
		||||
							usao->getArmorGroups()).value_or(props->pointable);
 | 
			
		||||
				} else if (PlayerSAO* psao = dynamic_cast<PlayerSAO*>(obj)) {
 | 
			
		||||
					pointable = pointabilities->matchPlayer(psao->getArmorGroups()).value_or(
 | 
			
		||||
							props->pointable);
 | 
			
		||||
				} else {
 | 
			
		||||
					pointable = props->pointable;
 | 
			
		||||
				}
 | 
			
		||||
		if (!collision)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		PointabilityType pointable;
 | 
			
		||||
		if (pointabilities) {
 | 
			
		||||
			if (LuaEntitySAO* lsao = dynamic_cast<LuaEntitySAO*>(obj)) {
 | 
			
		||||
				pointable = pointabilities->matchObject(lsao->getName(),
 | 
			
		||||
						usao->getArmorGroups()).value_or(props->pointable);
 | 
			
		||||
			} else if (PlayerSAO* psao = dynamic_cast<PlayerSAO*>(obj)) {
 | 
			
		||||
				pointable = pointabilities->matchPlayer(psao->getArmorGroups()).value_or(
 | 
			
		||||
						props->pointable);
 | 
			
		||||
			} else {
 | 
			
		||||
				pointable = props->pointable;
 | 
			
		||||
			}
 | 
			
		||||
			if (pointable != PointabilityType::POINTABLE_NOT) {
 | 
			
		||||
				current_intersection += pos;
 | 
			
		||||
				objects.emplace_back(
 | 
			
		||||
					(s16) obj->getId(), current_intersection, current_normal, current_raw_normal,
 | 
			
		||||
					(current_intersection - shootline_on_map.start).getLengthSQ(), pointable);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			pointable = props->pointable;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
		if (pointable != PointabilityType::POINTABLE_NOT) {
 | 
			
		||||
			current_intersection += pos;
 | 
			
		||||
			f32 d_sq = (current_intersection - shootline_on_map.start).getLengthSQ();
 | 
			
		||||
			objects.emplace_back(
 | 
			
		||||
				(s16) obj->getId(), current_intersection, current_normal,
 | 
			
		||||
				current_raw_normal, d_sq, pointable);
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Use "logic in callback" pattern to avoid useless vector filling
 | 
			
		||||
	std::vector<ServerActiveObject*> tmp;
 | 
			
		||||
	getObjectsInsideRadius(tmp, shootline_on_map.getMiddle(),
 | 
			
		||||
		0.5 * shootline_on_map.getLength() + 5 * BS, process);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -23,31 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "exceptions.h"
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
PointedThing::PointedThing(const v3s16 &under, const v3s16 &above,
 | 
			
		||||
	const v3s16 &real_under, const v3f &point, const v3f &normal,
 | 
			
		||||
	u16 box_id, f32 distSq, PointabilityType pointab):
 | 
			
		||||
	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),
 | 
			
		||||
	pointability(pointab)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
PointedThing::PointedThing(u16 id, const v3f &point, const v3f &normal,
 | 
			
		||||
	const v3f &raw_normal, f32 distSq, PointabilityType pointab) :
 | 
			
		||||
	type(POINTEDTHING_OBJECT),
 | 
			
		||||
	object_id(id),
 | 
			
		||||
	intersection_point(point),
 | 
			
		||||
	intersection_normal(normal),
 | 
			
		||||
	raw_intersection_normal(raw_normal),
 | 
			
		||||
	distanceSq(distSq),
 | 
			
		||||
	pointability(pointab)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
std::string PointedThing::dump() const
 | 
			
		||||
{
 | 
			
		||||
	std::ostringstream os(std::ios::binary);
 | 
			
		||||
@@ -131,8 +106,3 @@ bool PointedThing::operator==(const PointedThing &pt2) const
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PointedThing::operator!=(const PointedThing &pt2) const
 | 
			
		||||
{
 | 
			
		||||
	return !(*this == pt2);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,8 @@ struct PointedThing
 | 
			
		||||
{
 | 
			
		||||
	//! The type of the pointed object.
 | 
			
		||||
	PointedThingType type = POINTEDTHING_NOTHING;
 | 
			
		||||
	//! How the object or node can be pointed at.
 | 
			
		||||
	PointabilityType pointability = PointabilityType::POINTABLE_NOT;
 | 
			
		||||
	/*!
 | 
			
		||||
	 * Only valid if type is POINTEDTHING_NODE.
 | 
			
		||||
	 * The coordinates of the node which owns the
 | 
			
		||||
@@ -63,6 +65,11 @@ struct PointedThing
 | 
			
		||||
	 * The ID of the object the ray hit.
 | 
			
		||||
	 */
 | 
			
		||||
	u16 object_id = 0;
 | 
			
		||||
	/*!
 | 
			
		||||
	 * Only valid if type isn't POINTEDTHING_NONE.
 | 
			
		||||
	 * Indicates which selection box is selected, if there are more of them.
 | 
			
		||||
	 */
 | 
			
		||||
	u16 box_id = 0;
 | 
			
		||||
	/*!
 | 
			
		||||
	 * Only valid if type isn't POINTEDTHING_NONE.
 | 
			
		||||
	 * First intersection point of the ray and the nodebox in irrlicht
 | 
			
		||||
@@ -81,36 +88,49 @@ struct PointedThing
 | 
			
		||||
	 * Raw normal vector of the intersection before applying rotation.
 | 
			
		||||
	 */
 | 
			
		||||
	v3f raw_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 in irrlicht coordinates.
 | 
			
		||||
	 */
 | 
			
		||||
	f32 distanceSq = 0;
 | 
			
		||||
	/*!
 | 
			
		||||
	 * How the object or node has been pointed at.
 | 
			
		||||
	 */
 | 
			
		||||
	PointabilityType pointability = PointabilityType::POINTABLE_NOT;
 | 
			
		||||
 | 
			
		||||
	//! Constructor for POINTEDTHING_NOTHING
 | 
			
		||||
	PointedThing() = default;
 | 
			
		||||
	//! Constructor for POINTEDTHING_NODE
 | 
			
		||||
	PointedThing(const v3s16 &under, const v3s16 &above,
 | 
			
		||||
		const v3s16 &real_under, const v3f &point, const v3f &normal,
 | 
			
		||||
		u16 box_id, f32 distSq, PointabilityType pointability);
 | 
			
		||||
	inline PointedThing(const v3s16 under, const v3s16 above,
 | 
			
		||||
		const v3s16 real_under, const v3f point, const v3f normal,
 | 
			
		||||
		u16 box_id, f32 distSq, PointabilityType pointab) :
 | 
			
		||||
		type(POINTEDTHING_NODE),
 | 
			
		||||
		pointability(pointab),
 | 
			
		||||
		node_undersurface(under),
 | 
			
		||||
		node_abovesurface(above),
 | 
			
		||||
		node_real_undersurface(real_under),
 | 
			
		||||
		box_id(box_id),
 | 
			
		||||
		intersection_point(point),
 | 
			
		||||
		intersection_normal(normal),
 | 
			
		||||
		distanceSq(distSq)
 | 
			
		||||
	{}
 | 
			
		||||
	//! Constructor for POINTEDTHING_OBJECT
 | 
			
		||||
	PointedThing(u16 id, const v3f &point, const v3f &normal, const v3f &raw_normal, f32 distSq,
 | 
			
		||||
		PointabilityType pointability);
 | 
			
		||||
	inline PointedThing(u16 id, const v3f point, const v3f normal,
 | 
			
		||||
		const v3f raw_normal, f32 distSq, PointabilityType pointab) :
 | 
			
		||||
		type(POINTEDTHING_OBJECT),
 | 
			
		||||
		pointability(pointab),
 | 
			
		||||
		object_id(id),
 | 
			
		||||
		intersection_point(point),
 | 
			
		||||
		intersection_normal(normal),
 | 
			
		||||
		raw_intersection_normal(raw_normal),
 | 
			
		||||
		distanceSq(distSq)
 | 
			
		||||
	{}
 | 
			
		||||
 | 
			
		||||
	std::string dump() const;
 | 
			
		||||
	void serialize(std::ostream &os) const;
 | 
			
		||||
	void deSerialize(std::istream &is);
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * This function ignores the intersection point and normal.
 | 
			
		||||
	 */
 | 
			
		||||
	bool operator==(const PointedThing &pt2) const;
 | 
			
		||||
	bool operator!=(const PointedThing &pt2) const;
 | 
			
		||||
	bool operator!=(const PointedThing &pt2) const {
 | 
			
		||||
		return !(*this == pt2);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user