CauldronGPU.StudioModel (CauldronGPU v0.3.3)

Copy Markdown View Source

A Half-Life studio model (Cauldron3D.Formats.Studio) uploaded for drawing: one skinned mesh in the model's rest pose, every vertex weighted wholly to its own bone, one mesh part per skin reference, and its textures.

{:ok, studio} = Cauldron3D.Formats.Studio.parse(File.read!("barney.mdl"))
studio = Cauldron3D.Formats.Studio.add_textures(studio, File.read!("barneyt.mdl"))
model = CauldronGPU.StudioModel.upload(gpu, studio)
materials = CauldronGPU.StudioModel.materials(gpu, model)
instance = CauldronGPU.StudioModel.instance(model, materials, CauldronGPU.Placement.transform(1 / 32, origin, 90))
CauldronGPU.submit(gpu, [{:instance, 3, instance}, CauldronGPU.StudioModel.pose(model, 3, "walk", 0.8)])

Vertices stay in the model's own units and axes (x forward, y left, z up); CauldronGPU.Placement.transform/3 stands a model at a map point. Sequences that move their motion bone along x, y or z have that movement taken out, so the model walks in place and the caller moves the instance.

Texture flags are followed as far as the renderer's materials go: masked (0x40) textures are cut out at colour 255, fullbright (0x04) ones are drawn unlit; chrome and additive textures are drawn as plain textures.

Summary

Functions

The bone matrices (3×4, row by row) posing the rest-pose mesh in sequence (a name, without regard to case, or an index; an unknown one is sequence 0) at time seconds into it, at the sequence's own frame rate. opts go to Studio.locals/4 (:controllers, :subblend and so on).

Every handle the model holds.

An instance of the model with materials at transform.

One material per mesh part for skin family :family (default 0; a family the model lacks is family 0). Options: :lightmap, a texture whose texel at lightmap coordinates {0, 0} lights the whole model, times :light_scale (default 2.0).

The {:pose, id, …} change for bones/4.

The sequence names, in order.

Uploads studio's textures and its mesh. Options: :bodies, a map from body part index to the model index drawn for it (default 0 for each part), and :filter, :linear (default) or :nearest. The textures must already be in studio (Studio.add_textures/2 for a model whose textures are in a separate file).

Types

t()

@type t() :: %CauldronGPU.StudioModel{
  mesh: CauldronGPU.Handle.t(),
  skin_refs: [non_neg_integer()],
  studio: Cauldron3D.Formats.Studio.t(),
  textures: tuple(),
  unbind: tuple()
}

Functions

bones(studio_model, sequence, time, opts \\ [])

@spec bones(t(), String.t() | non_neg_integer(), number(), keyword()) :: [
  CauldronGPU.Pose.matrix()
]

The bone matrices (3×4, row by row) posing the rest-pose mesh in sequence (a name, without regard to case, or an index; an unknown one is sequence 0) at time seconds into it, at the sequence's own frame rate. opts go to Studio.locals/4 (:controllers, :subblend and so on).

handles(studio_model)

@spec handles(t()) :: [CauldronGPU.Handle.t()]

Every handle the model holds.

instance(studio_model, materials, transform)

An instance of the model with materials at transform.

materials(gpu, model, opts \\ [])

@spec materials(CauldronGPU.Target.t(), t(), keyword()) :: [CauldronGPU.Handle.t()]

One material per mesh part for skin family :family (default 0; a family the model lacks is family 0). Options: :lightmap, a texture whose texel at lightmap coordinates {0, 0} lights the whole model, times :light_scale (default 2.0).

pose(model, id, sequence, time, opts \\ [])

The {:pose, id, …} change for bones/4.

sequences(studio_model)

@spec sequences(t()) :: [String.t()]

The sequence names, in order.

upload(gpu, studio, opts \\ [])

Uploads studio's textures and its mesh. Options: :bodies, a map from body part index to the model index drawn for it (default 0 for each part), and :filter, :linear (default) or :nearest. The textures must already be in studio (Studio.add_textures/2 for a model whose textures are in a separate file).