The Parts and Whole: Entity with Primitives
By Geep 2022
Introduction
The Dark Radiant Users Guide covers this topic succinctly; see particularly
- Converting Primitives into Func Static
- Adding or Removing Primitives
- Selecting Individual Child Primitives
Here, the same ground is covered with a bit more depth and slightly different focus.
In TDM, an entity is a namable item (with a non-zero entity number) that is either:
- Based on a 3D model (either explicitly referenced through a "model" spawnarg, or implicitly through a "classname")
- Based on one or more 3D primitives (brushes and patches)
- Functional only, not representing a map object
Here, we consider case (2).
Use Cases
Worldspawn versus Func_static with Primitives
If a brush is to be used for sealing – either against the void, or as part of a volume delineation within your map – then it must be left as worldspawn. Conversely, it is often desirable to convert non-sealing "decorative" worldspawn to func_static. This make it easy to use the top menu "Filter/All entities" to hide non-sealing items, when checking your map for leak problems. We explore the issue next of when primitives should be combined into a single func_static, as opposed to a set of individual func_statics.
Need for Entity Reduction before TDM 2.10
Traditionally, TDM had a limit on the total number of entities (8K, which had to include headspace for dynamically spawned objects) that would cause problems if exceeded. This was restrictive for large maps. So mappers would strive for fewer entities by combining compatible ones, particularly adjacent and architecturally-similar func_statics. (This was a balancing act. So, while you could sweep the crown molding of all your castle's rooms into a single func_static, that would impede your editing.) With TDM 2.10, the limit is now 64K, which is unlikely to ever be a concern. Consequently, new FMs will likely see fewer func_statics having a large numbers of primitives.
Remaining Important Use Cases
- A func_static whose contained brushes and patches serve as a model for a single object, e.g., a table or chair. Combining makes it easier to position in DR as a whole, and is an alternative to using DR Groups.
- A mover representing a multi-part object that in the game will move as a whole, e.g., fan blades with a common axis of rotation.
- Various volumes representing water, Objectives-triggering locations, SEED locations, etc.
Creation in DR
Let's assume you've created a set of primitives. When created, each is a worldspawn object (formally, part of Entity #0). Select all members of the set, then RMB, "Convert to func_static", which converts the set into a single object, that you can view in the Entity Inspector and rename as desired. (You can change other things, e.g., its classname from func_static to another, typically by using the Change Class... button.)
Selection of an Individual Primitive
Main reasons to select an individual primitive are to:
- Resize/reshape it
- Move it relative to the entity as a whole
Even if the Entity just has a single primitive, you still have to select that primitive (e.g., tab to it) if you want to, say, resize it.
Note: When any individual Primitive is selected, if you open the Entity Inspector, it still shows information for the entity as a whole.
Select by Cycling to It
When you first select an entity, you are selecting it as a whole. But you can cycle through its individual primitives, then eventually back to the whole. Default key bindings are:
Tab for "Group Cycle Forward" Shift+Tab** for "Group Cycle Backward"
**Formally, ISO_Left_Tab
For cycling to work, begin from a state where nothing is selected, then select the object alone. The order in the cycle reflects the creation order of the primitives, and is not easily changed (i.e., involves hand-editing the .map file).
Select Directly
In the top toolbar, find the "Select Group Parts" button (which looks like a Rubik's Cube with a red corner tile). Toggle this on. Then Shift-LMB will let you select one or more primitives. Be sure to toggle "Select Group Parts" off when done.
Details
- Toggling on "Select Group Parts" will
- Clear any existing primitive components selection.
- For any existing selected whole-object(s), treat all components as if individually selected
- When using Shift-LMB to select primitive components:
- They can be within multiple objects
- Shift-LMB is a toggle, to select/deselect a component.
- Toggling off "Select Group Parts" will not change any selected items
Deleting an Individual Primitive
With an Individual primitive selected, just hit Backspace if you want to get rid of it entirely. If you want to retain it in the map instead (as a separate worldspawn), choose "Edit/Reparent primitives to worldspawn".
Adding a New Primitive
Select the entity and any primitives you wish to add to it. Then choose "Edit/Reparent primitives".
Dismembering an Entity: Reverting to Worldspawn
Select the entity, then either:
- RMB and choose "Revert to worldspawn"
- From top menu, use "Entity/Revert group to worldspawn"
- Shift-G (if default key binding)
All primitives become "unparented", i.e., individual worldspawn items. Caution: any entity info, such as spawnargs you set, will be lost.
Retexturing an Entire Entity, or All Surfaces of Particular Components
As you might expect, just select the entire entity or the components of interest. (You can select multiple entities and/or components across multiple entities.) Then, In the Texture Browser
- If the texture already is present (in the pane of the default Textures tab), LMB on it
- Otherwise, under the Media tab, find the texture of interest, RMB on its name in the main pane, and chose "Apply to Selection"
Retexturing a Primitive's Particular Surface
By Middle Mouse Button Copy-Paste
As with a worldspawn or a simple func_static object, you can:
- with no object or object component selected, click on a source surface with MMB; then
- click on a recipient surface with Ctrl-MMB (or for natural/curved surface: Shift-MMB).
By Blue-Dot Surface Choice and Texture Browser
CAUTION: To avoid unwanted retexturing, first make sure no object, or object component, is selected. If there is a selection, then retexturing will be applied to all surfaces of the selected object, in addition to the blue-dot surface(s).
- Click on one or more recipient surfaces with Ctrl-Shift-LMB
- In the Texture Browser
- If the texture already is present (in the pane of the default Textures tab), LMB on it
- Otherwise, under the Media tab, find the texture of interest, RMB on its name in the main pane, and chose "Apply to Selection"
Implementation of Entity with Primitives
If you open the .map file in a text editor, you will see that entities are listed in numerical order. Except for Entity #0 (which is worldspawn), the entity numbers are arbitrary and not fixed over time. Skip past the usually-extensive Entity #0. Also ignore those that don't have any "// primitive <number>" content; these are typically model-based entities under a dozen lines long. Entities with primitives are rather long, because each primitive must have an embedded description.
For more, see the Doom 3/idTech4 info about the map file format