Skip to main content

gl_utils/util/
gltf.rs

1use base64;
2use gltf::json;
3
4/// Create a buffer with base64 encoded embedded URI and return views to each
5/// given sub-buffer
6pub fn json_buffer_views (buffer_index : u32, bytes : &[&[u8]])
7  -> (json::Buffer, Vec <json::buffer::View>)
8{
9  use base64::Engine;
10  let buffer_bytes = bytes.concat();
11  let buffer = json::Buffer {
12    byte_length:  buffer_bytes.len().into(),
13    extensions:   None,
14    extras:       Default::default(),
15    name:         None,
16    uri:          Some (
17      format!("data:application/octet-stream;base64,{}",
18        base64::prelude::BASE64_STANDARD.encode (buffer_bytes)
19      )
20    )
21  };
22  let mut views    = vec![];
23  let mut offset   = 0;
24  let buffer_index = json::Index::new (buffer_index);
25  for sub_buffer in bytes.iter() {
26    let byte_length = sub_buffer.len();
27    let view = json::buffer::View {
28      buffer:      buffer_index,
29      byte_length: byte_length.into(),
30      byte_offset: if offset == 0 { None } else { Some (offset.into()) },
31      byte_stride: None,
32      extensions:  None,
33      extras:      Default::default(),
34      name:        None,
35      target:      None
36    };
37    views.push (view);
38    offset += byte_length;
39  }
40  (buffer, views)
41}
42
43pub fn json_accessor (
44  buffer_view_index : u32,
45  count             : u32,
46  type_             : json::accessor::Type,
47  component_type    : json::accessor::ComponentType,
48  min_max           : Option <[[f32; 3]; 2]>
49) -> json::Accessor {
50  let [min, max] = match min_max {
51    Some ([min, max]) => [
52      Some (min.to_vec().into()),
53      Some (max.to_vec().into())
54    ],
55    None => [None, None]
56  };
57  json::Accessor {
58    buffer_view: Some (json::Index::new (buffer_view_index)),
59    byte_offset: None,
60    count:       (count as u64).into(),
61    component_type: json::validation::Checked::Valid (
62      json::accessor::GenericComponentType (component_type)
63    ),
64    extensions:  None,
65    extras:      Default::default(),
66    type_:       json::validation::Checked::Valid (type_),
67    min,
68    max,
69    name:        None,
70    normalized:  false,
71    sparse:      None
72  }
73}
74
75pub fn json_primitive (
76  attribute              : json::mesh::Semantic,
77  mode                   : json::mesh::Mode,
78  indices_accessor_index : u32
79) -> json::mesh::Primitive {
80  json::mesh::Primitive {
81    attributes: FromIterator::from_iter (vec![
82      (json::validation::Checked::Valid (attribute), json::Index::new (0))
83    ]),
84    extensions: None,
85    extras:     Default::default(),
86    indices:    Some (json::Index::new (indices_accessor_index)),
87    material:   None,
88    mode:       json::validation::Checked::Valid (mode),
89    targets:    None
90  }
91}
92
93pub fn json_mesh (primitives : Vec <json::mesh::Primitive>) -> json::Mesh {
94  json::Mesh {
95    extensions: None,
96    extras:     Default::default(),
97    name:       None,
98    primitives,
99    weights:    None,
100  }
101}
102
103pub fn json_node (mesh_index : u32) -> json::Node {
104  json::Node {
105    camera:       None,
106    children:     None,
107    extensions:   None,
108    extras:       Default::default(),
109    matrix:       None,
110    mesh:         Some(json::Index::new (mesh_index)),
111    name:         None,
112    rotation:     None,
113    scale:        None,
114    translation:  None,
115    skin:         None,
116    weights:      None
117  }
118}
119
120pub fn json_root (
121  nodes        : Vec <json::Node>,
122  meshes       : Vec <json::Mesh>,
123  buffers      : Vec <json::Buffer>,
124  buffer_views : Vec <json::buffer::View>,
125  accessors    : Vec <json::Accessor>,
126) -> json::Root {
127  let node_indices = (0..nodes.len() as u32).map (json::Index::new)
128    .collect();
129  json::Root {
130    accessors,
131    buffers,
132    buffer_views,
133    meshes,
134    nodes,
135    scenes: vec![json::Scene {
136      extensions: None,
137      extras:     Default::default(),
138      name:       None,
139      nodes:      node_indices
140    }],
141    scene: Some (json::Index::new (0)),
142    .. Default::default()
143  }
144}