This commit is contained in:
Robin Appelman 2022-12-24 19:26:24 +01:00
commit f4f173c84e
11 changed files with 134 additions and 52 deletions

View file

@ -46,7 +46,7 @@ fn main() -> Result<(), Error> {
max_size: Some((1920, 1080)), max_size: Some((1920, 1080)),
..Default::default() ..Default::default()
}) })
.unwrap(); .unwrap();
let context = window.gl(); let context = window.gl();
let mut camera = Camera::new_perspective( let mut camera = Camera::new_perspective(
@ -82,10 +82,13 @@ fn main() -> Result<(), Error> {
..Default::default() ..Default::default()
}; };
let model: three_d::Model<PhysicalMaterial> = three_d::Model::new(&context, &CpuModel { let model: three_d::Model<PhysicalMaterial> = three_d::Model::new(
materials: vec![material], &context,
geometries: vec![cpu_mesh], &CpuModel {
})?; materials: vec![material],
geometries: vec![cpu_mesh],
},
)?;
let mut directional = [ let mut directional = [
DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(1.0, -1.0, 0.0)), DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(1.0, -1.0, 0.0)),
@ -107,16 +110,19 @@ fn main() -> Result<(), Error> {
window.render_loop(move |mut frame_input| { window.render_loop(move |mut frame_input| {
let mut change = frame_input.first_frame; let mut change = frame_input.first_frame;
let mut panel_width = frame_input.viewport.width; let mut panel_width = frame_input.viewport.width;
change |= gui change |= gui.update(
.update(&mut frame_input.events, frame_input.accumulated_time, frame_input.viewport, frame_input.device_pixel_ratio, |gui_context| { &mut frame_input.events,
frame_input.accumulated_time,
frame_input.viewport,
frame_input.device_pixel_ratio,
|gui_context| {
use three_d::egui::*; use three_d::egui::*;
SidePanel::left("side_panel").show(gui_context, |ui| { SidePanel::left("side_panel").show(gui_context, |ui| {
ui.heading("Debug Panel"); ui.heading("Debug Panel");
ui.label("Light options"); ui.label("Light options");
ui.add( ui.add(
Slider::new(&mut ambient.intensity, 0.0..=1.0) Slider::new(&mut ambient.intensity, 0.0..=1.0).text("Ambient intensity"),
.text("Ambient intensity"),
); );
ui.add( ui.add(
Slider::new(&mut directional_intensity, 0.0..=1.0) Slider::new(&mut directional_intensity, 0.0..=1.0)
@ -149,7 +155,8 @@ fn main() -> Result<(), Error> {
ui.add(Label::new(format!("\tz: {}", camera.position().z))); ui.add(Label::new(format!("\tz: {}", camera.position().z)));
}); });
panel_width = gui_context.used_size().x as u32; panel_width = gui_context.used_size().x as u32;
}); },
);
let viewport = Viewport { let viewport = Viewport {
x: panel_width as i32, x: panel_width as i32,
@ -158,70 +165,71 @@ fn main() -> Result<(), Error> {
height: frame_input.viewport.height, height: frame_input.viewport.height,
}; };
change |= camera.set_viewport(viewport); change |= camera.set_viewport(viewport);
change |= control change |= control.handle_events(&mut camera, &mut frame_input.events);
.handle_events(&mut camera, &mut frame_input.events);
// Draw // Draw
{ {
camera camera.set_perspective_projection(degrees(fov), camera.z_near(), camera.z_far());
.set_perspective_projection(degrees(fov), camera.z_near(), camera.z_far());
if shadows_enabled { if shadows_enabled {
directional[0] directional[0].generate_shadow_map(1024, model.iter().map(|gm| &gm.geometry));
.generate_shadow_map(1024, model.iter().map(|gm| &gm.geometry)); directional[1].generate_shadow_map(1024, model.iter().map(|gm| &gm.geometry));
directional[1]
.generate_shadow_map(1024, model.iter().map(|gm| &gm.geometry));
} }
let lights = &[&ambient as &dyn Light, &directional[0], &directional[1]];
let lights = &[
&ambient as &dyn Light,
&directional[0],
&directional[1],
];
// Light pass // Light pass
let screen = frame_input.screen(); let screen = frame_input.screen();
let target = screen.clear(ClearState::default()); let target = screen.clear(ClearState::default());
match debug_type { match debug_type {
DebugType::NORMAL => { DebugType::NORMAL => target.render_with_material(
target.render_with_material( &NormalMaterial::from_physical_material(&ph_material),
&NormalMaterial::from_physical_material(&ph_material), &camera,
&camera, model.iter().map(|gm| &gm.geometry),
model.iter().map(|gm| &gm.geometry), lights,
lights, ),
)
}
DebugType::DEPTH => { DebugType::DEPTH => {
let mut depth_material = DepthMaterial::default(); let mut depth_material = DepthMaterial::default();
depth_material.max_distance = Some(depth_max); depth_material.max_distance = Some(depth_max);
target.render_with_material(&depth_material, &camera, model.iter().map(|gm| &gm.geometry), lights)
}
DebugType::ORM => {
target.render_with_material( target.render_with_material(
&ORMMaterial::from_physical_material(&ph_material), &depth_material,
&camera, &camera,
model.iter().map(|gm| &gm.geometry), model.iter().map(|gm| &gm.geometry),
lights, lights,
) )
} }
DebugType::ORM => target.render_with_material(
&ORMMaterial::from_physical_material(&ph_material),
&camera,
model.iter().map(|gm| &gm.geometry),
lights,
),
DebugType::POSITION => { DebugType::POSITION => {
let position_material = PositionMaterial::default(); let position_material = PositionMaterial::default();
target.render_with_material(&position_material, &camera, model.iter().map(|gm| &gm.geometry), lights) target.render_with_material(
&position_material,
&camera,
model.iter().map(|gm| &gm.geometry),
lights,
)
} }
DebugType::UV => { DebugType::UV => {
let uv_material = UVMaterial::default(); let uv_material = UVMaterial::default();
target.render_with_material(&uv_material, &camera, model.iter().map(|gm| &gm.geometry), lights)
}
DebugType::COLOR => {
target.render_with_material( target.render_with_material(
&ColorMaterial::from_physical_material(&ph_material), &uv_material,
&camera, &camera,
model.iter().map(|gm| &gm.geometry), model.iter().map(|gm| &gm.geometry),
lights, lights,
) )
} }
DebugType::COLOR => target.render_with_material(
&ColorMaterial::from_physical_material(&ph_material),
&camera,
model.iter().map(|gm| &gm.geometry),
lights,
),
DebugType::NONE => target.render(&camera, &model, lights), DebugType::NONE => target.render(&camera, &model, lights),
}.write(|| gui.render()); }
.write(|| gui.render());
} }
let _ = change; let _ = change;
@ -261,9 +269,7 @@ fn model_to_mesh(model: &Model) -> CpuMesh {
let positions: Vec<Vec3> = model let positions: Vec<Vec3> = model
.vertices() .vertices()
.iter() .iter()
.map(|vertex| { .map(|vertex| ((vertex.position + offset) * UNIT_SCALE * 10.0).into())
((vertex.position + offset) * UNIT_SCALE * 10.0).into()
})
.collect(); .collect();
let normals: Vec<Vec3> = model let normals: Vec<Vec3> = model
.vertices() .vertices()

1
fuzz/.envrc Normal file
View file

@ -0,0 +1 @@
use flake

5
fuzz/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
target
corpus
artifacts
.direnv
result

25
fuzz/Cargo.toml Normal file
View file

@ -0,0 +1,25 @@
[package]
name = "vmdl-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"
[package.metadata]
cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4"
[dependencies.vmdl]
path = ".."
# Prevent this from interfering with workspaces
[workspace]
members = ["."]
[[bin]]
name = "fuzz_target_1"
path = "fuzz_targets/fuzz_target_1.rs"
test = false
doc = false

22
fuzz/flake.nix Normal file
View file

@ -0,0 +1,22 @@
{
inputs = {
utils.url = "github:numtide/flake-utils";
nixpkgs.url = "nixpkgs/release-22.11";
};
outputs = {
self,
nixpkgs,
utils,
}:
utils.lib.eachDefaultSystem (system: let
pkgs = (import nixpkgs) {
inherit system;
};
in rec {
# `nix develop`
devShell = pkgs.mkShell {
nativeBuildInputs = with pkgs; [rustup cargo-edit cargo-fuzz];
};
});
}

6
fuzz/fuzz_targets/mdl.rs Normal file
View file

@ -0,0 +1,6 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
// fuzzed code goes here
});

8
fuzz/fuzz_targets/vtx.rs Normal file
View file

@ -0,0 +1,8 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
fn fuzz(data: &[u8]) {
let _ = vmdl::Mdl::read(data).ok();
}
fuzz_target!(|data: &[u8]| {fuzz(data)});

8
fuzz/fuzz_targets/vvd.rs Normal file
View file

@ -0,0 +1,8 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
fn fuzz(data: &[u8]) {
let _ = vmdl::Mdl::read(data).ok();
}
fuzz_target!(|data: &[u8]| {fuzz(data)});

View file

@ -5,9 +5,10 @@ mod shared;
pub mod vtx; pub mod vtx;
pub mod vvd; pub mod vvd;
use crate::mdl::Mdl; pub use crate::mdl::Mdl;
use crate::vtx::Vtx; pub use crate::vtx::Vtx;
use crate::vvd::{Vertex, Vvd}; use crate::vvd::Vertex;
pub use crate::vvd::Vvd;
use bytemuck::{pod_read_unaligned, Pod}; use bytemuck::{pod_read_unaligned, Pod};
pub use error::*; pub use error::*;
pub use handle::Handle; pub use handle::Handle;

View file

@ -1,12 +1,12 @@
mod raw; mod raw;
use std::mem::size_of;
pub use raw::header::*; pub use raw::header::*;
pub use raw::header2::*; pub use raw::header2::*;
use std::mem::size_of;
use crate::mdl::raw::{BodyPartHeader, Bone, MeshHeader, ModelHeader}; use crate::mdl::raw::{BodyPartHeader, Bone, MeshHeader, ModelHeader};
use crate::{read_indexes, read_relative, FixedString, ModelError, ReadRelative, Readable};
use crate::vvd::Vertex; use crate::vvd::Vertex;
use crate::{read_indexes, read_relative, FixedString, ModelError, ReadRelative, Readable};
type Result<T> = std::result::Result<T, ModelError>; type Result<T> = std::result::Result<T, ModelError>;
@ -75,7 +75,7 @@ impl ReadRelative for Model {
name: header.name.try_into()?, name: header.name.try_into()?,
ty: header.ty, ty: header.ty,
bounding_radius: header.bounding_radius, bounding_radius: header.bounding_radius,
vertex_offset: header.vertex_index / (size_of::<Vertex>() as i32), vertex_offset: header.vertex_index / (size_of::<Vertex>() as i32),
}) })
} }
} }

View file

@ -1,10 +1,10 @@
use crate::{ModelError, StringError}; use crate::{ModelError, StringError};
use arrayvec::ArrayString; use arrayvec::ArrayString;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use cgmath::Vector3;
use std::fmt; use std::fmt;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::ops::{Add, Mul}; use std::ops::{Add, Mul};
use cgmath::Vector3;
#[derive(Debug, Clone, Copy, Zeroable, Pod)] #[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)] #[repr(C)]