Bending wall panels round curved rooms in Godot
A round room is now built from the theme's own wall pieces, bent to the arc at load, and furniture and meat follow the curve.
A round room or curved corridor corner in a themed dungeon is now built from that theme’s own wall panels and trims, bent to the curve at load. Furniture backed onto a round wall stands along the arc, and meat grows on every kind of wall the game has. The ceiling of a round room is still the one rough part.
How do you bend a wall panel round a room?
Round rooms had shipped with flat faces, because the theme’s pieces are laid square by square on straight walls. A dungeon with a round room lost its theme’s look there. I didn’t want new models, so the existing meshes are bent at load.
InteriorArc.runs() first chains the round walls into runs: a polyline with a normal at each point, the open side on the left. Those are the curve’s facets, the short straight faces where a door meets a round room, and what is left of a bent square’s own side against rock. A run is cut where the wall turns more than 35 degrees, since that is a corner and not a curve.
Each run gets round(length / 3 m) pieces, at least one, so a 4.5 m round room’s quarter is two pieces of 3.53 m. Each seam moves to the nearest facet line within 0.4 m, so a pilaster stands on a facet’s edge.
InteriorArc.bend() then carries a piece’s mesh onto its span. The mesh is made with x along the wall, y up and z out into the room. First it is sliced at every facet line it crosses, because a straight panel has no vertex in the middle, and a chord across 3 m of arc would stand 0.25 m off the wall. Then each vertex goes from (x, y, z) to the run’s point at x, plus z along the normal there, and its normal and tangent turn with it. Bent meshes are cached by member, state, length and cuts.
Why did the painted picture seam run down each quarter?
The painted sets project their picture by the world’s axes. Round an arc that turned the picture at 45 degrees and left a seam down the middle of each quarter. So each bent mesh also carries its unrolled place in CUSTOM0: x along the run as if it were straight, its own z, and its normal before the bend. The painted shader’s bent mode reads that instead, so the picture and its pilasters are laid as on a straight wall.
Floors and ceilings of bent squares are laid whole, with the part behind the arc hidden by the wall. The floor reads right. A ceiling piece’s beams are seen to end in the wall, though, and I’ve left that alone for now.
Why did furniture poke through the arc?
On a bent square a cell counted as floor when its middle was inside the curve. Near where an arc leaves a straight wall, a piece’s back corner could stand up to 0.26 m behind it. DungeonDresser.Grid.arc_spots now backs the piece onto the arc and turns it to face the open, and the layout’s collision boxes are turned with it. A test checks every box corner with DungeonCurve.holds: 1,369 pieces, none behind an arc.
How does meat grow on every wall?
I asked for meat on all the new wall variants: heights, curves, steps, arches. The growth reuses the bend, with two changes:
- A round wall’s growth is bent to its piece’s span without slicing. Its triangles are small beside a facet, and skipping the slice costs about a third as much. Boxes are cut along the arc. All bent growth is drawn as one merged mesh per chunk and level.
- A straight wall’s growth stands on the floor under both its ends, so beside a stair or ramp it is sheared up the slope, with the boxes left unsheared. A ledge’s face takes growth squashed to its rise, a doorway’s stubs and heads take growth narrowed to a cell, and the ceiling’s growth hangs at the square’s roof height.
A bent piece costs about 10 ms of load time.
tests/meat_walls goes over the one list of wall kinds that the every-theme wall test already keeps, with a rule or an exemption for each. A wall kind added later with no growth fails by name. That is 102 checks, beside 350 for the theme walls and 39 for the curves, with 14 tests run and none failed.