Skip to content

Commit

Permalink
optimize mesh rendering and use arc, fix sound volume
Browse files Browse the repository at this point in the history
  • Loading branch information
pizzart committed Oct 18, 2023
1 parent 0b556fb commit 10bf5ad
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 86 deletions.
33 changes: 22 additions & 11 deletions bff-gui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::collections::HashMap;
use std::fs::File;
use std::path::PathBuf;
use std::sync::Arc;

use bff::bigfile::BigFile;
use bff::names::Name;
Expand All @@ -21,11 +22,11 @@ mod views;
pub enum Artifact {
Bitmap(Vec<u8>),
Sound {
data: Vec<i16>,
data: Arc<Vec<i16>>,
sample_rate: u32,
channels: u16,
},
Mesh(CpuModel),
Mesh(Arc<CpuModel>),
}

fn main() -> Result<(), eframe::Error> {
Expand All @@ -51,7 +52,7 @@ struct Gui {
nickname_window_open: bool,
nickname_editing: (Name, String),
artifacts: HashMap<Name, Artifact>,
sound_volume: f32,
infos: HashMap<Name, String>,
}

impl Gui {
Expand All @@ -66,7 +67,7 @@ impl Gui {
nickname_window_open: false,
nickname_editing: (Name::default(), String::new()),
artifacts: HashMap::new(),
sound_volume: 1.0,
infos: HashMap::new(),
}
}
}
Expand All @@ -91,21 +92,31 @@ impl eframe::App for Gui {
self.resource_name = None;
}

let resource_list_response =
resource_list(ui, &self.bigfile, &self.nicknames, &self.artifacts);
let resource_list_response = resource_list(
ui,
&self.bigfile,
&self.nicknames,
&self.artifacts,
&self.infos,
);
if let Some(name) = resource_list_response.resource_context_menu {
self.nickname_window_open = true;
self.nickname_editing.0 = name;
}
if let Some(name) = resource_list_response.resource_clicked {
self.resource_name = Some(name);
}
if let Some((name, artifact)) = resource_list_response.artifact_created {
self.artifacts.insert(name, artifact);
if let Some(artifact) = resource_list_response.artifact_created {
self.artifacts.insert(name, artifact);
}
if let Some(info) = resource_list_response.info_created {
self.infos.insert(name, info);
}
}

resource_info(ui, &self.bigfile, &self.resource_name);
view(ui, &self.resource_name, &self.artifacts, self.sound_volume);
if let Some(name) = self.resource_name {
resource_info(ui, self.infos.get(&name));
}
view(ui, "center".into(), &self.resource_name, &self.artifacts);

if self.nickname_window_open {
egui::Window::new("Change resource nickname")
Expand Down
39 changes: 25 additions & 14 deletions bff-gui/src/panels/central.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::io::Cursor;
use std::sync::{Arc, Mutex};

use bff::names::Name;

Expand All @@ -8,9 +9,9 @@ use crate::Artifact;

pub fn view(
ui: &mut egui::Ui,
id_source: egui::Id,
resource_name: &Option<Name>,
artifacts: &HashMap<Name, Artifact>,
mut sound_volume: f32,
) {
// let mut response = ViewResponse::default();
egui::CentralPanel::default().show_inside(ui, |ui| {
Expand All @@ -26,17 +27,29 @@ pub fn view(
sample_rate,
channels,
} => {
ui.add(
egui::Slider::new(&mut sound_volume, 0.0..=1.0)
let mut volume = match ui
.memory(|mem| mem.data.get_temp::<Arc<Mutex<f32>>>(id_source))
{
Some(val) => *val.lock().unwrap(),
None => 1.0,
};
let response = ui.add(
egui::Slider::new(&mut volume, 0.0..=1.0)
.text("Volume")
.show_value(false),
);
if response.changed() {
ui.memory_mut(|mem| {
mem.data
.insert_temp(id_source, Arc::new(Mutex::new(volume)))
});
}
if ui.button("play").clicked() {
play_sound(data.clone(), *sample_rate, *channels, sound_volume);
play_sound(Arc::clone(data), *sample_rate, *channels, volume);
}
}
Artifact::Mesh(model) => {
ui.add(MeshView::new(model.clone()));
ui.add(MeshView::new(Arc::clone(model)));
}
}
}
Expand All @@ -45,17 +58,15 @@ pub fn view(
}

fn get_image<'a>(resource_name: &Name, data: &Vec<u8>) -> egui::Image<'a> {
egui::Image::new(
<(String, std::vec::Vec<u8>) as Into<egui::ImageSource>>::into((
format!("bytes://{}.dds", resource_name),
data.to_owned(),
)),
)
egui::Image::new(<(String, Vec<u8>) as Into<egui::ImageSource>>::into((
format!("bytes://{}.dds", resource_name),
data.to_owned(),
)))
.texture_options(egui::TextureOptions::NEAREST)
.shrink_to_fit()
}

fn play_sound(data: Vec<i16>, sample_rate: u32, channels: u16, volume: f32) {
fn play_sound(data: Arc<Vec<i16>>, sample_rate: u32, channels: u16, volume: f32) {
std::thread::spawn(move || {
let spec = hound::WavSpec {
channels,
Expand All @@ -69,8 +80,8 @@ fn play_sound(data: Vec<i16>, sample_rate: u32, channels: u16, volume: f32) {
let mut parent_writer = hound::WavWriter::new(&mut write_cursor, spec).unwrap();
let mut sample_writer = parent_writer.get_i16_writer(data.len() as u32);

for sample in data {
sample_writer.write_sample(sample);
for sample in data.iter() {
sample_writer.write_sample(*sample);
}
sample_writer.flush().unwrap();
parent_writer.finalize().unwrap();
Expand Down
30 changes: 19 additions & 11 deletions bff-gui/src/panels/left.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::{collections::HashMap, sync::Arc};

use bff::bigfile::resource::Resource;
use bff::bigfile::BigFile;
Expand All @@ -15,14 +15,16 @@ use crate::Artifact;
pub struct ResourceListResponse {
pub resource_context_menu: Option<Name>,
pub resource_clicked: Option<Name>,
pub artifact_created: Option<(Name, Artifact)>,
pub artifact_created: Option<Artifact>,
pub info_created: Option<String>,
}

pub fn resource_list(
ui: &mut egui::Ui,
bigfile: &Option<BigFile>,
nicknames: &HashMap<Name, String>,
artifacts: &HashMap<Name, Artifact>,
infos: &HashMap<Name, String>,
) -> ResourceListResponse {
let mut response = ResourceListResponse::default();
egui::SidePanel::left("left")
Expand Down Expand Up @@ -75,14 +77,20 @@ pub fn resource_list(
};
if btn.clicked() {
response.resource_clicked = Some(resource.name);
if artifacts.get(&resource.name).is_none() {
if artifacts.get(&resource.name).is_none()
|| infos.get(&resource.name).is_none()
{
match (*resource)
.try_into_version_platform(version.clone(), platform)
{
Ok(class) => {
response.info_created = Some(
serde_json::to_string_pretty::<Class>(&class)
.unwrap(),
);
if let Some(a) = create_artifact(class, &resource.name)
{
response.artifact_created = Some((resource.name, a))
response.artifact_created = Some(a);
}
}
Err(e) => {
Expand All @@ -103,11 +111,11 @@ pub fn resource_list(
fn create_artifact(class: Class, resource_name: &Name) -> Option<Artifact> {
match class {
Class::Bitmap(box_bitmap) => match *box_bitmap {
bff::class::bitmap::Bitmap::BitmapV1_291_03_06PC(ref bitmap) => {
Some(Artifact::Bitmap(bitmap.body.data.clone()))
bff::class::bitmap::Bitmap::BitmapV1_291_03_06PC(bitmap) => {
Some(Artifact::Bitmap(bitmap.body.data))
}
bff::class::bitmap::Bitmap::BitmapV1_381_67_09PC(ref bitmap) => {
Some(Artifact::Bitmap(bitmap.body.data.clone()))
bff::class::bitmap::Bitmap::BitmapV1_381_67_09PC(bitmap) => {
Some(Artifact::Bitmap(bitmap.body.data))
}
_ => None,
},
Expand Down Expand Up @@ -136,7 +144,7 @@ fn create_artifact(class: Class, resource_name: &Name) -> Option<Artifact> {
),
};
Some(Artifact::Sound {
data,
data: Arc::new(data),
sample_rate,
channels,
})
Expand Down Expand Up @@ -175,7 +183,7 @@ fn create_artifact(class: Class, resource_name: &Name) -> Option<Artifact> {
bff::class::mesh::v1_291_03_06_pc::VertexStruct::VertexStructUnknown { .. } => {
(&[0f32; 3], &[0f32; 2], &[0u8; 3], [0u8; 4])
}
}).map(|(p, u, n, t)| (Vec3::from(*p), (Vec2::from(*u), (Vec3::from(n.map(|i| (i as f32 - 128.0) / 128.0)), Vec4::from(t.map(|i| (i as f32 - 128.0) / 128.0)))))).unzip();
}).map(|(p, u, n, t)| (Vec3::from(*p), (Vec2::from(*u), ({let mut norm = n.map(|i| (i as f32 - 128.0) / 128.0); norm[2] *= -1.0; Vec3::from(norm)}, Vec4::from(t.map(|i| (i as f32 - 128.0) / 128.0)))))).unzip();
let indices: Vec<u16> = mesh
.body
.mesh_buffer
Expand Down Expand Up @@ -206,7 +214,7 @@ fn create_artifact(class: Class, resource_name: &Name) -> Option<Artifact> {
geometries: vec![primitive],
materials: vec![],
};
Some(Artifact::Mesh(model))
Some(Artifact::Mesh(Arc::new(model)))
}
_ => None,
}
Expand Down
23 changes: 3 additions & 20 deletions bff-gui/src/panels/right.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,12 @@
use bff::bigfile::BigFile;
use bff::class::Class;
use bff::names::Name;
use bff::traits::TryIntoVersionPlatform;
use egui;

pub fn resource_info(ui: &mut egui::Ui, bigfile: &Option<BigFile>, resource_name: &Option<Name>) {
pub fn resource_info(ui: &mut egui::Ui, info: Option<&String>) {
egui::SidePanel::right("right")
.resizable(true)
.width_range(100.0..=ui.available_width() / 2.0)
.show_inside(ui, |ui| {
if let Some(resource_name) = resource_name {
let json = match &bigfile
.as_ref()
.unwrap()
.objects
.get(resource_name)
.unwrap()
.try_into_version_platform(
bigfile.as_ref().unwrap().manifest.version.clone(),
bigfile.as_ref().unwrap().manifest.platform,
) {
Ok(v) => serde_json::to_string_pretty::<Class>(v).unwrap(),
Err(e) => e.to_string(),
};
let json_lines: Vec<&str> = json
if let Some(info) = info {
let json_lines: Vec<&str> = info
.split_inclusive('\n')
// .map(|s| s.to_string())
.collect();
Expand Down
Loading

0 comments on commit 10bf5ad

Please sign in to comment.