Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
448
third-party/vendor/metal/examples/raytracing/geometry.rs
vendored
Normal file
448
third-party/vendor/metal/examples/raytracing/geometry.rs
vendored
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
use std::{
|
||||
mem::{size_of, transmute},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use glam::{
|
||||
f32::{Mat4, Vec3, Vec4},
|
||||
Vec4Swizzles,
|
||||
};
|
||||
|
||||
use metal::*;
|
||||
|
||||
pub const GEOMETRY_MASK_TRIANGLE: u32 = 1;
|
||||
pub const GEOMETRY_MASK_SPHERE: u32 = 2;
|
||||
pub const GEOMETRY_MASK_LIGHT: u32 = 4;
|
||||
|
||||
pub const FACE_MASK_NONE: u16 = 0;
|
||||
pub const FACE_MASK_NEGATIVE_X: u16 = 1 << 0;
|
||||
pub const FACE_MASK_POSITIVE_X: u16 = 1 << 1;
|
||||
pub const FACE_MASK_NEGATIVE_Y: u16 = 1 << 2;
|
||||
pub const FACE_MASK_POSITIVE_Y: u16 = 1 << 3;
|
||||
pub const FACE_MASK_NEGATIVE_Z: u16 = 1 << 4;
|
||||
pub const FACE_MASK_POSITIVE_Z: u16 = 1 << 5;
|
||||
pub const FACE_MASK_ALL: u16 = (1 << 6) - 1;
|
||||
|
||||
pub trait Geometry {
|
||||
fn upload_to_buffers(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
fn clear(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
fn get_geometry_descriptor(&self) -> AccelerationStructureGeometryDescriptor {
|
||||
todo!()
|
||||
}
|
||||
fn get_resources(&self) -> Vec<Resource> {
|
||||
todo!()
|
||||
}
|
||||
fn get_intersection_function_name(&self) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_triangle_normal(v0: &Vec3, v1: &Vec3, v2: &Vec3) -> Vec3 {
|
||||
let e1 = Vec3::normalize(*v1 - *v0);
|
||||
let e2 = Vec3::normalize(*v2 - *v0);
|
||||
return Vec3::cross(e1, e2);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[repr(C)]
|
||||
pub struct Triangle {
|
||||
pub normals: [Vec4; 3],
|
||||
pub colours: [Vec4; 3],
|
||||
}
|
||||
|
||||
pub fn get_managed_buffer_storage_mode() -> MTLResourceOptions {
|
||||
return MTLResourceOptions::StorageModeManaged;
|
||||
}
|
||||
|
||||
pub struct TriangleGeometry {
|
||||
pub device: Device,
|
||||
pub name: String,
|
||||
pub index_buffer: Option<Buffer>,
|
||||
pub vertex_position_buffer: Option<Buffer>,
|
||||
pub vertex_normal_buffer: Option<Buffer>,
|
||||
pub vertex_colour_buffer: Option<Buffer>,
|
||||
pub per_primitive_data_buffer: Option<Buffer>,
|
||||
pub indices: Vec<u16>,
|
||||
pub vertices: Vec<Vec4>,
|
||||
pub normals: Vec<Vec4>,
|
||||
pub colours: Vec<Vec4>,
|
||||
pub triangles: Vec<Triangle>,
|
||||
}
|
||||
|
||||
impl TriangleGeometry {
|
||||
pub fn new(device: Device, name: String) -> Self {
|
||||
Self {
|
||||
device,
|
||||
name,
|
||||
index_buffer: None,
|
||||
vertex_position_buffer: None,
|
||||
vertex_normal_buffer: None,
|
||||
vertex_colour_buffer: None,
|
||||
per_primitive_data_buffer: None,
|
||||
indices: Vec::new(),
|
||||
vertices: Vec::new(),
|
||||
normals: Vec::new(),
|
||||
colours: Vec::new(),
|
||||
triangles: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_cube_face_with_cube_vertices(
|
||||
&mut self,
|
||||
cube_vertices: &[Vec3],
|
||||
colour: Vec3,
|
||||
i0: u16,
|
||||
i1: u16,
|
||||
i2: u16,
|
||||
i3: u16,
|
||||
inward_normals: bool,
|
||||
) {
|
||||
let v0 = cube_vertices[i0 as usize];
|
||||
let v1 = cube_vertices[i1 as usize];
|
||||
let v2 = cube_vertices[i2 as usize];
|
||||
let v3 = cube_vertices[i3 as usize];
|
||||
|
||||
let n0 = compute_triangle_normal(&v0, &v1, &v2) * if inward_normals { -1f32 } else { 1f32 };
|
||||
let n1 = compute_triangle_normal(&v0, &v2, &v3) * if inward_normals { -1f32 } else { 1f32 };
|
||||
|
||||
let first_index = self.indices.len();
|
||||
let base_index = self.vertices.len() as u16;
|
||||
|
||||
self.indices.push(base_index + 0);
|
||||
self.indices.push(base_index + 1);
|
||||
self.indices.push(base_index + 2);
|
||||
self.indices.push(base_index + 0);
|
||||
self.indices.push(base_index + 2);
|
||||
self.indices.push(base_index + 3);
|
||||
|
||||
self.vertices.push(From::from((v0, 0.0)));
|
||||
self.vertices.push(From::from((v1, 0.0)));
|
||||
self.vertices.push(From::from((v2, 0.0)));
|
||||
self.vertices.push(From::from((v3, 0.0)));
|
||||
|
||||
self.normals
|
||||
.push(From::from((Vec3::normalize(n0 + n1), 0.0)));
|
||||
self.normals.push(From::from((n0, 0.0)));
|
||||
self.normals
|
||||
.push(From::from((Vec3::normalize(n0 + n1), 0.0)));
|
||||
self.normals.push(From::from((n1, 0.0)));
|
||||
|
||||
for _ in 0..4 {
|
||||
self.colours.push(From::from((colour, 0.0)));
|
||||
}
|
||||
|
||||
for triangle_index in 0..2 {
|
||||
let mut triangle = Triangle::default();
|
||||
for i in 0..3 {
|
||||
let index = self.indices[first_index + triangle_index * 3 + i];
|
||||
triangle.normals[i] = self.normals[index as usize];
|
||||
triangle.colours[i] = self.colours[index as usize];
|
||||
}
|
||||
self.triangles.push(triangle);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_cube_with_faces(
|
||||
&mut self,
|
||||
face_mask: u16,
|
||||
colour: Vec3,
|
||||
transform: Mat4,
|
||||
inward_normals: bool,
|
||||
) {
|
||||
let mut cube_vertices = [
|
||||
Vec3::new(-0.5, -0.5, -0.5),
|
||||
Vec3::new(0.5, -0.5, -0.5),
|
||||
Vec3::new(-0.5, 0.5, -0.5),
|
||||
Vec3::new(0.5, 0.5, -0.5),
|
||||
Vec3::new(-0.5, -0.5, 0.5),
|
||||
Vec3::new(0.5, -0.5, 0.5),
|
||||
Vec3::new(-0.5, 0.5, 0.5),
|
||||
Vec3::new(0.5, 0.5, 0.5),
|
||||
];
|
||||
|
||||
for i in 0..8 {
|
||||
let transformed_vertex = Vec4::from((cube_vertices[i], 1.0));
|
||||
let transformed_vertex = transform * transformed_vertex;
|
||||
cube_vertices[i] = transformed_vertex.xyz();
|
||||
}
|
||||
|
||||
const CUBE_INDICES: [[u16; 4]; 6] = [
|
||||
[0, 4, 6, 2],
|
||||
[1, 3, 7, 5],
|
||||
[0, 1, 5, 4],
|
||||
[2, 6, 7, 3],
|
||||
[0, 2, 3, 1],
|
||||
[4, 5, 7, 6],
|
||||
];
|
||||
|
||||
for face in 0..6 {
|
||||
if face_mask & (1 << face) != 0 {
|
||||
self.add_cube_face_with_cube_vertices(
|
||||
&cube_vertices,
|
||||
colour,
|
||||
CUBE_INDICES[face][0],
|
||||
CUBE_INDICES[face][1],
|
||||
CUBE_INDICES[face][2],
|
||||
CUBE_INDICES[face][3],
|
||||
inward_normals,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Geometry for TriangleGeometry {
|
||||
fn upload_to_buffers(&mut self) {
|
||||
self.index_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(self.indices.as_ptr()),
|
||||
(self.indices.len() * size_of::<u16>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.vertex_position_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(self.vertices.as_ptr()),
|
||||
(self.vertices.len() * size_of::<Vec4>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.vertex_normal_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(self.normals.as_ptr()),
|
||||
(self.normals.len() * size_of::<Vec4>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.vertex_colour_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(self.colours.as_ptr()),
|
||||
(self.colours.len() * size_of::<Vec4>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.per_primitive_data_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(self.triangles.as_ptr()),
|
||||
(self.triangles.len() * size_of::<Triangle>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.index_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.index_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
self.vertex_position_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.vertex_position_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
self.vertex_normal_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.vertex_normal_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
self.vertex_colour_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.vertex_colour_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
self.per_primitive_data_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.per_primitive_data_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
|
||||
self.index_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label(&format!("index buffer of {}", self.name));
|
||||
self.vertex_position_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label(&format!("vertex position buffer of {}", self.name));
|
||||
self.vertex_normal_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label(&format!("vertex normal buffer of {}", self.name));
|
||||
self.vertex_colour_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label(&format!("vertex colour buffer of {}", self.name));
|
||||
self.per_primitive_data_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label(&format!("per primitive data buffer of {}", self.name));
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.indices.clear();
|
||||
self.vertices.clear();
|
||||
self.normals.clear();
|
||||
self.colours.clear();
|
||||
self.triangles.clear();
|
||||
}
|
||||
|
||||
fn get_geometry_descriptor(&self) -> AccelerationStructureGeometryDescriptor {
|
||||
let descriptor = AccelerationStructureTriangleGeometryDescriptor::descriptor();
|
||||
|
||||
descriptor.set_index_buffer(Some(self.index_buffer.as_ref().unwrap()));
|
||||
descriptor.set_index_type(MTLIndexType::UInt16);
|
||||
descriptor.set_vertex_buffer(Some(self.vertex_position_buffer.as_ref().unwrap()));
|
||||
descriptor.set_vertex_stride(size_of::<Vec4>() as NSUInteger);
|
||||
descriptor.set_triangle_count((self.indices.len() / 3) as NSUInteger);
|
||||
descriptor
|
||||
.set_primitive_data_buffer(Some(self.per_primitive_data_buffer.as_ref().unwrap()));
|
||||
descriptor.set_primitive_data_stride(size_of::<Triangle>() as NSUInteger);
|
||||
descriptor.set_primitive_data_element_size(size_of::<Triangle>() as NSUInteger);
|
||||
From::from(descriptor)
|
||||
}
|
||||
|
||||
fn get_resources(&self) -> Vec<Resource> {
|
||||
vec![
|
||||
From::from(self.index_buffer.as_ref().unwrap().clone()),
|
||||
From::from(self.vertex_normal_buffer.as_ref().unwrap().clone()),
|
||||
From::from(self.vertex_colour_buffer.as_ref().unwrap().clone()),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct BoundingBox {
|
||||
pub min: Vec3,
|
||||
pub max: Vec3,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Sphere {
|
||||
pub origin_radius_squared: Vec4,
|
||||
pub colour_radius: Vec4,
|
||||
}
|
||||
|
||||
pub struct SphereGeometry {
|
||||
pub device: Device,
|
||||
pub sphere_buffer: Option<Buffer>,
|
||||
pub bounding_box_buffer: Option<Buffer>,
|
||||
pub per_primitive_data_buffer: Option<Buffer>,
|
||||
pub spheres: Vec<Sphere>,
|
||||
}
|
||||
|
||||
impl SphereGeometry {
|
||||
pub fn new(device: Device) -> Self {
|
||||
Self {
|
||||
device,
|
||||
sphere_buffer: None,
|
||||
bounding_box_buffer: None,
|
||||
per_primitive_data_buffer: None,
|
||||
spheres: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_sphere_with_origin(&mut self, origin: Vec3, radius: f32, colour: Vec3) {
|
||||
self.spheres.push(Sphere {
|
||||
origin_radius_squared: Vec4::from((origin, radius * radius)),
|
||||
colour_radius: Vec4::from((colour, radius)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Geometry for SphereGeometry {
|
||||
fn upload_to_buffers(&mut self) {
|
||||
self.sphere_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(self.spheres.as_ptr()),
|
||||
(self.spheres.len() * size_of::<Sphere>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.sphere_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label("sphere buffer");
|
||||
let mut bounding_boxes = Vec::new();
|
||||
for sphere in &self.spheres {
|
||||
bounding_boxes.push(BoundingBox {
|
||||
min: sphere.origin_radius_squared.xyz() - sphere.colour_radius.w,
|
||||
max: sphere.origin_radius_squared.xyz() + sphere.colour_radius.w,
|
||||
});
|
||||
}
|
||||
self.bounding_box_buffer = Some(unsafe {
|
||||
self.device.new_buffer_with_data(
|
||||
transmute(bounding_boxes.as_ptr()),
|
||||
(bounding_boxes.len() * size_of::<BoundingBox>()) as NSUInteger,
|
||||
get_managed_buffer_storage_mode(),
|
||||
)
|
||||
});
|
||||
self.bounding_box_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.set_label("bounding box buffer");
|
||||
self.sphere_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.sphere_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
self.bounding_box_buffer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.did_modify_range(NSRange::new(
|
||||
0,
|
||||
self.bounding_box_buffer.as_ref().unwrap().length(),
|
||||
));
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.spheres.clear();
|
||||
}
|
||||
|
||||
fn get_geometry_descriptor(&self) -> AccelerationStructureGeometryDescriptor {
|
||||
let descriptor = AccelerationStructureBoundingBoxGeometryDescriptor::descriptor();
|
||||
descriptor.set_bounding_box_buffer(Some(self.bounding_box_buffer.as_ref().unwrap()));
|
||||
descriptor.set_bounding_box_count(self.spheres.len() as NSUInteger);
|
||||
descriptor.set_primitive_data_buffer(Some(&self.sphere_buffer.as_ref().unwrap()));
|
||||
descriptor.set_primitive_data_stride(size_of::<Sphere>() as NSUInteger);
|
||||
descriptor.set_primitive_data_element_size(size_of::<Sphere>() as NSUInteger);
|
||||
From::from(descriptor)
|
||||
}
|
||||
|
||||
fn get_resources(&self) -> Vec<Resource> {
|
||||
return vec![From::from(self.sphere_buffer.as_ref().unwrap().clone())];
|
||||
}
|
||||
|
||||
fn get_intersection_function_name(&self) -> Option<&str> {
|
||||
Some("sphereIntersectionFunction")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GeometryInstance {
|
||||
pub geometry: Arc<dyn Geometry>,
|
||||
pub transform: Mat4,
|
||||
pub mask: u32,
|
||||
pub index_in_scene: NSUInteger,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct AreaLight {
|
||||
pub position: Vec4,
|
||||
pub forward: Vec4,
|
||||
pub right: Vec4,
|
||||
pub up: Vec4,
|
||||
pub colour: Vec4,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue