Skip to content

Commit

Permalink
Fix getting pointed node
Browse files Browse the repository at this point in the history
Fixes #3719
Closes #3753
  • Loading branch information
RealBadAngel authored and est31 committed Feb 22, 2016
1 parent 31e0667 commit 9961185
Showing 1 changed file with 77 additions and 59 deletions.
136 changes: 77 additions & 59 deletions src/game.cpp
Expand Up @@ -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) {
Expand All @@ -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();
Expand All @@ -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);
Expand All @@ -357,87 +356,106 @@ 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) {
aabb3f box = *i;
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;

Expand Down

0 comments on commit 9961185

Please sign in to comment.