Skip to content

Commit

Permalink
feat: bevy 0.14 (#112)
Browse files Browse the repository at this point in the history
* feat: bevy 0.14 building

* fix: view matrices
  • Loading branch information
mosure authored Sep 4, 2024
1 parent b76171a commit 3913ef0
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 146 deletions.
18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bevy_gaussian_splatting"
description = "bevy gaussian splatting render pipeline plugin"
version = "2.2.1"
version = "2.3.0"
edition = "2021"
authors = ["mosure <[email protected]>"]
license = "MIT"
Expand Down Expand Up @@ -112,7 +112,7 @@ viewer = [
"bevy-inspector-egui",
"bevy_panorbit_camera",
# "bevy_transform_gizmo",
"bevy/multi-threaded", # bevy screenshot functionality requires bevy/multi-threaded as of 0.12.1
"bevy/multi_threaded", # bevy screenshot functionality requires bevy/multi_threaded as of 0.12.1
"clap",
"bevy/bevy_ui",
]
Expand All @@ -133,11 +133,11 @@ webgpu = ["bevy/webgpu"]


[dependencies]
bevy_args = { version = "1.4.2" }
bevy-inspector-egui = { version = "0.24", optional = true }
bevy_mod_picking = { version = "0.18", optional = true }
bevy_panorbit_camera = { version = "0.18", optional = true }
bevy_transform_gizmo = { version = "0.11", optional = true }
bevy_args = "1.6"
bevy-inspector-egui = { version = "0.25", optional = true }
bevy_mod_picking = { version = "0.20", optional = true }
bevy_panorbit_camera = { version = "0.19", optional = true }
bevy_transform_gizmo = { version = "0.12", optional = true }
bincode2 = { version = "2.0", optional = true }
byte-unit = { version = "5.0", optional = true }
bytemuck = "1.14"
Expand All @@ -154,7 +154,7 @@ rayon = { version = "1.8", optional = true }
serde = "1.0"
static_assertions = "1.1"
typenum = "1.17"
wgpu = "0.19.1"
wgpu = "0.20"


[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand All @@ -163,7 +163,7 @@ wasm-bindgen = "0.2"


[dependencies.bevy]
version = "0.13"
version = "0.14"
default-features = false
features = [
"bevy_asset",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ fn setup_gaussian_cloud(

| `bevy_gaussian_splatting` | `bevy` |
| :-- | :-- |
| `2.3` | `0.14` |
| `2.1` | `0.13` |
| `0.4 - 2.0` | `0.12` |
| `0.1 - 0.3` | `0.11` |
Expand Down
15 changes: 7 additions & 8 deletions examples/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mod frame_capture {
use bevy::render::render_graph::{self, NodeRunError, RenderGraph, RenderGraphContext, RenderLabel};
use bevy::render::renderer::{RenderContext, RenderDevice, RenderQueue};
use bevy::render::{Extract, RenderApp};
use bevy::render::texture::GpuImage;

use bevy::render::render_resource::{
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d,
Expand Down Expand Up @@ -85,10 +86,9 @@ mod frame_capture {

render_app.add_systems(ExtractSchedule, image_copy_extract);

let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
let mut graph = render_app.world_mut().get_resource_mut::<RenderGraph>().unwrap();

graph.add_node(ImageCopyLabel, ImageCopyDriver);

graph.add_node_edge(ImageCopyLabel, bevy::render::graph::CameraDriverLabel);
}
}
Expand Down Expand Up @@ -154,7 +154,7 @@ mod frame_capture {
world: &World,
) -> Result<(), NodeRunError> {
let image_copiers = world.get_resource::<ImageCopiers>().unwrap();
let gpu_images = world.get_resource::<RenderAssets<Image>>().unwrap();
let gpu_images = world.get_resource::<RenderAssets<GpuImage>>().unwrap();

for image_copier in image_copiers.iter() {
if !image_copier.enabled() {
Expand Down Expand Up @@ -333,7 +333,7 @@ mod frame_capture {
) {
if let SceneState::Render(n) = scene_controller.state {
if n < 1 {
for image in images_to_save.iter() {
for (i, image) in images_to_save.iter().enumerate() {
let img_bytes = images.get_mut(image.id()).unwrap();

let img = match img_bytes.clone().try_into_dynamic() {
Expand All @@ -345,14 +345,13 @@ mod frame_capture {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("headless_output");
std::fs::create_dir_all(&images_dir).unwrap();

let uuid = bevy::utils::Uuid::new_v4();
let image_path = images_dir.join(format!("{uuid}.png"));
let image_path = images_dir.join(format!("{i}.png"));
if let Err(e) = img.save(image_path){
panic!("Failed to save image: {}", e);
};
}
if scene_controller.single_image {
app_exit_writer.send(AppExit);
app_exit_writer.send(AppExit::Success);
}
} else {
scene_controller.state = SceneState::Render(n - 1);
Expand Down Expand Up @@ -428,7 +427,7 @@ fn headless_app() {

// setup frame capture
app.insert_resource(frame_capture::scene::SceneController::new(config.width, config.height, config.single_image));
app.insert_resource(ClearColor(Color::rgb_u8(0, 0, 0)));
app.insert_resource(ClearColor(Color::srgb_u8(0, 0, 0)));

app.add_plugins(
DefaultPlugins
Expand Down
68 changes: 31 additions & 37 deletions src/io/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ use std::io::{
ErrorKind,
};

use bevy::{
asset::{
AssetLoader,
AsyncReadExt,
LoadContext,
io::Reader,
},
utils::BoxedFuture,
use bevy::asset::{
AssetLoader,
AsyncReadExt,
LoadContext,
io::Reader,
};

use crate::{
Expand All @@ -29,42 +26,39 @@ impl AssetLoader for GaussianCloudLoader {
type Settings = ();
type Error = std::io::Error;

fn load<'a>(
async fn load<'a>(
&'a self,
reader: &'a mut Reader,
reader: &'a mut Reader<'_>,
_settings: &'a Self::Settings,
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;

Box::pin(async move {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
match load_context.path().extension() {
Some(ext) if ext == "ply" => {
#[cfg(feature = "io_ply")]
{
let cursor = Cursor::new(bytes);
let mut f = BufReader::new(cursor);

match load_context.path().extension() {
Some(ext) if ext == "ply" => {
#[cfg(feature = "io_ply")]
{
let cursor = Cursor::new(bytes);
let mut f = BufReader::new(cursor);
let gaussians = crate::io::ply::parse_ply(&mut f)?;

let gaussians = crate::io::ply::parse_ply(&mut f)?;
Ok(GaussianCloud::from_gaussians(gaussians))
}

Ok(GaussianCloud::from_gaussians(gaussians))
}
#[cfg(not(feature = "io_ply"))]
{
Err(std::io::Error::new(ErrorKind::Other, "ply support not enabled, enable with io_ply feature"))
}
},
Some(ext) if ext == "gcloud" => {
let cloud = GaussianCloud::decode(bytes.as_slice());

#[cfg(not(feature = "io_ply"))]
{
Err(std::io::Error::new(ErrorKind::Other, "ply support not enabled, enable with io_ply feature"))
}
},
Some(ext) if ext == "gcloud" => {
let cloud = GaussianCloud::decode(bytes.as_slice());

Ok(cloud)
},
_ => Err(std::io::Error::new(ErrorKind::Other, "only .ply and .gcloud supported")),
}
})
Ok(cloud)
},
_ => Err(std::io::Error::new(ErrorKind::Other, "only .ply and .gcloud supported")),
}
}

fn extensions(&self) -> &[&str] {
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub struct GaussianSplattingBundle {
}


#[derive(Component, Default)]
struct GaussianSplattingCamera;
// #[derive(Component, Default)]
// struct GaussianSplattingCamera;
// TODO: filter camera 3D entities

pub struct GaussianSplattingPlugin;
Expand Down
32 changes: 16 additions & 16 deletions src/morph/particle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ impl Plugin for ParticleBehaviorPlugin {
app.register_type::<ParticleBehaviors>();
app.init_asset::<ParticleBehaviors>();
app.register_asset_reflect::<ParticleBehaviors>();
app.add_plugins(RenderAssetPlugin::<ParticleBehaviors>::default());
app.add_plugins(RenderAssetPlugin::<GpuParticleBehaviorBuffers>::default());

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.add_render_graph_node::<ParticleBehaviorNode>(
Core3d,
Expand All @@ -128,14 +128,14 @@ impl Plugin for ParticleBehaviorPlugin {
.add_systems(
Render,
(
queue_particle_behavior_bind_group.in_set(RenderSet::QueueMeshes),
queue_particle_behavior_bind_group.in_set(RenderSet::Queue),
),
);
}
}

fn finish(&self, app: &mut App) {
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<ParticleBehaviorPipeline>();
}
Expand Down Expand Up @@ -172,20 +172,20 @@ pub struct GpuParticleBehaviorBuffers {
pub particle_behavior_buffer: Buffer,
}

impl RenderAsset for ParticleBehaviors {
type PreparedAsset = GpuParticleBehaviorBuffers;
impl RenderAsset for GpuParticleBehaviorBuffers {
type SourceAsset = ParticleBehaviors;
type Param = SRes<RenderDevice>;

fn prepare_asset(
self,
source: Self::SourceAsset,
render_device: &mut SystemParamItem<Self::Param>,
) -> Result<Self::PreparedAsset, PrepareAssetError<Self>> {
let particle_behavior_count = self.0.len() as u32;
) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
let particle_behavior_count = source.0.len() as u32;

let particle_behavior_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
label: Some("particle behavior buffer"),
contents: bytemuck::cast_slice(
self.0.as_slice()
source.0.as_slice()
),
usage: BufferUsages::VERTEX | BufferUsages::COPY_DST | BufferUsages::STORAGE,
});
Expand All @@ -196,8 +196,8 @@ impl RenderAsset for ParticleBehaviors {
})
}

fn asset_usage(&self) -> RenderAssetUsages {
RenderAssetUsages::RENDER_WORLD
fn asset_usage(_: &Self::SourceAsset) -> RenderAssetUsages {
RenderAssetUsages::default()
}
}

Expand Down Expand Up @@ -265,7 +265,7 @@ pub fn queue_particle_behavior_bind_group(
particle_behavior_pipeline: Res<ParticleBehaviorPipeline>,
render_device: Res<RenderDevice>,
asset_server: Res<AssetServer>,
particle_behaviors_res: Res<RenderAssets<ParticleBehaviors>>,
particle_behaviors_res: Res<RenderAssets<GpuParticleBehaviorBuffers>>,
particle_behaviors: Query<(
Entity,
&Handle<ParticleBehaviors>,
Expand All @@ -276,11 +276,11 @@ pub fn queue_particle_behavior_bind_group(
continue;
}

if particle_behaviors_res.get(behaviors_handle).is_none() {
if particle_behaviors_res.get(behaviors_handle.id()).is_none() {
continue;
}

let behaviors = particle_behaviors_res.get(behaviors_handle).unwrap();
let behaviors = particle_behaviors_res.get(behaviors_handle.id()).unwrap();

let particle_behavior_bindgroup = render_device.create_bind_group(
"particle_behavior_bind_group",
Expand Down Expand Up @@ -375,7 +375,7 @@ impl Node for ParticleBehaviorNode {
behaviors_handle,
particle_behavior_bind_group,
) in self.gaussian_clouds.iter_manual(world) {
let behaviors = world.get_resource::<RenderAssets<ParticleBehaviors>>().unwrap().get(behaviors_handle).unwrap();
let behaviors = world.get_resource::<RenderAssets<GpuParticleBehaviorBuffers>>().unwrap().get(behaviors_handle.id()).unwrap();
let gaussian_uniforms = world.resource::<GaussianUniformBindGroups>();

{
Expand Down
12 changes: 6 additions & 6 deletions src/render/gaussian.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ fn compute_cov2d(
cov3d[2], cov3d[4], cov3d[5],
);

var t = view.inverse_view * vec4<f32>(position, 1.0);
var t = view.view_from_world * vec4<f32>(position, 1.0);

let focal = vec2<f32>(
view.projection.x.x * view.viewport.z,
view.projection.y.y * view.viewport.w,
view.clip_from_view .x.x * view.viewport.z,
view.clip_from_view .y.y * view.viewport.w,
);

let s = 1.0 / (t.z * t.z);
Expand All @@ -226,9 +226,9 @@ fn compute_cov2d(

let W = transpose(
mat3x3<f32>(
view.inverse_view.x.xyz,
view.inverse_view.y.xyz,
view.inverse_view.z.xyz,
view.view_from_world.x.xyz,
view.view_from_world.y.xyz,
view.view_from_world.z.xyz,
)
);

Expand Down
Loading

0 comments on commit 3913ef0

Please sign in to comment.