+void transformNodeBox(const MapNode &n, const NodeBox &nodebox,
+ const NodeDefManager *nodemgr, std::vector<aabb3f> *p_boxes,
+ u8 neighbors = 0)
+{
+ std::vector<aabb3f> &boxes = *p_boxes;
+
+ if (nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) {
+ const std::vector<aabb3f> &fixed = nodebox.fixed;
+ int facedir = n.getFaceDir(nodemgr, true);
+ u8 axisdir = facedir>>2;
+ facedir&=0x03;
+ for (aabb3f box : fixed) {
+ if (nodebox.type == NODEBOX_LEVELED)
+ box.MaxEdge.Y = (-0.5f + n.getLevel(nodemgr) / 64.0f) * BS;
+
+ switch (axisdir) {
+ case 0:
+ if(facedir == 1)
+ {
+ box.MinEdge.rotateXZBy(-90);
+ box.MaxEdge.rotateXZBy(-90);
+ }
+ else if(facedir == 2)
+ {
+ box.MinEdge.rotateXZBy(180);
+ box.MaxEdge.rotateXZBy(180);
+ }
+ else if(facedir == 3)
+ {
+ box.MinEdge.rotateXZBy(90);
+ box.MaxEdge.rotateXZBy(90);
+ }
+ break;
+ case 1: // z+
+ box.MinEdge.rotateYZBy(90);
+ box.MaxEdge.rotateYZBy(90);
+ if(facedir == 1)
+ {
+ box.MinEdge.rotateXYBy(90);
+ box.MaxEdge.rotateXYBy(90);
+ }
+ else if(facedir == 2)
+ {
+ box.MinEdge.rotateXYBy(180);
+ box.MaxEdge.rotateXYBy(180);
+ }
+ else if(facedir == 3)
+ {
+ box.MinEdge.rotateXYBy(-90);
+ box.MaxEdge.rotateXYBy(-90);
+ }
+ break;
+ case 2: //z-
+ box.MinEdge.rotateYZBy(-90);
+ box.MaxEdge.rotateYZBy(-90);
+ if(facedir == 1)
+ {
+ box.MinEdge.rotateXYBy(-90);
+ box.MaxEdge.rotateXYBy(-90);
+ }
+ else if(facedir == 2)
+ {
+ box.MinEdge.rotateXYBy(180);
+ box.MaxEdge.rotateXYBy(180);
+ }
+ else if(facedir == 3)
+ {
+ box.MinEdge.rotateXYBy(90);
+ box.MaxEdge.rotateXYBy(90);
+ }
+ break;
+ case 3: //x+
+ box.MinEdge.rotateXYBy(-90);
+ box.MaxEdge.rotateXYBy(-90);
+ if(facedir == 1)
+ {
+ box.MinEdge.rotateYZBy(90);
+ box.MaxEdge.rotateYZBy(90);
+ }
+ else if(facedir == 2)
+ {
+ box.MinEdge.rotateYZBy(180);
+ box.MaxEdge.rotateYZBy(180);
+ }
+ else if(facedir == 3)
+ {
+ box.MinEdge.rotateYZBy(-90);
+ box.MaxEdge.rotateYZBy(-90);
+ }
+ break;
+ case 4: //x-
+ box.MinEdge.rotateXYBy(90);
+ box.MaxEdge.rotateXYBy(90);
+ if(facedir == 1)
+ {
+ box.MinEdge.rotateYZBy(-90);
+ box.MaxEdge.rotateYZBy(-90);
+ }
+ else if(facedir == 2)
+ {
+ box.MinEdge.rotateYZBy(180);
+ box.MaxEdge.rotateYZBy(180);
+ }
+ else if(facedir == 3)
+ {
+ box.MinEdge.rotateYZBy(90);
+ box.MaxEdge.rotateYZBy(90);
+ }
+ break;
+ case 5:
+ box.MinEdge.rotateXYBy(-180);
+ box.MaxEdge.rotateXYBy(-180);
+ if(facedir == 1)
+ {
+ box.MinEdge.rotateXZBy(90);
+ box.MaxEdge.rotateXZBy(90);
+ }
+ else if(facedir == 2)
+ {
+ box.MinEdge.rotateXZBy(180);
+ box.MaxEdge.rotateXZBy(180);
+ }
+ else if(facedir == 3)
+ {
+ box.MinEdge.rotateXZBy(-90);
+ box.MaxEdge.rotateXZBy(-90);
+ }
+ break;
+ default:
+ break;
+ }
+ box.repair();
+ boxes.push_back(box);
+ }
+ }
+ else if(nodebox.type == NODEBOX_WALLMOUNTED)
+ {
+ v3s16 dir = n.getWallMountedDir(nodemgr);
+
+ // top
+ if(dir == v3s16(0,1,0))
+ {
+ boxes.push_back(nodebox.wall_top);
+ }
+ // bottom
+ else if(dir == v3s16(0,-1,0))
+ {
+ boxes.push_back(nodebox.wall_bottom);
+ }
+ // side
+ else
+ {
+ v3f vertices[2] =
+ {
+ nodebox.wall_side.MinEdge,
+ nodebox.wall_side.MaxEdge
+ };
+
+ for (v3f &vertex : vertices) {
+ if(dir == v3s16(-1,0,0))
+ vertex.rotateXZBy(0);
+ if(dir == v3s16(1,0,0))
+ vertex.rotateXZBy(180);
+ if(dir == v3s16(0,0,-1))
+ vertex.rotateXZBy(90);
+ if(dir == v3s16(0,0,1))
+ vertex.rotateXZBy(-90);
+ }
+
+ aabb3f box = aabb3f(vertices[0]);
+ box.addInternalPoint(vertices[1]);
+ boxes.push_back(box);
+ }
+ }
+ else if (nodebox.type == NODEBOX_CONNECTED)
+ {
+ size_t boxes_size = boxes.size();
+ boxes_size += nodebox.fixed.size();
+ if (neighbors & 1)
+ boxes_size += nodebox.connect_top.size();
+ else
+ boxes_size += nodebox.disconnected_top.size();
+
+ if (neighbors & 2)
+ boxes_size += nodebox.connect_bottom.size();
+ else
+ boxes_size += nodebox.disconnected_bottom.size();
+
+ if (neighbors & 4)
+ boxes_size += nodebox.connect_front.size();
+ else
+ boxes_size += nodebox.disconnected_front.size();
+
+ if (neighbors & 8)
+ boxes_size += nodebox.connect_left.size();
+ else
+ boxes_size += nodebox.disconnected_left.size();
+
+ if (neighbors & 16)
+ boxes_size += nodebox.connect_back.size();
+ else
+ boxes_size += nodebox.disconnected_back.size();
+
+ if (neighbors & 32)
+ boxes_size += nodebox.connect_right.size();
+ else
+ boxes_size += nodebox.disconnected_right.size();
+
+ if (neighbors == 0)
+ boxes_size += nodebox.disconnected.size();
+
+ if (neighbors < 4)
+ boxes_size += nodebox.disconnected_sides.size();
+
+ boxes.reserve(boxes_size);
+
+#define BOXESPUSHBACK(c) \
+ for (std::vector<aabb3f>::const_iterator \
+ it = (c).begin(); \
+ it != (c).end(); ++it) \
+ (boxes).push_back(*it);
+
+ BOXESPUSHBACK(nodebox.fixed);
+
+ if (neighbors & 1) {
+ BOXESPUSHBACK(nodebox.connect_top);
+ } else {
+ BOXESPUSHBACK(nodebox.disconnected_top);
+ }
+
+ if (neighbors & 2) {
+ BOXESPUSHBACK(nodebox.connect_bottom);
+ } else {
+ BOXESPUSHBACK(nodebox.disconnected_bottom);
+ }
+
+ if (neighbors & 4) {
+ BOXESPUSHBACK(nodebox.connect_front);
+ } else {
+ BOXESPUSHBACK(nodebox.disconnected_front);
+ }
+
+ if (neighbors & 8) {
+ BOXESPUSHBACK(nodebox.connect_left);
+ } else {
+ BOXESPUSHBACK(nodebox.disconnected_left);
+ }
+
+ if (neighbors & 16) {
+ BOXESPUSHBACK(nodebox.connect_back);
+ } else {
+ BOXESPUSHBACK(nodebox.disconnected_back);
+ }
+
+ if (neighbors & 32) {
+ BOXESPUSHBACK(nodebox.connect_right);
+ } else {
+ BOXESPUSHBACK(nodebox.disconnected_right);
+ }
+
+ if (neighbors == 0) {
+ BOXESPUSHBACK(nodebox.disconnected);
+ }
+
+ if (neighbors < 4) {
+ BOXESPUSHBACK(nodebox.disconnected_sides);
+ }
+
+ }
+ else // NODEBOX_REGULAR
+ {
+ boxes.emplace_back(-BS/2,-BS/2,-BS/2,BS/2,BS/2,BS/2);
+ }