]> Dogcows Code - chaz/rasterize/blob - element.hh
finishing fifth project
[chaz/rasterize] / element.hh
1
2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
7
8 #ifndef _ELEMENT_HH_
9 #define _ELEMENT_HH_
10
11 #include "color.hh"
12 #include "contact.hh"
13 #include "light.hh"
14 #include "raster.hh"
15 #include "ray.hh"
16 #include "scene.hh"
17
18
19 namespace rt {
20
21
22 /*
23 * A base class for an object in a scene.
24 */
25 class element
26 {
27 color_t kd;
28 raster_t* tx;
29
30 public:
31
32 element() :
33 kd(COLOR_WHITE), tx(NULL)
34 {}
35
36 virtual ~element()
37 {}
38
39 /*
40 * Determine if a ray intersects this element.
41 */
42 virtual bool intersect(ray_t ray, contact_t& hit) const = 0;
43
44 /*
45 * Get the material color of the element at a surface point.
46 */
47 virtual color_t color(vec_t point) const
48 {
49 return kd;
50 }
51
52 /*
53 * Get texture-coordinates from a surface point.
54 */
55 virtual vec_t txcoord(vec_t point) const
56 {
57 return VEC_ZERO;
58 }
59
60 /*
61 * Cast a ray to this element, returning the correct color value.
62 */
63 color_t cast(const contact_t& hit, const scene_t* scene) const
64 {
65 color_t kd = txcolor(hit.p);
66 color_t Ia = color_mult(scene_ambient(scene), kd);
67 color_t Id = diffuse(kd, hit, scene);
68 return color_clamp(color_add(Ia, Id));
69 }
70
71 /*
72 * Get whether or not a particular surface point is shadowed by other
73 * objects for a given light source.
74 */
75 bool is_shadowed(const contact_t& hit, const scene_t* scene, const light_t* light) const
76 {
77 #if SHADOWS
78 ray_t ray = ray_normalize(ray_new(hit.p, vec_sub(light->v, hit.p)));
79 for (list_t* i = scene_elements(scene); i; i = i->link) {
80 rt::element* obj = (rt::element*)i->val;
81 contact_t hit;
82 if (this != obj && obj->intersect(ray, hit)) {
83 return true;
84 }
85 }
86 #endif
87
88 return false;
89 }
90
91 /*
92 * Get the color of the element at a surface point after diffuse
93 * lighting.
94 */
95 color_t diffuse(color_t kd, const contact_t& hit, const scene_t* scene) const
96 {
97 vec_t n = vec_normalize(hit.n);
98
99 color_t c = COLOR_BLACK;
100
101 for (list_t* i = scene_lights(scene); i; i = i->link) {
102 light_t* l = (light_t*)i->val;
103 if (!is_shadowed(hit, scene, l)) {
104 vec_t I = vec_normalize(vec_sub(l->v, hit.p));
105 scal_t dot = scal_max(vec_dot(I, n), S(0.0));
106 color_t Id = color_scale2(kd, l->d, dot);
107 c = color_add(c, Id);
108 }
109 }
110
111 return c;
112 }
113
114 color_t txcolor(vec_t point) const
115 {
116 #if TEXTURING
117 if (tx != NULL) {
118 vec_t uv = txcoord(point);
119 #if QUIRKS
120 return raster_uv(tx, uv);
121 #else
122 return color_mult(color(point), raster_uv(tx, uv));
123 #endif
124 }
125 #endif
126 return color(point);
127 }
128
129 void material(color_t color)
130 {
131 kd = color;
132 }
133
134 void texture(raster_t* texture)
135 {
136 tx = texture;
137 }
138 };
139
140
141 } // namespace rt
142
143 #endif // _ELEMENT_HH_
144
This page took 0.038348 seconds and 4 git commands to generate.