Making a *.map based Level in Blender: adding curves to the level (pt3)
In previous chapters we've learnt about the basics of building a .map based level in Blender. This included how to set up the grid, getting to grips with the 'building blocks' principle and then using that information to make a simple two room level through the duplication and reuse of some basic prefabricated shapes.
Although we do have a level that could be exported we'll hold off on that for now so that we can add a feature common to most types of level, a 'curve'.
Curves and making levels ^
There are two ways we can add 'valid' curves to a .map; 1) using Bezier curves or 2) standard mesh objects. If done correctly both techniques produce objects that are generally indistinguishable from each other in game. Having said that however, both approaches do have their associated caveats that are important to understand. Bezier curves for instance are; 1) not fully supported by all level editors or games based on the .map format; 2) they can only be edited or changed relative to their basic size/shape, i.e. they cannot be sliced or cut in any way (holes can't be cut into them); 3) they can be problematic to texture; 4) when used with more than a reasonable amount of frequency, their presence tends to cause performance issues.
Brushes (mesh objects) on the other hand tend to; 1) look slightly faceted when used to make curvatures of low frequency (number of subdivisions); 2) can produce faceted lighting due to each surface being treated as an individual element and 3) are slightly more time consuming to make. However, they can be 1) cut into any shape; 2) use far less resources; 3) are fully supported by all .map editors and games (due to their being standard brush volumes) and 4) are easier to manage and texture alongside other surfaces. What this means in practice is that when wanting to add curves to a level, the better approach is to use mesh objects because it guarantees broader compatibility.
Adding curves, making an arch from a tube ^
The inherent 'abstract' or 'non-axial' nature of curved surfaces means that few of their edges align to the grid, this is especially true of the internal subdivision within a curve - the more there are, the less likely they are to be properly positioned. This 'floating' alignment is a problem for .map based level design and typically requires meshes be edited to fit. Curves are no exception. With this in mind we'll add a cylinder to the scene, 'convert' that to a tube and then go on to make an arched corridor.
To make the following easier to do first switch to "Front" orthogonal view, "numPad5" then "numPad1". Next centre the cursor on the grid using "View Properties" ("N") - set the "3D Cursor Location:" options to "0.0000" for each of the "X", "Y" and "Z" coordinates. Once done press "Shift+A" to open the "Add" menu and select "Mesh » Cylinder" from the list, a (relatively) small 32 sided cylinder will appear centred on the cursor, accompanied by a set of "Add Cylinder" object properties in the ToolShelf (on the left - press "T" if not visible). Change "Vertices" to "16", "Radius" to "8", activate "Align to View" and deactivate "Cap Ends". This will produce an open ended cylinder (the ends facing the viewer) which can now be convert in to a 'tube'.
Design note: immediately after adding the cylinder primitive it's properties are also accessible by pressing "F6". Note that "Radius:" is a multiplication of grid "Scale:" 'units' and not actual 'units of measurement', "Radius:8" is actually 8 'radius' x 8 'scale' units; with each 'scale' unit containing 8 'real' units, that's a total or 64 real units.
Changing the cylinders settings to make it more appropriate from making an arch that will be converted into brushwork later. Set "Vertices: 16", "Radius: 8" (units), note that activating "Align to View" rotates the mesh so be sure to be in one of the flat Orthogonal views (front/right/top) [see *.blend "19"]
Solidify modifier ^
With the cylinders properties set it now needs to be converted into a 'tube' using the "Solidify" modifier. Make sure the object is selected in "Object" mode (select all when in "Edit" mode) and then click the 'wrench/spanner' icon in "Properties" to access the "Modifiers" panel. From here click the "Add Modifier" drop-down and select "Solidify" from the list, a set of parameters will appear. The two main settings we need to pay attention to are "Thickness:" and "Offset:". Change "Thickness:" to "24" or above, and "Offset:-1.0000" to "Offset:1.0000" (remove the "-"), changing the value to a 'positive' number results in an 'extrude' with an 'outward' rather than 'inward' facing direction. Click "Apply" to make the changes 'real'. This turns the cylinder in to a tube that can now be edited to make the arch.
Design note: when assigned in "Edit" mode, "Solidify" uses a 'ghost' image to represent the resulting effects changing various settings and options have on the mesh. It's not until exiting and switching back to "Object" mode that the modifier can be applied and made 'real'.
To turn the cylinder into a tube add a "Solidify" Modifier to the selected object...
... then change the defaults settings; give "Thickness: [n]" an appropriate value so it can be edited later; change "Offset: +/-" to a 'positive' value so the extrude is 'outward' orientated; click "Apply" to 'set' the changes and fully convert the original cylinder into a 'tube' [see *.blend "20, 21 & 22"]
Making half an arch ^
With the tubes basic parameters set, in Edit mode use "B" to "Border" or "C" to "Circle" select the top right quarter of the tube (switch to "Wire" view by pressing "Z" or deactivate "Limit Selection to Visible" to make sure selection 'drills-down' through the mesh, front and back). Duplicate the section with "Shift+D" and then press "P" to open the "Separate" menu, choose "Selection". This will detach the element into a completely new and independent object whilst keeping the original in the background; we can use this as a guide when editing the new section to make sure the eventual curve is 'smooth' relative to grid snapping.
With the tube made, in Edit mode, press "P" to detach a quarter section to a separate object, the arch is to be formed from this section, and then "Ctrl+Tab" to switch to "Vertex" select mode. Alternatively make the selection, "Shift+D" to duplicate and then detach [see *.blend "23"]
Select the new object and enter 'Edit' mode (remember, the new quarter section is a completely separate object so we need to make sure we exit 'Edit' mode for any actively selected objects - the tube - before we can do that). Next using a combination of "B" or "C" to border or circle select, drill-down through the mesh selecting vertices front and back along the outer edge of the curve and position them roughly ("G") to form the basis of what appears to be the corner of a box. Once the shape has been blocked out, use the "Location:" subsection of "View Properties" ("N") to alter their "X", "Y", and "Z" coordinates or each vertex more precisely, properly locating each vertex on the grid.
Design note: using "Ctrl"to move vertices helps to an extent but, because of the way a cylindrical shape is formed it often means vertices are not readily aligned in a useful way for .map based level design, hence the two step process above to correct this.
We can then use the same two-part process - rough placement and precise XYZ coordinates - to position vertices along the inner edge, using the original tube as a guide. The end result will be something similar to the image below, a 'corner' piece with a "concave" inner structure.
The point to keep in mind when shaping curves like this is that the position of each vertex should be 'grid snapped' and "axial" in nature. In practice this means locating individual vertices so that their XYZ coordinates use whole numbers; as with other aspects of making .map based levels, we have to ensure that positional data is 'valid' relative to the expectations of the format, i.e. "non-axial" or off-grid alignments are problematic so should be avoided.
Design note: generally speaking so long as the positional values are whole numbers this is all that's needed, removing 'decimal' or 'floating point' references is therefore important to keep an eye on - the .map format can't use "64.4561" properly so it should be changed (rounded 'up' or 'down' depending on the number) to "64.0000" (the nearest 'whole' number).
Manually edit the position of vertices from the separated section so they use "XYZ" coordinates that use 'whole' numbers, this is important to do to stop the eventual brushwork from collapsing or cause grid snapping issues in the level editor [see *.blend "24"]
Duplicate & mirror arch ^
Making the 'full' arch is now simply a matter of duplicating and mirroring the original section. First we need to check the cursor is correctly positioned at the centre of the mesh, which will be the pivot point for mirroring. This can be done in two ways, 1) we can use the objects "Point of Origin" (the small pink dot that appears when an object is selected) - if the origin point is still where it was originally, at the centre of what was the cylinder, then simply press "Shift+S" to open the "Snap" menu, choose "Cursor to Selected" from the list ("Object » Snap » Cursor to Selected"). The cursor will 'snap' to the objects centre. Or 2) we can manually position the cursor - using the "3D Cursor Location:" subsection of "View Properties" ("N"), set the "X", "Y" and "Z" parameters so the cursor repositions itself correctly and sits at the centre of what would be the cylinders centre-point. The latter can be done independently of the origins location.
With the rotational point set, select the mesh and use "Shift+D" duplicate it. Whilst still active press "Ctrl+M" to initiate "Mirror", then "X" or "Y" (depending or the scenes original orientation) to flip the object to the opposite side of the parent half of the arch (the original section). This should result in a full arch (shown below).
Design note: the arch could also be a linked duplication by using "Alt+D", only one side need be edited for those changes to propagate across.
Once the vertices are positioned, "Shift+D" to duplicate and mirror ("Ctrl+M" then "X", "Y" or "Z" to flip depending on orientation) the mesh to create a full archway [see *.blend "25"]
The completed (but not finished) arch in place in the short corridor passage showing the two halves of the arch in place [see *.blend "26"]
Mesh optimisation ^
The level now has an arched passage. However, there is a problem. As with other aspects of making a level in Blender, we need ensure mesh objects conform to the expectations of the .map format. In practice this means objects and/or structures cannot have, or be shaped with, any sort of inward facing curvature; if objects are "concave" (or "convex" for that matter) they will usually (ideally) need to be broken down into a series of individual sub-objects that are 'valid' structures in their own right. As the arch is a concave shape, it needs to be properly 'optimised'.
Select the arch and enter Edit mode. In "Wire" or "Limit Selection to Visible" mode, "Border Select" ("B") or "Circle Select" ("C") a group of faces, vertices or edges (depending on which "Ctrl+Tab" selection mode is being used) so they form a single sub-element of the mesh (shown below). Press "P" to open the "Separate" menu and choose "Selection" from the list ("Mesh » Vertices » Separate"). This will detach the sub-group into a completely independent object. Repeat this for each section, creating four sub-objects in total.
Design note: press "Z" to toggle "Wire" mode to make drill-down selections easier to do on both sides of the mesh.
Complex shapes, like the arch being made or other curved structures, must be broken apart into a series of sub-objects for proper export. When rearranging vertices to form a shape, this needs to be taken into account so the end result is a set of 'clean' "convex" and well aligned meshes
Once the elements have been detached they need to be 'closed', i.e. any open gaps in the mesh need to be filled. The easiest way to do this is to change "Select Mode" to "Edge" using "Ctrl+Tab" (whilst in Edit mode), then either "Alt+RMB" to "Loop Select" or "Shift+RMB" to individually select, edges around a gap. Once done press "F" to "Fill" the opening, sealing the mesh. This needs to be done for each sub-object of the arch so they all end up as closed and otherwise 'solid' meshes.
After separating mesh sections the open faces need to be filled and the mesh 'closed' before they can be properly used [see *.blend "27"]
Optimising and object overlap ^
Because we need to make sure objects are solid primitives, typically six-sided shapes, it often means we inadvertently cause a secondary issue when using Blender to make .map based levels, overlap. Exactly how we deal with this depends on whether the eventual exported brushes are to be flagged as 'detail' or 'structural' volumes in the level editor - "detail" brushes don't effect other volumes, so unless they intersect "structural" elements which do, the result is usually two or more surfaces 'flickering' on-screen as they fight to be displayed. This is called "z-fighting".
To fix this problem using Blender we need to adjust the placement of objects relative to each other to remove or at least reduce the problem. For example, because the arch overlaps the side wall we need to alter the width of that object (the wall section) so the outer edge butts up to the 'back' of the arch. This creates a gap that can then be filled by another object resized and shaped to fit.
Design note: another reason for building levels 'grid snapped' is to ensure when we need to do things like this that all surfaces snap together properly; we need to be careful not to have or create gaps in the eventual brushwork as they could potentially 'leak' the level when compiled.
Because of the way the arch is made, putting it into position results in overlap of another object. This should be fixed by adjusting how the various elements interact with each other...
... which typically means using more than one object shaped to fit around the arch; if this isn't done and overlap is left in place it often causes "z-fighting" in game (amongst other issues). This should be done for both halves of the arch where overlap occurs [see *.blend "28"]
The completed arch after "Shift+D" duplication and being mirrored along a central axis - note the top ceiling block is no longer necessary so can be removed [see *.blend "29"]
The same technique used to make the arch can also be used to make corner walls - use larger radius settings and increased number of side depending on the size of the curve and 'smoothness' required [see *.blend "30"]
For broader compatibility then, curved surfaces should be composed of suitably shaped and positioned mesh groups. These eventual brush volumes then ensure that entire levels with complex architectural structures can be imported or converted into other editors without too many issues. Next, with the level now built we can move on to applying textures.