|
1 | | -// Copyright 2017 Tristam MacDonald |
| 1 | +// Copyright 2018 Tristam MacDonald |
2 | 2 | // |
3 | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | 4 | // you may not use this file except in compliance with the License. |
|
17 | 17 | use isosurface::source::Source; |
18 | 18 |
|
19 | 19 | /// The distance-field equation for a torus |
20 | | -fn torus(x : f32, y : f32, z : f32) -> f32 { |
21 | | - const R1 : f32 = 1.0 / 4.0; |
22 | | - const R2 : f32 = 1.0 / 10.0; |
23 | | - let q_x = ((x*x + y*y).sqrt()).abs() - R1; |
24 | | - let len = (q_x*q_x + z*z).sqrt(); |
| 20 | +fn torus(x: f32, y: f32, z: f32) -> f32 { |
| 21 | + const R1: f32 = 1.0 / 4.0; |
| 22 | + const R2: f32 = 1.0 / 10.0; |
| 23 | + let q_x = ((x * x + y * y).sqrt()).abs() - R1; |
| 24 | + let len = (q_x * q_x + z * z).sqrt(); |
25 | 25 | len - R2 |
26 | 26 | } |
27 | 27 |
|
28 | 28 | pub struct Torus {} |
29 | 29 |
|
30 | 30 | impl Source for Torus { |
31 | | - fn sample(&self, x : f32, y : f32, z : f32) -> f32 { |
| 31 | + fn sample(&self, x: f32, y: f32, z: f32) -> f32 { |
32 | 32 | torus(x - 0.5, y - 0.5, z - 0.5) |
33 | 33 | } |
34 | 34 | } |
| 35 | + |
| 36 | +fn abs(x: f32, y: f32, z: f32) -> (f32, f32, f32) { |
| 37 | + ( |
| 38 | + if x > 0.0 { x } else { -x }, |
| 39 | + if y > 0.0 { y } else { -y }, |
| 40 | + if z > 0.0 { z } else { -z }, |
| 41 | + ) |
| 42 | +} |
| 43 | + |
| 44 | +fn max(px: f32, py: f32, pz: f32, qx: f32, qy: f32, qz: f32) -> (f32, f32, f32) { |
| 45 | + ( |
| 46 | + if px > qx { px } else { qx }, |
| 47 | + if py > qy { py } else { qy }, |
| 48 | + if pz > qz { pz } else { qz }, |
| 49 | + ) |
| 50 | +} |
| 51 | + |
| 52 | +/// The distance field equation for a cube |
| 53 | +fn cube(px: f32, py: f32, pz: f32, bx: f32, by: f32, bz: f32) -> f32 { |
| 54 | + let (ax, ay, az) = abs(px, py, pz); |
| 55 | + let (dx, dy, dz) = (ax - bx, ay - by, az - bz); |
| 56 | + let (mx, my, mz) = max(dx, dy, dz, 0.0, 0.0, 0.0); |
| 57 | + let l = (mx * mx + my * my + mz * mz).sqrt(); |
| 58 | + dx.max(dz.max(dy)).min(0.0) + l |
| 59 | +} |
| 60 | + |
| 61 | +/// The distance field equation for a sphere |
| 62 | +fn sphere(x: f32, y: f32, z: f32, r: f32) -> f32 { |
| 63 | + (x * x + y * y + z * z).sqrt() - r |
| 64 | +} |
| 65 | + |
| 66 | +/// Subtract one distance field from another (i.e. CSG difference operation) |
| 67 | +fn subtract(d1: f32, d2: f32) -> f32 { |
| 68 | + d2.max(-d1) |
| 69 | +} |
| 70 | + |
| 71 | +pub struct CubeSphere {} |
| 72 | + |
| 73 | +impl Source for CubeSphere { |
| 74 | + fn sample(&self, x: f32, y: f32, z: f32) -> f32 { |
| 75 | + subtract( |
| 76 | + sphere(x - 0.5, y - 0.5, z - 0.5, 0.25), |
| 77 | + cube(x - 0.5, y - 0.5, z - 0.5, 0.2, 0.2, 0.2), |
| 78 | + ) |
| 79 | + } |
| 80 | +} |
0 commit comments