diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 73bd620fb..42f020e71 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -266,10 +266,12 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox, std::vector &boxes = *p_boxes; if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) { - const std::vector &fixed = nodebox.fixed; + const auto &fixed = nodebox.fixed; int facedir = n.getFaceDir(nodemgr, true); u8 axisdir = facedir>>2; facedir&=0x03; + + boxes.reserve(boxes.size() + fixed.size()); for (aabb3f box : fixed) { if (nodebox.type == NODEBOX_LEVELED) box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS; @@ -437,41 +439,43 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox, { size_t boxes_size = boxes.size(); boxes_size += nodebox.fixed.size(); + const auto &c = nodebox.getConnected(); + if (neighbors & 1) - boxes_size += nodebox.connect_top.size(); + boxes_size += c.connect_top.size(); else - boxes_size += nodebox.disconnected_top.size(); + boxes_size += c.disconnected_top.size(); if (neighbors & 2) - boxes_size += nodebox.connect_bottom.size(); + boxes_size += c.connect_bottom.size(); else - boxes_size += nodebox.disconnected_bottom.size(); + boxes_size += c.disconnected_bottom.size(); if (neighbors & 4) - boxes_size += nodebox.connect_front.size(); + boxes_size += c.connect_front.size(); else - boxes_size += nodebox.disconnected_front.size(); + boxes_size += c.disconnected_front.size(); if (neighbors & 8) - boxes_size += nodebox.connect_left.size(); + boxes_size += c.connect_left.size(); else - boxes_size += nodebox.disconnected_left.size(); + boxes_size += c.disconnected_left.size(); if (neighbors & 16) - boxes_size += nodebox.connect_back.size(); + boxes_size += c.connect_back.size(); else - boxes_size += nodebox.disconnected_back.size(); + boxes_size += c.disconnected_back.size(); if (neighbors & 32) - boxes_size += nodebox.connect_right.size(); + boxes_size += c.connect_right.size(); else - boxes_size += nodebox.disconnected_right.size(); + boxes_size += c.disconnected_right.size(); if (neighbors == 0) - boxes_size += nodebox.disconnected.size(); + boxes_size += c.disconnected.size(); if (neighbors < 4) - boxes_size += nodebox.disconnected_sides.size(); + boxes_size += c.disconnected_sides.size(); boxes.reserve(boxes_size); @@ -484,47 +488,47 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox, BOXESPUSHBACK(nodebox.fixed); if (neighbors & 1) { - BOXESPUSHBACK(nodebox.connect_top); + BOXESPUSHBACK(c.connect_top); } else { - BOXESPUSHBACK(nodebox.disconnected_top); + BOXESPUSHBACK(c.disconnected_top); } if (neighbors & 2) { - BOXESPUSHBACK(nodebox.connect_bottom); + BOXESPUSHBACK(c.connect_bottom); } else { - BOXESPUSHBACK(nodebox.disconnected_bottom); + BOXESPUSHBACK(c.disconnected_bottom); } if (neighbors & 4) { - BOXESPUSHBACK(nodebox.connect_front); + BOXESPUSHBACK(c.connect_front); } else { - BOXESPUSHBACK(nodebox.disconnected_front); + BOXESPUSHBACK(c.disconnected_front); } if (neighbors & 8) { - BOXESPUSHBACK(nodebox.connect_left); + BOXESPUSHBACK(c.connect_left); } else { - BOXESPUSHBACK(nodebox.disconnected_left); + BOXESPUSHBACK(c.disconnected_left); } if (neighbors & 16) { - BOXESPUSHBACK(nodebox.connect_back); + BOXESPUSHBACK(c.connect_back); } else { - BOXESPUSHBACK(nodebox.disconnected_back); + BOXESPUSHBACK(c.disconnected_back); } if (neighbors & 32) { - BOXESPUSHBACK(nodebox.connect_right); + BOXESPUSHBACK(c.connect_right); } else { - BOXESPUSHBACK(nodebox.disconnected_right); + BOXESPUSHBACK(c.disconnected_right); } if (neighbors == 0) { - BOXESPUSHBACK(nodebox.disconnected); + BOXESPUSHBACK(c.disconnected); } if (neighbors < 4) { - BOXESPUSHBACK(nodebox.disconnected_sides); + BOXESPUSHBACK(c.disconnected_sides); } } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 8d63870b3..922554a2c 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -56,20 +56,7 @@ void NodeBox::reset() wall_bottom = aabb3f(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2); wall_side = aabb3f(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2); // no default for other parts - connect_top.clear(); - connect_bottom.clear(); - connect_front.clear(); - connect_left.clear(); - connect_back.clear(); - connect_right.clear(); - disconnected_top.clear(); - disconnected_bottom.clear(); - disconnected_front.clear(); - disconnected_left.clear(); - disconnected_back.clear(); - disconnected_right.clear(); - disconnected.clear(); - disconnected_sides.clear(); + connected.reset(); } void NodeBox::serialize(std::ostream &os, u16 protocol_version) const @@ -99,7 +86,7 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const writeV3F32(os, wall_side.MinEdge); writeV3F32(os, wall_side.MaxEdge); break; - case NODEBOX_CONNECTED: + case NODEBOX_CONNECTED: { writeU8(os, type); #define WRITEBOX(box) \ @@ -109,22 +96,25 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const writeV3F32(os, i.MaxEdge); \ }; + const auto &c = getConnected(); + WRITEBOX(fixed); - WRITEBOX(connect_top); - WRITEBOX(connect_bottom); - WRITEBOX(connect_front); - WRITEBOX(connect_left); - WRITEBOX(connect_back); - WRITEBOX(connect_right); - WRITEBOX(disconnected_top); - WRITEBOX(disconnected_bottom); - WRITEBOX(disconnected_front); - WRITEBOX(disconnected_left); - WRITEBOX(disconnected_back); - WRITEBOX(disconnected_right); - WRITEBOX(disconnected); - WRITEBOX(disconnected_sides); + WRITEBOX(c.connect_top); + WRITEBOX(c.connect_bottom); + WRITEBOX(c.connect_front); + WRITEBOX(c.connect_left); + WRITEBOX(c.connect_back); + WRITEBOX(c.connect_right); + WRITEBOX(c.disconnected_top); + WRITEBOX(c.disconnected_bottom); + WRITEBOX(c.disconnected_front); + WRITEBOX(c.disconnected_left); + WRITEBOX(c.disconnected_back); + WRITEBOX(c.disconnected_right); + WRITEBOX(c.disconnected); + WRITEBOX(c.disconnected_sides); break; + } default: writeU8(os, type); break; @@ -173,21 +163,23 @@ void NodeBox::deSerialize(std::istream &is) u16 count; + auto &c = getConnected(); + READBOXES(fixed); - READBOXES(connect_top); - READBOXES(connect_bottom); - READBOXES(connect_front); - READBOXES(connect_left); - READBOXES(connect_back); - READBOXES(connect_right); - READBOXES(disconnected_top); - READBOXES(disconnected_bottom); - READBOXES(disconnected_front); - READBOXES(disconnected_left); - READBOXES(disconnected_back); - READBOXES(disconnected_right); - READBOXES(disconnected); - READBOXES(disconnected_sides); + READBOXES(c.connect_top); + READBOXES(c.connect_bottom); + READBOXES(c.connect_front); + READBOXES(c.connect_left); + READBOXES(c.connect_back); + READBOXES(c.connect_right); + READBOXES(c.disconnected_top); + READBOXES(c.disconnected_bottom); + READBOXES(c.disconnected_front); + READBOXES(c.disconnected_left); + READBOXES(c.disconnected_back); + READBOXES(c.disconnected_right); + READBOXES(c.disconnected); + READBOXES(c.disconnected_sides); } } @@ -409,9 +401,9 @@ void ContentFeatures::reset() drowning = 0; light_source = 0; damage_per_second = 0; - node_box = NodeBox(); - selection_box = NodeBox(); - collision_box = NodeBox(); + node_box.reset(); + selection_box.reset(); + collision_box.reset(); waving = 0; legacy_facedir_simple = false; legacy_wallmounted = false; @@ -1091,10 +1083,8 @@ void NodeDefManager::clear() { ContentFeatures f; f.name = "unknown"; - TileDef unknownTile; - unknownTile.name = "unknown_node.png"; for (int t = 0; t < 6; t++) - f.tiledef[t] = unknownTile; + f.tiledef[t].name = "unknown_node.png"; // Insert directly into containers content_t c = CONTENT_UNKNOWN; m_content_features[c] = f; @@ -1296,22 +1286,23 @@ void getNodeBoxUnion(const NodeBox &nodebox, const ContentFeatures &features, break; } case NODEBOX_CONNECTED: { + const auto &c = nodebox.getConnected(); // Add all possible connected boxes - boxVectorUnion(nodebox.fixed, box_union); - boxVectorUnion(nodebox.connect_top, box_union); - boxVectorUnion(nodebox.connect_bottom, box_union); - boxVectorUnion(nodebox.connect_front, box_union); - boxVectorUnion(nodebox.connect_left, box_union); - boxVectorUnion(nodebox.connect_back, box_union); - boxVectorUnion(nodebox.connect_right, box_union); - boxVectorUnion(nodebox.disconnected_top, box_union); - boxVectorUnion(nodebox.disconnected_bottom, box_union); - boxVectorUnion(nodebox.disconnected_front, box_union); - boxVectorUnion(nodebox.disconnected_left, box_union); - boxVectorUnion(nodebox.disconnected_back, box_union); - boxVectorUnion(nodebox.disconnected_right, box_union); - boxVectorUnion(nodebox.disconnected, box_union); - boxVectorUnion(nodebox.disconnected_sides, box_union); + boxVectorUnion(nodebox.fixed, box_union); + boxVectorUnion(c.connect_top, box_union); + boxVectorUnion(c.connect_bottom, box_union); + boxVectorUnion(c.connect_front, box_union); + boxVectorUnion(c.connect_left, box_union); + boxVectorUnion(c.connect_back, box_union); + boxVectorUnion(c.connect_right, box_union); + boxVectorUnion(c.disconnected_top, box_union); + boxVectorUnion(c.disconnected_bottom, box_union); + boxVectorUnion(c.disconnected_front, box_union); + boxVectorUnion(c.disconnected_left, box_union); + boxVectorUnion(c.disconnected_back, box_union); + boxVectorUnion(c.disconnected_right, box_union); + boxVectorUnion(c.disconnected, box_union); + boxVectorUnion(c.disconnected_sides, box_union); break; } default: { diff --git a/src/nodedef.h b/src/nodedef.h index 8c817179d..edd8d00a7 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -99,17 +99,8 @@ enum NodeBoxType NODEBOX_CONNECTED, // optionally draws nodeboxes if a neighbor node attaches }; -struct NodeBox +struct NodeBoxConnected { - enum NodeBoxType type; - // NODEBOX_REGULAR (no parameters) - // NODEBOX_FIXED - std::vector fixed; - // NODEBOX_WALLMOUNTED - aabb3f wall_top; - aabb3f wall_bottom; - aabb3f wall_side; // being at the -X side - // NODEBOX_CONNECTED std::vector connect_top; std::vector connect_bottom; std::vector connect_front; @@ -124,9 +115,35 @@ struct NodeBox std::vector disconnected_right; std::vector disconnected; std::vector disconnected_sides; +}; + +struct NodeBox +{ + enum NodeBoxType type; + // NODEBOX_REGULAR (no parameters) + // NODEBOX_FIXED + std::vector fixed; + // NODEBOX_WALLMOUNTED + aabb3f wall_top; + aabb3f wall_bottom; + aabb3f wall_side; // being at the -X side + // NODEBOX_CONNECTED + // (kept externally to not bloat the structure) + std::shared_ptr connected; NodeBox() { reset(); } + ~NodeBox() = default; + + inline NodeBoxConnected &getConnected() { + if (!connected) + connected = std::make_shared(); + return *connected; + } + inline const NodeBoxConnected &getConnected() const { + assert(connected); + return *connected; + } void reset(); void serialize(std::ostream &os, u16 protocol_version) const; @@ -290,7 +307,6 @@ struct ContentFeatures // up down right left back front TileSpec tiles[6]; // Special tiles - // - Currently used for flowing liquids TileSpec special_tiles[CF_SPECIAL_COUNT]; u8 solidness; // Used when choosing which face is drawn u8 visual_solidness; // When solidness=0, this tells how it looks like diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 79830ddb4..f232e9e5d 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -1000,22 +1000,25 @@ void push_nodebox(lua_State *L, const NodeBox &box) push_aabb3f(L, box.wall_side); lua_setfield(L, -2, "wall_side"); break; - case NODEBOX_CONNECTED: + case NODEBOX_CONNECTED: { lua_pushstring(L, "connected"); lua_setfield(L, -2, "type"); - push_box(L, box.connect_top); + const auto &c = box.getConnected(); + push_box(L, c.connect_top); lua_setfield(L, -2, "connect_top"); - push_box(L, box.connect_bottom); + push_box(L, c.connect_bottom); lua_setfield(L, -2, "connect_bottom"); - push_box(L, box.connect_front); + push_box(L, c.connect_front); lua_setfield(L, -2, "connect_front"); - push_box(L, box.connect_back); + push_box(L, c.connect_back); lua_setfield(L, -2, "connect_back"); - push_box(L, box.connect_left); + push_box(L, c.connect_left); lua_setfield(L, -2, "connect_left"); - push_box(L, box.connect_right); + push_box(L, c.connect_right); lua_setfield(L, -2, "connect_right"); + // half the boxes are missing here? break; + } default: FATAL_ERROR("Invalid box.type"); break; @@ -1143,20 +1146,24 @@ NodeBox read_nodebox(lua_State *L, int index) NODEBOXREAD(nodebox.wall_top, "wall_top"); NODEBOXREAD(nodebox.wall_bottom, "wall_bottom"); NODEBOXREAD(nodebox.wall_side, "wall_side"); - NODEBOXREADVEC(nodebox.connect_top, "connect_top"); - NODEBOXREADVEC(nodebox.connect_bottom, "connect_bottom"); - NODEBOXREADVEC(nodebox.connect_front, "connect_front"); - NODEBOXREADVEC(nodebox.connect_left, "connect_left"); - NODEBOXREADVEC(nodebox.connect_back, "connect_back"); - NODEBOXREADVEC(nodebox.connect_right, "connect_right"); - NODEBOXREADVEC(nodebox.disconnected_top, "disconnected_top"); - NODEBOXREADVEC(nodebox.disconnected_bottom, "disconnected_bottom"); - NODEBOXREADVEC(nodebox.disconnected_front, "disconnected_front"); - NODEBOXREADVEC(nodebox.disconnected_left, "disconnected_left"); - NODEBOXREADVEC(nodebox.disconnected_back, "disconnected_back"); - NODEBOXREADVEC(nodebox.disconnected_right, "disconnected_right"); - NODEBOXREADVEC(nodebox.disconnected, "disconnected"); - NODEBOXREADVEC(nodebox.disconnected_sides, "disconnected_sides"); + + if (nodebox.type == NODEBOX_CONNECTED) { + auto &c = nodebox.getConnected(); + NODEBOXREADVEC(c.connect_top, "connect_top"); + NODEBOXREADVEC(c.connect_bottom, "connect_bottom"); + NODEBOXREADVEC(c.connect_front, "connect_front"); + NODEBOXREADVEC(c.connect_left, "connect_left"); + NODEBOXREADVEC(c.connect_back, "connect_back"); + NODEBOXREADVEC(c.connect_right, "connect_right"); + NODEBOXREADVEC(c.disconnected_top, "disconnected_top"); + NODEBOXREADVEC(c.disconnected_bottom, "disconnected_bottom"); + NODEBOXREADVEC(c.disconnected_front, "disconnected_front"); + NODEBOXREADVEC(c.disconnected_left, "disconnected_left"); + NODEBOXREADVEC(c.disconnected_back, "disconnected_back"); + NODEBOXREADVEC(c.disconnected_right, "disconnected_right"); + NODEBOXREADVEC(c.disconnected, "disconnected"); + NODEBOXREADVEC(c.disconnected_sides, "disconnected_sides"); + } return nodebox; }