summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-11-13 12:31:05 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-11-29 19:13:41 +0200
commit79c9f14aec52c0fa1b3c2b1850ab3c6a9124a313 (patch)
tree7d156fda616c189df7231301f6d954b6cd4d5f88 /src
parent2ef414d05fdfea7b0ced6dbfde254e3421f36162 (diff)
downloadminetest-79c9f14aec52c0fa1b3c2b1850ab3c6a9124a313.tar.gz
minetest-79c9f14aec52c0fa1b3c2b1850ab3c6a9124a313.tar.bz2
minetest-79c9f14aec52c0fa1b3c2b1850ab3c6a9124a313.zip
Generalize selection boxes
Diffstat (limited to 'src')
-rw-r--r--src/content_mapnode.cpp10
-rw-r--r--src/game.cpp186
-rw-r--r--src/mapnode_contentfeatures.h32
3 files changed, 80 insertions, 148 deletions
diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp
index a365f2ae9..0ba59fcbb 100644
--- a/src/content_mapnode.cpp
+++ b/src/content_mapnode.cpp
@@ -335,6 +335,7 @@ void content_mapnode_init()
f->solidness = 0; // drawn separately, makes no faces
f->air_equivalent = true; // grass grows underneath
f->walkable = false;
+ f->selection_box.type = NODEBOX_FIXED;
setDirtLikeDiggingProperties(f->digging_properties, 0.75);
i = CONTENT_LADDER;
@@ -350,6 +351,7 @@ void content_mapnode_init()
f->air_equivalent = true;
f->walkable = false;
f->climbable = true;
+ f->selection_box.type = NODEBOX_WALLMOUNTED;
setWoodLikeDiggingProperties(f->digging_properties, 0.5);
// Deprecated
@@ -606,6 +608,13 @@ void content_mapnode_init()
f->air_equivalent = true;
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
f->light_source = LIGHT_MAX-1;
+ f->selection_box.type = NODEBOX_WALLMOUNTED;
+ f->selection_box.wall_top = core::aabbox3d<f32>(
+ -BS/10, BS/2-BS/3.333*2, -BS/10, BS/10, BS/2, BS/10);
+ f->selection_box.wall_bottom = core::aabbox3d<f32>(
+ -BS/10, -BS/2, -BS/10, BS/10, -BS/2+BS/3.333*2, BS/10);
+ f->selection_box.wall_side = core::aabbox3d<f32>(
+ -BS/2, -BS/3.333, -BS/10, -BS/2+BS/3.333, BS/3.333, BS/10);
f->digging_properties.set("", DiggingProperties(true, 0.0, 0));
i = CONTENT_SIGN_WALL;
@@ -623,6 +632,7 @@ void content_mapnode_init()
if(f->initial_metadata == NULL)
f->initial_metadata = new SignNodeMetadata("Some sign");
f->digging_properties.set("", DiggingProperties(true, 0.5, 0));
+ f->selection_box.type = NODEBOX_WALLMOUNTED;
i = CONTENT_CHEST;
f = &content_features(i);
diff --git a/src/game.cpp b/src/game.cpp
index d7efbeae9..30bd1bcf7 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -43,7 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "gettext.h"
#include "log.h"
#include "filesys.h"
-// Needed for some special cases for CONTENT_TORCH and CONTENT_SIGN_WALL
+// Needed for writing to signs (CONTENT_SIGN_WALL)
// TODO: A generic way for handling such should be created
#include "content_mapnode.h"
// Needed for sign text input
@@ -343,43 +343,15 @@ void getPointedNode(Client *client, v3f player_position,
v3s16(-1,0,0), // left
};
- /*
- Meta-objects
- */
- if(n.getContent() == CONTENT_TORCH)
+ ContentFeatures &f = content_features(n);
+
+ if(f.selection_box.type == NODEBOX_FIXED)
{
- v3s16 dir = unpackDir(n.param2);
- 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();
+ f32 distance = (npf - camera_position).getLength();
- core::aabbox3d<f32> box;
-
- // bottom
- if(dir == v3s16(0,-1,0))
- {
- box = core::aabbox3d<f32>(
- npf - v3f(BS/6, BS/2, BS/6),
- npf + v3f(BS/6, -BS/2+BS/3*2, BS/6)
- );
- }
- // top
- else if(dir == v3s16(0,1,0))
- {
- box = core::aabbox3d<f32>(
- npf - v3f(BS/6, -BS/2+BS/3*2, BS/6),
- npf + v3f(BS/6, BS/2, BS/6)
- );
- }
- // side
- else
- {
- box = core::aabbox3d<f32>(
- cpf - v3f(BS/6, BS/3, BS/6),
- cpf + v3f(BS/6, BS/3, BS/6)
- );
- }
+ core::aabbox3d<f32> box = f.selection_box.fixed;
+ box.MinEdge += npf;
+ box.MaxEdge += npf;
if(distance < mindistance)
{
@@ -393,7 +365,7 @@ void getPointedNode(Client *client, v3f player_position,
}
}
}
- else if(n.getContent() == CONTENT_SIGN_WALL)
+ else if(f.selection_box.type == NODEBOX_WALLMOUNTED)
{
v3s16 dir = unpackDir(n.param2);
v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
@@ -401,122 +373,43 @@ void getPointedNode(Client *client, v3f player_position,
v3f cpf = npf + dir_f;
f32 distance = (cpf - camera_position).getLength();
- v3f vertices[4] =
- {
- v3f(BS*0.42,-BS*0.35,-BS*0.4),
- v3f(BS*0.49, BS*0.35, BS*0.4),
- };
-
- 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);
- if(dir == v3s16(0,-1,0))
- vertices[i].rotateXYBy(-90);
- if(dir == v3s16(0,1,0))
- vertices[i].rotateXYBy(90);
-
- vertices[i] += npf;
- }
-
core::aabbox3d<f32> box;
-
- box = core::aabbox3d<f32>(vertices[0]);
- box.addInternalPoint(vertices[1]);
-
- if(distance < mindistance)
- {
- if(box.intersectsWithLine(shootline))
- {
- nodefound = true;
- nodepos = np;
- neighbourpos = np;
- mindistance = distance;
- nodehilightbox = box;
- }
+
+ // top
+ if(dir == v3s16(0,1,0)){
+ box = f.selection_box.wall_top;
}
- }
-
- else if(n.getContent() == CONTENT_LADDER)
- {
- v3s16 dir = unpackDir(n.param2);
- 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();
-
- v3f vertices[4] =
- {
- v3f(BS*0.42,-BS/2,-BS/2),
- v3f(BS*0.49, BS/2, BS/2),
- };
-
- 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);
- if(dir == v3s16(0,-1,0))
- vertices[i].rotateXYBy(-90);
- if(dir == v3s16(0,1,0))
- vertices[i].rotateXYBy(90);
-
- vertices[i] += npf;
+ // 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
+ };
- core::aabbox3d<f32> box;
-
- box = core::aabbox3d<f32>(vertices[0]);
- box.addInternalPoint(vertices[1]);
-
- if(distance < mindistance)
- {
- if(box.intersectsWithLine(shootline))
+ for(s32 i=0; i<2; i++)
{
- nodefound = true;
- nodepos = np;
- neighbourpos = np;
- mindistance = distance;
- nodehilightbox = box;
+ 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);
}
- }
- }
- else if(n.getContent() == CONTENT_RAIL)
- {
- v3s16 dir = unpackDir(n.param0);
- 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();
- float d = (float)BS/16;
- v3f vertices[4] =
- {
- v3f(BS/2, -BS/2+d, -BS/2),
- v3f(-BS/2, -BS/2, BS/2),
- };
-
- for(s32 i=0; i<2; i++)
- {
- vertices[i] += npf;
+ box = core::aabbox3d<f32>(vertices[0]);
+ box.addInternalPoint(vertices[1]);
}
- core::aabbox3d<f32> box;
-
- box = core::aabbox3d<f32>(vertices[0]);
- box.addInternalPoint(vertices[1]);
-
+ box.MinEdge += npf;
+ box.MaxEdge += npf;
+
if(distance < mindistance)
{
if(box.intersectsWithLine(shootline))
@@ -529,10 +422,7 @@ void getPointedNode(Client *client, v3f player_position,
}
}
}
- /*
- Regular blocks
- */
- else
+ else // NODEBOX_REGULAR
{
for(u16 i=0; i<6; i++)
{
diff --git a/src/mapnode_contentfeatures.h b/src/mapnode_contentfeatures.h
index b60fc8d8b..7dd9df13b 100644
--- a/src/mapnode_contentfeatures.h
+++ b/src/mapnode_contentfeatures.h
@@ -57,6 +57,35 @@ enum LiquidType
LIQUID_SOURCE
};
+enum NodeBoxType
+{
+ NODEBOX_REGULAR, // Regular block; allows buildable_to
+ NODEBOX_FIXED, // Static separately defined box
+ NODEBOX_WALLMOUNTED, // Box for wall_mounted nodes; (top, bottom, side)
+};
+
+struct NodeBox
+{
+ enum NodeBoxType type;
+ // NODEBOX_REGULAR (no parameters)
+ // NODEBOX_FIXED
+ core::aabbox3d<f32> fixed;
+ // NODEBOX_WALLMOUNTED
+ core::aabbox3d<f32> wall_top;
+ core::aabbox3d<f32> wall_bottom;
+ core::aabbox3d<f32> wall_side; // being at the -X side
+
+ NodeBox():
+ type(NODEBOX_REGULAR),
+ // default is rail-like
+ fixed(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
+ // default is sign/ladder-like
+ wall_top(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2),
+ wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
+ wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2)
+ {}
+};
+
struct MapNode;
class NodeMetadata;
@@ -149,6 +178,8 @@ struct ContentFeatures
DiggingPropertiesList digging_properties;
u32 damage_per_second;
+
+ NodeBox selection_box;
// NOTE: Move relevant properties to here from elsewhere
@@ -186,6 +217,7 @@ struct ContentFeatures
light_source = 0;
digging_properties.clear();
damage_per_second = 0;
+ selection_box = NodeBox();
}
ContentFeatures()