-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
split panels into modules, not fully complete raw exporting
- Loading branch information
Showing
9 changed files
with
629 additions
and
394 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,30 @@ | ||
use bff::names::Name; | ||
use bff::platforms::Platform; | ||
use bff::versions::Version; | ||
use bff::BffError; | ||
use derive_more::{Constructor, Display, Error, From}; | ||
|
||
#[derive(Debug, Constructor, Display, Error)] | ||
#[display( | ||
fmt = "unimplemented exporter for class {} (version: {}, platform: {}) for resource {}", | ||
class_name, | ||
version, | ||
platform, | ||
object_name | ||
)] | ||
pub struct UnimplementedExporterError { | ||
pub object_name: Name, | ||
pub class_name: Name, | ||
pub version: Version, | ||
pub platform: Platform, | ||
} | ||
|
||
#[derive(Debug, Display, Error, From)] | ||
pub enum BffGuiError { | ||
Bff(BffError), | ||
Io(std::io::Error), | ||
SerdeJson(serde_json::Error), | ||
UnimplementedExporter(UnimplementedExporterError), | ||
} | ||
|
||
pub type BffGuiResult<T> = Result<T, BffGuiError>; |
Large diffs are not rendered by default.
Oops, something went wrong.
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,86 @@ | ||
use std::collections::HashMap; | ||
use std::io::Cursor; | ||
|
||
use bff::names::Name; | ||
|
||
use crate::views::mesh::MeshView; | ||
use crate::Artifact; | ||
|
||
pub fn view( | ||
ui: &mut egui::Ui, | ||
resource_name: &Option<Name>, | ||
artifacts: &HashMap<Name, Artifact>, | ||
mut sound_volume: f32, | ||
) { | ||
// let mut response = ViewResponse::default(); | ||
egui::CentralPanel::default().show_inside(ui, |ui| { | ||
if let Some(resource_name) = resource_name { | ||
let artifact = artifacts.get(resource_name); | ||
if let Some(a) = artifact { | ||
match a { | ||
Artifact::Bitmap(bitmap) => { | ||
ui.add(get_image(resource_name, bitmap)); | ||
} | ||
Artifact::Sound { | ||
data, | ||
sample_rate, | ||
channels, | ||
} => { | ||
ui.add( | ||
egui::Slider::new(&mut sound_volume, 0.0..=1.0) | ||
.text("Volume") | ||
.show_value(false), | ||
); | ||
if ui.button("play").clicked() { | ||
play_sound(data.clone(), *sample_rate, *channels, sound_volume); | ||
} | ||
} | ||
Artifact::Mesh(model) => { | ||
ui.add(MeshView::new(model.clone())); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
|
||
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(), | ||
)), | ||
) | ||
.texture_options(egui::TextureOptions::NEAREST) | ||
.shrink_to_fit() | ||
} | ||
|
||
fn play_sound(data: Vec<i16>, sample_rate: u32, channels: u16, volume: f32) { | ||
std::thread::spawn(move || { | ||
let spec = hound::WavSpec { | ||
channels, | ||
sample_rate, | ||
bits_per_sample: 16, | ||
sample_format: hound::SampleFormat::Int, | ||
}; | ||
|
||
let mut bytes = Vec::new(); | ||
let mut write_cursor = Cursor::new(&mut bytes); | ||
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); | ||
} | ||
sample_writer.flush().unwrap(); | ||
parent_writer.finalize().unwrap(); | ||
|
||
let (_stream, stream_handle) = rodio::OutputStream::try_default().unwrap(); | ||
let sink = rodio::Sink::try_new(&stream_handle).unwrap(); | ||
let buf = std::io::BufReader::new(Cursor::new(bytes)); | ||
let source = rodio::Decoder::new_wav(buf).unwrap(); | ||
sink.set_volume(volume); | ||
sink.append(source); | ||
sink.sleep_until_end(); | ||
}); | ||
} |
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,216 @@ | ||
use std::collections::HashMap; | ||
|
||
use bff::bigfile::resource::Resource; | ||
use bff::bigfile::BigFile; | ||
use bff::class::Class; | ||
use bff::names::Name; | ||
use bff::traits::TryIntoVersionPlatform; | ||
use egui; | ||
use three_d::renderer::CpuModel; | ||
use three_d_asset::{Vec2, Vec3, Vec4}; | ||
|
||
use crate::Artifact; | ||
|
||
#[derive(Default)] | ||
pub struct ResourceListResponse { | ||
pub resource_context_menu: Option<Name>, | ||
pub resource_clicked: Option<Name>, | ||
pub artifact_created: Option<(Name, Artifact)>, | ||
} | ||
|
||
pub fn resource_list( | ||
ui: &mut egui::Ui, | ||
bigfile: &Option<BigFile>, | ||
nicknames: &HashMap<Name, String>, | ||
artifacts: &HashMap<Name, Artifact>, | ||
) -> ResourceListResponse { | ||
let mut response = ResourceListResponse::default(); | ||
egui::SidePanel::left("left") | ||
.resizable(true) | ||
.width_range(70.0..=ui.available_width() / 2.0) | ||
.show_inside(ui, |ui| { | ||
// ui.set_width_range(150.0..=200.0); | ||
if let Some(bigfile) = bigfile { | ||
let version = &bigfile.manifest.version; | ||
let platform = bigfile.manifest.platform; | ||
let resources: Vec<&Resource> = bigfile.objects.values().collect(); | ||
let row_height = ui.spacing().interact_size.y; | ||
egui::ScrollArea::vertical().show_rows( | ||
ui, | ||
row_height, | ||
resources.len(), | ||
|ui, row_range| { | ||
ui.set_min_width(ui.available_width()); | ||
for row in row_range { | ||
let resource = resources.get(row).unwrap(); | ||
let nickname = nicknames.get(&resource.name); | ||
let temp_btn = ui | ||
.add( | ||
egui::Button::new(format!( | ||
"{}.{}", | ||
match nickname { | ||
Some(nn) => nn.to_owned(), | ||
None => resource.name.to_string(), | ||
}, | ||
resource.class_name | ||
)) | ||
.wrap(false) | ||
.rounding(0.0) | ||
.min_size(egui::vec2(ui.available_width(), 0.0)), | ||
) | ||
.context_menu(|ui| { | ||
if ui.button("Change nickname").clicked() { | ||
// self.nickname_window_open = true; | ||
// self.nickname_editing.0 = resource.name; | ||
response.resource_context_menu = Some(resource.name); | ||
ui.close_menu(); | ||
} | ||
}); | ||
let btn = if nickname.is_some() { | ||
temp_btn.on_hover_ui_at_pointer(|ui| { | ||
ui.label(resource.name.to_string()); | ||
}) | ||
} else { | ||
temp_btn | ||
}; | ||
if btn.clicked() { | ||
response.resource_clicked = Some(resource.name); | ||
if artifacts.get(&resource.name).is_none() { | ||
match (*resource) | ||
.try_into_version_platform(version.clone(), platform) | ||
{ | ||
Ok(class) => { | ||
if let Some(a) = create_artifact(class, &resource.name) | ||
{ | ||
response.artifact_created = Some((resource.name, a)) | ||
} | ||
} | ||
Err(e) => { | ||
println!("{:?}", e); | ||
} | ||
} | ||
} | ||
// self.resource_name = Some(resource.name); | ||
} | ||
} | ||
}, | ||
); | ||
} | ||
}); | ||
response | ||
} | ||
|
||
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_381_67_09PC(ref bitmap) => { | ||
Some(Artifact::Bitmap(bitmap.body.data.clone())) | ||
} | ||
_ => None, | ||
}, | ||
Class::Sound(box_sound) => { | ||
let (data, sample_rate, channels) = match *box_sound { | ||
bff::class::sound::Sound::SoundV1_291_03_06PC(sound) => { | ||
// let points = sound.body.data.iter().enumerate().map(|(i, s)| eframe::epaint::Pos2{x: ((i as f32 * ui.available_width()) / sound.body.data.len() as f32), y: (s / 200 + 200).into()}).collect(); | ||
// let shape = eframe::epaint::PathShape::line(points, eframe::epaint::Stroke::new(1.0, eframe::epaint::Color32::WHITE)); | ||
// ui.painter().add(shape); | ||
( | ||
sound.body.data, | ||
sound.body.sample_rate, | ||
match sound.body.flags.stereo().value() { | ||
1 => 2, | ||
_ => 1, | ||
}, | ||
) | ||
} | ||
bff::class::sound::Sound::SoundV1_381_67_09PC(sound) => ( | ||
sound.body.data, | ||
sound.link_header.sample_rate, | ||
match sound.link_header.flags.stereo().value() { | ||
1 => 2, | ||
_ => 1, | ||
}, | ||
), | ||
}; | ||
Some(Artifact::Sound { | ||
data, | ||
sample_rate, | ||
channels, | ||
}) | ||
} | ||
Class::Mesh(box_mesh) => { | ||
match *box_mesh { | ||
bff::class::mesh::Mesh::MeshV1_291_03_06PC(mesh) => { | ||
let (positions, (uvs, (normals, tangents))): (Vec<Vec3>, (Vec<Vec2>, (Vec<Vec3>, Vec<Vec4>))) = mesh.body.mesh_buffer.vertex_buffers.iter().flat_map(|buf| &buf.vertex_structs).map(|vs| match vs { | ||
bff::class::mesh::v1_291_03_06_pc::VertexStruct::VertexStruct24 { | ||
position, uv, .. | ||
} => (position, uv, &[0u8; 3], [0u8; 4]), | ||
bff::class::mesh::v1_291_03_06_pc::VertexStruct::VertexStruct36 { | ||
position, | ||
uv, | ||
normal, | ||
tangent, | ||
tangent_padding, | ||
.. | ||
} | ||
| bff::class::mesh::v1_291_03_06_pc::VertexStruct::VertexStruct48 { | ||
position, | ||
uv, | ||
normal, | ||
tangent, | ||
tangent_padding, | ||
.. | ||
} | ||
| bff::class::mesh::v1_291_03_06_pc::VertexStruct::VertexStruct60 { | ||
position, | ||
uv, | ||
normal, | ||
tangent, | ||
tangent_padding, | ||
.. | ||
} => (position, uv, normal, [&tangent[..], &[*tangent_padding]].concat().try_into().unwrap()), | ||
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(); | ||
let indices: Vec<u16> = mesh | ||
.body | ||
.mesh_buffer | ||
.index_buffers | ||
.iter() | ||
.flat_map(|buf| &buf.tris) | ||
.flat_map(|tri| tri.indices) | ||
.map(|i| u16::try_from(i).unwrap_or(0)) | ||
.collect(); | ||
let tri_mesh = three_d::geometry::CpuMesh { | ||
positions: three_d::Positions::F32(positions), | ||
indices: three_d::Indices::U16(indices), | ||
normals: Some(normals), | ||
tangents: Some(tangents), | ||
uvs: Some(uvs), | ||
colors: None, | ||
}; | ||
let triangles = three_d_asset::geometry::Geometry::Triangles(tri_mesh); | ||
let primitive = three_d_asset::Primitive { | ||
name: "mesh".to_string(), | ||
transformation: three_d_asset::Mat4::from_translation([0.0; 3].into()), | ||
animations: vec![], | ||
geometry: triangles, | ||
material_index: None, | ||
}; | ||
let model = CpuModel { | ||
name: resource_name.to_string(), | ||
geometries: vec![primitive], | ||
materials: vec![], | ||
}; | ||
Some(Artifact::Mesh(model)) | ||
} | ||
_ => None, | ||
} | ||
} | ||
_ => None, | ||
} | ||
} |
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,4 @@ | ||
pub mod central; | ||
pub mod left; | ||
pub mod right; | ||
pub mod top; |
Oops, something went wrong.