reorganize some geometry stuff

This commit is contained in:
wires 2025-05-29 11:32:31 -04:00
parent 1ab382c5b3
commit a30b29a130
Signed by: wires
SSH key fingerprint: SHA256:9GtP+M3O2IivPDlw1UY872UPUuJH2gI0yG6ExBxaaiM
4 changed files with 265 additions and 103 deletions

View file

@ -3,52 +3,24 @@ use std::{
ops::{Add, AddAssign, Deref, Div, DivAssign, Mul, Sub},
};
pub mod shapes;
mod _2d;
mod shapes;
mod transform;
pub use _2d::*;
pub use shapes::Shape;
pub use transform::Transform;
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Vector(glam::Vec3A);
impl fmt::Debug for Vector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!(Vector))
.field(&self.0.x)
.field(&self.0.y)
.field(&self.0.z)
.finish()
}
}
impl From<Vector> for glam::Vec3 {
fn from(value: Vector) -> Self {
value.0.into()
}
}
impl From<(f32, f32, f32)> for Vector {
fn from((x, y, z): (f32, f32, f32)) -> Self {
Self::new(x, y, z)
}
}
impl Deref for Vector {
type Target = glam::Vec3A;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Vector {
pub const ZERO: Self = Self(glam::Vec3A::ZERO);
pub const I: Self = Self(glam::Vec3A::X);
pub const J: Self = Self(glam::Vec3A::Y);
pub const K: Self = Self(glam::Vec3A::Z);
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self(glam::vec3a(x, y, z))
}
pub fn length(self) -> f32 {
self.0.length()
}
@ -68,6 +40,50 @@ impl Vector {
pub fn cross(self, other: Vector) -> Vector {
Self(self.0.cross(other.0))
}
pub fn same_hemisphere(self, other: Vector) -> bool {
self.dot(other) > 0.0
}
}
pub fn vec3(x: f32, y: f32, z: f32) -> Vector {
Vector(glam::vec3a(x, y, z))
}
impl fmt::Debug for Vector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!(Vector))
.field(&self.0.x)
.field(&self.0.y)
.field(&self.0.z)
.finish()
}
}
impl From<(f32, f32, f32)> for Vector {
fn from((x, y, z): (f32, f32, f32)) -> Self {
vec3(x, y, z)
}
}
impl From<Point> for Vector {
fn from(p: Point) -> Self {
Self(p.0)
}
}
impl Deref for Vector {
type Target = glam::Vec3A;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<Vector> for glam::Vec3 {
fn from(value: Vector) -> Self {
value.0.into()
}
}
impl Mul<f32> for Vector {
@ -118,6 +134,14 @@ impl AddAssign for Vector {
#[derive(Clone, Copy)]
pub struct Point(glam::Vec3A);
impl Point {
pub const ORIGIN: Self = Self(glam::Vec3A::ZERO);
}
pub fn point3(x: f32, y: f32, z: f32) -> Point {
Point(glam::vec3a(x, y, z))
}
impl fmt::Debug for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!(Point))
@ -136,19 +160,7 @@ impl From<Point> for glam::Vec3 {
impl From<(f32, f32, f32)> for Point {
fn from((x, y, z): (f32, f32, f32)) -> Self {
Self::new(x, y, z)
}
}
impl Point {
pub const ORIGIN: Self = Self(glam::Vec3A::ZERO);
pub fn new(x: f32, y: f32, z: f32) -> Self {
Self(glam::vec3a(x, y, z))
}
pub fn to_vector(self) -> Vector {
Vector(self.0)
point3(x, y, z)
}
}
@ -168,58 +180,11 @@ impl Sub for Point {
}
}
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct Transform(glam::Affine3A);
impl fmt::Debug for Transform {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(stringify!(Transform))
.field(stringify!(matrix3), &self.0.matrix3)
.field(stringify!(translation), &self.0.translation)
.finish()
}
}
impl Transform {
pub fn scale(x: f32, y: f32, z: f32) -> Self {
Self(glam::Affine3A::from_scale(glam::vec3(x, y, z)))
}
pub fn inverse(self) -> Self {
Self(self.0.inverse())
}
pub fn look_at(eye: Point, center: Point, up: Vector) -> Self {
Self(glam::Affine3A::look_at_lh(
eye.into(),
center.into(),
up.into(),
))
}
}
impl Mul for Transform {
type Output = Transform;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}
impl Mul<Vector> for Transform {
type Output = Vector;
fn mul(self, rhs: Vector) -> Self::Output {
Vector(self.0.transform_vector3a(rhs.0))
}
}
impl Mul<Point> for Transform {
impl Sub<Vector> for Point {
type Output = Point;
fn mul(self, rhs: Point) -> Self::Output {
Point(self.0.transform_point3a(rhs.0))
fn sub(self, rhs: Vector) -> Self::Output {
Point(self.0 - rhs.0)
}
}
@ -230,11 +195,11 @@ pub struct Ray {
}
impl Ray {
pub fn new(origin: Point, direction: Vector) -> Self {
Self { origin, direction }
}
pub fn at(&self, t: f32) -> Point {
self.origin + t * self.direction
}
}
pub fn ray(origin: Point, direction: Vector) -> Ray {
Ray { origin, direction }
}

128
core/src/geometry/_2d.rs Normal file
View file

@ -0,0 +1,128 @@
use std::{
fmt,
ops::{Add, AddAssign, Div, DivAssign, Mul, Sub},
};
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Vector2(glam::Vec2);
impl Vector2 {
pub const ZERO: Self = Self(glam::Vec2::ZERO);
pub const U: Self = Self(glam::Vec2::X);
pub const V: Self = Self(glam::Vec2::Y);
}
pub const fn vec2(x: f32, y: f32) -> Vector2 {
Vector2(glam::vec2(x, y))
}
impl fmt::Debug for Vector2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!(Vector))
.field(&self.0.x)
.field(&self.0.y)
.finish()
}
}
impl From<(f32, f32)> for Vector2 {
fn from((x, y): (f32, f32)) -> Self {
vec2(x, y)
}
}
impl Mul<f32> for Vector2 {
type Output = Self;
fn mul(self, rhs: f32) -> Self::Output {
Self(self.0 * rhs)
}
}
impl Mul<Vector2> for f32 {
type Output = Vector2;
fn mul(self, rhs: Vector2) -> Self::Output {
Vector2(self * rhs.0)
}
}
impl Div<f32> for Vector2 {
type Output = Self;
fn div(self, rhs: f32) -> Self::Output {
Self(self.0 / rhs)
}
}
impl DivAssign<f32> for Vector2 {
fn div_assign(&mut self, rhs: f32) {
*self = *self / rhs;
}
}
impl Add for Vector2 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign for Vector2 {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Point2(glam::Vec2);
impl Point2 {
pub const ORIGIN: Self = Self(glam::Vec2::ZERO);
}
pub const fn point2(x: f32, y: f32) -> Point2 {
Point2(glam::vec2(x, y))
}
impl fmt::Debug for Point2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple(stringify!(Point))
.field(&self.0.x)
.field(&self.0.y)
.finish()
}
}
impl From<(f32, f32)> for Point2 {
fn from((x, y): (f32, f32)) -> Self {
point2(x, y)
}
}
impl Add<Vector2> for Point2 {
type Output = Point2;
fn add(self, rhs: Vector2) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Sub<Vector2> for Point2 {
type Output = Point2;
fn sub(self, rhs: Vector2) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl Sub for Point2 {
type Output = Vector2;
fn sub(self, rhs: Self) -> Self::Output {
Vector2(self.0 - rhs.0)
}
}

View file

@ -52,7 +52,7 @@ impl Hittable for Plane {
let n_dot_r = self.normal.dot(ray.direction);
(n_dot_r.abs() > f32::EPSILON)
.then(|| {
let n_dot_o = self.normal.dot(ray.origin.to_vector());
let n_dot_o = self.normal.dot(ray.origin.into());
-(n_dot_o - self.d) / n_dot_r
})
.filter(|t| *t < t_max && *t > 0.0)

View file

@ -0,0 +1,69 @@
use std::{fmt, ops::Mul};
use super::{Point, Ray, Vector};
#[derive(Copy, Clone)]
#[repr(transparent)]
pub struct Transform(glam::Affine3A);
impl fmt::Debug for Transform {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(stringify!(Transform))
.field(stringify!(matrix3), &self.0.matrix3)
.field(stringify!(translation), &self.0.translation)
.finish()
}
}
impl Transform {
pub fn scale(x: f32, y: f32, z: f32) -> Self {
Self(glam::Affine3A::from_scale(glam::vec3(x, y, z)))
}
pub fn inverse(self) -> Self {
Self(self.0.inverse())
}
pub fn look_at(eye: Point, center: Point, up: Vector) -> Self {
Self(glam::Affine3A::look_at_lh(
eye.into(),
center.into(),
up.into(),
))
}
}
impl Mul for Transform {
type Output = Transform;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}
impl Mul<Vector> for Transform {
type Output = Vector;
fn mul(self, rhs: Vector) -> Self::Output {
Vector(self.0.transform_vector3a(rhs.0))
}
}
impl Mul<Point> for Transform {
type Output = Point;
fn mul(self, rhs: Point) -> Self::Output {
Point(self.0.transform_point3a(rhs.0))
}
}
impl Mul<Ray> for Transform {
type Output = Ray;
fn mul(self, rhs: Ray) -> Self::Output {
Ray {
origin: self * rhs.origin,
direction: self * rhs.direction,
}
}
}