-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor: remote_asset dir and use .workspace syntax * refactor: setup bevy_remote_asset
- Loading branch information
1 parent
0258a91
commit e50c550
Showing
11 changed files
with
291 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "bevy_remote_asset" | ||
version = "0.1.0" | ||
edition = "2021" | ||
rust-version.workspace = true | ||
|
||
[dependencies] | ||
bevy.workspace = true | ||
pin-project = "1.1.3" | ||
surf = {version = "2.3", default-features = false, features = ["h1-client-rustls"]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// derived from https://github.com/johanhelsing/bevy_web_asset | ||
|
||
mod web_asset_plugin; | ||
mod web_asset_source; | ||
|
||
pub use web_asset_plugin::WebAssetPlugin; | ||
pub use web_asset_source::WebAssetReader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use bevy::prelude::*; | ||
|
||
use crate::web_asset_source::*; | ||
use bevy::asset::io::AssetSource; | ||
|
||
/// Add this plugin to bevy to support loading http and https urls. | ||
/// | ||
/// Needs to be added before Bevy's `DefaultPlugins`. | ||
/// | ||
/// # Example | ||
/// | ||
/// ```no_run | ||
/// # use bevy::prelude::*; | ||
/// # use bevy_web_asset::WebAssetPlugin; | ||
/// | ||
/// let mut app = App::new(); | ||
/// | ||
/// app.add_plugins(( | ||
/// WebAssetPlugin::default(), | ||
/// DefaultPlugins | ||
/// )); | ||
/// ``` | ||
#[derive(Default)] | ||
pub struct WebAssetPlugin; | ||
|
||
impl Plugin for WebAssetPlugin { | ||
fn build(&self, app: &mut App) { | ||
app.register_asset_source( | ||
"https", | ||
AssetSource::build().with_reader(|| Box::new(WebAssetReader::Https)), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
use bevy::{asset::io::PathStream, utils::BoxedFuture}; | ||
use std::path::{Path, PathBuf}; | ||
|
||
use bevy::asset::io::{AssetReader, AssetReaderError, Reader}; | ||
|
||
/// Treats paths as urls to load assets from. | ||
pub enum WebAssetReader { | ||
/// Use TLS for setting up connections. | ||
Https, | ||
} | ||
|
||
impl WebAssetReader { | ||
fn make_uri(&self, path: &Path) -> PathBuf { | ||
PathBuf::from(match self { | ||
Self::Https => "https://", | ||
}) | ||
.join(path) | ||
} | ||
|
||
/// See [bevy::asset::io::get_meta_path] | ||
fn make_meta_uri(&self, path: &Path) -> PathBuf { | ||
let mut uri = self.make_uri(path); | ||
let mut extension = | ||
path.extension().expect("asset paths must have extensions").to_os_string(); | ||
extension.push(".meta"); | ||
uri.set_extension(extension); | ||
uri | ||
} | ||
} | ||
|
||
async fn get<'a>(path: PathBuf) -> Result<Box<Reader<'a>>, AssetReaderError> { | ||
use std::{ | ||
future::Future, | ||
io, | ||
pin::Pin, | ||
task::{Context, Poll}, | ||
}; | ||
|
||
use bevy::asset::io::VecReader; | ||
use surf::StatusCode; | ||
|
||
#[pin_project::pin_project] | ||
struct ContinuousPoll<T>(#[pin] T); | ||
|
||
impl<T: Future> Future for ContinuousPoll<T> { | ||
type Output = T::Output; | ||
|
||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | ||
// Always wake - blocks on single threaded executor. | ||
cx.waker().wake_by_ref(); | ||
|
||
self.project().0.poll(cx) | ||
} | ||
} | ||
|
||
let str_path = path.to_str().ok_or_else(|| { | ||
AssetReaderError::Io(io::Error::new( | ||
io::ErrorKind::Other, | ||
format!("non-utf8 path: {}", path.display()), | ||
)) | ||
})?; | ||
let mut response = ContinuousPoll(surf::get(str_path)).await.map_err(|err| { | ||
AssetReaderError::Io(io::Error::new( | ||
io::ErrorKind::Other, | ||
format!( | ||
"unexpected status code {} while loading {}: {}", | ||
err.status(), | ||
path.display(), | ||
err.into_inner(), | ||
), | ||
)) | ||
})?; | ||
|
||
match response.status() { | ||
StatusCode::Ok => Ok(Box::new(VecReader::new( | ||
ContinuousPoll(response.body_bytes()) | ||
.await | ||
.map_err(|_| AssetReaderError::NotFound(path.to_path_buf()))?, | ||
)) as _), | ||
StatusCode::NotFound => Err(AssetReaderError::NotFound(path)), | ||
code => Err(AssetReaderError::Io(io::Error::new( | ||
io::ErrorKind::Other, | ||
format!("unexpected status code {} while loading {}", code, path.display()), | ||
))), | ||
} | ||
} | ||
|
||
impl AssetReader for WebAssetReader { | ||
fn read<'a>( | ||
&'a self, | ||
path: &'a Path, | ||
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> { | ||
Box::pin(get(self.make_uri(path))) | ||
} | ||
|
||
fn read_meta<'a>( | ||
&'a self, | ||
path: &'a Path, | ||
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> { | ||
Box::pin(get(self.make_meta_uri(path))) | ||
} | ||
|
||
fn is_directory<'a>( | ||
&'a self, | ||
_path: &'a Path, | ||
) -> BoxedFuture<'a, Result<bool, AssetReaderError>> { | ||
Box::pin(async { Ok(false) }) | ||
} | ||
|
||
fn read_directory<'a>( | ||
&'a self, | ||
path: &'a Path, | ||
) -> BoxedFuture<'a, Result<Box<PathStream>, AssetReaderError>> { | ||
Box::pin(async { Err(AssetReaderError::NotFound(self.make_uri(path))) }) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn make_https_uri() { | ||
assert_eq!( | ||
WebAssetReader::Https | ||
.make_uri(Path::new("s3.johanhelsing.studio/dump/favicon.png")) | ||
.to_str() | ||
.unwrap(), | ||
"https://s3.johanhelsing.studio/dump/favicon.png" | ||
); | ||
} | ||
|
||
#[test] | ||
fn make_https_meta_uri() { | ||
assert_eq!( | ||
WebAssetReader::Https | ||
.make_meta_uri(Path::new("s3.johanhelsing.studio/dump/favicon.png")) | ||
.to_str() | ||
.unwrap(), | ||
"https://s3.johanhelsing.studio/dump/favicon.png.meta" | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use bevy::{ | ||
asset::{AssetServer, Assets}, | ||
core::Name, | ||
core_pipeline::{core_3d::Camera3dBundle, tonemapping::Tonemapping}, | ||
ecs::system::{Commands, Res, ResMut}, | ||
math::Vec3, | ||
render::{camera::Camera, texture::Image}, | ||
transform::components::Transform, | ||
utils::default, | ||
}; | ||
use bevy_headless::ImageExportSource; | ||
use bevy_panorbit_camera::PanOrbitCamera; | ||
|
||
use bevy_gaussian_splatting::{GaussianCloud, GaussianSplattingBundle}; | ||
|
||
pub fn setup_gaussian_cloud( | ||
mut commands: Commands, | ||
asset_server: Res<AssetServer>, | ||
mut gaussian_assets: ResMut<Assets<GaussianCloud>>, | ||
mut scene_controller: ResMut<bevy_headless::SceneInfo>, | ||
mut images: ResMut<Assets<Image>>, | ||
export_sources: ResMut<Assets<ImageExportSource>>, | ||
) { | ||
// let remote_file = Some("https://huggingface.co/datasets/cs50victor/splats/resolve/main/train/point_cloud/iteration_7000/point_cloud.gcloud"); | ||
// TODO: figure out how to load remote files later | ||
let splat_file = "splats/garden/point_cloud/iteration_7000/point_cloud.gcloud"; | ||
log::info!("loading {}", splat_file); | ||
// let cloud = asset_server.load(splat_file.to_string()); | ||
|
||
let cloud = gaussian_assets.add(GaussianCloud::test_model()); | ||
|
||
let render_target = bevy_headless::setup_render_target( | ||
&mut commands, | ||
&mut images, | ||
&mut scene_controller, | ||
export_sources, | ||
); | ||
|
||
let gs = GaussianSplattingBundle { cloud, ..default() }; | ||
commands.spawn((gs, Name::new("gaussian_cloud"))); | ||
|
||
commands.spawn(( | ||
Camera3dBundle { | ||
transform: Transform::from_translation(Vec3::new(0.0, 1.5, 5.0)), | ||
tonemapping: Tonemapping::None, | ||
camera: Camera { target: render_target, ..default() }, | ||
..default() | ||
}, | ||
PanOrbitCamera { | ||
allow_upside_down: true, | ||
orbit_smoothness: 0.0, | ||
pan_smoothness: 0.0, | ||
zoom_smoothness: 0.0, | ||
..default() | ||
}, | ||
)); | ||
} |
Oops, something went wrong.