diff --git a/ray.asd b/ray.asd --- a/ray.asd +++ b/ray.asd @@ -1,6 +1,6 @@ (asdf:defsystem "ray" :defsystem-depends-on ("coalton-asdf") - :depends-on ("coalton" "sb-simd" "coalton-io" "cffi") + :depends-on ("coalton" "sb-simd" "coalton-io") :pathname "src/" :serial t :components @@ -9,7 +9,7 @@ (:ct-file "color") (:ct-file "ppm") (:ct-file "vec3") - (:ct-file "vector") + ;(:ct-file "vector") (:ct-file "ray") (:ct-file "material") (:ct-file "hittable") diff --git a/src/color.ct b/src/color.ct --- a/src/color.ct +++ b/src/color.ct @@ -20,17 +20,19 @@ (declare white Color) (define white (Color 1.0d0 1.0d0 1.0d0)) + (inline) (declare mul (Color * Color -> Color)) (define (mul (Color r g b) (Color r2 g2 b2)) "Multiply a color by a given scalar value" (Color (* r r2) (* g g2) (* b b2))) - + (inline) (declare mul-scalar (Color * F64 -> Color)) (define (mul-scalar (Color r g b) v) "Multiply a color by a given scalar value" (Color (* r v) (* g v) (* b v))) + (inline) (declare add (Color * Color -> Color)) (define (add (Color r1 g1 b1) (Color r2 g2 b2)) (Color (+ r1 r2) (+ g1 g2) (+ b1 b2)))) diff --git a/src/hittable.ct b/src/hittable.ct --- a/src/hittable.ct +++ b/src/hittable.ct @@ -13,8 +13,8 @@ (coalton-toplevel (define-struct HitRecord - (point v:Vec3) - (normal v:Vec3) + (point v::Vec3) + (normal v::Vec3) (t F64) (front-face? Boolean) (material m:Material)) diff --git a/src/main.ct b/src/main.ct --- a/src/main.ct +++ b/src/main.ct @@ -28,7 +28,7 @@ (cl:in-package #:ray) -(cl:declaim (cl:optimize (cl:speed 3) (cl:safety 0) (cl:debug 0))) +(cl:declaim (cl:optimize (cl:speed 2) (cl:safety 1) (cl:debug 1))) (coalton-toplevel (declare ASPECT-RATIO Fraction) @@ -55,14 +55,14 @@ (declare FOCUS-DIST F64) (define FOCUS-DIST 10.0d0) - (declare LOOK-FROM v:Vec3) - (define LOOK-FROM (v:Vec3 13.0d0 2.0d0 3.0d0)) + (declare LOOK-FROM v::Vec3) + (define LOOK-FROM (v:v3 13.0d0 2.0d0 3.0d0)) - (declare LOOK-AT v:Vec3) - (define LOOK-AT (v:Vec3 0.0d0 0.0d0 0.0d0)) + (declare LOOK-AT v::Vec3) + (define LOOK-AT (v:v3 0.0d0 0.0d0 0.0d0)) - (declare CAMERA-UP v:Vec3) - (define CAMERA-UP (v:Vec3 0.0d0 1.0d0 0.0d0)) + (declare CAMERA-UP v::Vec3) + (define CAMERA-UP (v:v3 0.0d0 1.0d0 0.0d0)) (declare FOCAL-LENGTH F64) (define FOCAL-LENGTH (v:vec-length (v:vec-sub LOOK-FROM LOOK-AT))) @@ -81,29 +81,29 @@ (declare COLORS UFix) (define COLORS 255) - (declare CAMERA-CENTER v:Vec3) + (declare CAMERA-CENTER v::Vec3) (define CAMERA-CENTER LOOK-FROM) - (declare VIEWPORT-U v:Vec3) + (declare VIEWPORT-U v::Vec3) (define VIEWPORT-U (v:vec-mul-scalar U VIEWPORT-WIDTH)) - (declare VIEWPORT-V v:Vec3) + (declare VIEWPORT-V v::Vec3) (define VIEWPORT-V (v:vec-mul-scalar (v:vec-negate V) VIEWPORT-HEIGHT)) - (declare PIXEL-DELTA-U v:Vec3) + (declare PIXEL-DELTA-U v::Vec3) (define PIXEL-DELTA-U (v:vec-div-scalar VIEWPORT-U (unwrap-as F64 IMAGE-WIDTH))) - (declare PIXEL-DELTA-V v:Vec3) + (declare PIXEL-DELTA-V v::Vec3) (define PIXEL-DELTA-V (v:vec-div-scalar VIEWPORT-V (unwrap-as F64 IMAGE-HEIGHT))) - (declare VIEWPORT-UPPER-LEFT v:Vec3) + (declare VIEWPORT-UPPER-LEFT v::Vec3) (define VIEWPORT-UPPER-LEFT (v:vec-sub (v:vec-sub (v:vec-sub CAMERA-CENTER (v:vec-mul-scalar W FOCUS-DIST)) (v:vec-div-scalar VIEWPORT-U 2.0d0)) (v:vec-div-scalar VIEWPORT-V 2.0d0))) - (declare PIXEL-00-LOC v:Vec3) + (declare PIXEL-00-LOC v::Vec3) (define PIXEL-00-LOC (v:vec-add VIEWPORT-UPPER-LEFT (v:vec-mul-scalar (v:vec-add PIXEL-DELTA-U PIXEL-DELTA-V) 0.5d0))) @@ -136,9 +136,11 @@ (let direction = (v:vec-sub pixel-sample ray-origin)) (r:Ray ray-origin direction)) - (declare defocus-disk-sample (Void -> v:Vec3)) + (declare defocus-disk-sample (Void -> v::Vec3)) (define (defocus-disk-sample) - (let (v:Vec3 x y _) = (v:random-in-unit-disk)) + (let vec = (v:random-in-unit-disk)) + (let x = (v:get-x vec)) + (let y = (v:get-y vec)) (v:vec-add CAMERA-CENTER (v:vec-add (v:vec-mul-scalar DEFOCUS-DISK-U x) (v:vec-mul-scalar DEFOCUS-DISK-V y)))) @@ -163,7 +165,7 @@ (cond ((<= depth 0) c:black) (True - (match (hit-any? r 0.0d001 INFINITY) + (match (hit-any? r 0.0d0 INFINITY) ((Some (h:HitRecord point normal _ front-face? material)) (let (values maybe-ray attenuation) = (m:scatter r point normal front-face? material)) (match maybe-ray @@ -171,14 +173,15 @@ ; We return 0,0,0 in the None case ((None) attenuation))) ((None) - (let (v:Vec3 _ y _) = (v:unit-vector (.direction r))) + (let vec = (v:unit-vector (.direction r))) + (let y = (v:get-y vec)) (let alpha = (* 0.5d0 (+ y 1.0d0))) (c:add (c:mul-scalar c:white (- 1.0d0 alpha)) (c:mul-scalar (c:Color 0.5d0 0.7d0 1.0d0) alpha))))))) - (declare pixel-center (UFix * UFix -> v:Vec3)) + (declare pixel-center (UFix * UFix -> v::Vec3)) (define (pixel-center i j) (v:vec-add PIXEL-00-LOC (v:vec-add (v:vec-mul-scalar PIXEL-DELTA-U (unwrap-as F64 i)) diff --git a/src/material.ct b/src/material.ct --- a/src/material.ct +++ b/src/material.ct @@ -21,7 +21,7 @@ (Lambertian c:Color) (Dielectric F64)) - (declare scatter-lambertian (v:Vec3 * v:Vec3 * c:Color -> Optional r:Ray * c:Color)) + (declare scatter-lambertian (v::Vec3 * v::Vec3 * c:Color -> Optional r:Ray * c:Color)) (define (scatter-lambertian point normal albedo) (let scatter-direction = (v:vec-add normal (v:random-unit-vector))) (if (v:near-zero? scatter-direction) @@ -29,16 +29,16 @@ (values (Some (r:Ray point normal)) albedo) (values (Some (r:Ray point scatter-direction)) albedo))) - (declare scatter-metal (v:Vec3 * v:Vec3 * v:Vec3 * c:Color * F64 -> Optional r:Ray * c:Color)) + (declare scatter-metal (v::Vec3 * v::Vec3 * v::Vec3 * c:Color * F64 -> Optional r:Ray * c:Color)) (define (scatter-metal direction point normal albedo fuzz) (let reflected = (v:reflect direction normal)) (let re-reflected = (v:vec-add (v:unit-vector reflected) (v:vec-mul-scalar (v:random-unit-vector) fuzz))) - (if (> (v:vec-dot re-reflected normal) 0) + (if (> (v:vec-dot re-reflected normal) 0.0d0) (values (Some (r:Ray point re-reflected)) albedo) (values None c:black))) - (declare scatter-dielectric (v:Vec3 * v:Vec3 * v:Vec3 * Boolean * F64 -> Optional r:Ray * c:Color)) + (declare scatter-dielectric (v::Vec3 * v::Vec3 * v::Vec3 * Boolean * F64 -> Optional r:Ray * c:Color)) (define (scatter-dielectric direction point normal front-face? refraction-index) (let ri = (if front-face? (/ 1.0d0 refraction-index) refraction-index)) (let unit-direction = (v:unit-vector direction)) @@ -59,7 +59,7 @@ (let r0-sq = (* r0 r0)) (+ r0-sq (* (- 1.0d0 r0-sq) (^ (- 1.0d0 cosine) 5)))) - (declare scatter (r:Ray * v:Vec3 * v:Vec3 * Boolean * Material -> Optional r:Ray * c:Color)) + (declare scatter (r:Ray * v::Vec3 * v::Vec3 * Boolean * Material -> Optional r:Ray * c:Color)) (define (scatter (r:Ray _ direction) point normal front-face? material) (match material ((Lambertian albedo) (scatter-lambertian point normal albedo)) diff --git a/src/ppm.ct b/src/ppm.ct --- a/src/ppm.ct +++ b/src/ppm.ct @@ -11,13 +11,15 @@ (cl:declaim (cl:optimize (cl:speed 3) (cl:safety 0) (cl:debug 0))) (coalton-toplevel + (inline) (declare linear-to-gamma (F64 -> F64)) (define (linear-to-gamma linear-comp) "Convert from linear color space to gamma-corrected" (if (> 0 linear-comp) 0 - (math:sqrt linear-comp))) + (math:sqrt linear-comp)))) +(coalton-toplevel (declare write-pixel (file:FileStream Char * c:Color -> Void)) (define (write-pixel stream (c:Color r g b)) (let rbyte = (floor (* 255.999d0 (linear-to-gamma r)))) @@ -25,22 +27,24 @@ (let bbyte = (floor (* 255.999d0 (linear-to-gamma b)))) (lisp (-> Void) (stream rbyte gbyte bbyte) (cl:format stream "~D ~D ~D~%" rbyte gbyte bbyte) - (cl:values))) + (cl:values)))) +(coalton-toplevel (declare write-pixels ((la:LispArray c:Color) * file:FileStream Char -> Void)) (define (write-pixels buffer stream) (for* ((i 0 (1+ i))) :repeat (la:length buffer) (let color = (la:aref buffer i)) - (write-pixel stream color))) + (write-pixel stream color)))) - +(coalton-toplevel (declare write-header (UFix * UFix * UFix * file:FileStream Char -> Void)) (define (write-header width height colors stream) (lisp (-> Void) (width height colors stream) (cl:format stream "P3~%~D ~D~%~D~%" width height colors) - (cl:values))) + (cl:values)))) +(coalton-toplevel (declare save-image ((la:LispArray c:Color) * UFix * UFix * UFix -> Void)) (define (save-image buffer width height colors) (let result = (file:with-open-file "out.ppm" @@ -56,6 +60,4 @@ (match errored ((file:FileError str) (print "File error: ") (print str)) - (_None (print "Unknown error occurred")))))) - -) \ No newline at end of file + (_None (print "Unknown error occurred"))))))) \ No newline at end of file diff --git a/src/ray.ct b/src/ray.ct --- a/src/ray.ct +++ b/src/ray.ct @@ -10,10 +10,11 @@ (coalton-toplevel (define-struct Ray - (:origin vec:Vec3) - (:direction vec:Vec3)) - - (declare ray-at (Ray * F64 -> vec:Vec3)) + (:origin vec::Vec3) + (:direction vec::Vec3)) + + (inline) + (declare ray-at (Ray * F64 -> vec::Vec3)) (define (ray-at (Ray origin direction) t) (vec:vec-add origin (vec:vec-mul-scalar direction t))) ) diff --git a/src/scene.ct b/src/scene.ct --- a/src/scene.ct +++ b/src/scene.ct @@ -16,17 +16,16 @@ (cl:in-package #:ray/scene) (coalton-toplevel - (declare complex-world (List s:Sphere)) (define complex-world (fold (fn (acc i) (let x = (- (integ:mod i 21) 10)) (let z = (- (/ i 21) 6)) (let choose-mat = (util:rand-f64)) - (let center = (v:Vec3 (+ x (* 0.9d0 (util:rand-f64))) + (let center = (v:v3 (+ x (* 0.9d0 (util:rand-f64))) 0.2d0 (+ z (* 0.9d0 (util:rand-f64))))) - (if (< 0.9d0 (v:vec-length (v:vec-sub center (v:Vec3 4.0d0 0.2d0 0.0d0)))) + (if (< 0.9d0 (v:vec-length (v:vec-sub center (v:v3 4.0d0 0.2d0 0.0d0)))) (cons (if (< choose-mat 0.8d0) (s:Sphere center 0.2d0 (m:Lambertian (rand-color))) (if (< choose-mat 0.95d0) @@ -36,27 +35,27 @@ acc)) [ ; Big ass world sphere - (s:Sphere (v:Vec3 0.0d0 -1000.0d0 0.0d0) 1000.0d0 (m:Lambertian (c:Color 0.5d0 0.5d0 0.5d0))) + (s:Sphere (v:v3 0.0d0 -1000.0d0 0.0d0) 1000.0d0 (m:Lambertian (c:Color 0.5d0 0.5d0 0.5d0))) ; 3 med-big spheres - (s:Sphere (v:Vec3 0.0d0 1.0d0 0.0d0) 1.0d0 (m:Dielectric 1.5d0)) - (s:Sphere (v:Vec3 -4.0d0 1.0d0 0.0d0) 1.0d0 (m:Lambertian (c:Color 0.4d0 0.2d0 0.1d0))) - (s:Sphere (v:Vec3 4.0d0 1.0d0 0.0d0) 1.0d0 (m:Metal (c:Color 0.7d0 0.6d0 0.5d0) 0.0d0)) + (s:Sphere (v:v3 0.0d0 1.0d0 0.0d0) 1.0d0 (m:Dielectric 1.5d0)) + (s:Sphere (v:v3 -4.0d0 1.0d0 0.0d0) 1.0d0 (m:Lambertian (c:Color 0.4d0 0.2d0 0.1d0))) + (s:Sphere (v:v3 4.0d0 1.0d0 0.0d0) 1.0d0 (m:Metal (c:Color 0.7d0 0.6d0 0.5d0) 0.0d0)) ] (the (List F64) (it:collect! (it:range-increasing 1 1 200))))) (declare basic-world (List s:Sphere)) (define basic-world [ ; Big ass world sphere - (s:Sphere (v:Vec3 0.0d0 -100.5d0 -1.0d0) 100.0d0 (m:Lambertian (c:Color 0.8d0 0.8d0 0.0d0))) + (s:Sphere (v:v3 0.0d0 -100.5d0 -1.0d0) 100.0d0 (m:Lambertian (c:Color 0.8d0 0.8d0 0.0d0))) ; Center - (s:Sphere (v:Vec3 0.0d0 0.0d0 -1.2d0) 0.5d0 (m:Lambertian (c:Color 0.1d0 0.2d0 0.5d0))) + (s:Sphere (v:v3 0.0d0 0.0d0 -1.2d0) 0.5d0 (m:Lambertian (c:Color 0.1d0 0.2d0 0.5d0))) ; Left - (s:Sphere (v:Vec3 -1.0d0 0.0d0 -1.0d0) 0.5d0 (m:Dielectric 1.5d0)) + (s:Sphere (v:v3 -1.0d0 0.0d0 -1.0d0) 0.5d0 (m:Dielectric 1.5d0)) ; Bubble - (s:Sphere (v:Vec3 -1.0d0 0.0d0 -1.0d0) 0.4d0 (m:Dielectric (/ 1.0d0 1.5d0))) + (s:Sphere (v:v3 -1.0d0 0.0d0 -1.0d0) 0.4d0 (m:Dielectric (/ 1.0d0 1.5d0))) ; Right - (s:Sphere (v:Vec3 1.0d0 0.0d0 -1.0d0) 0.5d0 (m:Metal (c:Color 0.8d0 0.6d0 0.2d0) 1.0d0)) + (s:Sphere (v:v3 1.0d0 0.0d0 -1.0d0) 0.5d0 (m:Metal (c:Color 0.8d0 0.6d0 0.2d0) 1.0d0)) ]) (declare R F64) @@ -64,8 +63,8 @@ (declare SMALL-WORLD (List s:Sphere)) (define SMALL-WORLD [ - (s:Sphere (v:Vec3 (negate R) 0 -1) R (m:Lambertian (c:Color 0.0d0 0.0d0 1.0d0))) - (s:Sphere (v:Vec3 R 0 -1) R (m:Lambertian (c:Color 1.0d0 0.0d0 0.0d0))) + (s:Sphere (v:v3 (negate R) 0 -1) R (m:Lambertian (c:Color 0.0d0 0.0d0 1.0d0))) + (s:Sphere (v:v3 R 0 -1) R (m:Lambertian (c:Color 1.0d0 0.0d0 0.0d0))) ]) (declare rand-color (Void -> c:Color)) diff --git a/src/sphere.ct b/src/sphere.ct --- a/src/sphere.ct +++ b/src/sphere.ct @@ -12,7 +12,7 @@ (coalton-toplevel (define-struct Sphere - (center v:Vec3) + (center v::Vec3) (radius F64) (material m:Material)) diff --git a/src/util.ct b/src/util.ct --- a/src/util.ct +++ b/src/util.ct @@ -10,15 +10,18 @@ (cl:declaim (cl:optimize (cl:speed 3) (cl:safety 0) (cl:debug 0))) (coalton-toplevel - + + (inline) (declare deg-to-rad (F64 -> F64)) (define (deg-to-rad degrees) (* degrees (/ (the F64 trig:pi) 180.0d0))) + (inline) (declare rand-f64 (Void -> F64)) (define (rand-f64) (lisp (-> F64) () (cl:random 1.0d0))) + (inline) (declare rand-f64-range (F64 * F64 -> F64)) (define (rand-f64-range min max) (+ min (* (- max min) (rand-f64)))) diff --git a/src/vec3.ct b/src/vec3.ct --- a/src/vec3.ct +++ b/src/vec3.ct @@ -1,47 +1,172 @@ (cl:defpackage #:ray/vec3 (:use #:coalton #:coalton-prelude) (:local-nicknames (#:math #:coalton/math) + (#:simd #:sb-simd-avx2) (#:util #:ray/util)) - (:export #:Vec3 - #:random - #:random-within - #:random-on-hemisphere - #:random-unit-vector - #:random-in-unit-disk - #:reflect - #:refract - #:near-zero? - #:unit-vector - #:vec-length - #:vec-length-squared - #:vec-add - #:vec-add-scalar - #:vec-sub - #:vec-mul - #:vec-mul-scalar - #:vec-div-scalar - #:vec-dot - #:vec-cross - #:vec-negate)) + (:export + ;#:Vec3 + #:v3 + #:get-x + #:get-y + #:get-z + #:random + #:random-within + #:random-on-hemisphere + #:random-unit-vector + #:random-in-unit-disk + #:reflect + #:refract + #:near-zero? + #:unit-vector + #:vec-length + #:vec-length-squared + #:vec-add + #:vec-add-scalar + #:vec-sub + #:vec-mul + #:vec-mul-scalar + #:vec-div-scalar + #:vec-dot + #:vec-cross + #:vec-negate)) (cl:in-package #:ray/vec3) (cl:declaim (cl:optimize (cl:speed 3) (cl:safety 0) (cl:debug 0))) (coalton-toplevel + (repr :native (sb-simd-avx:f64.4)) + (define-type Vec3) - (define-type Vec3 (Vec3 F64 F64 F64)) + (inline) + (declare v3 (F64 * F64 * F64 -> Vec3)) + (define (v3 x y z) + (lisp (-> Vec3) (x y z) (simd:make-f64.4 x y z 0.0d0)))) + +(coalton-toplevel + (inline) + (declare get-x (Vec3 -> F64)) + (define (get-x vec3) (lisp (-> F64) (vec3) (cl:nth-value 0 (simd:f64.4-values vec3))))) +(coalton-toplevel + (inline) + (declare get-y (Vec3 -> F64)) + (define (get-y vec3) (lisp (-> F64) (vec3) (cl:nth-value 1 (simd:f64.4-values vec3))))) + +(coalton-toplevel + (inline) + (declare get-z (Vec3 -> F64)) + (define (get-z vec3) (lisp (-> F64) (vec3) (cl:nth-value 2 (simd:f64.4-values vec3))))) + +(coalton-toplevel + (inline) (declare random (Void -> Vec3)) (define (random) - (Vec3 (util:rand-f64) (util:rand-f64) (util:rand-f64))) + (v3 (util:rand-f64) (util:rand-f64) (util:rand-f64)))) +(coalton-toplevel + (inline) (declare random-within (F64 * F64 -> Vec3)) (define (random-within min max) - (Vec3 (util:rand-f64-range min max) - (util:rand-f64-range min max) - (util:rand-f64-range min max))) + (v3 (util:rand-f64-range min max) + (util:rand-f64-range min max) + (util:rand-f64-range min max)))) + +(coalton-toplevel + (inline) + (declare near-zero? (Vec3 -> Boolean)) + (define (near-zero? vec) + (let a = 1.0d-8) + (and (< (get-x vec) a) (< (get-y vec) a) (< (get-z vec) a)))) + +(coalton-toplevel + (inline) + (declare vec-length-squared (Vec3 -> F64)) + (define (vec-length-squared vec) + (lisp (-> F64) (vec) (simd:f64.4-horizontal+ (simd:f64.4* vec vec))))) +(coalton-toplevel + (inline) + (declare vec-length (Vec3 -> F64)) + (define (vec-length vec) + (math:sqrt (vec-length-squared vec)))) + +(coalton-toplevel + (inline) + (declare vec-add (Vec3 * Vec3 -> Vec3)) + (define (vec-add u v) + "Adds two vectors together" + (lisp (-> Vec3) (u v) (simd:f64.4+ u v)))) + +(coalton-toplevel + (inline) + (declare vec-add-scalar (Vec3 * F64 -> Vec3)) + (define (vec-add-scalar vec t) + "Add a scalar to all fields of a vector" + (lisp (-> Vec3) (vec t) (simd:f64.4+ vec (Vec3 t t t))))) + +(coalton-toplevel + (inline) + (declare vec-sub (Vec3 * Vec3 -> Vec3)) + (define (vec-sub u v) + "Subtract one vector from another" + (lisp (-> Vec3) (u v) (simd:f64.4- u v)))) + +(coalton-toplevel + (inline) + (declare vec-mul (Vec3 * Vec3 -> Vec3)) + (define (vec-mul u v) + "Multiply two vectors together" + (lisp (-> Vec3) (u v) (simd:f64.4* u v)))) + +(coalton-toplevel + (inline) + (declare vec-mul-scalar (Vec3 * F64 -> Vec3)) + (define (vec-mul-scalar vec t) + "Multiply a vector by a scalar" + (lisp (-> Vec3) (vec t) (simd:f64.4* vec (Vec3 t t t))))) + +(coalton-toplevel + (inline) + (declare vec-dot (Vec3 * Vec3 -> F64)) + (define (vec-dot u v) + "Compute the dot-product of two vectors" + (lisp (-> F64) (u v) (simd:f64.4-horizontal+ (simd:f64.4* u v))))) + +(coalton-toplevel + (inline) + (declare vec-cross (Vec3 * Vec3 -> Vec3)) + (define (vec-cross u v) + (let ux = (get-x u)) + (let uy = (get-y u)) + (let uz = (get-z u)) + (let vx = (get-x v)) + (let vy = (get-y v)) + (let vz = (get-z v)) + (v3 (- (* uy vz) (* uz vy)) + (- (* uz vx) (* ux vz)) + (- (* ux vy) (* uy vx))))) + +(coalton-toplevel + (inline) + (declare vec-div-scalar (Vec3 * F64 -> Vec3)) + (define (vec-div-scalar vec t) + (vec-mul-scalar vec (/ 1.0d0 t)))) + +(coalton-toplevel + (inline) + (declare vec-negate (Vec3 -> Vec3)) + (define (vec-negate vec) + (lisp (-> Vec3) (vec) (simd:f64.4* vec (simd:f64.4-broadcast -1.0d0))))) + +(coalton-toplevel + (inline) + (declare unit-vector (Vec3 -> Vec3)) + (define (unit-vector v) + (vec-div-scalar v (vec-length v)))) + +(coalton-toplevel + (inline) (declare random-unit-vector (Void -> Vec3)) (define (random-unit-vector) (let p = (random-within -1.0d0 1.0d0)) @@ -49,26 +174,34 @@ (if (and (> lensq 1.0d-160) (<= lensq 1)) (vec-div-scalar p (math:sqrt lensq)) - (random-unit-vector))) - + (random-unit-vector)))) + +(coalton-toplevel + (inline) (declare random-on-hemisphere (Vec3 -> Vec3)) (define (random-on-hemisphere normal) (let on-unit-sphere = (random-unit-vector)) (if (> (vec-dot on-unit-sphere normal) 0.0d0) on-unit-sphere - (vec-negate on-unit-sphere))) + (vec-negate on-unit-sphere)))) +(coalton-toplevel + (inline) (declare random-in-unit-disk (Void -> Vec3)) (define (random-in-unit-disk) - (let p = (Vec3 (util:rand-f64-range -1.0d0 1.0d0) (util:rand-f64-range -1.0d0 1.0d0) 0.0d0)) + (let p = (v3 (util:rand-f64-range -1.0d0 1.0d0) (util:rand-f64-range -1.0d0 1.0d0) 0.0d0)) (if (< (vec-length-squared p) 1.0d0) p - (random-in-unit-disk))) + (random-in-unit-disk)))) +(coalton-toplevel + (inline) (declare reflect (Vec3 * Vec3 -> Vec3)) (define (reflect v n) - (vec-sub v (vec-mul-scalar n (* (vec-dot v n) 2.0d0)))) + (vec-sub v (vec-mul-scalar n (* (vec-dot v n) 2.0d0))))) +(coalton-toplevel + (inline) (declare refract (Vec3 * Vec3 * F64 -> Vec3)) (define (refract uv n etai-over-etat) (let cos-theta = (min (vec-dot (vec-negate uv) n) 1.0d0)) @@ -77,67 +210,5 @@ etai-over-etat)) (let r-out-parallel = (vec-mul-scalar n (negate (math:sqrt (abs (- 1.0d0 (vec-length-squared r-out-perp))))))) - (vec-add r-out-perp r-out-parallel)) - - (declare near-zero? (Vec3 -> Boolean)) - (define (near-zero? (Vec3 x y z)) - (let a = 1.0d-8) - (and (< x a) (< y a) (< z a))) - - (declare unit-vector (Vec3 -> Vec3)) - (define (unit-vector v) - (vec-div-scalar v (vec-length v))) - - (declare vec-length-squared (Vec3 -> F64)) - (define (vec-length-squared (Vec3 x y z)) - (+ (* x x) (+ (* y y) (* z z)))) - - (declare vec-length (Vec3 -> F64)) - (define (vec-length vec) - (math:sqrt (vec-length-squared vec))) - - (declare vec-add (Vec3 * Vec3 -> Vec3)) - (define (vec-add (Vec3 ux uy uz) (Vec3 vx vy vz)) - "Adds two vectors together" - (Vec3 (+ ux vx) (+ uy vy) (+ uz vz))) - - (declare vec-add-scalar (Vec3 * F64 -> Vec3)) - (define (vec-add-scalar (Vec3 x y z) t) - "Add a scalar to all fields of a vector" - (Vec3 (+ x t) (+ y t) (+ z t))) - - (declare vec-sub (Vec3 * Vec3 -> Vec3)) - (define (vec-sub (Vec3 ux uy uz) (Vec3 vx vy vz)) - "Subtract one vector from another" - (Vec3 (- ux vx) (- uy vy) (- uz vz))) - - (declare vec-mul (Vec3 * Vec3 -> Vec3)) - (define (vec-mul (Vec3 ux uy uz) (Vec3 vx vy vz)) - "Multiply two vectors together" - (Vec3 (* ux vx) (* uy vy) (* uz vz))) - - (declare vec-mul-scalar (Vec3 * F64 -> Vec3)) - (define (vec-mul-scalar (Vec3 x y z) t) - "Multiply a vector by a scalar" - (Vec3 (* t x) (* t y) (* t z))) - - (declare vec-dot (Vec3 * Vec3 -> F64)) - (define (vec-dot (Vec3 ux uy uz) (Vec3 vx vy vz)) - "Compute the dot-product of two vectors" - (+ (* ux vx) (+ (* uy vy) (* uz vz)))) - - (declare vec-cross (Vec3 * Vec3 -> Vec3)) - (define (vec-cross (Vec3 ux uy uz) (Vec3 vx vy vz)) - (Vec3 (- (* uy vz) (* uz vy)) - (- (* uz vx) (* ux vz)) - (- (* ux vy) (* uy vx)))) - - (declare vec-div-scalar (Vec3 * F64 -> Vec3)) - (define (vec-div-scalar vec t) - (vec-mul-scalar vec (/ 1.0d0 t))) - - (declare vec-negate (Vec3 -> Vec3)) - (define (vec-negate (Vec3 x y z)) - (Vec3 (negate x) (negate y) (negate z))) + (vec-add r-out-perp r-out-parallel))) -) diff --git a/src/vector.ct b/src/vector.ct deleted file mode 100644 --- a/src/vector.ct +++ /dev/null @@ -1,181 +0,0 @@ -(cl:defpackage #:ray/vector - (:use #:coalton) - (:local-nicknames - (#:cp #:coalton-prelude) - (#:math #:coalton/math)) - (:export #:Vector - #:V3 - #:Vec3 - #:+ - #:- - #:* - #:⋆ - #:/ - #:· - #:negate - #:near-zero?)) - -(cl:in-package #:ray/vector) - -(cl:declaim (cl:optimize (cl:speed 3) (cl:safety 0) (cl:debug 0))) - -(coalton-toplevel - (define-class (Vector :v) - (+ "Add two vectors together" - (cp:Num :a => :v :a * :v :a -> :v :a)) - (- "Subtract one vector from another" - (cp:Num :a => :v :a * :v :a -> :v :a)) - (* "Multiply two vectors" - (cp:Num :a => :v :a * :v :a -> :v :a)) - (⋆ "Multiply a vector by a scalar (note: this name is \\star not *)" - (cp:Num :a => :v :a * :a -> :v :a)) - (/ "Divide a vector by a scalar" - (cp:Reciprocable :a => :v :a * :a -> :v :a)) - (· "Dot-product of two vectors" - (cp:Num :a => :v :a * :v :a -> :a)) - (negate "Negate a vector" - (cp:Num :a => :v :a -> :v :a)) - ;(near-zero? (cp:Num :a => :v :a -> Boolean)) - ) - - (repr :native (cl:simple-array cl:double-float (3))) - (define-type V3) - - (declare make-v3 (F64 * F64 * F64 -> V3)) - (define (make-v3 x y z) - (lisp (-> V3) (x y z) - (cl:make-array 3 :element-type 'cl:double-float :initial-contents (make-list x y z)))) - - (define-type (Vec3 :a) (Vec3 :a :a :a)) - - (define-instance (Vector Vec3) - (define (+ (Vec3 x1 y1 z1) (Vec3 x2 y2 z2)) - (Vec3 (cp:+ x1 x2) (cp:+ y1 y2) (cp:+ z1 z2))) - - (define (- (Vec3 x1 y1 z1) (Vec3 x2 y2 z2)) - (Vec3 (cp:- x1 x2) (cp:- y1 y2) (cp:- z1 z2))) - - (define (· (Vec3 x1 y1 z1) (Vec3 x2 y2 z2)) - (cp:+ (cp:* x1 x2) (cp:+ (cp:* y1 y2) (cp:* z1 z2)))) - - (define (* (Vec3 x1 y1 z1) (Vec3 x2 y2 z2)) - (Vec3 (cp:* x1 x2) (cp:* y1 y2) (cp:* z1 z2))) - - (define (⋆ (Vec3 x y z) t) - (Vec3 (cp:* x t) (cp:* y t) (cp:* z t))) - - (define (/ (Vec3 x y z) t) - (Vec3 (cp:/ x t) (cp:/ y t) (cp:/ z t))) - - (define (negate (Vec3 x y z)) - (Vec3 (cp:negate x) (cp:negate y) (cp:negate z))) - - ; (define (near-zero? (Vec3 x y z)) - ; (let a = 1.0e-8) - ; (and (cp:< x a) (cp:< y a) (cp:< z a))) - - ) - -; (declare random-unit-vector (Void -> Vec3)) -; (define (random-unit-vector) -; (let p = (random-within -1.0 1.0)) -; (let lensq = (vec-length-squared p)) -; (if (and (> lensq 1.0e-45) -; (<= lensq 1)) -; (vec-div-scalar p (math:sqrt lensq)) -; (random-unit-vector))) -; -; (declare random-on-hemisphere (Vec3 -> Vec3)) -; (define (random-on-hemisphere normal) -; (let on-unit-sphere = (random-unit-vector)) -; (if (> (vec-dot on-unit-sphere normal) 0.0) -; on-unit-sphere -; (vec-negate on-unit-sphere))) -; -; (declare reflect (Vec3 * Vec3 -> Vec3)) -; (define (reflect v n) -; (vec-sub v (vec-mul-scalar n (* (vec-dot v n) 2)))) -; -; (declare refract (Vec3 * Vec3 * F32 -> Vec3)) -; (define (refract uv n etai-over-etat) -; (let cos-theta = (min (vec-dot (vec-negate uv) n) 1.0)) -; (let r-out-perp = (vec-mul-scalar -; (vec-add uv (vec-mul-scalar n cos-theta)) -; etai-over-etat)) -; (let r-out-parallel = (vec-mul-scalar n -; (negate (math:sqrt (abs (- 1.0 (vec-length-squared r-out-perp))))))) -; (vec-add r-out-perp r-out-parallel)) -; -; (declare near-zero? (Vec3 -> Boolean)) -; (define (near-zero? (Vec3 x y z)) -; (let a = 1.0e-8) -; (and (< x a) (< y a) (< z a))) -; -; (declare unit-vector (Vec3 -> Vec3)) -; (define (unit-vector v) -; (vec-div-scalar v (vec-length v))) -; -; (declare vec-length-squared (Vec3 -> F32)) -; (define (vec-length-squared (Vec3 x y z)) -; (+ (* x x) (+ (* y y) (* z z)))) -; -; (declare vec-length (Vec3 -> F32)) -; (define (vec-length vec) -; (math:sqrt (vec-length-squared vec))) -; -; (declare vec-add (Vec3 * Vec3 -> Vec3)) -; (define (vec-add (Vec3 ux uy uz) (Vec3 vx vy vz)) -; "Adds two vectors together" -; (Vec3 (+ ux vx) (+ uy vy) (+ uz vz))) -; -; (declare vec-add-scalar (Vec3 * F32 -> Vec3)) -; (define (vec-add-scalar (Vec3 x y z) t) -; "Add a scalar to all fields of a vector" -; (Vec3 (+ x t) (+ y t) (+ z t))) -; -; (declare vec-sub (Vec3 * Vec3 -> Vec3)) -; (define (vec-sub (Vec3 ux uy uz) (Vec3 vx vy vz)) -; "Subtract one vector from another" -; (Vec3 (- ux vx) (- uy vy) (- uz vz))) -; -; (declare vec-mul (Vec3 * Vec3 -> Vec3)) -; (define (vec-mul (Vec3 ux uy uz) (Vec3 vx vy vz)) -; "Multiply two vectors together" -; (Vec3 (* ux vx) (* uy vy) (* uz vz))) -; -; (declare vec-mul-scalar (Vec3 * F32 -> Vec3)) -; (define (vec-mul-scalar (Vec3 x y z) t) -; "Multiply a vector by a scalar" -; (Vec3 (* t x) (* t y) (* t z))) -; -; (declare vec-dot (Vec3 * Vec3 -> F32)) -; (define (vec-dot (Vec3 ux uy uz) (Vec3 vx vy vz)) -; "Compute the dot-product of two vectors" -; (+ (* ux vx) (+ (* uy vy) (* uz vz)))) -; -; (declare vec-div-scalar (Vec3 * F32 -> Vec3)) -; (define (vec-div-scalar vec t) -; (vec-mul-scalar vec (/ 1.0 t))) -; -; (declare vec-negate (Vec3 -> Vec3)) -; (define (vec-negate (Vec3 x y z)) -; (Vec3 (negate x) (negate y) (negate z))) -; -; -; (declare random (Void -> Vec3)) -; (define (random) -; (Vec3 (rand-f64) (rand-f64) (rand-f64))) -; -; (declare random-within (cp:F32 * cp:F32 -> Vec3)) -; (define (random-within min max) -; (Vec3 (rand-f64-range min max) (rand-f64-range min max) (rand-f64-range min max))) -; -; (declare rand-f64 (Void -> cp:F32)) -; (define (rand-f64) -; (lisp (-> F32) () (cl:random 1.0))) -; -; (declare rand-f64-range (cp:F32 * cp:F32 -> cp:F32)) -; (define (rand-f64-range min max) -; (+ min (* (- max min) (rand-f64)))) - -)