Skip to content

Instantly share code, notes, and snippets.

@exelotl
Created November 16, 2019 17:22
Show Gist options
  • Save exelotl/3cf6c15e4ac2c93f2274c48352808c1b to your computer and use it in GitHub Desktop.
Save exelotl/3cf6c15e4ac2c93f2274c48352808c1b to your computer and use it in GitHub Desktop.
Nim bindings for cgltf - a single-file glTF 2.0 parser written in C99
# Nim bindings for cgltf - a single-file glTF 2.0 parser written in C99.
# Version: 1.3
# Website: https://github.com/jkuhlmann/cgltf
# See cgltf.h for license information
type
FileType* {.size: sizeof(cint), pure.} = enum
invalid
gltf
glb
GltfOptions* {.importc: "cgltf_options", header: "cgltf.h", bycopy.} = object
## This struct is passed to `parse()` to control parts of the parsing process.
## You can use it to force the file type and provide memory allocation callbacks.
## Should be zero-initialized to trigger default behavior.
fileType* {.importc: "type".}: FileType ## invalid == auto detect
jsonTokenCount* {.importc: "json_token_count".}: csize ## 0 == auto
memoryAlloc* {.importc: "memory_alloc".}: proc (user: pointer; size: csize): pointer
memoryFree* {.importc: "memory_free".}: proc (user: pointer; `ptr`: pointer)
memoryUserData* {.importc: "memory_user_data".}: pointer
GltfResult* {.size: sizeof(cint), pure.} = enum
success
dataTooShort
unknownFormat
invalidJson
invalidGltf
invalidOptions
fileNotFound
ioError
outOfMemory
BufferViewType* {.size: sizeof(cint), pure.} = enum
invalid
indices
vertices
AttributeType* {.size: sizeof(cint), pure.} = enum
invalid
position
normal
tangent
texcoord
color
joints
weights
ComponentType* {.size: sizeof(cint), pure.} = enum
invalid
r8 ## BYTE
r8u ## UNSIGNED_BYTE
r16 ## SHORT
r16u ## UNSIGNED_SHORT
r32u ## UNSIGNED_INT
r32f ## FLOAT
Type* {.size: sizeof(cint), pure.} = enum
invalid
scalar
vec2
vec3
vec4
mat2
mat3
mat4
PrimitiveType* {.size: sizeof(cint), pure.} = enum
points
lines
lineLoop
lineStrip
triangles
triangleStrip
triangleFan
AlphaMode* {.size: sizeof(cint), pure.} = enum
opaque
mask
blend
AnimationPathType* {.size: sizeof(cint), pure.} = enum
invalid
translation
rotation
scale
weights
InterpolationType* {.size: sizeof(cint), pure.} = enum
linear
step
cubicSpline
CameraType* {.size: sizeof(cint), pure.} = enum
invalid
perspective
orthographic
LightType* {.size: sizeof(cint), pure.} = enum
invalid
directional
point
spot
Extras* {.importc: "cgltf_extras", header: "cgltf.h", bycopy.} = object
startOffset* {.importc: "start_offset".}: csize
endOffset* {.importc: "end_offset".}: csize
Buffer* {.importc: "cgltf_buffer", header: "cgltf.h", bycopy.} = object
size* {.importc: "size".}: csize
uri* {.importc: "uri".}: cstring
data* {.importc: "data".}: pointer ## loaded by cgltf_load_buffers
extras* {.importc: "extras".}: Extras
BufferView* {.importc: "cgltf_buffer_view", header: "cgltf.h", bycopy.} = object
buffer* {.importc: "buffer".}: ptr Buffer
offset* {.importc: "offset".}: csize
size* {.importc: "size".}: csize
stride* {.importc: "stride".}: csize ## 0 == automatically determined by accessor
typ* {.importc: "type".}: BufferViewType
extras* {.importc: "extras".}: Extras
AccessorSparse* {.importc: "cgltf_accessor_sparse", header: "cgltf.h", bycopy.} = object
count* {.importc: "count".}: csize
indicesBufferView* {.importc: "indices_buffer_view".}: ptr BufferView
indicesByteOffset* {.importc: "indices_byte_offset".}: csize
indicesComponentType* {.importc: "indices_component_type".}: ComponentType
valuesBufferView* {.importc: "values_buffer_view".}: ptr BufferView
valuesByteOffset* {.importc: "values_byte_offset".}: csize
extras* {.importc: "extras".}: Extras
indicesExtras* {.importc: "indices_extras".}: Extras
valuesExtras* {.importc: "values_extras".}: Extras
Accessor* {.importc: "cgltf_accessor", header: "cgltf.h", bycopy.} = object
componentType* {.importc: "component_type".}: ComponentType
normalized* {.importc: "normalized".}: bool
typ* {.importc: "type".}: Type
offset* {.importc: "offset".}: csize
count* {.importc: "count".}: csize
stride* {.importc: "stride".}: csize
bufferView* {.importc: "buffer_view".}: ptr BufferView
hasMin* {.importc: "has_min".}: bool
min* {.importc: "min".}: array[16, cfloat]
hasMax* {.importc: "has_max".}: bool
max* {.importc: "max".}: array[16, cfloat]
isSparse* {.importc: "is_sparse".}: bool
sparse* {.importc: "sparse".}: AccessorSparse
extras* {.importc: "extras".}: Extras
Attribute* {.importc: "cgltf_attribute", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
typ* {.importc: "type".}: AttributeType
index* {.importc: "index".}: cint
data* {.importc: "data".}: ptr Accessor
Image* {.importc: "cgltf_image", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
uri* {.importc: "uri".}: cstring
bufferView* {.importc: "buffer_view".}: ptr BufferView
mimeType* {.importc: "mime_type".}: cstring
extras* {.importc: "extras".}: Extras
Sampler* {.importc: "cgltf_sampler", header: "cgltf.h", bycopy.} = object
magFilter* {.importc: "mag_filter".}: cint
minFilter* {.importc: "min_filter".}: cint
wrapS* {.importc: "wrap_s".}: cint
wrapT* {.importc: "wrap_t".}: cint
extras* {.importc: "extras".}: Extras
Texture* {.importc: "cgltf_texture", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
image* {.importc: "image".}: ptr Image
sampler* {.importc: "sampler".}: ptr Sampler
extras* {.importc: "extras".}: Extras
TextureTransform* {.importc: "cgltf_texture_transform", header: "cgltf.h", bycopy.} = object
offset* {.importc: "offset".}: array[2, cfloat]
rotation* {.importc: "rotation".}: cfloat
scale* {.importc: "scale".}: array[2, cfloat]
texcoord* {.importc: "texcoord".}: cint
TextureView* {.importc: "cgltf_texture_view", header: "cgltf.h", bycopy.} = object
texture* {.importc: "texture".}: ptr Texture
texcoord* {.importc: "texcoord".}: cint
scale* {.importc: "scale".}: cfloat ## equivalent to strength for occlusion_texture
hasTransform* {.importc: "has_transform".}: bool
transform* {.importc: "transform".}: TextureTransform
extras* {.importc: "extras".}: Extras
PbrMetallicRoughness* {.importc: "cgltf_pbr_metallic_roughness", header: "cgltf.h", bycopy.} = object
baseColorTexture* {.importc: "base_color_texture".}: TextureView
metallicRoughnessTexture* {.importc: "metallic_roughness_texture".}: TextureView
baseColorFactor* {.importc: "base_color_factor".}: array[4, cfloat]
metallicFactor* {.importc: "metallic_factor".}: cfloat
roughnessFactor* {.importc: "roughness_factor".}: cfloat
extras* {.importc: "extras".}: Extras
PbrSpecularGlossiness* {.importc: "cgltf_pbr_specular_glossiness", header: "cgltf.h", bycopy.} = object
diffuseTexture* {.importc: "diffuse_texture".}: TextureView
specularGlossinessTexture* {.importc: "specular_glossiness_texture".}: TextureView
diffuseFactor* {.importc: "diffuse_factor".}: array[4, cfloat]
specularFactor* {.importc: "specular_factor".}: array[3, cfloat]
glossinessFactor* {.importc: "glossiness_factor".}: cfloat
Material* {.importc: "cgltf_material", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
hasPbrMetallicRoughness* {.importc: "has_pbr_metallic_roughness".}: bool
hasPbrSpecularGlossiness* {.importc: "has_pbr_specular_glossiness".}: bool
pbrMetallicRoughness* {.importc: "pbr_metallic_roughness".}: PbrMetallicRoughness
pbrSpecularGlossiness* {.importc: "pbr_specular_glossiness".}: PbrSpecularGlossiness
normalTexture* {.importc: "normal_texture".}: TextureView
occlusionTexture* {.importc: "occlusion_texture".}: TextureView
emissiveTexture* {.importc: "emissive_texture".}: TextureView
emissiveFactor* {.importc: "emissive_factor".}: array[3, cfloat]
alphaMode* {.importc: "alpha_mode".}: AlphaMode
alphaCutoff* {.importc: "alpha_cutoff".}: cfloat
doubleSided* {.importc: "double_sided".}: bool
unlit* {.importc: "unlit".}: bool
extras* {.importc: "extras".}: Extras
MorphTarget* {.importc: "cgltf_morph_target", header: "cgltf.h", bycopy.} = object
attributes* {.importc: "attributes".}: ptr Attribute
attributesCount* {.importc: "attributes_count".}: csize
Primitive* {.importc: "cgltf_primitive", header: "cgltf.h", bycopy.} = object
typ* {.importc: "type".}: PrimitiveType
indices* {.importc: "indices".}: ptr Accessor
material* {.importc: "material".}: ptr Material
attributes* {.importc: "attributes".}: ptr Attribute
attributesCount* {.importc: "attributes_count".}: csize
targets* {.importc: "targets".}: ptr MorphTarget
targetsCount* {.importc: "targets_count".}: csize
extras* {.importc: "extras".}: Extras
Mesh* {.importc: "cgltf_mesh", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
primitives* {.importc: "primitives".}: ptr Primitive
primitivesCount* {.importc: "primitives_count".}: csize
weights* {.importc: "weights".}: ptr cfloat
weightsCount* {.importc: "weights_count".}: csize
targetNames* {.importc: "target_names".}: cstringArray
targetNamesCount* {.importc: "target_names_count".}: csize
extras* {.importc: "extras".}: Extras
Skin* {.importc: "cgltf_skin", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
joints* {.importc: "joints".}: ptr ptr Node
jointsCount* {.importc: "joints_count".}: csize
skeleton* {.importc: "skeleton".}: ptr Node
inverseBindMatrices* {.importc: "inverse_bind_matrices".}: ptr Accessor
extras* {.importc: "extras".}: Extras
CameraPerspective* {.importc: "cgltf_camera_perspective", header: "cgltf.h", bycopy.} = object
aspectRatio* {.importc: "aspect_ratio".}: cfloat
yfov* {.importc: "yfov".}: cfloat
zfar* {.importc: "zfar".}: cfloat
znear* {.importc: "znear".}: cfloat
extras* {.importc: "extras".}: Extras
CameraOrthographic* {.importc: "cgltf_camera_orthographic", header: "cgltf.h", bycopy.} = object
xmag* {.importc: "xmag".}: cfloat
ymag* {.importc: "ymag".}: cfloat
zfar* {.importc: "zfar".}: cfloat
znear* {.importc: "znear".}: cfloat
extras* {.importc: "extras".}: Extras
CameraData* {.importc: "no_name", header: "cgltf.h", bycopy, union.} = object
perspective* {.importc: "perspective".}: CameraPerspective
orthographic* {.importc: "orthographic".}: CameraOrthographic
Camera* {.importc: "cgltf_camera", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
typ* {.importc: "type".}: CameraType
data* {.importc: "data".}: CameraData
extras* {.importc: "extras".}: Extras
Light* {.importc: "cgltf_light", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
color* {.importc: "color".}: array[3, cfloat]
intensity* {.importc: "intensity".}: cfloat
typ* {.importc: "type".}: LightType
range* {.importc: "range".}: cfloat
spotInnerConeAngle* {.importc: "spot_inner_cone_angle".}: cfloat
spotOuterConeAngle* {.importc: "spot_outer_cone_angle".}: cfloat
Node* {.importc: "cgltf_node", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
parent* {.importc: "parent".}: ptr Node
children* {.importc: "children".}: ptr ptr Node
childrenCount* {.importc: "children_count".}: csize
skin* {.importc: "skin".}: ptr Skin
mesh* {.importc: "mesh".}: ptr Mesh
camera* {.importc: "camera".}: ptr Camera
light* {.importc: "light".}: ptr Light
weights* {.importc: "weights".}: ptr cfloat
weightsCount* {.importc: "weights_count".}: csize
hasTranslation* {.importc: "has_translation".}: bool
hasRotation* {.importc: "has_rotation".}: bool
hasScale* {.importc: "has_scale".}: bool
hasMatrix* {.importc: "has_matrix".}: bool
translation* {.importc: "translation".}: array[3, cfloat]
rotation* {.importc: "rotation".}: array[4, cfloat]
scale* {.importc: "scale".}: array[3, cfloat]
matrix* {.importc: "matrix".}: array[16, cfloat]
extras* {.importc: "extras".}: Extras
Scene* {.importc: "cgltf_scene", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
nodes* {.importc: "nodes".}: ptr ptr Node
nodesCount* {.importc: "nodes_count".}: csize
extras* {.importc: "extras".}: Extras
AnimationSampler* {.importc: "cgltf_animation_sampler", header: "cgltf.h", bycopy.} = object
input* {.importc: "input".}: ptr Accessor
output* {.importc: "output".}: ptr Accessor
interpolation* {.importc: "interpolation".}: InterpolationType
extras* {.importc: "extras".}: Extras
AnimationChannel* {.importc: "cgltf_animation_channel", header: "cgltf.h", bycopy.} = object
sampler* {.importc: "sampler".}: ptr AnimationSampler
targetNode* {.importc: "target_node".}: ptr Node
targetPath* {.importc: "target_path".}: AnimationPathType
extras* {.importc: "extras".}: Extras
Animation* {.importc: "cgltf_animation", header: "cgltf.h", bycopy.} = object
name* {.importc: "name".}: cstring
samplers* {.importc: "samplers".}: ptr AnimationSampler
samplersCount* {.importc: "samplers_count".}: csize
channels* {.importc: "channels".}: ptr AnimationChannel
channelsCount* {.importc: "channels_count".}: csize
extras* {.importc: "extras".}: Extras
Asset* {.importc: "cgltf_asset", header: "cgltf.h", bycopy.} = object
copyright* {.importc: "copyright".}: cstring
generator* {.importc: "generator".}: cstring
version* {.importc: "version".}: cstring
minVersion* {.importc: "min_version".}: cstring
extras* {.importc: "extras".}: Extras
GltfData* = ptr GltfDataObj
GltfDataObj* {.importc: "cgltf_data", header: "cgltf.h", bycopy.} = object
## The struct allocated and filled by `cgltf_parse()`.
## It generally mirrors the glTF format as described by the spec
## (see https://github.com/KhronosGroup/glTF/tree/master/specification/2.0)
fileType* {.importc: "file_type".}: FileType
fileData* {.importc: "file_data".}: pointer
asset* {.importc: "asset".}: Asset
meshes* {.importc: "meshes".}: ptr Mesh
meshesCount* {.importc: "meshes_count".}: csize
materials* {.importc: "materials".}: ptr Material
materialsCount* {.importc: "materials_count".}: csize
accessors* {.importc: "accessors".}: ptr Accessor
accessorsCount* {.importc: "accessors_count".}: csize
bufferViews* {.importc: "buffer_views".}: ptr BufferView
bufferViewsCount* {.importc: "buffer_views_count".}: csize
buffers* {.importc: "buffers".}: ptr Buffer
buffersCount* {.importc: "buffers_count".}: csize
images* {.importc: "images".}: ptr Image
imagesCount* {.importc: "images_count".}: csize
textures* {.importc: "textures".}: ptr Texture
texturesCount* {.importc: "textures_count".}: csize
samplers* {.importc: "samplers".}: ptr Sampler
samplersCount* {.importc: "samplers_count".}: csize
skins* {.importc: "skins".}: ptr Skin
skinsCount* {.importc: "skins_count".}: csize
cameras* {.importc: "cameras".}: ptr Camera
camerasCount* {.importc: "cameras_count".}: csize
lights* {.importc: "lights".}: ptr Light
lightsCount* {.importc: "lights_count".}: csize
nodes* {.importc: "nodes".}: ptr Node
nodesCount* {.importc: "nodes_count".}: csize
scenes* {.importc: "scenes".}: ptr Scene
scenesCount* {.importc: "scenes_count".}: csize
scene* {.importc: "scene".}: ptr Scene
animations* {.importc: "animations".}: ptr Animation
animationsCount* {.importc: "animations_count".}: csize
extras* {.importc: "extras".}: Extras
extensionsUsed* {.importc: "extensions_used".}: cstringArray
extensionsUsedCount* {.importc: "extensions_used_count".}: csize
extensionsRequired* {.importc: "extensions_required".}: cstringArray
extensionsRequiredCount* {.importc: "extensions_required_count".}: csize
json* {.importc: "json".}: cstring
jsonSize* {.importc: "json_size".}: csize
bin* {.importc: "bin".}: pointer
binSize* {.importc: "bin_size".}: csize
memoryFree* {.importc: "memory_free".}: proc (user: pointer; `ptr`: pointer)
memoryUserData* {.importc: "memory_user_data".}: pointer
# note:
# For these bindings I assume that `bool` and `cgltf_bool` (cint) are compatible.
# This seems safe since `cgltf_bool` is only ever used as a return value.
proc parse*(options: ptr GltfOptions; data: pointer; size: csize; outData: ptr GltfData): GltfResult {.importc: "cgltf_parse", header: "cgltf.h".}
## Parses both glTF and GLB data.
## If this function returns `GltfResult.success`, you have to call
## `free()` on the created `GltfData` variable.
## Note that contents of external files for buffers and images are not
## automatically loaded. You'll need to read these files yourself using
## URIs in the `GltfData` structure.
proc parseFile*(options: ptr GltfOptions; path: cstring; outData: ptr GltfData): GltfResult {.importc: "cgltf_parse_file", header: "cgltf.h".}
## Open the given file using `FILE*` APIs and parse the data using `parse()`.
proc loadBuffers*(options: ptr GltfOptions; data: GltfData; gltfPath: cstring): GltfResult {.importc: "cgltf_load_buffers", header: "cgltf.h".}
## Can be optionally called to open and read buffer files using the `FILE*` APIs.
## The `gltfPath` argument is the path to the original glTF file, which allows the
## parser to resolve the path to buffer files.
proc loadBufferBase64*(options: ptr GltfOptions; size: csize; base64: cstring; outData: ptr pointer): GltfResult {.importc: "cgltf_load_buffer_base64", header: "cgltf.h".}
## Decodes base64-encoded data content.
## Used internally by `cgltf_load_buffers()` and may be useful if you're not dealing with normal files.
proc validate*(data: GltfData): GltfResult {.importc: "cgltf_validate", header: "cgltf.h".}
## Perform additional checks to make sure the parsed glTF data is valid.
proc free*(data: GltfData) {.importc: "cgltf_free", header: "cgltf.h".}
## Frees the allocated `GltfData` variable.
proc nodeTransformLocal*(node: ptr Node; outMatrix: ptr cfloat) {.importc: "cgltf_node_transform_local", header: "cgltf.h".}
## Converts the translation / rotation / scale properties of a node into a mat4.
proc nodeTransformWorld*(node: ptr Node; outMatrix: ptr cfloat) {.importc: "cgltf_node_transform_world", header: "cgltf.h".}
## Calls `nodeTransformLocal()` on every ancestor in order to compute the root-to-node transformation.
proc accessorReadFloat*(accessor: ptr Accessor; index: csize; `out`: ptr cfloat; elementSize: csize): bool {.importc: "cgltf_accessor_read_float", header: "cgltf.h".}
## Reads a certain element from a non-sparse accessor and converts it to floating point,
## assuming that `loadBuffers` has already been called. The passed-in element size is the
## number of floats in the output buffer, which should be in the range 1..16.
## Returns false if the passed-in element_size is too small, or if the accessor is sparse.
proc accessorReadIndex*(accessor: ptr Accessor; index: csize): csize {.importc: "cgltf_accessor_read_index", header: "cgltf.h".}
## Similar to its floating-point counterpart, but it returns `csize` and
## only works with single-component data types.
proc numComponents*(typ: Type): csize {.importc: "cgltf_num_components", header: "cgltf.h".}
## Tiny utility that tells you the dimensionality of a certain accessor type.
## This can be used before `accessorUnpackFloats()` to help allocate the necessary amount of memory.
proc accessorUnpackFloats*(accessor: ptr Accessor; `out`: ptr cfloat; floatCount: csize): csize {.importc: "cgltf_accessor_unpack_floats", header: "cgltf.h".}
## Reads in the data from an accessor, applies sparse data (if any),
## and converts them to floating point. Assumes that `cgltf_load_buffers` has already been called.
## By passing null for the output pointer, users can find out how many floats are required in the
## output buffer.
proc copyExtrasJson*(data: GltfData; extras: ptr Extras; dest: cstring; destSize: ptr csize): GltfResult {.importc: "cgltf_copy_extras_json", header: "cgltf.h".}
## Allows users to retrieve the "extras" data that can be attached to many glTF objects
## (which can be arbitrary JSON data). The `Extras` struct stores the offsets of the
## start and end of the extras JSON data as it appears in the complete glTF JSON data.
## This function copies the extras data into the provided buffer.
## If `dest` is NULL, the length of the data is written into `destSize`.
## You can then parse this data using your own JSON parser or, if you've included the
## cgltf implementation using the integrated JSMN JSON parser.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment