summaryrefslogtreecommitdiff
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp272
1 files changed, 66 insertions, 206 deletions
diff --git a/src/game.cpp b/src/game.cpp
index c8defd82d..98ffac3d5 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -61,6 +61,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif
#include "event_manager.h"
#include <list>
+#include "util/directiontables.h"
/*
Text input system
@@ -294,14 +295,12 @@ PointedThing getPointedThing(Client *client, v3f player_position,
core::line3d<f32> shootline, f32 d,
bool liquids_pointable,
bool look_for_object,
- core::aabbox3d<f32> &hilightbox,
- bool &should_show_hilightbox,
+ std::vector<aabb3f> &hilightboxes,
ClientActiveObject *&selected_object)
{
PointedThing result;
- hilightbox = core::aabbox3d<f32>(0,0,0,0,0,0);
- should_show_hilightbox = false;
+ hilightboxes.clear();
selected_object = NULL;
INodeDefManager *nodedef = client->getNodeDefManager();
@@ -312,27 +311,27 @@ PointedThing getPointedThing(Client *client, v3f player_position,
{
selected_object = client->getSelectedActiveObject(d*BS,
camera_position, shootline);
- }
- if(selected_object != NULL)
- {
- core::aabbox3d<f32> *selection_box
- = selected_object->getSelectionBox();
- // Box should exist because object was returned in the
- // first place
- assert(selection_box);
-
- v3f pos = selected_object->getPosition();
- hilightbox = core::aabbox3d<f32>(
- selection_box->MinEdge + pos,
- selection_box->MaxEdge + pos
- );
+ if(selected_object != NULL)
+ {
+ if(selected_object->doShowSelectionBox())
+ {
+ aabb3f *selection_box = selected_object->getSelectionBox();
+ // Box should exist because object was
+ // returned in the first place
+ assert(selection_box);
+
+ v3f pos = selected_object->getPosition();
+ hilightboxes.push_back(aabb3f(
+ selection_box->MinEdge + pos,
+ selection_box->MaxEdge + pos));
+ }
- should_show_hilightbox = selected_object->doShowSelectionBox();
- result.type = POINTEDTHING_OBJECT;
- result.object_id = selected_object->getId();
- return result;
+ result.type = POINTEDTHING_OBJECT;
+ result.object_id = selected_object->getId();
+ return result;
+ }
}
// That didn't work, try to find a pointed at node
@@ -368,196 +367,64 @@ PointedThing getPointedThing(Client *client, v3f player_position,
if(!isPointableNode(n, client, liquids_pointable))
continue;
+ std::vector<aabb3f> boxes = n.getSelectionBoxes(nodedef);
+
v3s16 np(x,y,z);
v3f npf = intToFloat(np, BS);
-
- f32 d = 0.01;
-
- v3s16 dirs[6] = {
- v3s16(0,0,1), // back
- v3s16(0,1,0), // top
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(0,-1,0), // bottom
- v3s16(-1,0,0), // left
- };
-
- const ContentFeatures &f = nodedef->get(n);
-
- if(f.selection_box.type == NODEBOX_FIXED)
+
+ for(std::vector<aabb3f>::const_iterator
+ i = boxes.begin();
+ i != boxes.end(); i++)
{
- core::aabbox3d<f32> box = f.selection_box.fixed;
+ aabb3f box = *i;
box.MinEdge += npf;
box.MaxEdge += npf;
- v3s16 facedirs[6] = {
- v3s16(-1,0,0),
- v3s16(1,0,0),
- v3s16(0,-1,0),
- v3s16(0,1,0),
- v3s16(0,0,-1),
- v3s16(0,0,1),
- };
-
- core::aabbox3d<f32> faceboxes[6] = {
- // X-
- core::aabbox3d<f32>(
- box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z,
- box.MinEdge.X+d, box.MaxEdge.Y, box.MaxEdge.Z
- ),
- // X+
- core::aabbox3d<f32>(
- box.MaxEdge.X-d, box.MinEdge.Y, box.MinEdge.Z,
- box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z
- ),
- // Y-
- core::aabbox3d<f32>(
- box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z,
- box.MaxEdge.X, box.MinEdge.Y+d, box.MaxEdge.Z
- ),
- // Y+
- core::aabbox3d<f32>(
- box.MinEdge.X, box.MaxEdge.Y-d, box.MinEdge.Z,
- box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z
- ),
- // Z-
- core::aabbox3d<f32>(
- box.MinEdge.X, box.MinEdge.Y, box.MinEdge.Z,
- box.MaxEdge.X, box.MaxEdge.Y, box.MinEdge.Z+d
- ),
- // Z+
- core::aabbox3d<f32>(
- box.MinEdge.X, box.MinEdge.Y, box.MaxEdge.Z-d,
- box.MaxEdge.X, box.MaxEdge.Y, box.MaxEdge.Z
- ),
- };
-
- for(u16 i=0; i<6; i++)
+ for(u16 j=0; j<6; j++)
{
- v3f facedir_f(facedirs[i].X, facedirs[i].Y, facedirs[i].Z);
- v3f centerpoint = npf + facedir_f * BS/2;
+ 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(!faceboxes[i].intersectsWithLine(shootline))
+ if(!facebox.intersectsWithLine(shootline))
continue;
+
+ v3s16 np_above = np + facedir;
+
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
- result.node_abovesurface = np+facedirs[i];
+ result.node_abovesurface = np_above;
mindistance = distance;
- hilightbox = box;
- should_show_hilightbox = true;
- }
- }
- else if(f.selection_box.type == NODEBOX_WALLMOUNTED)
- {
- v3s16 dir = n.getWallMountedDir(nodedef);
- v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
- dir_f *= BS/2 - BS/6 - BS/20;
- v3f cpf = npf + dir_f;
- f32 distance = (cpf - camera_position).getLength();
-
- core::aabbox3d<f32> box;
-
- // top
- if(dir == v3s16(0,1,0)){
- box = f.selection_box.wall_top;
- }
- // bottom
- else if(dir == v3s16(0,-1,0)){
- box = f.selection_box.wall_bottom;
- }
- // side
- else{
- v3f vertices[2] =
- {
- f.selection_box.wall_side.MinEdge,
- f.selection_box.wall_side.MaxEdge
- };
-
- for(s32 i=0; i<2; i++)
- {
- if(dir == v3s16(-1,0,0))
- vertices[i].rotateXZBy(0);
- if(dir == v3s16(1,0,0))
- vertices[i].rotateXZBy(180);
- if(dir == v3s16(0,0,-1))
- vertices[i].rotateXZBy(90);
- if(dir == v3s16(0,0,1))
- vertices[i].rotateXZBy(-90);
- }
-
- box = core::aabbox3d<f32>(vertices[0]);
- box.addInternalPoint(vertices[1]);
- }
- box.MinEdge += npf;
- box.MaxEdge += npf;
-
- if(distance < mindistance)
- {
- if(box.intersectsWithLine(shootline))
+ hilightboxes.clear();
+ for(std::vector<aabb3f>::const_iterator
+ i2 = boxes.begin();
+ i2 != boxes.end(); i2++)
{
- result.type = POINTEDTHING_NODE;
- result.node_undersurface = np;
- result.node_abovesurface = np;
- mindistance = distance;
- hilightbox = box;
- should_show_hilightbox = true;
+ aabb3f box = *i2;
+ box.MinEdge += npf + v3f(-d,-d,-d);
+ box.MaxEdge += npf + v3f(d,d,d);
+ hilightboxes.push_back(box);
}
}
}
- else // NODEBOX_REGULAR
- {
- for(u16 i=0; i<6; i++)
- {
- v3f dir_f = v3f(dirs[i].X,
- dirs[i].Y, dirs[i].Z);
- v3f centerpoint = npf + dir_f * BS/2;
- f32 distance =
- (centerpoint - camera_position).getLength();
-
- if(distance < mindistance)
- {
- core::CMatrix4<f32> m;
- m.buildRotateFromTo(v3f(0,0,1), dir_f);
-
- // This is the back face
- v3f corners[2] = {
- v3f(BS/2, BS/2, BS/2),
- v3f(-BS/2, -BS/2, BS/2+d)
- };
-
- for(u16 j=0; j<2; j++)
- {
- m.rotateVect(corners[j]);
- corners[j] += npf;
- }
-
- core::aabbox3d<f32> facebox(corners[0]);
- facebox.addInternalPoint(corners[1]);
-
- if(facebox.intersectsWithLine(shootline))
- {
- result.type = POINTEDTHING_NODE;
- result.node_undersurface = np;
- result.node_abovesurface = np + dirs[i];
- mindistance = distance;
-
- //hilightbox = facebox;
-
- const float d = 0.502;
- core::aabbox3d<f32> nodebox
- (-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
- v3f nodepos_f = intToFloat(np, BS);
- nodebox.MinEdge += nodepos_f;
- nodebox.MaxEdge += nodepos_f;
- hilightbox = nodebox;
- should_show_hilightbox = true;
- }
- } // if distance < mindistance
- } // for dirs
- } // regular block
} // for coords
return result;
@@ -1514,7 +1381,7 @@ void the_game(
hotbar_imagesize = 64;
// Hilight boxes collected during the loop and displayed
- core::list< core::aabbox3d<f32> > hilightboxes;
+ std::vector<aabb3f> hilightboxes;
// Info text
std::wstring infotext;
@@ -2127,8 +1994,6 @@ void the_game(
core::line3d<f32> shootline(camera_position,
camera_position + camera_direction * BS * (d+1));
- core::aabbox3d<f32> hilightbox;
- bool should_show_hilightbox = false;
ClientActiveObject *selected_object = NULL;
PointedThing pointed = getPointedThing(
@@ -2137,7 +2002,7 @@ void the_game(
camera_position, shootline, d,
playeritem_liquids_pointable, !ldown_for_dig,
// output
- hilightbox, should_show_hilightbox,
+ hilightboxes,
selected_object);
if(pointed != pointed_old)
@@ -2147,12 +2012,6 @@ void the_game(
}
/*
- Visualize selection
- */
- if(should_show_hilightbox)
- hilightboxes.push_back(hilightbox);
-
- /*
Stop digging when
- releasing left mouse button
- pointing away from node
@@ -2818,9 +2677,10 @@ void the_game(
if(show_hud)
{
- for(core::list<aabb3f>::Iterator i=hilightboxes.begin();
- i != hilightboxes.end(); i++)
- {
+ for(std::vector<aabb3f>::const_iterator
+ i = hilightboxes.begin();
+ i != hilightboxes.end(); i++)
+ {
/*infostream<<"hilightbox min="
<<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
<<" max="