.. _stdlib_gltf_types: ========================================================================================================================================= glTF 2.0 loader (dasGLTF): GLB/.gltf parse, accessor decode, node hierarchy, skinning and keyframe animation into a backend-neutral scene ========================================================================================================================================= .. das:module:: gltf_types dasGLTF loads `glTF 2.0 `_ models — ``.glb`` (binary), ``.gltf`` (JSON), external or base64-embedded buffers — into a **backend-neutral scene**, with no new native code (it builds on ``json_boost``, ``base64``, ``fio``, ``stbimage`` and ``math``). The backend-neutral core parses, decodes accessors, builds the node hierarchy, and evaluates skinning and keyframe animation with **no OpenGL or Vulkan dependency** — usable headless for tooling or a future renderer. Require it with: .. code-block:: das require gltf/gltf_boost An opt-in OpenGL adapter (``gltf/gltf_gl`` + ``gltf/gltf_pbr``, requiring ``dasOpenGL`` / ``dasGlsl``) maps a loaded scene to GL buffers and renders it with a Cook-Torrance metallic-roughness PBR shader; it is documented with the OpenGL examples, not here. The scene model ^^^^^^^^^^^^^^^ :ref:`load_gltf ` returns a :ref:`GltfScene `, which aggregates the meshes, materials, textures, images, samplers, nodes, skins and animations of the default scene. Geometry is decoded to a fixed :ref:`GltfVertex ` layout (position, normal, tangent, two UV sets, color, and joints/weights decoded to ``float4``), so interleaved, normalized and integer-lane attributes need no downstream handling. .. code-block:: das require gltf/gltf_boost var scene <- load_gltf("model.glb") update_world_transforms(scene) // fill GltfNode.world from the hierarchy let (mn, mx) = gltf_scene_bounds(scene) // world-space AABB for auto-framing Animation and skinning ^^^^^^^^^^^^^^^^^^^^^^ :ref:`evaluate_animation ` samples one animation at a time ``t`` (STEP / LINEAR / CUBICSPLINE), writes the result into each target node's TRS, and refreshes the world transforms. :ref:`gltf_joint_matrix ` returns the per-joint skinning matrix (``jointNode.world * inverseBind[j]``) that deforms skinned geometry. Morph targets and saving/export are out of scope. ++++++++++++ Enumerations ++++++++++++ .. _enum-gltf_types-GltfAlphaMode: .. das:attribute:: GltfAlphaMode enum GltfAlphaMode .. _enum-gltf_types-GltfInterp: .. das:attribute:: GltfInterp enum GltfInterp .. _enum-gltf_types-GltfPath: .. das:attribute:: GltfPath enum GltfPath .. _enum-gltf_types-GltfPrimitiveMode: .. das:attribute:: GltfPrimitiveMode enum GltfPrimitiveMode ++++++++++ Structures ++++++++++ .. _struct-gltf_types-GltfVertex: .. das:attribute:: GltfVertex struct GltfVertex .. _struct-gltf_types-GltfPrimitive: .. das:attribute:: GltfPrimitive struct GltfPrimitive .. _struct-gltf_types-GltfMesh: .. das:attribute:: GltfMesh struct GltfMesh .. _struct-gltf_types-GltfMaterial: .. das:attribute:: GltfMaterial struct GltfMaterial .. _struct-gltf_types-GltfImage: .. das:attribute:: GltfImage struct GltfImage .. _struct-gltf_types-GltfSampler: .. das:attribute:: GltfSampler struct GltfSampler .. _struct-gltf_types-GltfTexture: .. das:attribute:: GltfTexture struct GltfTexture .. _struct-gltf_types-GltfNode: .. das:attribute:: GltfNode struct GltfNode .. _struct-gltf_types-GltfSkin: .. das:attribute:: GltfSkin struct GltfSkin .. _struct-gltf_types-GltfAnimSampler: .. das:attribute:: GltfAnimSampler struct GltfAnimSampler .. _struct-gltf_types-GltfAnimChannel: .. das:attribute:: GltfAnimChannel struct GltfAnimChannel .. _struct-gltf_types-GltfAnimation: .. das:attribute:: GltfAnimation struct GltfAnimation .. _struct-gltf_types-GltfScene: .. das:attribute:: GltfScene struct GltfScene +++++++ Loading +++++++ * :ref:`load_gltf (path: string) : GltfScene ` * :ref:`load_gltf_from_memory (bytes: array\; baseDir: string = "") : GltfScene ` .. _function-gltf_parse_load_gltf_string: .. das:function:: load_gltf(path: string) : GltfScene Load a glTF 2.0 file (.gltf, .glb, or base64-embedded .gltf) into a backend-agnostic `GltfScene`. Returns an empty scene on failure. :Arguments: * **path** : string .. _function-gltf_parse_load_gltf_from_memory_array_ls_uint8_gr__string: .. das:function:: load_gltf_from_memory(bytes: array; baseDir: string = "") : GltfScene Load a glTF 2.0 document (.gltf JSON, .glb binary, or base64-embedded .gltf) from an in-memory byte buffer. `baseDir` resolves external buffer/image URIs (pass "" for a self-contained .glb). Returns an empty scene on failure. :Arguments: * **bytes** : array * **baseDir** : string +++++++++++++++++++++++++++++ Scene, skinning and animation +++++++++++++++++++++++++++++ * :ref:`evaluate_animation (var scene: GltfScene; animation: int; t: float) ` * :ref:`gltf_joint_matrix (scene: GltfScene; skinIndex: int; j: int) : float4x4 ` * :ref:`gltf_scene_bounds (scene: GltfScene) : tuple\ ` * :ref:`update_world_transforms (var scene: GltfScene) ` .. _function-gltf_scene_evaluate_animation_GltfScene_int_float: .. das:function:: evaluate_animation(scene: GltfScene; animation: int; t: float) Evaluate animation `animation` at time `t` (seconds): sample each channel and write the result into its target node's TRS, then recompose those nodes' local matrices and refresh every world transform. Nodes given by an explicit `matrix` are never animation targets (glTF forbids it), so only touched (hence TRS-defined) nodes are recomposed — matrix-defined nodes keep their parsed local. :Arguments: * **scene** : :ref:`GltfScene ` * **animation** : int * **t** : float .. _function-gltf_scene_gltf_joint_matrix_GltfScene_int_int: .. das:function:: gltf_joint_matrix(scene: GltfScene; skinIndex: int; j: int) : float4x4 Skinning matrix for joint slot `j` of skin `skinIndex`: jointNode.world * inverseBind[j]. This is the palette the GPU multiplies each skinned vertex by; the mesh node's own transform is intentionally omitted (glTF renders skinned geometry directly in skin space). Returns identity for an invalid index. :Arguments: * **scene** : :ref:`GltfScene ` * **skinIndex** : int * **j** : int .. _function-gltf_scene_gltf_scene_bounds_GltfScene: .. das:function:: gltf_scene_bounds(scene: GltfScene) : tuple World-space axis-aligned bounds (min, max) over every mesh vertex, using each node's `world` transform. Returns (0, 0) for a scene with no drawable vertices. Handy for auto-framing a camera. :Arguments: * **scene** : :ref:`GltfScene ` .. _function-gltf_scene_update_world_transforms_GltfScene: .. das:function:: update_world_transforms(scene: GltfScene) Recompute every node's `world` transform by walking the hierarchy from the scene roots (world = parent.world * local). :Arguments: * **scene** : :ref:`GltfScene ` +++++++++++++++++++++ Accessor byte readers +++++++++++++++++++++ * :ref:`gltf_comp_size (compType: int) : int64 ` * :ref:`gltf_rd_f32 (b: array\|array\#; o: int64) : float ` * :ref:`gltf_rd_i16 (b: array\|array\#; o: int64) : int ` * :ref:`gltf_rd_i8 (b: array\|array\#; o: int64) : int ` * :ref:`gltf_rd_u16 (b: array\|array\#; o: int64) : uint ` * :ref:`gltf_rd_u32 (b: array\|array\#; o: int64) : uint ` * :ref:`gltf_rd_u8 (b: array\|array\#; o: int64) : uint ` * :ref:`gltf_read_comp_float (b: array\|array\#; o: int64; compType: int; normalized: bool) : float ` * :ref:`gltf_read_comp_uint (b: array\|array\#; o: int64; compType: int) : uint ` * :ref:`gltf_type_ncomp (t: string) : int ` .. _function-gltf_accessor_gltf_comp_size_int: .. das:function:: gltf_comp_size(compType: int) : int64 Byte size of one accessor component for the given glTF componentType. :Arguments: * **compType** : int .. _function-gltf_accessor_gltf_rd_f32_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64: .. das:function:: gltf_rd_f32(b: array|array#; o: int64) : float def gltf_rd_f32 (b: array|array#; o: int64) : float :Arguments: * **b** : option\ | array\ #> * **o** : int64 .. _function-gltf_accessor_gltf_rd_i16_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64: .. das:function:: gltf_rd_i16(b: array|array#; o: int64) : int def gltf_rd_i16 (b: array|array#; o: int64) : int :Arguments: * **b** : option\ | array\ #> * **o** : int64 .. _function-gltf_accessor_gltf_rd_i8_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64: .. das:function:: gltf_rd_i8(b: array|array#; o: int64) : int def gltf_rd_i8 (b: array|array#; o: int64) : int :Arguments: * **b** : option\ | array\ #> * **o** : int64 .. _function-gltf_accessor_gltf_rd_u16_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64: .. das:function:: gltf_rd_u16(b: array|array#; o: int64) : uint def gltf_rd_u16 (b: array|array#; o: int64) : uint :Arguments: * **b** : option\ | array\ #> * **o** : int64 .. _function-gltf_accessor_gltf_rd_u32_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64: .. das:function:: gltf_rd_u32(b: array|array#; o: int64) : uint def gltf_rd_u32 (b: array|array#; o: int64) : uint :Arguments: * **b** : option\ | array\ #> * **o** : int64 .. _function-gltf_accessor_gltf_rd_u8_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64: .. das:function:: gltf_rd_u8(b: array|array#; o: int64) : uint def gltf_rd_u8 (b: array|array#; o: int64) : uint :Arguments: * **b** : option\ | array\ #> * **o** : int64 .. _function-gltf_accessor_gltf_read_comp_float_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64_int_bool: .. das:function:: gltf_read_comp_float(b: array|array#; o: int64; compType: int; normalized: bool) : float Read one component at byte offset `o` as float, applying glTF `normalized` integer→float conversion (unsigned: /max; signed: max(v/max, -1)). :Arguments: * **b** : option\ | array\ #> * **o** : int64 * **compType** : int * **normalized** : bool .. _function-gltf_accessor_gltf_read_comp_uint_array_ls_uint8_gr_array_ls_uint8_gr__hh__int64_int: .. das:function:: gltf_read_comp_uint(b: array|array#; o: int64; compType: int) : uint Read one component at byte offset `o` as uint (index accessors: u8/u16/u32). :Arguments: * **b** : option\ | array\ #> * **o** : int64 * **compType** : int .. _function-gltf_accessor_gltf_type_ncomp_string: .. das:function:: gltf_type_ncomp(t: string) : int Number of components for a glTF accessor `type` string (SCALAR/VECn/MATn). :Arguments: * **t** : string