nuclear@5: #include nuclear@17: #include nuclear@1: #include "scene.h" nuclear@12: #include "min3d.h" nuclear@1: nuclear@1: Scene::Scene() nuclear@1: { nuclear@1: name = 0; nuclear@6: active_cam = 0; nuclear@17: nuclear@17: fog_exp = 1.0; nuclear@17: nuclear@17: set_ambient(Vector3(0.05, 0.05, 0.05)); nuclear@17: nuclear@17: set_background(Vector3(0.4, 0.3, 0.05), SCN_BG_LOW); nuclear@17: set_background(Vector3(0.6, 0.6, 0.6), SCN_BG_MID); nuclear@17: set_background(Vector3(0.1, 0.5, 1.0), SCN_BG_HIGH); nuclear@1: } nuclear@1: nuclear@1: Scene::~Scene() nuclear@1: { nuclear@1: clear(); nuclear@1: } nuclear@1: nuclear@1: void Scene::clear() nuclear@1: { nuclear@1: delete [] name; nuclear@1: nuclear@1: size_t i; nuclear@1: for(i=0; iname; nuclear@1: this->name = new char[strlen(name) + 1]; nuclear@1: strcpy(this->name, name); nuclear@1: } nuclear@1: nuclear@1: const char *Scene::get_name() const nuclear@1: { nuclear@1: return name ? name : ""; nuclear@1: } nuclear@1: nuclear@17: void Scene::set_background(const Vector3 &col, int idx) nuclear@17: { nuclear@17: if(idx == -1) { nuclear@17: bg[0] = bg[1] = bg[2] = col; nuclear@17: } else { nuclear@17: bg[idx] = col; nuclear@17: } nuclear@17: } nuclear@17: nuclear@17: const Vector3 &Scene::get_background(int idx) const nuclear@17: { nuclear@17: return bg[idx == -1 ? 0 : idx]; nuclear@17: } nuclear@17: nuclear@17: #define LERP(a, b, t) ((a) + ((b) - (a)) * t) nuclear@17: nuclear@17: Vector3 Scene::get_background(const Ray &ray) const nuclear@17: { nuclear@17: Vector3 dir = normalize(ray.dir); nuclear@17: nuclear@17: float v; nuclear@17: if(dir.z == 0.0) { nuclear@17: v = dir.y > 0.0 ? 1.0 : -1.0; nuclear@17: } else { nuclear@17: float angle = atan2(dir.z, dir.y); nuclear@17: v = angle / M_PI; nuclear@17: } nuclear@17: nuclear@17: float r = v >= 0.0 ? LERP(bg[1].x, bg[2].x, v) : LERP(bg[1].x, bg[0].x, -v); nuclear@17: float g = v >= 0.0 ? LERP(bg[1].y, bg[2].y, v) : LERP(bg[1].y, bg[0].y, -v); nuclear@17: float b = v >= 0.0 ? LERP(bg[1].z, bg[2].z, v) : LERP(bg[1].z, bg[0].z, -v); nuclear@17: return Vector3(r, g, b); nuclear@17: } nuclear@17: nuclear@17: void Scene::set_ambient(const Vector3 &col) nuclear@17: { nuclear@17: ambient = col; nuclear@17: } nuclear@17: nuclear@17: const Vector3 &Scene::get_ambient() const nuclear@17: { nuclear@17: return ambient; nuclear@17: } nuclear@17: nuclear@17: nuclear@12: void Scene::add(SceneNode *node) nuclear@6: { nuclear@12: nodes.push_back(node); nuclear@12: nuclear@12: switch(node->get_type()) { nuclear@12: case NODE_OBJECT: nuclear@12: objects.push_back((Object*)node); nuclear@12: break; nuclear@12: nuclear@12: case NODE_LIGHT: nuclear@12: lights.push_back((Light*)node); nuclear@12: break; nuclear@12: nuclear@12: case NODE_CAMERA: nuclear@12: cameras.push_back((Camera*)node); nuclear@12: break; nuclear@12: nuclear@12: default: nuclear@12: break; nuclear@12: } nuclear@12: nuclear@12: sel.clear(); nuclear@6: } nuclear@6: nuclear@12: int Scene::get_node_count() const nuclear@6: { nuclear@12: return (int)nodes.size(); nuclear@6: } nuclear@6: nuclear@6: int Scene::get_object_count() const nuclear@6: { nuclear@6: return (int)objects.size(); nuclear@6: } nuclear@6: nuclear@6: int Scene::get_light_count() const nuclear@6: { nuclear@6: return (int)lights.size(); nuclear@6: } nuclear@6: nuclear@6: int Scene::get_camera_count() const nuclear@6: { nuclear@6: return (int)cameras.size(); nuclear@6: } nuclear@6: nuclear@12: SceneNode *Scene::get_node(int idx) nuclear@12: { nuclear@12: return nodes[idx]; nuclear@12: } nuclear@12: nuclear@12: const SceneNode *Scene::get_node(int idx) const nuclear@12: { nuclear@12: return nodes[idx]; nuclear@12: } nuclear@6: nuclear@6: Object *Scene::get_object(int idx) nuclear@6: { nuclear@6: return objects[idx]; nuclear@6: } nuclear@6: nuclear@6: const Object *Scene::get_object(int idx) const nuclear@6: { nuclear@6: return objects[idx]; nuclear@6: } nuclear@6: nuclear@6: Light *Scene::get_light(int idx) nuclear@6: { nuclear@6: return lights[idx]; nuclear@6: } nuclear@6: nuclear@6: const Light *Scene::get_light(int idx) const nuclear@6: { nuclear@6: return lights[idx]; nuclear@6: } nuclear@6: nuclear@6: Camera *Scene::get_camera(int idx) nuclear@6: { nuclear@6: return cameras[idx]; nuclear@6: } nuclear@6: nuclear@6: const Camera *Scene::get_camera(int idx) const nuclear@6: { nuclear@6: return cameras[idx]; nuclear@6: } nuclear@6: nuclear@15: void Scene::set_active_camera(Camera *cam) nuclear@15: { nuclear@15: active_cam = cam; nuclear@15: } nuclear@15: nuclear@15: Camera *Scene::get_active_camera() const nuclear@15: { nuclear@15: return active_cam; nuclear@15: } nuclear@15: nuclear@1: void Scene::draw() const nuclear@1: { nuclear@6: if(active_cam) { nuclear@6: // TODO nuclear@6: } nuclear@6: nuclear@12: int num_nodes = get_node_count(); nuclear@12: for(int i=0; idraw(selected); nuclear@6: } nuclear@1: } nuclear@12: nuclear@12: void Scene::select(int s) nuclear@12: { nuclear@12: for(size_t i=0; i= 0 && idx < (int)sel.size() ? sel[idx] : -1; nuclear@12: } nuclear@17: nuclear@17: bool Scene::intersect(const Ray &ray, RayHit *hit) const nuclear@17: { nuclear@17: if(hit) { nuclear@17: hit->dist = FLT_MAX; nuclear@17: hit->obj = 0; nuclear@17: } nuclear@17: nuclear@17: int num_obj = (int)objects.size(); nuclear@17: for(int i=0; iintersect(ray, hit ? &tmphit : 0)) { nuclear@17: if(!hit) return true; nuclear@17: if(tmphit.dist < hit->dist) { nuclear@17: *hit = tmphit; nuclear@17: } nuclear@17: } nuclear@17: } nuclear@17: return hit && hit->obj; nuclear@17: } nuclear@20: nuclear@20: bool Scene::load(const char *fname) nuclear@20: { nuclear@20: FILE *fp = fopen(fname, "r"); nuclear@20: if(!fp) { nuclear@20: return false; nuclear@20: } nuclear@20: bool res = load(fp); nuclear@20: fclose(fp); nuclear@20: return res; nuclear@20: } nuclear@20: nuclear@20: bool Scene::save(const char *fname) const nuclear@20: { nuclear@20: FILE *fp = fopen(fname, "w"); nuclear@20: if(!fp) { nuclear@20: return false; nuclear@20: } nuclear@20: bool res = save(fp); nuclear@20: fclose(fp); nuclear@20: return res; nuclear@20: } nuclear@20: nuclear@20: bool Scene::load(FILE *fp) nuclear@20: { nuclear@20: char *block; nuclear@20: while((block = get_next_block(fp))) { nuclear@20: nuclear@20: } nuclear@20: }