aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRealBadAngel <maciej.kasatkin@o2.pl>2016-02-20 10:58:40 +0100
committerest31 <MTest31@outlook.com>2016-02-22 15:54:32 +0100
commit9961185550ff2a8ada61455ac351f85ea7122aa2 (patch)
tree8b1758d8dd2c84f191acd2935b618a7cb1a55d15
parent31e0667a4a53a238d0321194b57b083bd74c0a5b (diff)
downloadminetest-9961185550ff2a8ada61455ac351f85ea7122aa2.tar.gz
minetest-9961185550ff2a8ada61455ac351f85ea7122aa2.tar.bz2
minetest-9961185550ff2a8ada61455ac351f85ea7122aa2.zip
Fix getting pointed node
Fixes #3719 Closes #3753
-rw-r--r--src/game.cpp136
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;