Fix getting pointed node

Fixes #3719
Closes #3753
This commit is contained in:
RealBadAngel 2016-02-20 10:58:40 +01:00 committed by est31
parent 31e0667a4a
commit 9961185550

@ -304,7 +304,7 @@ PointedThing getPointedThing(Client *client, Hud *hud, const v3f &player_positio
INodeDefManager *nodedef = client->getNodeDefManager();
ClientMap &map = client->getEnv().getClientMap();
f32 mindistance = BS * 1001;
f32 min_distance = BS * 1001;
// First try to find a pointed at active object
if (look_for_object) {
@ -324,7 +324,7 @@ PointedThing getPointedThing(Client *client, Hud *hud, const v3f &player_positio
hud->setSelectionPos(pos, camera_offset);
}
mindistance = (selected_object->getPosition() - camera_position).getLength();
min_distance = (selected_object->getPosition() - camera_position).getLength();
result.type = POINTEDTHING_OBJECT;
result.object_id = selected_object->getId();
@ -333,14 +333,13 @@ PointedThing getPointedThing(Client *client, Hud *hud, const v3f &player_positio
// That didn't work, try to find a pointed at node
v3s16 pos_i = floatToInt(player_position, BS);
/*infostream<<"pos_i=("<<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z<<")"
<<std::endl;*/
s16 a = d;
s16 ystart = pos_i.Y + 0 - (camera_direction.Y < 0 ? a : 1);
s16 ystart = pos_i.Y - (camera_direction.Y < 0 ? a : 1);
s16 zstart = pos_i.Z - (camera_direction.Z < 0 ? a : 1);
s16 xstart = pos_i.X - (camera_direction.X < 0 ? a : 1);
s16 yend = pos_i.Y + 1 + (camera_direction.Y > 0 ? a : 1);
@ -357,24 +356,25 @@ PointedThing getPointedThing(Client *client, Hud *hud, const v3f &player_positio
if (xend == 32767)
xend = 32766;
for (s16 y = ystart; y <= yend; y++)
for (s16 z = zstart; z <= zend; z++)
v3s16 pointed_pos(0, 0, 0);
for (s16 y = ystart; y <= yend; y++) {
for (s16 z = zstart; z <= zend; z++) {
for (s16 x = xstart; x <= xend; x++) {
MapNode n;
bool is_valid_position;
n = map.getNodeNoEx(v3s16(x, y, z), &is_valid_position);
if (!is_valid_position)
if (!is_valid_position) {
continue;
if (!isPointableNode(n, client, liquids_pointable))
}
if (!isPointableNode(n, client, liquids_pointable)) {
continue;
}
std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
v3s16 np(x, y, z);
v3f npf = intToFloat(np, BS);
for (std::vector<aabb3f>::const_iterator
i = boxes.begin();
i != boxes.end(); ++i) {
@ -382,62 +382,80 @@ PointedThing getPointedThing(Client *client, Hud *hud, const v3f &player_positio
box.MinEdge += npf;
box.MaxEdge += npf;
for (u16 j = 0; j < 6; j++) {
v3s16 facedir = g_6dirs[j];
aabb3f facebox = box;
f32 d = 0.001 * BS;
if (facedir.X > 0)
facebox.MinEdge.X = facebox.MaxEdge.X - d;
else if (facedir.X < 0)
facebox.MaxEdge.X = facebox.MinEdge.X + d;
else if (facedir.Y > 0)
facebox.MinEdge.Y = facebox.MaxEdge.Y - d;
else if (facedir.Y < 0)
facebox.MaxEdge.Y = facebox.MinEdge.Y + d;
else if (facedir.Z > 0)
facebox.MinEdge.Z = facebox.MaxEdge.Z - d;
else if (facedir.Z < 0)
facebox.MaxEdge.Z = facebox.MinEdge.Z + d;
v3f centerpoint = facebox.getCenter();
f32 distance = (centerpoint - camera_position).getLength();
if (distance >= mindistance)
continue;
if (!facebox.intersectsWithLine(shootline))
continue;
v3s16 np_above = np + facedir;
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
result.node_abovesurface = np_above;
mindistance = distance;
selectionboxes->clear();
for (std::vector<aabb3f>::const_iterator
i2 = boxes.begin();
i2 != boxes.end(); ++i2) {
aabb3f box = *i2;
box.MinEdge += v3f(-d, -d, -d);
box.MaxEdge += v3f(d, d, d);
selectionboxes->push_back(box);
}
hud->setSelectionPos(npf, camera_offset);
v3f centerpoint = box.getCenter();
f32 distance = (centerpoint - camera_position).getLength();
if (distance >= min_distance) {
continue;
}
if (!box.intersectsWithLine(shootline)) {
continue;
}
result.type = POINTEDTHING_NODE;
min_distance = distance;
pointed_pos = np;
}
} // for coords
}
}
}
if (result.type == POINTEDTHING_NODE) {
f32 d = 0.001 * BS;
MapNode n = map.getNodeNoEx(pointed_pos);
v3f npf = intToFloat(pointed_pos, BS);
std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
f32 face_min_distance = 1000 * BS;
for (std::vector<aabb3f>::const_iterator
i = boxes.begin();
i != boxes.end(); ++i) {
aabb3f box = *i;
box.MinEdge += npf;
box.MaxEdge += npf;
for (u16 j = 0; j < 6; j++) {
v3s16 facedir = g_6dirs[j];
aabb3f facebox = box;
if (facedir.X > 0) {
facebox.MinEdge.X = facebox.MaxEdge.X - d;
} else if (facedir.X < 0) {
facebox.MaxEdge.X = facebox.MinEdge.X + d;
} else if (facedir.Y > 0) {
facebox.MinEdge.Y = facebox.MaxEdge.Y - d;
} else if (facedir.Y < 0) {
facebox.MaxEdge.Y = facebox.MinEdge.Y + d;
} else if (facedir.Z > 0) {
facebox.MinEdge.Z = facebox.MaxEdge.Z - d;
} else if (facedir.Z < 0) {
facebox.MaxEdge.Z = facebox.MinEdge.Z + d;
}
v3f centerpoint = facebox.getCenter();
f32 distance = (centerpoint - camera_position).getLength();
if (distance >= face_min_distance)
continue;
if (!facebox.intersectsWithLine(shootline))
continue;
result.node_abovesurface = pointed_pos + facedir;
face_min_distance = distance;
}
}
selectionboxes->clear();
for (std::vector<aabb3f>::const_iterator
i = boxes.begin();
i != boxes.end(); ++i) {
aabb3f box = *i;
box.MinEdge += v3f(-d, -d, -d);
box.MaxEdge += v3f(d, d, d);
selectionboxes->push_back(box);
}
hud->setSelectionPos(intToFloat(pointed_pos, BS), camera_offset);
result.node_undersurface = pointed_pos;
}
// Update selection mesh light level and vertex colors
if (selectionboxes->size() > 0) {
v3f pf = hud->getSelectionPos();
v3s16 p = floatToInt(pf, BS);
v3s16 p = floatToInt(pf, BS);
// Get selection mesh light level
MapNode n = map.getNodeNoEx(p);
MapNode n = map.getNodeNoEx(p);
u16 node_light = getInteriorLight(n, -1, nodedef);
u16 light_level = node_light;