diff options
author | RealBadAngel <maciej.kasatkin@o2.pl> | 2016-02-20 10:58:40 +0100 |
---|---|---|
committer | est31 <MTest31@outlook.com> | 2016-02-22 15:54:32 +0100 |
commit | 9961185550ff2a8ada61455ac351f85ea7122aa2 (patch) | |
tree | 8b1758d8dd2c84f191acd2935b618a7cb1a55d15 | |
parent | 31e0667a4a53a238d0321194b57b083bd74c0a5b (diff) | |
download | minetest-9961185550ff2a8ada61455ac351f85ea7122aa2.tar.gz minetest-9961185550ff2a8ada61455ac351f85ea7122aa2.tar.bz2 minetest-9961185550ff2a8ada61455ac351f85ea7122aa2.zip |
Fix getting pointed node
Fixes #3719
Closes #3753
-rw-r--r-- | src/game.cpp | 136 |
1 files changed, 77 insertions, 59 deletions
diff --git a/src/game.cpp b/src/game.cpp index 9729ca477..18ca11d6f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -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; |