]> git.lizzy.rs Git - minetest.git/commitdiff
Fix getting pointed node
authorRealBadAngel <maciej.kasatkin@o2.pl>
Sat, 20 Feb 2016 09:58:40 +0000 (10:58 +0100)
committerest31 <MTest31@outlook.com>
Mon, 22 Feb 2016 14:54:32 +0000 (15:54 +0100)
Fixes #3719
Closes #3753

src/game.cpp

index 9729ca477257120b60caa286b0f23c2e8fafd6bb..18ca11d6feb2d154becdf6dec1d201e84465f201 100644 (file)
@@ -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;