This commit is contained in:
2024-12-29 20:38:02 +00:00
parent 12832b3deb
commit 3d401b0ae1
12 changed files with 2122 additions and 1033 deletions
+1 -2
View File
@@ -1,2 +1 @@
/target /target
Cargo.lock
+8 -8
View File
@@ -7,15 +7,15 @@
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Debug executable 'erroccfisumreg'", "name": "Debug executable 'erroccfisuvsc'",
"cargo": { "cargo": {
"args": [ "args": [
"build", "build",
"--bin=erroccfisumreg", "--bin=erroccfisuvsc",
"--package=erroccfisumreg" "--package=erroccfisuvsc"
], ],
"filter": { "filter": {
"name": "erroccfisumreg", "name": "erroccfisuvsc",
"kind": "bin" "kind": "bin"
} }
}, },
@@ -25,16 +25,16 @@
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
"name": "Debug unit tests in executable 'erroccfisumreg'", "name": "Debug unit tests in executable 'erroccfisuvsc'",
"cargo": { "cargo": {
"args": [ "args": [
"test", "test",
"--no-run", "--no-run",
"--bin=erroccfisumreg", "--bin=erroccfisuvsc",
"--package=erroccfisumreg" "--package=erroccfisuvsc"
], ],
"filter": { "filter": {
"name": "erroccfisumreg", "name": "erroccfisuvsc",
"kind": "bin" "kind": "bin"
} }
}, },
-8
View File
@@ -1,8 +0,0 @@
{
"folders": [
{
"path": ".."
}
],
"settings": {}
}
Generated
+1253 -373
View File
File diff suppressed because it is too large Load Diff
+13 -18
View File
@@ -1,21 +1,16 @@
[package] [package]
name = "erroccfisumreg" name = "erroccfisuvsc"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
vulkano = "0.32" vulkano = "0.34"
# Provides the `shader!` macro that is used to generate code for using shaders. vulkano-shaders = "0.34"
vulkano-shaders = "0.32" winit = "0.30"
# The Vulkan library doesn't provide any functionality to create and handle windows, as vulkano-win = "0.34"
# this would be out of scope. In order to open a window, we are going to use the `winit` crate. vulkano-util = "0.34"
winit = "0.28"
# The `vulkano_win` crate is the link between `vulkano` and `winit`. Vulkano doesn't know about winit,
# and winit doesn't know about vulkano, so import a crate that will provide a link between the two.
vulkano-win = "0.32"
vulkano-util = "0.32"
obj = "0.10" obj = "0.10"
bytemuck = { version = "1.13", features = [ bytemuck = { version = "1.13", features = [
@@ -26,8 +21,8 @@ bytemuck = { version = "1.13", features = [
cgmath = "0.18" cgmath = "0.18"
egui = "0.21" egui = "0.30"
egui_winit_vulkano = "0.23" egui_winit_vulkano = "0.27"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
@@ -40,8 +35,8 @@ rand = "0.8.5"
# using latest gits # using latest gits
[patch.crates-io] [patch.crates-io]
vulkano = { git = "https://github.com/Molive-0/vulkano" } vulkano = { git = "https://github.com/vulkano-rs/vulkano" }
vulkano-shaders = { git = "https://github.com/Molive-0/vulkano" } vulkano-shaders = { git = "https://github.com/vulkano-rs/vulkano" }
vulkano-win = { git = "https://github.com/Molive-0/vulkano" } vulkano-win = { git = "https://github.com/vulkano-rs/vulkano" }
vulkano-util = { git = "https://github.com/Molive-0/vulkano" } vulkano-util = { git = "https://github.com/vulkano-rs/vulkano" }
egui_winit_vulkano = { git = "https://github.com/Molive-0/egui_winit_vulkano" } egui_winit_vulkano = { git = "https://github.com/hakolao/egui_winit_vulkano" }
+2 -2
View File
@@ -1,3 +1,3 @@
# Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces Using Modern RTX Enabled GPUs # Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces Using Vulkan Specialisation Constants
## See the [report](https://mo.molive.live/dump/Final_Report.pdf) "The elites don’t want you to know this but the Specialisation Constants at the Vulkan are free you can take them home I have 458 Specialisation Constants." - Adolphe Vulk, inventor of Vulkan
+7 -8
View File
@@ -1,11 +1,10 @@
use std::env; use std::{
env, fs,
use std::fs; fs::File,
use std::fs::File; io,
use std::io; io::{BufRead, BufReader},
use std::io::BufRead; path::Path,
use std::io::BufReader; };
use std::path::Path;
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
println!("cargo:rerun-if-changed=src/instructionset.glsl"); println!("cargo:rerun-if-changed=src/instructionset.glsl");
+132 -40
View File
@@ -12,22 +12,22 @@ fn sized_text(ui: &mut egui::Ui, text: impl Into<String>, size: f32) {
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub(crate) struct PreviousDebug { pub(crate) struct PreviousDebug {
pub(crate) bounding_boxes: bool, pub(crate) bounding_boxes: bool,
pub(crate) disable_meshcull: bool, pub(crate) disable_meshcull: bool,
pub(crate) disable_meshscale1: bool, pub(crate) disable_meshscale1: bool,
pub(crate) disable_meshscale2: bool, pub(crate) disable_meshscale2: bool,
pub(crate) disable_taskcull: bool, pub(crate) disable_taskcull: bool,
pub(crate) brute_force: bool, pub(crate) brute_force: bool,
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct GState { pub(crate) struct GState {
pub(crate) cursor_sensitivity: f32, pub(crate) cursor_sensitivity: f32,
pub(crate) move_speed: f32, pub(crate) move_speed: f32,
pub(crate) meshes: Vec<Mesh>, pub(crate) meshes: Vec<Mesh>,
pub(crate) lights: Vec<Light>, pub(crate) lights: Vec<Light>,
pub(crate) csg: Vec<CSG>, pub(crate) csg: Vec<CSG>,
pub(crate) fps: [f64; 128], pub(crate) fps: [f64; 128],
@@ -38,11 +38,11 @@ impl Default for GState {
fn default() -> Self { fn default() -> Self {
Self { Self {
cursor_sensitivity: 1.0, cursor_sensitivity: 1.0,
move_speed: 1.0, move_speed: 1.0,
meshes: vec![], meshes: vec![],
lights: vec![], lights: vec![],
csg: vec![], csg: vec![],
fps: [0.0; 128], fps: [0.0; 128],
@@ -58,31 +58,61 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
.frame(Frame::default().fill(Color32::from_rgba_unmultiplied(50, 50, 50, 200))) .frame(Frame::default().fill(Color32::from_rgba_unmultiplied(50, 50, 50, 200)))
.show(&ctx, |ui| { .show(&ctx, |ui| {
ui.vertical_centered(|ui| { ui.vertical_centered(|ui| {
ui.add(egui::widgets::Label::new("Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces Using Modern RTX Enabled GPUs")); ui.add(egui::widgets::Label::new(
"Efficient Realtime Rendering of Complex Closed Form Implicit Surfaces \
Using Modern RTX Enabled GPUs",
));
sized_text(ui, "Settings", 32.0); sized_text(ui, "Settings", 32.0);
}); });
ui.separator(); ui.separator();
egui::ScrollArea::vertical().show(ui, |ui| { egui::ScrollArea::vertical().show(ui, |ui| {
ui.vertical_centered(|ui| { ui.vertical_centered(|ui| {
ui.heading("Camera Control"); ui.heading("Camera Control");
ui.add(egui::Slider::new(&mut state.cursor_sensitivity, 0.0..=2.0).text("Mouse Sensitivity")); ui.add(
ui.add(egui::Slider::new(&mut state.move_speed, 0.0..=2.0).text("Movement Speed")); egui::Slider::new(&mut state.cursor_sensitivity, 0.0..=2.0)
.text("Mouse Sensitivity"),
);
ui.add(
egui::Slider::new(&mut state.move_speed, 0.0..=2.0)
.text("Movement Speed"),
);
ui.heading("Meshes"); ui.heading("Meshes");
let mut meshdel = vec![]; let mut meshdel = vec![];
for mesh in &mut state.meshes { for mesh in &mut state.meshes {
ui.label(mesh.name.clone()); ui.label(mesh.name.clone());
meshdel.push(ui.small_button("remove mesh").clicked()); meshdel.push(ui.small_button("remove mesh").clicked());
ui.add(egui::Slider::new(&mut mesh.pos.x, -100.0..=100.0).text("Position.x")); ui.add(
ui.add(egui::Slider::new(&mut mesh.pos.y, -100.0..=100.0).text("Position.y")); egui::Slider::new(&mut mesh.pos.x, -100.0..=100.0)
ui.add(egui::Slider::new(&mut mesh.pos.z, -100.0..=100.0).text("Position.z")); .text("Position.x"),
ui.add(egui::Slider::new(&mut mesh.rot.x.0, 0.0..=360.0).text("Rotation.x")); );
ui.add(egui::Slider::new(&mut mesh.rot.y.0, 0.0..=360.0).text("Rotation.y")); ui.add(
ui.add(egui::Slider::new(&mut mesh.rot.z.0, 0.0..=360.0).text("Rotation.z")); egui::Slider::new(&mut mesh.pos.y, -100.0..=100.0)
.text("Position.y"),
);
ui.add(
egui::Slider::new(&mut mesh.pos.z, -100.0..=100.0)
.text("Position.z"),
);
ui.add(
egui::Slider::new(&mut mesh.rot.x.0, 0.0..=360.0)
.text("Rotation.x"),
);
ui.add(
egui::Slider::new(&mut mesh.rot.y.0, 0.0..=360.0)
.text("Rotation.y"),
);
ui.add(
egui::Slider::new(&mut mesh.rot.z.0, 0.0..=360.0)
.text("Rotation.z"),
);
ui.add(egui::Slider::new(&mut mesh.scale.x, 0.0..=2.0).text("Scale.x")); ui.add(egui::Slider::new(&mut mesh.scale.x, 0.0..=2.0).text("Scale.x"));
ui.add(egui::Slider::new(&mut mesh.scale.y, 0.0..=2.0).text("Scale.y")); ui.add(egui::Slider::new(&mut mesh.scale.y, 0.0..=2.0).text("Scale.y"));
ui.add(egui::Slider::new(&mut mesh.scale.z, 0.0..=2.0).text("Scale.z")); ui.add(egui::Slider::new(&mut mesh.scale.z, 0.0..=2.0).text("Scale.z"));
} }
for i in meshdel.into_iter().enumerate().filter_map(|(a,b)| if b {Some(a)} else {None}) for i in meshdel
.into_iter()
.enumerate()
.filter_map(|(a, b)| if b { Some(a) } else { None })
{ {
state.meshes.remove(i); state.meshes.remove(i);
} }
@@ -91,17 +121,35 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
for csg in &mut state.csg { for csg in &mut state.csg {
ui.label(csg.name.clone()); ui.label(csg.name.clone());
csgdel.push(ui.small_button("remove csg").clicked()); csgdel.push(ui.small_button("remove csg").clicked());
ui.add(egui::Slider::new(&mut csg.pos.x, -100.0..=100.0).text("Position.x")); ui.add(
ui.add(egui::Slider::new(&mut csg.pos.y, -100.0..=100.0).text("Position.y")); egui::Slider::new(&mut csg.pos.x, -100.0..=100.0)
ui.add(egui::Slider::new(&mut csg.pos.z, -100.0..=100.0).text("Position.z")); .text("Position.x"),
ui.add(egui::Slider::new(&mut csg.rot.x.0, 0.0..=360.0).text("Rotation.x")); );
ui.add(egui::Slider::new(&mut csg.rot.y.0, 0.0..=360.0).text("Rotation.y")); ui.add(
ui.add(egui::Slider::new(&mut csg.rot.z.0, 0.0..=360.0).text("Rotation.z")); egui::Slider::new(&mut csg.pos.y, -100.0..=100.0)
.text("Position.y"),
);
ui.add(
egui::Slider::new(&mut csg.pos.z, -100.0..=100.0)
.text("Position.z"),
);
ui.add(
egui::Slider::new(&mut csg.rot.x.0, 0.0..=360.0).text("Rotation.x"),
);
ui.add(
egui::Slider::new(&mut csg.rot.y.0, 0.0..=360.0).text("Rotation.y"),
);
ui.add(
egui::Slider::new(&mut csg.rot.z.0, 0.0..=360.0).text("Rotation.z"),
);
ui.add(egui::Slider::new(&mut csg.scale.x, 0.0..=2.0).text("Scale.x")); ui.add(egui::Slider::new(&mut csg.scale.x, 0.0..=2.0).text("Scale.x"));
ui.add(egui::Slider::new(&mut csg.scale.y, 0.0..=2.0).text("Scale.y")); ui.add(egui::Slider::new(&mut csg.scale.y, 0.0..=2.0).text("Scale.y"));
ui.add(egui::Slider::new(&mut csg.scale.z, 0.0..=2.0).text("Scale.z")); ui.add(egui::Slider::new(&mut csg.scale.z, 0.0..=2.0).text("Scale.z"));
} }
for i in csgdel.into_iter().enumerate().filter_map(|(a,b)| if b {Some(a)} else {None}) for i in csgdel
.into_iter()
.enumerate()
.filter_map(|(a, b)| if b { Some(a) } else { None })
{ {
state.csg.remove(i); state.csg.remove(i);
} }
@@ -110,14 +158,32 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
for light in &mut state.lights { for light in &mut state.lights {
ui.label("Light"); ui.label("Light");
lightdel.push(ui.small_button("remove light").clicked()); lightdel.push(ui.small_button("remove light").clicked());
ui.add(egui::Slider::new(&mut light.pos.x, -100.0..=100.0).text("Position.x")); ui.add(
ui.add(egui::Slider::new(&mut light.pos.y, -100.0..=100.0).text("Position.y")); egui::Slider::new(&mut light.pos.x, -100.0..=100.0)
ui.add(egui::Slider::new(&mut light.pos.z, -100.0..=100.0).text("Position.z")); .text("Position.x"),
ui.add(egui::Slider::new(&mut light.colour.x, 0.0..=1.0).text("Colour.r")); );
ui.add(egui::Slider::new(&mut light.colour.y, 0.0..=1.0).text("Colour.g")); ui.add(
ui.add(egui::Slider::new(&mut light.colour.z, 0.0..=1.0).text("Colour.b")); egui::Slider::new(&mut light.pos.y, -100.0..=100.0)
.text("Position.y"),
);
ui.add(
egui::Slider::new(&mut light.pos.z, -100.0..=100.0)
.text("Position.z"),
);
ui.add(
egui::Slider::new(&mut light.colour.x, 0.0..=1.0).text("Colour.r"),
);
ui.add(
egui::Slider::new(&mut light.colour.y, 0.0..=1.0).text("Colour.g"),
);
ui.add(
egui::Slider::new(&mut light.colour.z, 0.0..=1.0).text("Colour.b"),
);
} }
for i in lightdel.into_iter().enumerate().filter_map(|(a,b)| if b {Some(a)} else {None}) for i in lightdel
.into_iter()
.enumerate()
.filter_map(|(a, b)| if b { Some(a) } else { None })
{ {
state.lights.remove(i); state.lights.remove(i);
} }
@@ -125,18 +191,44 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
state.lights.push(Light::default()); state.lights.push(Light::default());
} }
let fps: PlotPoints = state.fps.iter().enumerate().map(|(x,y)| [x as f64,*y]).collect::<Vec<_>>().into(); let fps: PlotPoints = state
.fps
.iter()
.enumerate()
.map(|(x, y)| [x as f64, *y])
.collect::<Vec<_>>()
.into();
let line = Line::new(fps); let line = Line::new(fps);
ui.heading("FPS"); ui.heading("FPS");
Plot::new("fps").view_aspect(2.0).show(ui, |plot_ui| plot_ui.line(line)); Plot::new("fps")
.view_aspect(2.0)
.show(ui, |plot_ui| plot_ui.line(line));
ui.heading("Debug"); ui.heading("Debug");
ui.toggle_value(&mut state.debug.bounding_boxes, "Render bounding boxes instead"); ui.toggle_value(
ui.toggle_value(&mut state.debug.disable_meshcull, "Disable mesh shader culling"); &mut state.debug.bounding_boxes,
ui.toggle_value(&mut state.debug.disable_meshscale1, "Disable mesh shader scaling part 1"); "Render bounding boxes instead",
ui.toggle_value(&mut state.debug.disable_meshscale2, "Disable mesh shader scaling part 2"); );
ui.toggle_value(&mut state.debug.disable_taskcull, "Disable task shader culling"); ui.toggle_value(
ui.toggle_value(&mut state.debug.brute_force, "Brute force the render (use no new techniques)"); &mut state.debug.disable_meshcull,
"Disable mesh shader culling",
);
ui.toggle_value(
&mut state.debug.disable_meshscale1,
"Disable mesh shader scaling part 1",
);
ui.toggle_value(
&mut state.debug.disable_meshscale2,
"Disable mesh shader scaling part 2",
);
ui.toggle_value(
&mut state.debug.disable_taskcull,
"Disable task shader culling",
);
ui.toggle_value(
&mut state.debug.brute_force,
"Brute force the render (use no new techniques)",
);
}); });
}); });
}); });
+271 -274
View File
File diff suppressed because it is too large Load Diff
+379 -247
View File
File diff suppressed because it is too large Load Diff
+26 -23
View File
@@ -1,13 +1,16 @@
use std::fmt::Display; use std::{
use std::io::{BufReader, Read}; fmt::Display,
io::{BufReader, Read},
use std::str::Chars; str::Chars,
};
use serde::de::{
self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, use serde::{
Visitor, de::{
self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess,
Visitor,
},
forward_to_deserialize_any, Deserialize,
}; };
use serde::{forward_to_deserialize_any, Deserialize};
use utf8::BufReadDecoder; use utf8::BufReadDecoder;
type Result<T> = core::result::Result<T, Error>; type Result<T> = core::result::Result<T, Error>;
@@ -50,9 +53,9 @@ impl serde::ser::Error for Error {
pub(crate) struct Deserializer<'de> { pub(crate) struct Deserializer<'de> {
// This string starts with the input data and characters are truncated off // This string starts with the input data and characters are truncated off
// the beginning as data is parsed. // the beginning as data is parsed.
input: BufReadDecoder<BufReader<&'de mut dyn Read>>, input: BufReadDecoder<BufReader<&'de mut dyn Read>>,
read_buf: String, read_buf: String,
peek: Option<(char, usize)>, peek: Option<(char, usize)>,
} }
impl<'de> Deserializer<'de> { impl<'de> Deserializer<'de> {
@@ -63,9 +66,9 @@ impl<'de> Deserializer<'de> {
pub(crate) fn from_reader(input: &'de mut dyn Read) -> Self { pub(crate) fn from_reader(input: &'de mut dyn Read) -> Self {
Deserializer { Deserializer {
input: BufReadDecoder::new(BufReader::new(input)), input: BufReadDecoder::new(BufReader::new(input)),
read_buf: String::new(), read_buf: String::new(),
peek: None, peek: None,
} }
} }
} }
@@ -128,16 +131,16 @@ impl<'de> Deserializer<'de> {
Ok(c) => { Ok(c) => {
self.peek = Some(c); self.peek = Some(c);
return Ok(c); return Ok(c);
} },
Err(Error::Eof) => match self.input.next_strict() { Err(Error::Eof) => match self.input.next_strict() {
Some(e) => { Some(e) => {
match e { match e {
Ok(s) => { Ok(s) => {
s.clone_into(&mut self.read_buf); s.clone_into(&mut self.read_buf);
} },
Err(e) => return Err(Error::UTF8(format!("{e}"))), Err(e) => return Err(Error::UTF8(format!("{e}"))),
}; };
} },
None => return Err(Error::Eof), None => return Err(Error::Eof),
}, },
Err(e) => return Err(e), Err(e) => return Err(e),
@@ -168,16 +171,16 @@ impl<'de> Deserializer<'de> {
let out = self.read_buf[..len].to_string(); let out = self.read_buf[..len].to_string();
self.read_buf = self.read_buf[len + 1..].to_string(); self.read_buf = self.read_buf[len + 1..].to_string();
return Ok(out); return Ok(out);
} },
None => match self.input.next_strict() { None => match self.input.next_strict() {
Some(e) => { Some(e) => {
match e { match e {
Ok(s) => { Ok(s) => {
s.clone_into(&mut self.read_buf); s.clone_into(&mut self.read_buf);
} },
Err(e) => return Err(Error::UTF8(format!("{e}"))), Err(e) => return Err(Error::UTF8(format!("{e}"))),
}; };
} },
None => return Err(Error::Eof), None => return Err(Error::Eof),
}, },
} }
@@ -188,6 +191,10 @@ impl<'de> Deserializer<'de> {
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = Error; type Error = Error;
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char bytes byte_buf option unit unit_struct
}
// Look at the input data to decide what Serde data model type to // Look at the input data to decide what Serde data model type to
// deserialize as. Not all data formats are able to support this operation. // deserialize as. Not all data formats are able to support this operation.
// Formats that support `deserialize_any` are known as self-describing. // Formats that support `deserialize_any` are known as self-describing.
@@ -371,10 +378,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
{ {
self.deserialize_any(visitor) self.deserialize_any(visitor)
} }
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char bytes byte_buf option unit unit_struct
}
} }
// In order to handle commas correctly when deserializing a JSON array or map, // In order to handle commas correctly when deserializing a JSON array or map,
+30 -30
View File
@@ -16,41 +16,41 @@ use vulkano::{
pipeline::graphics::vertex_input::Vertex, pipeline::graphics::vertex_input::Vertex,
}; };
use crate::instruction_set::InstructionSet; use crate::{instruction_set::InstructionSet, mcsg_deserialise::from_reader, MemoryAllocator};
use crate::{mcsg_deserialise::from_reader, MemoryAllocator};
pub(crate) const PLATONIC_SOLIDS: [(&str, &[u8]); 1] = [("Buny", include_bytes!("bunny.obj"))]; pub(crate) const PLATONIC_SOLIDS: [(&str, &[u8]); 1] = [("Buny", include_bytes!("bunny.obj"))];
pub(crate) const CSG_SOLIDS: [(&str, &[u8]); 1] = pub(crate) const CSG_SOLIDS: [(&str, &[u8]); 1] =
[("Primitives", include_bytes!("primitive.mcsg"))]; [("Primitives", include_bytes!("primitive.mcsg"))];
// We now create a buffer that will store the shape of our triangle. // We now create a buffer that will store the shape of our triangle.
// We use #[repr(C)] here to force rustc to not do anything funky with our data, although for this // We use #[repr(C)] here to force rustc to not do anything funky with our data,
// particular example, it doesn't actually change the in-memory representation. // although for this particular example, it doesn't actually change the
// in-memory representation.
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod, Vertex)] #[derive(Clone, Copy, Debug, Default, Zeroable, Pod, Vertex)]
pub(crate) struct OVertex { pub(crate) struct OVertex {
#[format(R32G32B32_SFLOAT)] #[format(R32G32B32_SFLOAT)]
position: [f32; 3], position: [f32; 3],
#[format(R32G32B32_SFLOAT)] #[format(R32G32B32_SFLOAT)]
normal: [f32; 3], normal: [f32; 3],
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Mesh { pub(crate) struct Mesh {
pub(crate) name: String, pub(crate) name: String,
pub(crate) vertices: Subbuffer<[OVertex]>, pub(crate) vertices: Subbuffer<[OVertex]>,
pub(crate) indices: Subbuffer<[u32]>, pub(crate) indices: Subbuffer<[u32]>,
pub(crate) pos: Point3<f32>, pub(crate) pos: Point3<f32>,
pub(crate) rot: Euler<Deg<f32>>, pub(crate) rot: Euler<Deg<f32>>,
pub(crate) scale: Vector3<f32>, pub(crate) scale: Vector3<f32>,
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct CSG { pub(crate) struct CSG {
pub(crate) name: String, pub(crate) name: String,
pub(crate) parts: Vec<CSGPart>, pub(crate) parts: Vec<CSGPart>,
pub(crate) pos: Point3<f32>, pub(crate) pos: Point3<f32>,
pub(crate) rot: Euler<Deg<f32>>, pub(crate) rot: Euler<Deg<f32>>,
pub(crate) scale: Vector3<f32>, pub(crate) scale: Vector3<f32>,
} }
@@ -78,10 +78,10 @@ pub(crate) enum Inputs {
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct CSGPart { pub(crate) struct CSGPart {
pub(crate) code: u16, pub(crate) code: u16,
pub(crate) opcode: InstructionSet, pub(crate) opcode: InstructionSet,
pub(crate) constants: Vec<Inputs>, pub(crate) constants: Vec<Inputs>,
pub(crate) material: Option<Mat4>, pub(crate) material: Option<Mat4>,
} }
impl CSGPart { impl CSGPart {
@@ -130,9 +130,9 @@ pub(crate) fn load_obj(
let mut temp_hash_map = HashMap::<(u32, u32), u32>::new(); let mut temp_hash_map = HashMap::<(u32, u32), u32>::new();
// We're gonna have to remap all the indices that OBJ uses. Annoying. // We're gonna have to remap all the indices that OBJ uses. Annoying.
// Get each pair of vertex position to vertex normal and assign it a new index. This might duplicate // Get each pair of vertex position to vertex normal and assign it a new index.
// vertices or normals but each *pair* needs a unique index // This might duplicate vertices or normals but each *pair* needs a unique
// Uses the hash map to check that we're not duplicating unnecessarily // index Uses the hash map to check that we're not duplicating unnecessarily
for g in &object.objects[0].groups { for g in &object.objects[0].groups {
for p in &g.polys { for p in &g.polys {
for v in &p.0 { for v in &p.0 {
@@ -144,7 +144,7 @@ pub(crate) fn load_obj(
} else { } else {
vertices.push(OVertex { vertices.push(OVertex {
position: object.position[mapping.0 as usize], position: object.position[mapping.0 as usize],
normal: object.normal[mapping.1 as usize], normal: object.normal[mapping.1 as usize],
}); });
temp_hash_map.insert(mapping, (vertices.len() - 1) as u32); temp_hash_map.insert(mapping, (vertices.len() - 1) as u32);
indices.push((vertices.len() - 1) as u32); indices.push((vertices.len() - 1) as u32);
@@ -194,7 +194,7 @@ pub(crate) fn load_obj(
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct MCSG { struct MCSG {
object: Vec<MCSGObject>, object: Vec<MCSGObject>,
csg: Vec<MCSGCSG>, csg: Vec<MCSGCSG>,
} }
type MCSGObject = HashMap<String, String>; type MCSGObject = HashMap<String, String>;
type MCSGCSG = Vec<MCSGCSGPart>; type MCSGCSG = Vec<MCSGCSGPart>;
@@ -234,8 +234,8 @@ fn point3_from_string(input: &str) -> Result<Point3<f32>, String> {
} }
struct TRS { struct TRS {
translation: Point3<f32>, translation: Point3<f32>,
rotation: Matrix3<f32>, rotation: Matrix3<f32>,
scale: Vector3<f32>, scale: Vector3<f32>,
} }
fn get_trs(o: &HashMap<String, String>) -> Result<TRS, String> { fn get_trs(o: &HashMap<String, String>) -> Result<TRS, String> {
@@ -246,13 +246,13 @@ fn get_trs(o: &HashMap<String, String>) -> Result<TRS, String> {
.map(point3_from_string) .map(point3_from_string)
.transpose()? .transpose()?
.unwrap_or(Point3::origin()), .unwrap_or(Point3::origin()),
rotation: o rotation: o
.get("r") .get("r")
.map(String::as_str) .map(String::as_str)
.map(matrix3_from_string) .map(matrix3_from_string)
.transpose()? .transpose()?
.unwrap_or(Matrix3::identity()), .unwrap_or(Matrix3::identity()),
scale: o scale: o
.get("s") .get("s")
.map(String::as_str) .map(String::as_str)
.map(vector3_from_string) .map(vector3_from_string)
@@ -379,8 +379,8 @@ pub(crate) fn load_csg(
let _rgb = get_rgb(inpart)?; let _rgb = get_rgb(inpart)?;
let _trs = get_trs(inpart)?; let _trs = get_trs(inpart)?;
let _half = get_half(inpart)?; let _half = get_half(inpart)?;
} },
_ => {} //return Err("unknown type of csg".to_owned()), _ => {}, //return Err("unknown type of csg".to_owned()),
} }
Ok(csgpart) Ok(csgpart)
}) })
@@ -407,7 +407,7 @@ pub(crate) fn load_csg(
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Light { pub(crate) struct Light {
pub(crate) pos: Point3<f32>, pub(crate) pos: Point3<f32>,
pub(crate) colour: Vector3<f32>, pub(crate) colour: Vector3<f32>,
} }
@@ -415,7 +415,7 @@ impl Light {
pub(crate) fn new(pos: [f32; 3], colour: [f32; 3], intensity: f32) -> Light { pub(crate) fn new(pos: [f32; 3], colour: [f32; 3], intensity: f32) -> Light {
let c: Vector3<f32> = colour.into(); let c: Vector3<f32> = colour.into();
Light { Light {
pos: pos.into(), pos: pos.into(),
colour: c * intensity, colour: c * intensity,
} }
} }
@@ -424,7 +424,7 @@ impl Light {
impl Default for Light { impl Default for Light {
fn default() -> Self { fn default() -> Self {
Self { Self {
pos: Point3::origin(), pos: Point3::origin(),
colour: Vector3 { colour: Vector3 {
x: 1., x: 1.,
y: 1., y: 1.,