mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Optimize code patterns around raycasting
This commit is contained in:
parent
e10adf83d5
commit
9c3c286aab
@ -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);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user