gl_utils/util/
gltf.rs

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