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