Add support for embedded buffers in GLTF loader

This commit is contained in:
Milan Vaško 2020-08-12 19:23:54 +02:00
parent a7f1889a35
commit e96afc33a7
2 changed files with 13 additions and 1 deletions

View file

@ -19,3 +19,4 @@ bevy_render = { path = "../bevy_render", version = "0.1" }
gltf = { version = "0.15.2", default-features = false, features = ["utils"] } gltf = { version = "0.15.2", default-features = false, features = ["utils"] }
thiserror = "1.0" thiserror = "1.0"
anyhow = "1.0" anyhow = "1.0"
base64 = "0.12.3"

View file

@ -38,6 +38,10 @@ pub enum GltfError {
Io(#[from] io::Error), Io(#[from] io::Error),
#[error("Binary buffers not supported yet.")] #[error("Binary buffers not supported yet.")]
BinaryBuffersUnsupported, BinaryBuffersUnsupported,
#[error("Failed to decode base64 mesh data.")]
Base64Decode(#[from] base64::DecodeError),
#[error("Unsupported buffer format.")]
BufferFormatUnsupported,
} }
fn get_primitive_topology(mode: Mode) -> Result<PrimitiveTopology, GltfError> { fn get_primitive_topology(mode: Mode) -> Result<PrimitiveTopology, GltfError> {
@ -111,11 +115,18 @@ fn load_node(buffer_data: &[Vec<u8>], node: &gltf::Node, depth: i32) -> Result<M
} }
fn load_buffers(buffers: iter::Buffers, asset_path: &Path) -> Result<Vec<Vec<u8>>, GltfError> { fn load_buffers(buffers: iter::Buffers, asset_path: &Path) -> Result<Vec<Vec<u8>>, GltfError> {
const OCTET_STREAM_URI: &str = "data:application/octet-stream;base64,";
let mut buffer_data = Vec::new(); let mut buffer_data = Vec::new();
for buffer in buffers { for buffer in buffers {
match buffer.source() { match buffer.source() {
Source::Uri(uri) => { Source::Uri(uri) => {
if uri.starts_with("data:") { if uri.starts_with("data:") {
if uri.starts_with(OCTET_STREAM_URI) {
buffer_data.push(base64::decode(&uri[OCTET_STREAM_URI.len()..])?);
} else {
return Err(GltfError::BufferFormatUnsupported);
}
} else { } else {
let buffer_path = asset_path.parent().unwrap().join(uri); let buffer_path = asset_path.parent().unwrap().join(uri);
let buffer_bytes = fs::read(buffer_path)?; let buffer_bytes = fs::read(buffer_path)?;