-------------------------------------------
var,funct: write glTF/GLB (GL Transmission Format) surface
  set outsurf <surface>
  write_glb_surface
-------------------------------------------

Large Panel Only: [fn-]F3

The "GLB" button on the "outsurf:" line on the
large fn-F3 panel writes out current surface
including current surface color, as a binary glTF
2.0 file (*.glb, little-endian) whose name is
current value of $outsurf (entry at left) after
auto-appending ".glb" if it isn't already there.

The GLB button checks overwrite but the
equivalent C/tcl funct, write_glb_surface,
doesn't.

Media Types (formerly known as MIME type)

The media type for a *.glb file was registered
in Nov 2017 as:

  model/gltf-binary
  https://www.iana.org/assignments/media-types/model/gltf-binary

A *.glb file can also be linked as:

  <a href="brain.glb" download>Get Brain Model</a>

Without these, a brower may attempt to (and fail
to) load it as html.

Binary glTF file format

The output file is an all-in-one, little-endian
binary (*.glb) glTF 2.0 file with the following
format:

  Header (12 bytes)

   4byte UInt magic ("glTF", 0x46546C67)
   4byte UInt version (2)
   4byte UInt length (bytes)

  Chunk0 (JSON, variable length)

   4byte UInt chunkLength (bytes)
   4byte UInt chunkType ("JSON", 0x4E4F534A)
   1byte UChar chunkData (ASCII, space pad to 4byte bound)
 
  Chunk1 (BIN, variable length)
 
   4byte UInt chunkLength (bytes)
   4byte UInt chunkType ("BIN", 0x004E4942)
   1byte UChar chunkData (binary, zero-pad to 4byte bound)

JSON (Chunk0) details

Here is an example of the ASCII data in the JSON
chunk for a typical FreeSurfer human hemisphere:

{
  "asset":{"generator":"CSURF2GLTF","version":"2.0"},
  "scene":0,
  "scenes":[
    {"nodes":[0]}
  ],
  "nodes":[
    {"children":[1],"matrix":
        [1.0, 0.0, 0.0, 0.0,
         0.0, 0.0,-1.0, 0.0,
         0.0, 1.0, 0.0, 0.0,
         0.0, 0.0, 0.0, 1.0]},
    {"mesh":0}
  ],
  "meshes":[
    {
      "primitives":[
        {
          "attributes":{
            "NORMAL":1,
            "POSITION":2,
            "COLOR_0":3
          },
          "indices":0,
          "mode":4
        },
      ],
      "name":"Mesh"
    }
  ],
  "accessors":[
    {
      "bufferView":0,
      "byteOffset":0,
      "componentType":5125,
      "count":893946,
      "max":[148992], 
      "min":[0],
      "type":"SCALAR"
    },
    {
      "bufferView":1,
      "byteOffset":0,
      "componentType":5126,
      "count":148993,
      "max":[1.0,1.0,1.0],
      "min":[-1.0,-1.0,-1.0],
      "type":"VEC3"
    },
    {
      "bufferView":1,
      "byteOffset":1787916,
      "componentType":5126,
      "count":148993,
      "max":[101.0,150.0,101.0],
      "min":[-101.0,-150.0,-101.0],
      "type":"VEC3"
    },
    {
      "bufferView":1,
      "byteOffset":3575832,
      "componentType":5126,
      "count":148993,
      "max":[1.0,1.0,1.0],
      "min":[0.0,0.0,0.0],
      "type":"VEC3"
    }
  ],
  "bufferViews":[
    {
      "buffer":0,
      "byteOffset":5363748,
      "byteLength":3575784,
      "target":34963
    },
    {
      "buffer":0,
      "byteOffset":0,
      "byteLength":5363748,
      "byteStride":12,
      "target":34962
    }
  ],
  "buffers":[
    {"byteLength":8939532}
  ]
}

BIN (Chunk0) details

Here is the format and order of the binary data
in the BIN chunk:

 ---------- vertex normals ---------------
   [normal triples are implicitly numbered]
   4-byte float vertex normal x comp (normlength=1)
   4-byte float vertex normal y comp (normlength=1)
   4-byte float vertex normal z comp (normlength=1)
   ... [x,y,z triples up to vertex count]
 ---------- vertex positions ---------------
   [vertex triples are implicitly numbered]
   4-byte float vertex x-position (mm)
   4-byte float vertex y-position (mm)
   4-byte float vertex z-position (mm)
   ... [x,y,z triples up to vertex count]
 ---------- vertex colors ---------------
   [color triples are implicitly numbered]
   4-byte float red (0-1), vertex0
   4-byte float green (0-1), vertex0
   4-byte float blue (0-1), vertex0
   ... [r,g,b, triples up to vertex count]
 ---- vertex numbers around each face ------
   [faces are implicitly numbered]
   [vtx nums here are implicit vtx nums above]
   [num each face ordered CCW from outside]
   4-byte unsigned int corner1, face0
   4-byte unsigned int corner2, face0
   4-byte unsigned int corner3, face0
   4-byte unsigned int corner1, face1
   4-byte unsigned int corner2, face1
   4-byte unsigned int corner3, face1
   ... [triples up to face count]
 -------------------------------------------

Full format documentation

The current full specification of the glTF 2.0
format can be found here:

  https://github.com/KhronosGroup/glTF/tree/master/specification/2.0

