Reduce size of ContentFeatures structure

On my system this is a reduction from 4664 to 3704 bytes.
This is not for the sake of saving RAM but ensuring
commonly used structures fit into caches better.
This commit is contained in:
sfan5 2022-05-09 20:59:28 +02:00
parent 9a01581cdd
commit 8b74257bf3
4 changed files with 143 additions and 125 deletions

@ -266,10 +266,12 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
std::vector<aabb3f> &boxes = *p_boxes; std::vector<aabb3f> &boxes = *p_boxes;
if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) { if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) {
const std::vector<aabb3f> &fixed = nodebox.fixed; const auto &fixed = nodebox.fixed;
int facedir = n.getFaceDir(nodemgr, true); int facedir = n.getFaceDir(nodemgr, true);
u8 axisdir = facedir>>2; u8 axisdir = facedir>>2;
facedir&=0x03; facedir&=0x03;
boxes.reserve(boxes.size() + fixed.size());
for (aabb3f box : fixed) { for (aabb3f box : fixed) {
if (nodebox.type == NODEBOX_LEVELED) if (nodebox.type == NODEBOX_LEVELED)
box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS; 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(); size_t boxes_size = boxes.size();
boxes_size += nodebox.fixed.size(); boxes_size += nodebox.fixed.size();
const auto &c = nodebox.getConnected();
if (neighbors & 1) if (neighbors & 1)
boxes_size += nodebox.connect_top.size(); boxes_size += c.connect_top.size();
else else
boxes_size += nodebox.disconnected_top.size(); boxes_size += c.disconnected_top.size();
if (neighbors & 2) if (neighbors & 2)
boxes_size += nodebox.connect_bottom.size(); boxes_size += c.connect_bottom.size();
else else
boxes_size += nodebox.disconnected_bottom.size(); boxes_size += c.disconnected_bottom.size();
if (neighbors & 4) if (neighbors & 4)
boxes_size += nodebox.connect_front.size(); boxes_size += c.connect_front.size();
else else
boxes_size += nodebox.disconnected_front.size(); boxes_size += c.disconnected_front.size();
if (neighbors & 8) if (neighbors & 8)
boxes_size += nodebox.connect_left.size(); boxes_size += c.connect_left.size();
else else
boxes_size += nodebox.disconnected_left.size(); boxes_size += c.disconnected_left.size();
if (neighbors & 16) if (neighbors & 16)
boxes_size += nodebox.connect_back.size(); boxes_size += c.connect_back.size();
else else
boxes_size += nodebox.disconnected_back.size(); boxes_size += c.disconnected_back.size();
if (neighbors & 32) if (neighbors & 32)
boxes_size += nodebox.connect_right.size(); boxes_size += c.connect_right.size();
else else
boxes_size += nodebox.disconnected_right.size(); boxes_size += c.disconnected_right.size();
if (neighbors == 0) if (neighbors == 0)
boxes_size += nodebox.disconnected.size(); boxes_size += c.disconnected.size();
if (neighbors < 4) if (neighbors < 4)
boxes_size += nodebox.disconnected_sides.size(); boxes_size += c.disconnected_sides.size();
boxes.reserve(boxes_size); boxes.reserve(boxes_size);
@ -484,47 +488,47 @@ void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
BOXESPUSHBACK(nodebox.fixed); BOXESPUSHBACK(nodebox.fixed);
if (neighbors & 1) { if (neighbors & 1) {
BOXESPUSHBACK(nodebox.connect_top); BOXESPUSHBACK(c.connect_top);
} else { } else {
BOXESPUSHBACK(nodebox.disconnected_top); BOXESPUSHBACK(c.disconnected_top);
} }
if (neighbors & 2) { if (neighbors & 2) {
BOXESPUSHBACK(nodebox.connect_bottom); BOXESPUSHBACK(c.connect_bottom);
} else { } else {
BOXESPUSHBACK(nodebox.disconnected_bottom); BOXESPUSHBACK(c.disconnected_bottom);
} }
if (neighbors & 4) { if (neighbors & 4) {
BOXESPUSHBACK(nodebox.connect_front); BOXESPUSHBACK(c.connect_front);
} else { } else {
BOXESPUSHBACK(nodebox.disconnected_front); BOXESPUSHBACK(c.disconnected_front);
} }
if (neighbors & 8) { if (neighbors & 8) {
BOXESPUSHBACK(nodebox.connect_left); BOXESPUSHBACK(c.connect_left);
} else { } else {
BOXESPUSHBACK(nodebox.disconnected_left); BOXESPUSHBACK(c.disconnected_left);
} }
if (neighbors & 16) { if (neighbors & 16) {
BOXESPUSHBACK(nodebox.connect_back); BOXESPUSHBACK(c.connect_back);
} else { } else {
BOXESPUSHBACK(nodebox.disconnected_back); BOXESPUSHBACK(c.disconnected_back);
} }
if (neighbors & 32) { if (neighbors & 32) {
BOXESPUSHBACK(nodebox.connect_right); BOXESPUSHBACK(c.connect_right);
} else { } else {
BOXESPUSHBACK(nodebox.disconnected_right); BOXESPUSHBACK(c.disconnected_right);
} }
if (neighbors == 0) { if (neighbors == 0) {
BOXESPUSHBACK(nodebox.disconnected); BOXESPUSHBACK(c.disconnected);
} }
if (neighbors < 4) { if (neighbors < 4) {
BOXESPUSHBACK(nodebox.disconnected_sides); BOXESPUSHBACK(c.disconnected_sides);
} }
} }

@ -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_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); wall_side = aabb3f(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2);
// no default for other parts // no default for other parts
connect_top.clear(); connected.reset();
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();
} }
void NodeBox::serialize(std::ostream &os, u16 protocol_version) const 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.MinEdge);
writeV3F32(os, wall_side.MaxEdge); writeV3F32(os, wall_side.MaxEdge);
break; break;
case NODEBOX_CONNECTED: case NODEBOX_CONNECTED: {
writeU8(os, type); writeU8(os, type);
#define WRITEBOX(box) \ #define WRITEBOX(box) \
@ -109,22 +96,25 @@ void NodeBox::serialize(std::ostream &os, u16 protocol_version) const
writeV3F32(os, i.MaxEdge); \ writeV3F32(os, i.MaxEdge); \
}; };
const auto &c = getConnected();
WRITEBOX(fixed); WRITEBOX(fixed);
WRITEBOX(connect_top); WRITEBOX(c.connect_top);
WRITEBOX(connect_bottom); WRITEBOX(c.connect_bottom);
WRITEBOX(connect_front); WRITEBOX(c.connect_front);
WRITEBOX(connect_left); WRITEBOX(c.connect_left);
WRITEBOX(connect_back); WRITEBOX(c.connect_back);
WRITEBOX(connect_right); WRITEBOX(c.connect_right);
WRITEBOX(disconnected_top); WRITEBOX(c.disconnected_top);
WRITEBOX(disconnected_bottom); WRITEBOX(c.disconnected_bottom);
WRITEBOX(disconnected_front); WRITEBOX(c.disconnected_front);
WRITEBOX(disconnected_left); WRITEBOX(c.disconnected_left);
WRITEBOX(disconnected_back); WRITEBOX(c.disconnected_back);
WRITEBOX(disconnected_right); WRITEBOX(c.disconnected_right);
WRITEBOX(disconnected); WRITEBOX(c.disconnected);
WRITEBOX(disconnected_sides); WRITEBOX(c.disconnected_sides);
break; break;
}
default: default:
writeU8(os, type); writeU8(os, type);
break; break;
@ -173,21 +163,23 @@ void NodeBox::deSerialize(std::istream &is)
u16 count; u16 count;
auto &c = getConnected();
READBOXES(fixed); READBOXES(fixed);
READBOXES(connect_top); READBOXES(c.connect_top);
READBOXES(connect_bottom); READBOXES(c.connect_bottom);
READBOXES(connect_front); READBOXES(c.connect_front);
READBOXES(connect_left); READBOXES(c.connect_left);
READBOXES(connect_back); READBOXES(c.connect_back);
READBOXES(connect_right); READBOXES(c.connect_right);
READBOXES(disconnected_top); READBOXES(c.disconnected_top);
READBOXES(disconnected_bottom); READBOXES(c.disconnected_bottom);
READBOXES(disconnected_front); READBOXES(c.disconnected_front);
READBOXES(disconnected_left); READBOXES(c.disconnected_left);
READBOXES(disconnected_back); READBOXES(c.disconnected_back);
READBOXES(disconnected_right); READBOXES(c.disconnected_right);
READBOXES(disconnected); READBOXES(c.disconnected);
READBOXES(disconnected_sides); READBOXES(c.disconnected_sides);
} }
} }
@ -409,9 +401,9 @@ void ContentFeatures::reset()
drowning = 0; drowning = 0;
light_source = 0; light_source = 0;
damage_per_second = 0; damage_per_second = 0;
node_box = NodeBox(); node_box.reset();
selection_box = NodeBox(); selection_box.reset();
collision_box = NodeBox(); collision_box.reset();
waving = 0; waving = 0;
legacy_facedir_simple = false; legacy_facedir_simple = false;
legacy_wallmounted = false; legacy_wallmounted = false;
@ -1091,10 +1083,8 @@ void NodeDefManager::clear()
{ {
ContentFeatures f; ContentFeatures f;
f.name = "unknown"; f.name = "unknown";
TileDef unknownTile;
unknownTile.name = "unknown_node.png";
for (int t = 0; t < 6; t++) for (int t = 0; t < 6; t++)
f.tiledef[t] = unknownTile; f.tiledef[t].name = "unknown_node.png";
// Insert directly into containers // Insert directly into containers
content_t c = CONTENT_UNKNOWN; content_t c = CONTENT_UNKNOWN;
m_content_features[c] = f; m_content_features[c] = f;
@ -1296,22 +1286,23 @@ void getNodeBoxUnion(const NodeBox &nodebox, const ContentFeatures &features,
break; break;
} }
case NODEBOX_CONNECTED: { case NODEBOX_CONNECTED: {
const auto &c = nodebox.getConnected();
// Add all possible connected boxes // Add all possible connected boxes
boxVectorUnion(nodebox.fixed, box_union); boxVectorUnion(nodebox.fixed, box_union);
boxVectorUnion(nodebox.connect_top, box_union); boxVectorUnion(c.connect_top, box_union);
boxVectorUnion(nodebox.connect_bottom, box_union); boxVectorUnion(c.connect_bottom, box_union);
boxVectorUnion(nodebox.connect_front, box_union); boxVectorUnion(c.connect_front, box_union);
boxVectorUnion(nodebox.connect_left, box_union); boxVectorUnion(c.connect_left, box_union);
boxVectorUnion(nodebox.connect_back, box_union); boxVectorUnion(c.connect_back, box_union);
boxVectorUnion(nodebox.connect_right, box_union); boxVectorUnion(c.connect_right, box_union);
boxVectorUnion(nodebox.disconnected_top, box_union); boxVectorUnion(c.disconnected_top, box_union);
boxVectorUnion(nodebox.disconnected_bottom, box_union); boxVectorUnion(c.disconnected_bottom, box_union);
boxVectorUnion(nodebox.disconnected_front, box_union); boxVectorUnion(c.disconnected_front, box_union);
boxVectorUnion(nodebox.disconnected_left, box_union); boxVectorUnion(c.disconnected_left, box_union);
boxVectorUnion(nodebox.disconnected_back, box_union); boxVectorUnion(c.disconnected_back, box_union);
boxVectorUnion(nodebox.disconnected_right, box_union); boxVectorUnion(c.disconnected_right, box_union);
boxVectorUnion(nodebox.disconnected, box_union); boxVectorUnion(c.disconnected, box_union);
boxVectorUnion(nodebox.disconnected_sides, box_union); boxVectorUnion(c.disconnected_sides, box_union);
break; break;
} }
default: { default: {

@ -99,17 +99,8 @@ enum NodeBoxType
NODEBOX_CONNECTED, // optionally draws nodeboxes if a neighbor node attaches 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<aabb3f> fixed;
// NODEBOX_WALLMOUNTED
aabb3f wall_top;
aabb3f wall_bottom;
aabb3f wall_side; // being at the -X side
// NODEBOX_CONNECTED
std::vector<aabb3f> connect_top; std::vector<aabb3f> connect_top;
std::vector<aabb3f> connect_bottom; std::vector<aabb3f> connect_bottom;
std::vector<aabb3f> connect_front; std::vector<aabb3f> connect_front;
@ -124,9 +115,35 @@ struct NodeBox
std::vector<aabb3f> disconnected_right; std::vector<aabb3f> disconnected_right;
std::vector<aabb3f> disconnected; std::vector<aabb3f> disconnected;
std::vector<aabb3f> disconnected_sides; std::vector<aabb3f> disconnected_sides;
};
struct NodeBox
{
enum NodeBoxType type;
// NODEBOX_REGULAR (no parameters)
// NODEBOX_FIXED
std::vector<aabb3f> 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<NodeBoxConnected> connected;
NodeBox() NodeBox()
{ reset(); } { reset(); }
~NodeBox() = default;
inline NodeBoxConnected &getConnected() {
if (!connected)
connected = std::make_shared<NodeBoxConnected>();
return *connected;
}
inline const NodeBoxConnected &getConnected() const {
assert(connected);
return *connected;
}
void reset(); void reset();
void serialize(std::ostream &os, u16 protocol_version) const; void serialize(std::ostream &os, u16 protocol_version) const;
@ -290,7 +307,6 @@ struct ContentFeatures
// up down right left back front // up down right left back front
TileSpec tiles[6]; TileSpec tiles[6];
// Special tiles // Special tiles
// - Currently used for flowing liquids
TileSpec special_tiles[CF_SPECIAL_COUNT]; TileSpec special_tiles[CF_SPECIAL_COUNT];
u8 solidness; // Used when choosing which face is drawn u8 solidness; // Used when choosing which face is drawn
u8 visual_solidness; // When solidness=0, this tells how it looks like u8 visual_solidness; // When solidness=0, this tells how it looks like

@ -1000,22 +1000,25 @@ void push_nodebox(lua_State *L, const NodeBox &box)
push_aabb3f(L, box.wall_side); push_aabb3f(L, box.wall_side);
lua_setfield(L, -2, "wall_side"); lua_setfield(L, -2, "wall_side");
break; break;
case NODEBOX_CONNECTED: case NODEBOX_CONNECTED: {
lua_pushstring(L, "connected"); lua_pushstring(L, "connected");
lua_setfield(L, -2, "type"); 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"); lua_setfield(L, -2, "connect_top");
push_box(L, box.connect_bottom); push_box(L, c.connect_bottom);
lua_setfield(L, -2, "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"); lua_setfield(L, -2, "connect_front");
push_box(L, box.connect_back); push_box(L, c.connect_back);
lua_setfield(L, -2, "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"); lua_setfield(L, -2, "connect_left");
push_box(L, box.connect_right); push_box(L, c.connect_right);
lua_setfield(L, -2, "connect_right"); lua_setfield(L, -2, "connect_right");
// half the boxes are missing here?
break; break;
}
default: default:
FATAL_ERROR("Invalid box.type"); FATAL_ERROR("Invalid box.type");
break; break;
@ -1143,20 +1146,24 @@ NodeBox read_nodebox(lua_State *L, int index)
NODEBOXREAD(nodebox.wall_top, "wall_top"); NODEBOXREAD(nodebox.wall_top, "wall_top");
NODEBOXREAD(nodebox.wall_bottom, "wall_bottom"); NODEBOXREAD(nodebox.wall_bottom, "wall_bottom");
NODEBOXREAD(nodebox.wall_side, "wall_side"); NODEBOXREAD(nodebox.wall_side, "wall_side");
NODEBOXREADVEC(nodebox.connect_top, "connect_top");
NODEBOXREADVEC(nodebox.connect_bottom, "connect_bottom"); if (nodebox.type == NODEBOX_CONNECTED) {
NODEBOXREADVEC(nodebox.connect_front, "connect_front"); auto &c = nodebox.getConnected();
NODEBOXREADVEC(nodebox.connect_left, "connect_left"); NODEBOXREADVEC(c.connect_top, "connect_top");
NODEBOXREADVEC(nodebox.connect_back, "connect_back"); NODEBOXREADVEC(c.connect_bottom, "connect_bottom");
NODEBOXREADVEC(nodebox.connect_right, "connect_right"); NODEBOXREADVEC(c.connect_front, "connect_front");
NODEBOXREADVEC(nodebox.disconnected_top, "disconnected_top"); NODEBOXREADVEC(c.connect_left, "connect_left");
NODEBOXREADVEC(nodebox.disconnected_bottom, "disconnected_bottom"); NODEBOXREADVEC(c.connect_back, "connect_back");
NODEBOXREADVEC(nodebox.disconnected_front, "disconnected_front"); NODEBOXREADVEC(c.connect_right, "connect_right");
NODEBOXREADVEC(nodebox.disconnected_left, "disconnected_left"); NODEBOXREADVEC(c.disconnected_top, "disconnected_top");
NODEBOXREADVEC(nodebox.disconnected_back, "disconnected_back"); NODEBOXREADVEC(c.disconnected_bottom, "disconnected_bottom");
NODEBOXREADVEC(nodebox.disconnected_right, "disconnected_right"); NODEBOXREADVEC(c.disconnected_front, "disconnected_front");
NODEBOXREADVEC(nodebox.disconnected, "disconnected"); NODEBOXREADVEC(c.disconnected_left, "disconnected_left");
NODEBOXREADVEC(nodebox.disconnected_sides, "disconnected_sides"); NODEBOXREADVEC(c.disconnected_back, "disconnected_back");
NODEBOXREADVEC(c.disconnected_right, "disconnected_right");
NODEBOXREADVEC(c.disconnected, "disconnected");
NODEBOXREADVEC(c.disconnected_sides, "disconnected_sides");
}
return nodebox; return nodebox;
} }