All Projects → qmuntal → gltf

qmuntal / gltf

Licence: BSD-2-Clause license
👓 Go library for encoding glTF 2.0 files

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to gltf

android-3d-model-viewer
Android app to load 3D models in obj, stl, dae & gltf format using pure OpenGL ES 2.0. Published on Play Store https://play.google.com/store/apps/details?id=org.andresoviedo.dddmodel2
Stars: ✭ 150 (-3.85%)
Mutual labels:  gltf
panda3d-gltf
glTF utilities for Panda3D
Stars: ✭ 63 (-59.62%)
Mutual labels:  gltf
glTF-Shell-Extensions
Microsoft Windows shell extensions that pack .gltf to .glb and unpack .glb to .gltf
Stars: ✭ 82 (-47.44%)
Mutual labels:  gltf
gltf-bounding-box
Computes the global bounding box of a gltf model
Stars: ✭ 18 (-88.46%)
Mutual labels:  gltf
VGltf
A glTF 2.0 importer/exporter library written in pure C# with support for use in Unity
Stars: ✭ 53 (-66.03%)
Mutual labels:  gltf
binary-gltf-utils
Bundles glTF models, images, shaders and other assets into a Binary glTF (.glb) file.
Stars: ✭ 31 (-80.13%)
Mutual labels:  gltf
gdx-gltf
GLTF 2.0 3D format support and PBR shader implementation for LibGDX
Stars: ✭ 156 (+0%)
Mutual labels:  gltf
rendering-fw
Rendering framework with rasterizers & path tracers implemented using Vulkan, OptiX & OpenGL
Stars: ✭ 81 (-48.08%)
Mutual labels:  gltf
verge3d-blender-addon
WebGL exporter add-on ripped from Verge3D for Blender toolkit
Stars: ✭ 91 (-41.67%)
Mutual labels:  gltf
godot-dynamic-gltf-loader
Dynamic GLTF loader module for Godot 3.2.4+
Stars: ✭ 14 (-91.03%)
Mutual labels:  gltf
importer-exporter
3D City Database client for high-performance import and export of 3D city model data
Stars: ✭ 104 (-33.33%)
Mutual labels:  gltf
Ogre glTF
glTF 2.0 asset loader plugin for Ogre 2.1
Stars: ✭ 44 (-71.79%)
Mutual labels:  gltf
gemini-viewer
WebGL BIM Viewer based on xeoKit-sdk, written with TypeScript.
Stars: ✭ 24 (-84.62%)
Mutual labels:  gltf
glTF-Blender-IO-materials-variants
Blender3D addon for glTF KHR_materials_variants extension
Stars: ✭ 56 (-64.1%)
Mutual labels:  gltf
mixed-reality-extension-sdk
The Mixed Reality Extension SDK enables developers to build 3D world extensions for AltspaceVR, using Node.JS.
Stars: ✭ 139 (-10.9%)
Mutual labels:  gltf
docker-gltf-to-udsz
Docker container for converting gltf files into apple usdz quicklook files
Stars: ✭ 42 (-73.08%)
Mutual labels:  gltf
lol2gltf
Tool for converting between the glTF format and League of Legends models and animations
Stars: ✭ 74 (-52.56%)
Mutual labels:  gltf
playcanvas-gltf
glTF 2.0 support for the PlayCanvas Engine
Stars: ✭ 97 (-37.82%)
Mutual labels:  gltf
GLTFKit2
A glTF 2.0 asset loader and exporter for Objective-C and Swift.
Stars: ✭ 30 (-80.77%)
Mutual labels:  gltf
redcube
JS renderer based on GLTF to WebGPU or WebGL backends.
Stars: ✭ 86 (-44.87%)
Mutual labels:  gltf

gltf PkgGoDev Build Status Coverage Status License Mentioned in Awesome Go

A Go module for efficient and robust serialization/deserialization of glTF 2.0, a royalty-free specification for the efficient transmission and loading of 3D scenes and models by applications, also known as "the JPEG of 3D".

Main FeaturesGetting StartedContributingAbout The Project

Gopher glTF

Main Features

📜 Getting started

Data Model

qmuntal/gltf implements the whole glTF 2.0 specification. The top level element is the gltf.Document and it contains all the information to hold a gltf document in memory:

// This document does not produce any valid glTF, it is just an example.
gltf.Document{
  Accessors: []*gltf.Accessor{
      {BufferView: gltf.Index(0), ComponentType: gltf.ComponentUshort, Type: gltf.AccessorScalar},
  },
  Asset: gltf.Asset{Version: "2.0", Generator: "qmuntal/gltf"},
  BufferViews: []*gltf.BufferView{
      {ByteLength: 72, ByteOffset: 0, Target: gltf.TargetElementArrayBuffer},
  },
  Buffers: []*gltf.Buffer{{ByteLength: 1033, URI: bufferData}},
  Meshes: []*gltf.Mesh{{
    Name: "Cube",
  }},
  Nodes: []*gltf.Node{{Name: "Cube", Mesh: gltf.Index(0)}},
  Scene:    gltf.Index(0),
  Scenes:   []*gltf.Scene{{Name: "Root Scene", Nodes: []uint32{0}}},
}

Optional parameters

All optional properties whose default value does not match with the golang type zero value are defines as pointers. Take the following guidelines into account when working with optional values:

  • It is safe to not define them when writing the glTF if the desired value is the default one.
  • It is safe to expect that the optional values are not nil when reading a glTF.
  • When assigning values to optional properties it may be helpful to use these utility functions:
    • gltf.Index(1)
    • gltf.Float(0.5)

Reading a document

A gltf.Document can be decoded from any io.Reader by using gltf.Decoder:

resp, _ := http.Get("https://example.com/static/foo.gltf")
var doc gltf.Document
gltf.NewDecoder(resp.Body).Decode(&doc)
fmt.Print(doc.Asset)

When working with the file system it is more convenient to use gltf.Open as it automatically manages relative external buffers:

doc, _ := gltf.Open("./foo.gltf")
fmt.Print(doc.Asset)

In both cases the decoder will automatically detect if the file is JSON/ASCII (gltf) or Binary (glb) based on its content.

Writing a document

A gltf.Document can be encoded to any io.Writer by using gltf.Encoder:

var buf bytes.Buffer
gltf.NewEncoder(&buf).Encode(&doc)
http.Post("http://example.com/upload", "model/gltf+binary", &buf)

By default gltf.NewEncoder outputs a binary file, to generate a JSON/ASCII file set AsBinary to false:

var buf bytes.Buffer
enc := gltf.NewEncoder(&buf)
enc.AsBinary = false
enc.Encode(&doc)
http.Post("http://example.com/upload", "model/gltf+json", &buf)

When working with the file system it is more convenient to use gltf.Save and gltf.SaveBinary as it automatically manages relative external buffers:

gltf.Save(&doc, "./foo.gltf")
gltf.SaveBinary(&doc, "./foo.glb")

Manipulating buffer views and accessors

The package gltf/modeler defines a friendly API to read and write accessors and buffer views, abstracting away all the byte manipulation work and the idiosyncrasy of the glTF spec.

The following example creates a single colored triangle:

screenshot

doc := gltf.NewDocument()
doc.Meshes = []*gltf.Mesh{{
    Name: "Pyramid",
    Primitives: []*gltf.Primitive{{
        Indices: gltf.Index(modeler.WriteIndices(doc, []uint16{0, 1, 2})),
        Attributes: map[string]uint32{
          gltf.POSITION: modeler.WritePosition(doc, [][3]float32{{0, 0, 0}, {0, 10, 0}, {0, 0, 10}}),
          gltf.COLOR_0:  modeler.WriteColor(doc, [][3]uint8{{255, 0, 0}, {0, 255, 0}, {0, 0, 255}}),
        },
    }},
}}
doc.Nodes = []*gltf.Node{{Name: "Pyramid", Mesh: gltf.Index(0)}}
doc.Scenes[0].Nodes = append(doc.Scenes[0].Nodes, 0)
gltf.Save(doc, "./test.gltf")

Data interleaving

The data of the attributes that are stored in a single bufferView may be stored as an Array-Of-Structures, which may produce a rendering perfomance boost in static attributes. qmuntal/gltf/modeler facilitates the creation of interleaved accessors and buffer views with the methods WriteAttributesInterleaved, WriteAccessorsInterleaved, and WriteBufferViewInterleaved being the first one the most recommended for creating mesh primitives:

doc := gltf.NewDocument()
attrs, _ := modeler.WriteAttributesInterleaved(doc, modeler.Attributes{
  Position:       [][3]float32{{0, 0, 0}, {0, 10, 0}, {0, 0, 10}},
  Color:          [][3]uint8{{255, 0, 0}, {0, 255, 0}, {0, 0, 255}},
})
doc.Meshes = []*gltf.Mesh{{
    Name: "Pyramid",
    Primitives: []*gltf.Primitive{{
        Indices: gltf.Index(modeler.WriteIndices(doc, []uint16{0, 1, 2})),
        Attributes: attrs,
    }},
}}
doc.Nodes = []*gltf.Node{{Name: "Pyramid", Mesh: gltf.Index(0)}}
doc.Scenes[0].Nodes = append(doc.Scenes[0].Nodes, 0)
gltf.Save(doc, "./test.gltf")

Manipulating bytes

The package gltf/binary defines a friendly and efficient API to read and write bytes from buffers, abstracting away all the byte manipulation work. This package is very low level and normal users should use gltf/modeler instead as it provides another level of abstraction that understands how bytes are associated to other entities.

This package is very similary to the Go binary package, the main differences are that it is highly specialized in glTF data types and that it only have to deal with little endian encoding.

Dealing with extensions

qmuntal/gltf is designed to support dynamic extensions. By default only the core specification is decoded and the data inside the extensions objects are stored as json.RawMessage so they can be decoded by the caller or automatically encoded when saving the document.

Some of the official extensions are implemented under ext.

To decode one of the supported extensions the only required action is to import the associated package, this way the extension will not be stored as json.RawMessage but as the type defined in the extension package:

import (
  "github.com/qmuntal/gltf"
  "github.com/qmuntal/gltf/ext/lightspuntual"
)

func main() {
  doc, _ := gltf.Open("./foo.gltf")
    if v, ok := doc.Extensions[lightspuntual.ExtensionName]; ok {
        for _, l := range v.(lightspuntual.Lights) {
            fmt.Print(l.Type)
        }
    }
}

It is not necessary to call gltf.RegisterExtension for built-in extensions, as these auto-register themselves when the package is initialized.

External extension

This list is the list of known extensions implemented in other modules:

Custom extensions

To implement a custom extension encoding, provide a struct that can be encoded as a JSON object as dictated by the spec.

To implement a custom extension decoding, call gltf.RegisterExtension at least once before decoding, providing the identifier of the extension and a function that decodes the JSON bytes to the desired struct:

const ExtensionName = "FAKE_Extension"

type Foo struct {
    BufferView uint32          `json:"bufferView"`
    Attributes gltf.Attribute  `json:"attributes"`
}

func init() {
    gltf.RegisterExtension(ExtensionName, Unmarshal)
}

func Unmarshal(data []byte) (interface{}, error) {
    foo := new(Foo)
    err := json.Unmarshal(data, foo)
    return foo, err
}

🙋 Contributing

PRs, issues, and feedback from ninja gophers are very welcomed.

About The Project

This library is a complete implementation of glTF 2.0, and its explicit aim is to provide a production-ready, idiomatic and curated API to perform any kind of glTF manipulation.

It is out of the scope to implement convertes to/from other file formats and to provide mechanisms to create and manipulate 3D geometry.

The current API is still not frozen and can suffer minor changes until it reached v1.0.

Please use the issue tracker or the if you'd like to report problems or discuss features.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].