mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-16 18:01:40 +00:00
Add rotation support for wallmounted nodes in 'ceiling' or 'floor' mode (#11073)
This commit is contained in:
parent
e7dd9737bd
commit
08ee6d8d4b
25 changed files with 375 additions and 33 deletions
|
@ -1008,7 +1008,9 @@ void MapblockMeshGenerator::drawTorchlikeNode()
|
|||
switch (wall) {
|
||||
case DWM_YP: tileindex = 1; break; // ceiling
|
||||
case DWM_YN: tileindex = 0; break; // floor
|
||||
default: tileindex = 2; // side (or invalid—should we care?)
|
||||
case DWM_S1: tileindex = 1; break; // ceiling, but rotated
|
||||
case DWM_S2: tileindex = 0; break; // floor, but rotated
|
||||
default: tileindex = 2; // side (or invalid, shouldn't happen)
|
||||
}
|
||||
useTile(tileindex, MATERIAL_FLAG_CRACK_OVERLAY, MATERIAL_FLAG_BACKFACE_CULLING);
|
||||
|
||||
|
@ -1044,6 +1046,17 @@ void MapblockMeshGenerator::drawTorchlikeNode()
|
|||
case DWM_ZN:
|
||||
vertex.X += -size + BS/2;
|
||||
vertex.rotateXZBy(-90);
|
||||
break;
|
||||
case DWM_S1:
|
||||
// same as DWM_YP, but rotated 90°
|
||||
vertex.Y += -size + BS/2;
|
||||
vertex.rotateXZBy(45);
|
||||
break;
|
||||
case DWM_S2:
|
||||
// same as DWM_YN, but rotated -90°
|
||||
vertex.Y += size - BS/2;
|
||||
vertex.rotateXZBy(-45);
|
||||
break;
|
||||
}
|
||||
}
|
||||
drawQuad(vertices);
|
||||
|
@ -1077,6 +1090,10 @@ void MapblockMeshGenerator::drawSignlikeNode()
|
|||
vertex.rotateXZBy( 90); break;
|
||||
case DWM_ZN:
|
||||
vertex.rotateXZBy(-90); break;
|
||||
case DWM_S1:
|
||||
vertex.rotateXYBy( 90); vertex.rotateXZBy(90); break;
|
||||
case DWM_S2:
|
||||
vertex.rotateXYBy(-90); vertex.rotateXZBy(-90); break;
|
||||
}
|
||||
}
|
||||
drawQuad(vertices);
|
||||
|
|
|
@ -3704,7 +3704,36 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
|
|||
v3s16 dir = nodepos - neighborpos;
|
||||
|
||||
if (abs(dir.Y) > MYMAX(abs(dir.X), abs(dir.Z))) {
|
||||
predicted_node.setParam2(dir.Y < 0 ? 1 : 0);
|
||||
// If you change this code, also change builtin/game/item.lua
|
||||
u8 predicted_param2 = dir.Y < 0 ? 1 : 0;
|
||||
if (selected_def.wallmounted_rotate_vertical) {
|
||||
bool rotate90 = false;
|
||||
v3f fnodepos = v3f(neighborpos.X, neighborpos.Y, neighborpos.Z);
|
||||
v3f ppos = client->getEnv().getLocalPlayer()->getPosition() / BS;
|
||||
v3f pdir = fnodepos - ppos;
|
||||
switch (predicted_f.drawtype) {
|
||||
case NDT_TORCHLIKE: {
|
||||
rotate90 = !((pdir.X < 0 && pdir.Z > 0) ||
|
||||
(pdir.X > 0 && pdir.Z < 0));
|
||||
if (dir.Y > 0) {
|
||||
rotate90 = !rotate90;
|
||||
}
|
||||
break;
|
||||
};
|
||||
case NDT_SIGNLIKE: {
|
||||
rotate90 = abs(pdir.X) < abs(pdir.Z);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
rotate90 = abs(pdir.X) > abs(pdir.Z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rotate90) {
|
||||
predicted_param2 += 6;
|
||||
}
|
||||
}
|
||||
predicted_node.setParam2(predicted_param2);
|
||||
} else if (abs(dir.X) > abs(dir.Z)) {
|
||||
predicted_node.setParam2(dir.X < 0 ? 3 : 2);
|
||||
} else {
|
||||
|
|
|
@ -76,6 +76,7 @@ ItemDefinition& ItemDefinition::operator=(const ItemDefinition &def)
|
|||
groups = def.groups;
|
||||
node_placement_prediction = def.node_placement_prediction;
|
||||
place_param2 = def.place_param2;
|
||||
wallmounted_rotate_vertical = def.wallmounted_rotate_vertical;
|
||||
sound_place = def.sound_place;
|
||||
sound_place_failed = def.sound_place_failed;
|
||||
sound_use = def.sound_use;
|
||||
|
@ -124,6 +125,7 @@ void ItemDefinition::reset()
|
|||
range = -1;
|
||||
node_placement_prediction.clear();
|
||||
place_param2.reset();
|
||||
wallmounted_rotate_vertical = false;
|
||||
}
|
||||
|
||||
void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const
|
||||
|
@ -183,6 +185,7 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const
|
|||
os << (u8)place_param2.has_value(); // protocol_version >= 43
|
||||
if (place_param2)
|
||||
os << *place_param2;
|
||||
writeU8(os, wallmounted_rotate_vertical);
|
||||
}
|
||||
|
||||
void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version)
|
||||
|
@ -251,6 +254,8 @@ void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version)
|
|||
|
||||
if (readU8(is)) // protocol_version >= 43
|
||||
place_param2 = readU8(is);
|
||||
|
||||
wallmounted_rotate_vertical = readU8(is); // 0 if missing
|
||||
} catch(SerializationError &e) {};
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ struct ItemDefinition
|
|||
// "" = no prediction
|
||||
std::string node_placement_prediction;
|
||||
std::optional<u8> place_param2;
|
||||
bool wallmounted_rotate_vertical;
|
||||
|
||||
/*
|
||||
Some helpful methods
|
||||
|
|
|
@ -95,6 +95,8 @@ v3s16 MapNode::getWallMountedDir(const NodeDefManager *nodemgr) const
|
|||
case 3: return v3s16(-1,0,0);
|
||||
case 4: return v3s16(0,0,1);
|
||||
case 5: return v3s16(0,0,-1);
|
||||
case 6: return v3s16(0,1,0);
|
||||
case 7: return v3s16(0,-1,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,16 +325,45 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
|
|||
else if(nodebox.type == NODEBOX_WALLMOUNTED)
|
||||
{
|
||||
v3s16 dir = n.getWallMountedDir(nodemgr);
|
||||
u8 wall = n.getWallMounted(nodemgr);
|
||||
|
||||
// top
|
||||
if(dir == v3s16(0,1,0))
|
||||
{
|
||||
boxes.push_back(nodebox.wall_top);
|
||||
if (wall == DWM_S1) {
|
||||
v3f vertices[2] =
|
||||
{
|
||||
nodebox.wall_top.MinEdge,
|
||||
nodebox.wall_top.MaxEdge
|
||||
};
|
||||
for (v3f &vertex : vertices) {
|
||||
vertex.rotateXZBy(90);
|
||||
}
|
||||
aabb3f box = aabb3f(vertices[0]);
|
||||
box.addInternalPoint(vertices[1]);
|
||||
boxes.push_back(box);
|
||||
} else {
|
||||
boxes.push_back(nodebox.wall_top);
|
||||
}
|
||||
}
|
||||
// bottom
|
||||
else if(dir == v3s16(0,-1,0))
|
||||
{
|
||||
boxes.push_back(nodebox.wall_bottom);
|
||||
if (wall == DWM_S2) {
|
||||
v3f vertices[2] =
|
||||
{
|
||||
nodebox.wall_bottom.MinEdge,
|
||||
nodebox.wall_bottom.MaxEdge
|
||||
};
|
||||
for (v3f &vertex : vertices) {
|
||||
vertex.rotateXZBy(-90);
|
||||
}
|
||||
aabb3f box = aabb3f(vertices[0]);
|
||||
box.addInternalPoint(vertices[1]);
|
||||
boxes.push_back(box);
|
||||
} else {
|
||||
boxes.push_back(nodebox.wall_bottom);
|
||||
}
|
||||
}
|
||||
// side
|
||||
else
|
||||
|
|
|
@ -136,6 +136,8 @@ void read_item_definition(lua_State* L, int index,
|
|||
int place_param2;
|
||||
if (getintfield(L, index, "place_param2", place_param2))
|
||||
def.place_param2 = rangelim(place_param2, 0, U8_MAX);
|
||||
|
||||
getboolfield(L, index, "wallmounted_rotate_vertical", def.wallmounted_rotate_vertical);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -195,6 +197,8 @@ void push_item_definition_full(lua_State *L, const ItemDefinition &i)
|
|||
lua_setfield(L, -2, "sound_place_failed");
|
||||
lua_pushstring(L, i.node_placement_prediction.c_str());
|
||||
lua_setfield(L, -2, "node_placement_prediction");
|
||||
lua_pushboolean(L, i.wallmounted_rotate_vertical);
|
||||
lua_setfield(L, -2, "wallmounted_rotate_vertical");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -110,13 +110,15 @@ const v3s16 g_27dirs[27] =
|
|||
v3s16(0,0,0),
|
||||
};
|
||||
|
||||
const u8 wallmounted_to_facedir[6] = {
|
||||
const u8 wallmounted_to_facedir[8] = {
|
||||
20,
|
||||
0,
|
||||
16 + 1,
|
||||
12 + 3,
|
||||
8,
|
||||
4 + 2
|
||||
4 + 2,
|
||||
20 + 1, // special 1
|
||||
0 + 1 // special 2
|
||||
};
|
||||
|
||||
const v3s16 wallmounted_dirs[8] = {
|
||||
|
|
|
@ -69,16 +69,22 @@ enum Direction6D {
|
|||
/// Direction in the wallmounted format.
|
||||
/// P is Positive, N is Negative.
|
||||
enum DirectionWallmounted {
|
||||
// The 6 wallmounted directions
|
||||
DWM_YP,
|
||||
DWM_YN,
|
||||
DWM_XP,
|
||||
DWM_XN,
|
||||
DWM_ZP,
|
||||
DWM_ZN,
|
||||
DWM_COUNT,
|
||||
// There are 6 wallmounted directions, but 8 possible states (3 bits).
|
||||
// So we have 2 additional states, which drawtypes might use for
|
||||
// special ("S") behavior.
|
||||
DWM_S1,
|
||||
DWM_S2,
|
||||
DWM_COUNT
|
||||
};
|
||||
|
||||
extern const v3s16 g_6dirs[DWM_COUNT];
|
||||
extern const v3s16 g_6dirs[6];
|
||||
|
||||
extern const v3s16 g_7dirs[7];
|
||||
|
||||
|
@ -87,9 +93,9 @@ extern const v3s16 g_26dirs[26];
|
|||
// 26th is (0,0,0)
|
||||
extern const v3s16 g_27dirs[27];
|
||||
|
||||
extern const u8 wallmounted_to_facedir[6];
|
||||
extern const u8 wallmounted_to_facedir[DWM_COUNT];
|
||||
|
||||
extern const v3s16 wallmounted_dirs[8];
|
||||
extern const v3s16 wallmounted_dirs[DWM_COUNT];
|
||||
|
||||
extern const v3s16 facedir_dirs[32];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue