Skip to content
A Golang efficient and robust glTf 2.0 reader, writer and validator
Branch: master
Clone or download
Latest commit 7fc6bd8 Mar 15, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
testdata
.gitignore
.travis.yml
LICENSE
README.md
bench_test.go
const.go
decoder.go
decoder_test.go
doc.go
encode.go
encode_test.go
example_test.go
extensions.go
extensions_test.go
go.mod
go.sum
struct.go
struct_test.go
validator.go
validator_test.go

README.md

gltf

Documentation Build Status Go Report Card codecov codeclimate License

A Go package for simple, efficient, and robust serialization/deserialization of glTF 2.0 (GL Transmission Format), a royalty-free specification for the efficient transmission and loading of 3D scenes and models by applications.

Features

  • High parsing time and moderate memory consumption.
  • glTF specification v2.0.0
    • ASCII glTF.
    • Binary glTF(GLB).
    • PBR material description.
  • glTF validaton
    • Validate against schemas.
    • Validate coherence.
  • Buffers
    • Parse BASE64 encoded embedded buffer data(DataURI).
    • Load .bin file.
  • Read from io.Reader
    • Boilerplate for disk loading.
    • Custom callback handlers.
    • Automatic ASCII / glTF detection.
  • Write to io.Writer
    • Boilerplate for disk saving.
    • Custom callback handlers.
    • ASCII / Binary
  • Extensions
    • KHR_draco_mesh_compression
    • KHR_lights_punctual
    • KHR_materials_pbrSpecularGlossiness
    • KHR_materials_unlit
    • KHR_techniques_webgl
    • KHR_texture_transform

Perfomance

All the functionality is benchmarked and tested using the official glTF Samples in the utility package qmuntal/gltf-bench. The results show that the perfomance of this package is equivalent to fx-gltf, a reference perfomance-driven glTF implementation for C++, .

Examples

Read

doc, err := gltf.Open("./a.gltf")
if err != nil {
  panic(err)
}
fmt.Print(doc.Asset)

Write

doc := &gltf.Document{
  Scene: 0, 
  Asset: gltf.Asset{Generator: "qmuntal/gltf"}, 
  Scenes: []gltf.Scene{{Extras: 8.0, Extensions: gltf.Extensions{"a": "b"}, Name: "s_1"}}
}
 
if err := gltf.Save(doc, "./a.gltf", true); err != nil {
  panic(err)
}

Write complex

doc := &gltf.Document{
  Accessors: []gltf.Accessor{
    {BufferView: 0, ByteOffset: 0, ComponentType: gltf.UnsignedShort, Count: 36, Type: gltf.Scalar},
    {BufferView: 1, ByteOffset: 0, ComponentType: gltf.Float, Count: 24, Max: []float64{0.5, 0.5, 0.5}, Min: []float64{-0.5, -0.5, -0.5}, Type: gltf.Vec3},
    {BufferView: 2, ByteOffset: 0, ComponentType: gltf.Float, Count: 24, Type: gltf.Vec3},
    {BufferView: 3, ByteOffset: 0, ComponentType: gltf.Float, Count: 24, Type: gltf.Vec4},
    {BufferView: 4, ByteOffset: 0, ComponentType: gltf.Float, Count: 24, Type: gltf.Vec2},
  },
  Asset: gltf.Asset{Version: "2.0", Generator: "FBX2glTF"},
  BufferViews: []gltf.BufferView{
    {Buffer: 0, ByteLength: 72, ByteOffset: 0, Target: gltf.ElementArrayBuffer},
    {Buffer: 0, ByteLength: 288, ByteOffset: 72, Target: gltf.ArrayBuffer},
    {Buffer: 0, ByteLength: 288, ByteOffset: 360, Target: gltf.ArrayBuffer},
    {Buffer: 0, ByteLength: 384, ByteOffset: 648, Target: gltf.ArrayBuffer},
    {Buffer: 0, ByteLength: 192, ByteOffset: 1032, Target: gltf.ArrayBuffer},
  },
  Buffers: []gltf.Buffer{{ByteLength: 1224, Data: readFile("testdata/BoxVertexColors/glTF-Binary/BoxVertexColors.glb")[1628+20+8:]}},
  Materials: []gltf.Material{{Name: "Default", AlphaMode: gltf.Opaque, AlphaCutoff: 0.5, 
    PBRMetallicRoughness: &gltf.PBRMetallicRoughness{BaseColorFactor: [4]float64{0.8, 0.8, 0.8, 1}, MetallicFactor: 0.1, RoughnessFactor: 0.99}}
  },
  Meshes: []gltf.Mesh{{Name: "Cube", Primitives: []gltf.Primitive{{Indices: 0, Material: 0, Mode: gltf.Triangles, Attributes: map[string]uint32{"POSITION": 1, "COLOR_0": 3, "NORMAL": 2, "TEXCOORD_0": 4}}}}},
  Nodes: []gltf.Node{
    {Name: "RootNode", Mesh: -1, Camera: -1, Skin: -1, Children: []uint32{1, 2, 3}, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}},
    {Name: "Mesh", Mesh: -1, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}},
    {Name: "Cube", Mesh: 0, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}},
    {Name: "Texture Group", Mesh: -1, Camera: -1, Skin: -1, Matrix: [16]float64{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, Rotation: [4]float64{0, 0, 0, 1}, Scale: [3]float64{1, 1, 1}},
  },
  Samplers: []gltf.Sampler{{WrapS: gltf.Repeat, WrapT: gltf.Repeat}},
  Scene: 0,
  Scenes: []gltf.Scene{{Name: "Root Scene", Nodes: []uint32{0}}},
}
if err := gltf.Save(doc, "./a.gltf", true); err != nil {
  panic(err)
}
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.