mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
Add support for binary glTF (.glb) (#271)
Add support for binary glTF (.glb)
This commit is contained in:
parent
c9000deafa
commit
9aff0bcc2a
3 changed files with 27 additions and 9 deletions
BIN
assets/models/monkey/Monkey.glb
Normal file
BIN
assets/models/monkey/Monkey.glb
Normal file
Binary file not shown.
|
@ -5,7 +5,7 @@ use bevy_render::{
|
|||
|
||||
use anyhow::Result;
|
||||
use bevy_asset::AssetLoader;
|
||||
use gltf::{buffer::Source, iter, mesh::Mode};
|
||||
use gltf::{buffer::Source, mesh::Mode};
|
||||
use std::{fs, io, path::Path};
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -22,7 +22,7 @@ impl AssetLoader<Mesh> for GltfLoader {
|
|||
}
|
||||
|
||||
fn extensions(&self) -> &[&str] {
|
||||
static EXTENSIONS: &[&str] = &["gltf"];
|
||||
static EXTENSIONS: &[&str] = &["gltf", "glb"];
|
||||
EXTENSIONS
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ pub enum GltfError {
|
|||
Gltf(#[from] gltf::Error),
|
||||
#[error("Failed to load file.")]
|
||||
Io(#[from] io::Error),
|
||||
#[error("Binary buffers not supported yet.")]
|
||||
BinaryBuffersUnsupported,
|
||||
#[error("Binary blob is missing.")]
|
||||
MissingBlob,
|
||||
#[error("Failed to decode base64 mesh data.")]
|
||||
Base64Decode(#[from] base64::DecodeError),
|
||||
#[error("Unsupported buffer format.")]
|
||||
|
@ -58,7 +58,7 @@ fn get_primitive_topology(mode: Mode) -> Result<PrimitiveTopology, GltfError> {
|
|||
// TODO: this should return a scene
|
||||
pub fn load_gltf(asset_path: &Path, bytes: Vec<u8>) -> Result<Mesh, GltfError> {
|
||||
let gltf = gltf::Gltf::from_slice(&bytes)?;
|
||||
let buffer_data = load_buffers(gltf.buffers(), asset_path)?;
|
||||
let buffer_data = load_buffers(&gltf, asset_path)?;
|
||||
for scene in gltf.scenes() {
|
||||
if let Some(node) = scene.nodes().next() {
|
||||
return Ok(load_node(&buffer_data, &node, 1)?);
|
||||
|
@ -112,11 +112,11 @@ fn load_node(buffer_data: &[Vec<u8>], node: &gltf::Node, depth: i32) -> Result<M
|
|||
panic!("failed to find mesh")
|
||||
}
|
||||
|
||||
fn load_buffers(buffers: iter::Buffers, asset_path: &Path) -> Result<Vec<Vec<u8>>, GltfError> {
|
||||
fn load_buffers(gltf: &gltf::Gltf, asset_path: &Path) -> Result<Vec<Vec<u8>>, GltfError> {
|
||||
const OCTET_STREAM_URI: &str = "data:application/octet-stream;base64,";
|
||||
|
||||
let mut buffer_data = Vec::new();
|
||||
for buffer in buffers {
|
||||
for buffer in gltf.buffers() {
|
||||
match buffer.source() {
|
||||
Source::Uri(uri) => {
|
||||
if uri.starts_with("data:") {
|
||||
|
@ -131,7 +131,13 @@ fn load_buffers(buffers: iter::Buffers, asset_path: &Path) -> Result<Vec<Vec<u8>
|
|||
buffer_data.push(buffer_bytes);
|
||||
}
|
||||
}
|
||||
Source::Bin => return Err(GltfError::BinaryBuffersUnsupported),
|
||||
Source::Bin => {
|
||||
if let Some(blob) = gltf.blob.as_deref() {
|
||||
buffer_data.push(blob.into());
|
||||
} else {
|
||||
return Err(GltfError::MissingBlob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,24 @@ fn setup(
|
|||
commands
|
||||
// mesh
|
||||
.spawn(PbrComponents {
|
||||
// load the mesh
|
||||
// load a mesh from glTF
|
||||
mesh: asset_server
|
||||
.load("assets/models/monkey/Monkey.gltf")
|
||||
.unwrap(),
|
||||
// create a material for the mesh
|
||||
material: materials.add(Color::rgb(0.5, 0.4, 0.3).into()),
|
||||
translation: Translation::new(-1.5, 0.0, 0.0),
|
||||
..Default::default()
|
||||
})
|
||||
// mesh
|
||||
.spawn(PbrComponents {
|
||||
// load a mesh from binary glTF
|
||||
mesh: asset_server
|
||||
.load("assets/models/monkey/Monkey.glb")
|
||||
.unwrap(),
|
||||
// create a material for the mesh
|
||||
material: materials.add(Color::rgb(0.5, 0.4, 0.3).into()),
|
||||
translation: Translation::new(1.5, 0.0, 0.0),
|
||||
..Default::default()
|
||||
})
|
||||
// light
|
||||
|
|
Loading…
Reference in a new issue