Monday, March 20, 2023

Procedural Buildings: Interiors for Non-Cube Buildings

I think I'm going to continue with these shorter posts every week or two since they're easier to write in a single night. I'm continuing to work on adding a variety of smaller features to 3DWorld's procedural buildings. It seems there are an infinite number of these changes to make.

One item that's been on my TODO list on Trello for awhile is generating interiors for non-axis aligned cube shaped buildings. This includes buildings formed from rotated cubes, cylinders, cylindrical sections (with a flat side), and N-gon buildings with 3 or 5-8 sides. These shapes are difficult to work with because everything is so much easier when using cubes: Boolean operations, intersection queries, point containment, collision detection. Each of these is a few lines of code when using cubes, but tens to a hundred lines of code for arbitrary polygons and curved shapes. To make things a bit easier, I've diverged from the normal way I do things in 3DWorld and represented cylinders as 36 sided polygons rather than actual mathematical cylinders. This allows me to work with N-sided polygons for all of the possible building shapes, including cubes. Another simplification is to skip buildings composed of intersecting shapes for now and only generate interiors for vertically stacked sections.

I've decided that I want to continue using X-Y axis aligned interior walls for now due to their simplicity. This means I can really only divide the interior up into 2 or 4 pie slices by adding an X oriented and/or Y oriented wall through the center of each building, depending on space. Most buildings are large enough for both walls. This makes rooms bounded on two sides by interior walls, with exterior walls on the remaining side(s). Each room is effectively a cube clipped to the building exterior shape. This allows me to reuse most of the existing room code with an additional outer polygon test for queries such as collision detection, point containment, cube overlap, etc. For example, objects can be placed in rooms like normal with an additional check that they're completely contained inside the building polygon. Since these polygons are always convex, it's sufficient to test that each vertex of the bounding cube of the room object is contained in the polygon.

The difficult part is implementing this for every query, in particular all of the collision and containment tests done for dynamic objects. This includes people inside buildings, balls, rats, spiders, snakes, flies, and, of course, the player. It's not enough to handle collisions with the exterior walls. All of the AI controllers for these must be aware of the valid building/room bounds and avoid walking into walls in the first place.

Here's an example of the interior of a cylindrical building divided into four equal sized rooms. The rooms are rather large. Maybe I should fill some of them with office cubicles?

Interior of a cylindrical building that's divided into four pie slice rooms, one with stairs.

You can see from this picture that I've added proper handling of stairs, ceiling lights, and even the wall trim along the edges of the floor. Stairs and elevators were particularly difficult for two reasons. First, they must be placed so that they don't intersect the exterior walls on either the floor above or below, and they also have enough space for people to enter them from each end without leaving the building. Second, I had to write the polygon clipping code that cuts a square hole for stairs and elevators into a circular ceiling and floor polygon. This was very math heavy and took me several hours to get right.

Some stacked building sections are probably too small to be practical and don't have enough space for both a wall and stairs. Here is an example of one such building. I'm not quite sure what to do with this one.

Interior of an oddly shaped, narrow, non-cube building with a single room containing stairs. This one is a cube with chamfered edges.

There's one other glaring issue: This type of building has no windows or exterior doors. Right now I only have support for axis aligned cube windows and doors. The way windows are cut into walls using constructive solid geometry (CSG) on cubes with the stencil buffer doesn't really apply to curved/angled wall sections. I have windows on the exterior textures, but not on the interiors. It looks a bit odd when the player is inside these windowless buildings, though it may matter less in gameplay mode when the player is looking for items and avoiding the zombies.

Doors are interactive as they can be opened and closed by the player, which makes them more difficult to model on non-cube buildings. I probably need to find a way to add doors to one side of at least the non-cylinder N-gon shapes. At the very least I can add them to the axis aligned edges of hexagons and octagons. I added the code for this as an experiment. The doors look fine from the outside of the building and work correctly for letting players in and out, but they don't have their door openings cut into the interior walls. This is because I haven't yet written a CSG subtraction of the door from the angled building sides. So the doors don't actually show the interior or exterior through them when open. This looks wrong, but I suppose it's better than having no doors at all.

Next, I assigned the interior room types to offices so that the larger rooms can be filled with cubicles.

Round office building room filled with cubicles, with indirect lighting enabled.

The cubicle placement algorithm is smart enough to only add cubicles that are fully contained in the room, and to leave paths on the sides of the cubicles and between the doors. I think this looks much better than mostly empty rooms with a single desk or table. Sometime in the future I might add different room objects that can be placed in this style of building.

Just for reference, here is what some of these buildings look like from the outside. You can see there are cylindrical/oval buildings, some with a number of sides at odd angles, and stacks of building parts.

Exterior of some non-cube shaped office buildings. Sorry, no cars or people in these screenshots.

 

Saturday, March 11, 2023

Procedural Buildings: Flies

I've made some new additions to 3DWorld's procedural buildings: bugs. No, not that type of bug! I'm not talking about software bugs, I'm talking about insects. Flies, in particular. I've already added walking animals (rats), animals that crawl on walls (spiders ... which technically aren't animals), and animals that slide on the floor (snakes). I'm missing something that flies. I do have butterflies flying around outdoors, but they're not inside buildings.

I initially drew flies as black spheres. This looked fine initially because they were so small, but when I added logic for them to fly around the player the simple sphere model broke down. So I started by copying and pasting the code to generate the geometry for spiders, since flies have a similar look. They're both black, have bodies that can be formed from transformed spheres, have multiple eyes, and have thin legs that can be made with cylinders and cones. The differences are minor. For example, flies have only six legs rather than eight. The biggest difference is that flies have wings, and it's the wings rather than the legs that are animated. Wing animation is a simple sine wave transition between horizontal and mostly vertical, similar to how I animated butterfly wings. Wings are small and partially transparent, though the alpha blending doesn't work very well due to a lack of proper depth sorting.

Flies will fly around randomly with smooth direction changes and will avoid colliding with walls and room objects. They follow zombies around when a target gets close to them. They'll also follow the player if a trashcan, toilet, urinal, or dead animal is picked up and stored in their inventory. (Note that the player can't actually carry a urinal.) They don't do any damage or have any other gameplay effect other than getting in the player's view, buzzing constantly, and generally being annoying. Here is what it looks like to be swarmed by flies:

Flies follow the player inside a house when the player picks up a trashcan.

I recorded a video of a swarm of flies following the player around. Aren't they annoying? I'm hoping they distract the player from watching and avoiding the zombies.

At this point I have all of the components in place for adding other insect and animal types to 3DWorld's buildings. I have support for walking on the floor, climbing walls and objects, and flying through rooms. It's fun to add new creatures!