1
0
Fork 0
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:
Wuzzy 2024-01-17 17:47:06 +01:00 committed by GitHub
parent e7dd9737bd
commit 08ee6d8d4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 375 additions and 33 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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) {};
}

View file

@ -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

View file

@ -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

View file

@ -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");
}
/******************************************************************************/

View file

@ -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] = {

View file

@ -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];