rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <float.h>
|
nuclear@0
|
4 #include <algorithm>
|
nuclear@0
|
5 #include "scene.h"
|
nuclear@0
|
6 #include "texture.h"
|
nuclear@0
|
7
|
nuclear@0
|
8 bool load_scene_file(Scene *scn, const char *fname);
|
nuclear@0
|
9 bool save_scene_file(const Scene *scn, const char *fname);
|
nuclear@0
|
10
|
nuclear@0
|
11
|
nuclear@0
|
12 // default camera
|
nuclear@0
|
13 TargetCamera Scene::def_cam(Vector3(0, 0, -10), Vector3(0, 0, 0));
|
nuclear@0
|
14
|
nuclear@0
|
15 Scene::Scene()
|
nuclear@0
|
16 {
|
nuclear@0
|
17 camera = &def_cam;
|
nuclear@0
|
18 bgcolor = Color(0, 0, 0);
|
nuclear@0
|
19 envmap = envmap_conv = 0;
|
nuclear@0
|
20 fog_start = fog_end = -1;
|
nuclear@0
|
21 }
|
nuclear@0
|
22
|
nuclear@0
|
23 Scene::~Scene()
|
nuclear@0
|
24 {
|
nuclear@0
|
25 for(auto obj: objects) {
|
nuclear@0
|
26 delete obj;
|
nuclear@0
|
27 }
|
nuclear@0
|
28 for(auto lt: lights) {
|
nuclear@0
|
29 delete lt;
|
nuclear@0
|
30 }
|
nuclear@0
|
31 if(camera != &def_cam) {
|
nuclear@0
|
32 delete camera;
|
nuclear@0
|
33 }
|
nuclear@0
|
34
|
nuclear@0
|
35 delete envmap;
|
nuclear@0
|
36 if(envmap_conv != envmap) {
|
nuclear@0
|
37 delete envmap_conv;
|
nuclear@0
|
38 }
|
nuclear@0
|
39 }
|
nuclear@0
|
40
|
nuclear@0
|
41 bool Scene::load(const char *fname)
|
nuclear@0
|
42 {
|
nuclear@0
|
43 return load_scene_file(this, fname);
|
nuclear@0
|
44 }
|
nuclear@0
|
45
|
nuclear@0
|
46 bool Scene::save(const char *fname) const
|
nuclear@0
|
47 {
|
nuclear@0
|
48 return save_scene_file(this, fname);
|
nuclear@0
|
49 }
|
nuclear@0
|
50
|
nuclear@0
|
51 void Scene::set_background_color(const Color &color)
|
nuclear@0
|
52 {
|
nuclear@0
|
53 bgcolor = color;
|
nuclear@0
|
54 }
|
nuclear@0
|
55
|
nuclear@0
|
56 void Scene::set_fog(float fog_start, float fog_end)
|
nuclear@0
|
57 {
|
nuclear@0
|
58 this->fog_start = fog_start;
|
nuclear@0
|
59 this->fog_end = fog_end;
|
nuclear@0
|
60 }
|
nuclear@0
|
61
|
nuclear@0
|
62 void Scene::get_fog(float *fog_start, float *fog_end) const
|
nuclear@0
|
63 {
|
nuclear@0
|
64 *fog_start = this->fog_start;
|
nuclear@0
|
65 *fog_end = this->fog_end;
|
nuclear@0
|
66 }
|
nuclear@0
|
67
|
nuclear@0
|
68 void Scene::set_environment_map(TextureCube *map, TextureCube *map_conv)
|
nuclear@0
|
69 {
|
nuclear@0
|
70 envmap = map;
|
nuclear@0
|
71 envmap_conv = map_conv;//map_conv ? map_conv : map;
|
nuclear@0
|
72 }
|
nuclear@0
|
73
|
nuclear@0
|
74 void Scene::add_object(Object *obj)
|
nuclear@0
|
75 {
|
nuclear@0
|
76 objects.push_back(obj);
|
nuclear@0
|
77 }
|
nuclear@0
|
78
|
nuclear@0
|
79 Object *Scene::get_object(int i) const
|
nuclear@0
|
80 {
|
nuclear@0
|
81 if(i < 0 || i >= (int)objects.size()) {
|
nuclear@0
|
82 return 0;
|
nuclear@0
|
83 }
|
nuclear@0
|
84 return objects[i];
|
nuclear@0
|
85 }
|
nuclear@0
|
86
|
nuclear@0
|
87 int Scene::get_object_count() const
|
nuclear@0
|
88 {
|
nuclear@0
|
89 return (int)objects.size();
|
nuclear@0
|
90 }
|
nuclear@0
|
91
|
nuclear@0
|
92 void Scene::add_light(Light *lt)
|
nuclear@0
|
93 {
|
nuclear@0
|
94 lights.push_back(lt);
|
nuclear@0
|
95 }
|
nuclear@0
|
96
|
nuclear@0
|
97 Light *Scene::get_light(int i) const
|
nuclear@0
|
98 {
|
nuclear@0
|
99 if(i < 0 || i >= (int)lights.size()) {
|
nuclear@0
|
100 return 0;
|
nuclear@0
|
101 }
|
nuclear@0
|
102 return lights[i];
|
nuclear@0
|
103 }
|
nuclear@0
|
104
|
nuclear@0
|
105 int Scene::get_light_count() const
|
nuclear@0
|
106 {
|
nuclear@0
|
107 return (int)lights.size();
|
nuclear@0
|
108 }
|
nuclear@0
|
109
|
nuclear@0
|
110 void Scene::set_camera(Camera *cam)
|
nuclear@0
|
111 {
|
nuclear@0
|
112 if(camera != &def_cam) {
|
nuclear@0
|
113 delete camera;
|
nuclear@0
|
114 }
|
nuclear@0
|
115 camera = cam;
|
nuclear@0
|
116 }
|
nuclear@0
|
117
|
nuclear@0
|
118 Camera *Scene::get_camera() const
|
nuclear@0
|
119 {
|
nuclear@0
|
120 return camera;
|
nuclear@0
|
121 }
|
nuclear@0
|
122
|
nuclear@0
|
123 bool Scene::intersect(const Ray &ray, HitPoint *nearest_hit) const
|
nuclear@0
|
124 {
|
nuclear@0
|
125 nearest_hit->obj = 0;
|
nuclear@0
|
126 nearest_hit->dist = FLT_MAX;
|
nuclear@0
|
127
|
nuclear@0
|
128 // find the nearest hit (if any)
|
nuclear@0
|
129 for(Object *obj: objects) {
|
nuclear@0
|
130 HitPoint hit;
|
nuclear@0
|
131 if(obj->intersect(ray, &hit) && hit.dist < nearest_hit->dist) {
|
nuclear@0
|
132 *nearest_hit = hit;
|
nuclear@0
|
133 }
|
nuclear@0
|
134 }
|
nuclear@0
|
135 return nearest_hit->obj != 0;
|
nuclear@0
|
136 }
|
nuclear@0
|
137
|
nuclear@0
|
138 Color Scene::env_color(const Ray &ray) const
|
nuclear@0
|
139 {
|
nuclear@0
|
140 if(envmap) {
|
nuclear@0
|
141 Vector3 dir = ray.dir.normalized();
|
nuclear@0
|
142 return envmap->sample(dir.x, dir.y, dir.z);
|
nuclear@0
|
143 }
|
nuclear@0
|
144 return bgcolor;
|
nuclear@0
|
145 }
|
nuclear@0
|
146
|
nuclear@0
|
147 void Scene::prepare_xform(long msec)
|
nuclear@0
|
148 {
|
nuclear@0
|
149 int nobj = get_object_count();
|
nuclear@0
|
150 for(int i=0; i<nobj; i++) {
|
nuclear@0
|
151 objects[i]->prepare_xform(msec);
|
nuclear@0
|
152 }
|
nuclear@0
|
153 }
|