Inlining

From The DarkMod Wiki
Jump to navigationJump to search

By Geep 2022, drawing on a 2014 thread by motorsep, SteveL, and Moonbo and more recently by stgatilov regarding TDM 2.10

Introduction

CAUTION: Inlining is generally not recommended. Drawbacks outweigh advantages.

The use case for inlining is quite limited. It can be applied only to a func_static object that uses a model instead of primitives. By marking that entity as inline, it gets treated as just a non-solid textured mesh.

Advantages are:

  • Primarily, to speed up game load time by precomputation of func_static model surfaces (vertices, meshes, and applied textures). That precomputation, stored in the PROC file, also includes provisioning stencil shadows and removal of the model's hidden surfaces.

Advantages at one time, but no longer:

  • To reduce the entity count, since it suppresses spawning of the func_static and replaces it with a surfaces-only subset. With TDM 2.10, reducing the entity count is no longer important.
  • As an arguably-reasonable technique to use with multiple cloned objects, e.g., grass clumps. Nowadays, SEED or other model-combining methods are preferred in TDM. (If you are targeting non-TDM engines with DR, inlining may be implemented differently and, in the absence of SEED, still be a viable choice.)
  • As a work-around to avoid clipping if scaling a model to more than 100%. Given the DR’s current model-scaling capabilities, this is no longer needed.

Drawbacks are:

  • It increases dmap time and the size of the PROC file, sometimes dramatically.
  • The model's surfaces are rendered in a fast but less visually appealing way. The less-refined algorithm may cause additional problems, increasing the chance of complicated geometric algorithms failing.
  • If you need solidity, you must provide it with a separate nodraw solid. The object’s collision model is ignored. Physics and particle effects won’t happen.

Invocation

Whenever you use DR's RMB "Create Model...", you get an object of class func_static, with the "model" spawnarg pointing to the model def. You will see "inline 0" among the spawnargs. Change it to:

inline 1

DMAP and PROC File Generation

During dmap, when generating the PROC file, what happens to a model-based func_static object?

  • Without inlining. The object is skipped. No precomputation and output to PROC is done for it.
  • With inlining. Dmap will treat it like worldspawn is treated in the PROC file, with the same format of precomputed information used for a brush or patch. (However, in the MAP file, it remains an entity, not worldspawn. An inline func_static cannot be used for sealing purposes.)

More specifically, the portion of the PROC file dedicated to worldspawn lists one or more volumetric "areas" (think: visleaves). Each area is concerned with what we will call here “contained objects”, namely worldspawn and inlined-func_static. An area holds a list of "surfaces" of contained objects, each named after a texturing material. A surface batches together all the contained objects that use that texture. Each surface include all primitive and inline-model triangular meshes, in the form of:

  1. Vertex descriptors (map location, UV texture coordinates, surface normal)
  2. Mesh triangles, defined by numeric indices to (1)

When an object is inlined, dmap will report it to the console as:

"inlining <name>\n"

Other Details

Inlining has specialized engine code, and will work only with classname "func_static", not objects inheriting from func_static (in spite of exposing the "inline" keyword for the latter).

The online help for the inline spawnarg states:

"If true, turns an FS model into map geometry at dmap time, saving entity count. The entity will be non-solid and inlining won't preserve texture blending on a single mesh so check your model looks ok in game before doing 100 of them."

InlineAllStatics

Also in the category of bad ideas overall, a global may be set on any worldspawn to inline all func_statics:

inlineAllStatics 1

The latter appears to be implemented differently than the individual "inline 1" flags. For each func_static, besides creating the surfaces-only subset, the full entity is also spawned but then immediately hidden to avoid duplicate renders. So the entity count is not reduced. But hiding does release resources associated with the rendered model and its lit surfaces.

See Also

  • For mass cloning, more recommended methods like SEED are discussed elsewhere.