Model¶
Inherits: Mesh
C++ type: Model
Description¶
Loads and displays 3D model files in a scene. Model extends Mesh and adds support for loading OBJ and GLTF files (including binary GLB), including skeletal animation (via Animation / Bone), blend-shape morph targets, and PBR materials.
A single GLTF file can contain multiple meshes, materials, textures, skeletons, and animations; Doriax imports all of them into the scene hierarchy and makes each accessible through the API. Use getAnimation() and getBone() to drive skeletal playback, and setMorphWeight() to control blend shapes.
For static multi-node GLTFs that need GPU instancing on the root entity, set ModelComponent::mergeStaticMeshes (or use Merge static model in the editor) so child transforms bake into the root mesh instead of creating child mesh entities. See 3D Graphics — Merging static model meshes.
Methods¶
| Type | Name | Langs |
|---|---|---|
| bool | loadModel | C++ | Lua |
| bool | loadOBJ | C++ | Lua |
| bool | loadGLTF | C++ | Lua |
| Animation | getAnimation | C++ | Lua |
| Animation | findAnimation | C++ | Lua |
| void | playAnimation | C++ | Lua |
| void | stopAnimations | C++ | Lua |
| Bone | getBone | C++ | Lua |
| float | getMorphWeight | C++ | Lua |
| void | setMorphWeight | C++ | Lua |
| void | resetToBindPose | C++ | Lua |
GLTF import support and limits¶
| Feature | Import behaviour |
|---|---|
| Skinning | Up to 128 joints per skin. A GLTF skin above this limit is rejected and the loader writes an error to the log. |
| Position-only morph targets | Up to 8 targets per mesh primitive. |
| Position + normal or position + tangent morph targets | Up to 4 targets per mesh primitive. |
| Position + normal + tangent morph targets | Up to 2 targets per mesh primitive. |
| Sparse morph accessors | Supported. The loader expands sparse target data into a dense GPU buffer, including accessors that omit the optional base bufferView and therefore start from zeroes. |
The morph limit is derived from the leading target prefix that the loader actually binds. Extra trailing targets are ignored; semantics that appear only after that loaded prefix do not reduce its shader capacity. Keep the same morph semantics on every target when exporting from a DCC tool for predictable results.
Imported PBR materials also preserve GLTF OPAQUE, MASK, and BLEND alpha modes and
the alphaCutoff value used by masked materials. See Material.
Method details¶
loadModel¶
- bool loadModel(const std::string& filename)
Loads a 3D model file from disk. Doriax automatically detects the format based on file extension:
.obj— Wavefront OBJ.gltf/.glb— GL Transmission Format (GLTF 2.0 / binary GLB)
Returns true on success. On failure, check the log for details.
loadOBJ / loadGLTF¶
- bool loadOBJ(const std::string& filename)
- bool loadGLTF(const std::string& filename)
Format-specific loaders. Use these when you want to be explicit about the format, or when the file extension is non-standard. loadGLTF() accepts both text .gltf and binary .glb files.
getAnimation / findAnimation¶
Retrieve a skeletal or morph-target animation embedded in the loaded model.
getAnimation() accesses by zero-based index; findAnimation() searches the animation
entity name. GLTF import initializes that entity name from the clip name exported by the
DCC tool, and an unnamed imported clip receives a generated name such as "Animation 0".
Both methods return an Animation object that can be started, stopped, and
configured for looping.
Renaming an animation entity changes the string accepted by findAnimation() and the
named playAnimation() overloads. The
AnimationComponent itself has no separate name property.
playAnimation / stopAnimations¶
- void playAnimation(int index)
- void playAnimation(int index, float fadeTime)
- void playAnimation(const std::string& name)
- void playAnimation(const std::string& name, float fadeTime)
- void stopAnimations(float fadeTime)
Switch the model's active clip with a smooth crossfade instead of an instant pose snap. playAnimation() fades out every other running clip on this model and fades the requested one in over fadeTime seconds; stopAnimations() fades all running clips out.
This is the recommended way to change animation state at runtime (idle → run → jump → die). During the fade both clips play and their poses are blended by weight, so the character eases between motions rather than popping. When fadeTime is omitted, the target clip's authored defaultFadeTime is used (set per-clip as AnimationComponent → Fade time). A fadeTime of 0 switches instantly.
Unlike getAnimation(), which returns a handle you start yourself, playAnimation() manages the transition for you. Set looping on the clips you intend to hold (idle, run) via Animation::loop.
Model hero(&scene);
hero.loadModel("characters/hero.glb");
// Make locomotion clips loop, then start on idle
hero.findAnimation("Idle").setLoop(true);
hero.findAnimation("Run").setLoop(true);
hero.playAnimation("Idle"); // uses each clip's Fade time
// Later, on input:
hero.playAnimation("Run", 0.2f); // crossfade to run over 0.2s
hero.playAnimation("Die", 0.1f); // snappy transition into a one-shot
local hero = Model(scene)
hero:loadModel("characters/hero.glb")
hero:findAnimation("Idle").loop = true
hero:findAnimation("Run").loop = true
hero:playAnimation("Idle") -- uses each clip's Fade time
-- Later, on input:
hero:playAnimation("Run", 0.2) -- crossfade to run over 0.2s
hero:playAnimation("Die", 0.1) -- snappy transition into a one-shot
Crossfades assume full-skeleton clips
The blend is a weight-normalized average per bone, so it looks best when both clips animate the whole skeleton (the usual case for GLTF character clips). A bone animated by only the outgoing clip holds its pose until that clip finishes fading rather than easing.
getBone¶
Returns a Bone handle by name or by index. A Bone inherits Object so you can read and write its local transform to override the skeleton. For example, you can aim a character's head bone toward a target while the rest of the body plays a walk cycle.
getMorphWeight / setMorphWeight¶
- float getMorphWeight(const std::string& name)
- float getMorphWeight(int id)
- void setMorphWeight(const std::string& name, float value)
- void setMorphWeight(int id, float value)
Read or write the weight of a blend-shape morph target. Weights range from 0.0 (no influence) to 1.0 (full influence). Multiple morphs can be active simultaneously. Access by exported name or by zero-based index.
resetToBindPose¶
- void resetToBindPose()
Resets all bones back to the bind pose defined in the model file, clearing any programmatic or animation-driven overrides. Useful when switching between animations or when stopping all playback.