diff options
author | eug-vs <eugene@eug-vs.xyz> | 2021-10-27 18:19:01 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2021-10-27 18:19:01 +0300 |
commit | 4150e01639a96c233822a46aa23875faa7ecfd47 (patch) | |
tree | 4e61417fb28f7c7fd7cd9f6951d39e9c63fd9b8e | |
parent | b3bef1bdddb73e386e6f54635d6bcc39efd1b911 (diff) | |
download | pistol-4150e01639a96c233822a46aa23875faa7ecfd47.tar.gz |
feat: add box and sphere SDF
-rw-r--r-- | src/camera.rs | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/src/camera.rs b/src/camera.rs index ff4b4f7..9f22e99 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -48,35 +48,47 @@ fn softmin(left: f32, right: f32, k: f32) -> f32 { return left.min(right) - h*h*k*(1.0/4.0); } +fn sphere(point: Vector, center: Vector, radius: f32) -> f32 { + (point - center).magnitude() - radius +} + +fn r#box(point: Vector, center: Vector, size: Vector) -> f32 { + let diff = center - point; + let q = diff.map(|n| n.abs()) - size / 2.0; + return q.map(|n| n.max(0.0)).magnitude() + (q.y.max(q.z).max(q.x)).min(0.0) +} + + impl Camera { pub fn sdf(&self, point: Vector) -> f32 { + let mut dist: f32; // Floor at z = -2 let floor_dist = point.z + 1.0; + dist = floor_dist; + // Sphere - let center = Vector { x: 4.0, y: 0.0, z: 0.0 }; - let radius = 1.0 + 0.5 * self.time.sin(); - let sphere_dist = (point - center).magnitude() - radius; - - // Small sphere - let center2 = Vector { x: 3.5, y: 0.5, z: 0.0 }; - let radius2 = 0.7; - let sphere2_dist = (point - center2).magnitude() - radius2; - - // Second sphere - let center3 = Vector { x: 4.0 + self.time.sin() * 1.6, y: -2.5, z: 0.0 - self.time.sin() * 0.8 }; - let radius3 = 1.0; - let sphere3_dist = (point - center3).magnitude() - radius3; - - softmin( - softmin( - sphere_dist.max(-sphere2_dist), - sphere3_dist, - 1.5 - ), - floor_dist, - 0.8 - ) + { + let center = Vector { x: 4.0, y: 0.0, z: 0.0 }; + let radius = 1.5; + dist = softmin(dist, sphere(point, center, radius), 1.2); + } + + // Hole + { + let center = Vector { x: 4.0, y: 0.0, z: 0.0 }; + let size = Vector::new(5.0, 2.0, 2.0); + dist = dist.max(-r#box(point, center, size)); + } + + // Windows + { + let center = Vector { x: 4.0, y: 0.0, z: 0.0 }; + let size = Vector::new(1.0, 5.0, 1.0); + dist = dist.max(-(r#box(point, center, size))); + } + + return dist } pub fn rorate_around_point(& mut self, point: Vector) { |