rayzor

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