git.fiddlerwoaroof.com
Raw Blame History
(in-package :fwoar.lisp-sandbox.1)

(defun deg2rad (deg)
  (/ (* deg pi)
     180.0d0))

(defun rand-min-max (min max)
  (+ min
     (* (- max min)
        (random 1.0d0))))

(defun rand-vec3 ()
  (vec3 (random 1.0d0)
        (random 1.0d0)
        (random 1.0d0)))

(defun rand-vec3-min-max (min max)
  (vec3 (rand-min-max min max)
        (rand-min-max min max)
        (rand-min-max min max)))

(declaim (inline vec+ vec* vec- vec/ random-in-unit-sphere negate))
(defun random-in-unit-sphere ()
  (loop for p = (rand-vec3-min-max -1.0d0 1.0d0)
        while (>= (length-squared p)
                  1)
        finally (return p)))

(defun random-unit-vector ()
  (unit-vector (random-in-unit-sphere)))

(defun vec+ (vec1 vec2)
  (declare (optimize (speed 3)))
  (fw.lu:vector-destructuring-bind (a b c) vec1
    (fw.lu:vector-destructuring-bind (a1 b1 c1) vec2
      (vec3 (+ a a1)
            (+ b b1)
            (+ c c1)))))
(define-compiler-macro vec+ (&whole whole vec1 vec2)
  (cond ((and (vectorp vec1)
              (vectorp vec2))
         (vec+ vec1 vec2))
        ((vectorp vec1)
         (alexandria:once-only (vec2)
           `(fw.lu:vector-destructuring-bind (a b c) ,vec1
              (vec3
               (+ a (aref ,vec2 0))
               (+ b (aref ,vec2 1))
               (+ c (aref ,vec2 2))))))
        ((vectorp vec2)
         (alexandria:once-only (vec1)
           `(fw.lu:vector-destructuring-bind (a b c) ,vec2
              (vec3
               (+ a (aref ,vec1 0))
               (+ b (aref ,vec1 1))
               (+ c (aref ,vec1 2))))))
        (t whole)))
(defun vec- (vec1 vec2)
  (declare (optimize (speed 3)))
  (fw.lu:vector-destructuring-bind (a b c) vec1
    (fw.lu:vector-destructuring-bind (a1 b1 c1) vec2
      (vec3 (- a a1)
            (- b b1)
            (- c c1)))))
(defun vec* (vec1 vec2)
  (declare (optimize (speed 3)))
  (etypecase vec1
    ((array * (3)) (fw.lu:vector-destructuring-bind (a b c) vec1
                     (fw.lu:vector-destructuring-bind (a1 b1 c1) vec2
                       (vec3 (* a a1)
                             (* b b1)
                             (* c c1)))))
    (double-float (fw.lu:vector-destructuring-bind (a1 b1 c1) vec2
                    (vec3 (* vec1 a1)
                          (* vec1 b1)
                          (* vec1 c1))))
    (single-float (fw.lu:vector-destructuring-bind (a1 b1 c1) vec2
                    (vec3 (* vec1 a1)
                          (* vec1 b1)
                          (* vec1 c1))))
    (number (fw.lu:vector-destructuring-bind (a1 b1 c1) vec2
              (vec3 (* vec1 a1)
                    (* vec1 b1)
                    (* vec1 c1))))))
(defun negate (vec)
  (fw.lu:vector-destructuring-bind (x y z) vec
    (vec3 (- x)
          (- y)
          (- z))))

(defun vec/ (vec it)
  (declare (optimize (speed 3)))
  (vec* (/ 1.0 it)
        vec))
(defun dot (u v)
  (fw.lu:vector-destructuring-bind (a1 b1 c1) u
    (fw.lu:vector-destructuring-bind (a2 b2 c2) v
      (+ (* a1 a2)
         (* b1 b2)
         (* c1 c2)))))
(defun cross (u v)
  (fw.lu:vector-destructuring-bind (a1 b1 c1) u
    (fw.lu:vector-destructuring-bind (a2 b2 c2) v
      (vec3 (- (* b1 c2)
               (* c1 b2))
            (- (* c1 a2)
               (* a1 c2))
            (- (* a1 b2)
               (* b1 a2))))))

(defun length-squared (v)
  (fw.lu:vector-destructuring-bind (x y z) v
    (+ (* x x)
       (* y y)
       (* z z))))
(defun vec-length (v)
  (sqrt (length-squared v)))
(defun unit-vector (v)
  (vec/ v
        (vec-length v)))

(declaim (inline near-zero))
(defun near-zero (vec)
  (fw.lu:vector-destructuring-bind (x y z) vec
    (let* ((s 1.0d-8))
      (and (< (abs x) s)
           (< (abs y) s)
           (< (abs z) s)))))

(defvar *color-depth* 255)

(defun clamp (x min max)
  (cond ((< x min) min)
        ((> x max) max)
        (t x)))

(defvar *samples-per-pixel* 1)
(defun scale-to-8bit (color)
  (let ((scale (/ *samples-per-pixel*)))
    (flet ((scale-to-depth (c)
             (floor
              (* *color-depth*
                 (clamp (sqrt (* c scale))
                        0.0d0 0.999d0)))))
      (fwoar.lisputils:vector-destructuring-bind (r g b) color
        (let ((r (scale-to-depth r))
              (g (scale-to-depth g))
              (b (scale-to-depth b)))
          (vec3 r g b))))))