rayzor
view src/scene.cc @ 17:79609d482762
the renderer renders, also fixed an unnoticed matrix conversion problem between scenegraph and min3d
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 14 Apr 2014 07:34:45 +0300 |
parents | be616b58df99 |
children | 6b11a3f8706e |
line source
1 #include <string.h>
2 #include <float.h>
3 #include "scene.h"
4 #include "min3d.h"
6 Scene::Scene()
7 {
8 name = 0;
9 active_cam = 0;
11 fog_exp = 1.0;
13 set_ambient(Vector3(0.05, 0.05, 0.05));
15 set_background(Vector3(0.4, 0.3, 0.05), SCN_BG_LOW);
16 set_background(Vector3(0.6, 0.6, 0.6), SCN_BG_MID);
17 set_background(Vector3(0.1, 0.5, 1.0), SCN_BG_HIGH);
18 }
20 Scene::~Scene()
21 {
22 clear();
23 }
25 void Scene::clear()
26 {
27 delete [] name;
29 size_t i;
30 for(i=0; i<objects.size(); i++) {
31 delete objects[i];
32 }
33 for(i=0; i<lights.size(); i++) {
34 delete lights[i];
35 }
36 for(i=0; i<cameras.size(); i++) {
37 delete cameras[i];
38 }
39 }
41 void Scene::set_name(const char *name)
42 {
43 delete [] this->name;
44 this->name = new char[strlen(name) + 1];
45 strcpy(this->name, name);
46 }
48 const char *Scene::get_name() const
49 {
50 return name ? name : "<unknown>";
51 }
53 void Scene::set_background(const Vector3 &col, int idx)
54 {
55 if(idx == -1) {
56 bg[0] = bg[1] = bg[2] = col;
57 } else {
58 bg[idx] = col;
59 }
60 }
62 const Vector3 &Scene::get_background(int idx) const
63 {
64 return bg[idx == -1 ? 0 : idx];
65 }
67 #define LERP(a, b, t) ((a) + ((b) - (a)) * t)
69 Vector3 Scene::get_background(const Ray &ray) const
70 {
71 Vector3 dir = normalize(ray.dir);
73 float v;
74 if(dir.z == 0.0) {
75 v = dir.y > 0.0 ? 1.0 : -1.0;
76 } else {
77 float angle = atan2(dir.z, dir.y);
78 v = angle / M_PI;
79 }
81 float r = v >= 0.0 ? LERP(bg[1].x, bg[2].x, v) : LERP(bg[1].x, bg[0].x, -v);
82 float g = v >= 0.0 ? LERP(bg[1].y, bg[2].y, v) : LERP(bg[1].y, bg[0].y, -v);
83 float b = v >= 0.0 ? LERP(bg[1].z, bg[2].z, v) : LERP(bg[1].z, bg[0].z, -v);
84 return Vector3(r, g, b);
85 }
87 void Scene::set_ambient(const Vector3 &col)
88 {
89 ambient = col;
90 }
92 const Vector3 &Scene::get_ambient() const
93 {
94 return ambient;
95 }
98 void Scene::add(SceneNode *node)
99 {
100 nodes.push_back(node);
102 switch(node->get_type()) {
103 case NODE_OBJECT:
104 objects.push_back((Object*)node);
105 break;
107 case NODE_LIGHT:
108 lights.push_back((Light*)node);
109 break;
111 case NODE_CAMERA:
112 cameras.push_back((Camera*)node);
113 break;
115 default:
116 break;
117 }
119 sel.clear();
120 }
122 int Scene::get_node_count() const
123 {
124 return (int)nodes.size();
125 }
127 int Scene::get_object_count() const
128 {
129 return (int)objects.size();
130 }
132 int Scene::get_light_count() const
133 {
134 return (int)lights.size();
135 }
137 int Scene::get_camera_count() const
138 {
139 return (int)cameras.size();
140 }
142 SceneNode *Scene::get_node(int idx)
143 {
144 return nodes[idx];
145 }
147 const SceneNode *Scene::get_node(int idx) const
148 {
149 return nodes[idx];
150 }
152 Object *Scene::get_object(int idx)
153 {
154 return objects[idx];
155 }
157 const Object *Scene::get_object(int idx) const
158 {
159 return objects[idx];
160 }
162 Light *Scene::get_light(int idx)
163 {
164 return lights[idx];
165 }
167 const Light *Scene::get_light(int idx) const
168 {
169 return lights[idx];
170 }
172 Camera *Scene::get_camera(int idx)
173 {
174 return cameras[idx];
175 }
177 const Camera *Scene::get_camera(int idx) const
178 {
179 return cameras[idx];
180 }
182 void Scene::set_active_camera(Camera *cam)
183 {
184 active_cam = cam;
185 }
187 Camera *Scene::get_active_camera() const
188 {
189 return active_cam;
190 }
192 void Scene::draw() const
193 {
194 if(active_cam) {
195 // TODO
196 }
198 int num_nodes = get_node_count();
199 for(int i=0; i<num_nodes; i++) {
200 bool selected = false;
202 for(size_t j=0; j<sel.size(); j++) {
203 if(sel[j] == i) {
204 selected = true;
205 break;
206 }
207 }
209 nodes[i]->draw(selected);
210 }
211 }
213 void Scene::select(int s)
214 {
215 for(size_t i=0; i<sel.size(); i++) {
216 if(sel[i] == s) {
217 return;
218 }
219 }
220 sel.push_back(s);
221 }
223 void Scene::clear_selection()
224 {
225 sel.clear();
226 }
228 int Scene::get_selection_count() const
229 {
230 return (int)sel.size();
231 }
233 int Scene::get_selection(int idx) const
234 {
235 return idx >= 0 && idx < (int)sel.size() ? sel[idx] : -1;
236 }
238 bool Scene::intersect(const Ray &ray, RayHit *hit) const
239 {
240 if(hit) {
241 hit->dist = FLT_MAX;
242 hit->obj = 0;
243 }
245 int num_obj = (int)objects.size();
246 for(int i=0; i<num_obj; i++) {
247 RayHit tmphit;
248 if(objects[i]->intersect(ray, hit ? &tmphit : 0)) {
249 if(!hit) return true;
250 if(tmphit.dist < hit->dist) {
251 *hit = tmphit;
252 }
253 }
254 }
255 return hit && hit->obj;
256 }