-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsphere.lisp
62 lines (56 loc) · 2.14 KB
/
sphere.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
;;;; -*- Mode: Lisp -*-
(in-package :raytracer)
(defclass sphere (shape)
((radius
:initarg :radius
:initform 1)))
(defmethod draw ((shape sphere))
(let ((incr (/ pi 15)))
(do ((long 0 (+ long incr)))
((>= long (* 2 pi)))
(let ((nextLong (min (+ long incr) (* 2 pi))))
(cl-opengl:with-primitives :triangle-strip
(do ((lat 0 (+ lat (/ incr 2))))
((>= lat pi))
(apply #'cl-opengl:vertex
(vmult
(slot-value shape 'radius)
(list (* (sin lat) (cos long))
(* -1 (cos lat))
(* (sin lat) (sin long)))))
(apply #'cl-opengl:vertex
(vmult
(slot-value shape 'radius)
(list (* (sin lat) (cos nextLong))
(* -1 (cos lat))
(* (sin lat) (sin nextLong))))))
(apply #'cl-opengl:vertex
(vmult
(slot-value shape 'radius)
(list (* (sin pi) (cos long))
(* -1 (cos pi))
(* (sin pi) (sin long)))))
(apply #'cl-opengl:vertex
(vmult
(slot-value shape 'radius)
(list (* (sin pi) (cos nextLong))
(* -1 (cos pi))
(* (sin pi) (sin nextLong))))))))))
(defmethod intersect ((shape sphere) direction eye)
(with-slots (position radius) shape
(let* ((a (dot direction direction))
(b (* 2 (dot direction (vmin eye position))))
(c (- (dot
(vmin eye position)
(vmin eye position))
(* radius radius)))
(det (- (* b b) (* 4 (* a c)))))
(cond ((< det 0) +inf+)
(t
(min
(/ (- (* -1 b) (expt det 0.5)) (* 2 a))
(/ (+ (* -1 b) (expt det 0.5)) (* 2 a))))))))
(defmethod normal ((shape sphere) direction eye vecscale)
(with-slots (position) shape
(normalize (vmin (vadd eye (vmult vecscale direction)) position))))
(defmethod texture (shape direction eye vecscale))