crt/light.hpp
#pragma once
#include "vertex.hpp"
#include "object.hpp"
#include "lightmap.hpp"
#include "common.hpp"
#include <map>
#include <set>
#include <vector>
class Light {
public:
const bool is_static;
const Img::rgb_t color;
Light(bool s): is_static(s), color(255, 255, 255) {}
Light(bool s, Img::rgb_t c): is_static(s), color(c) {}
virtual ~Light() {}
virtual light_t get(std::vector<const Object*>&, const vertex_t& hit, const vertex_t* norm_ray, const vertex_t& norm) const = 0; // [0..1]
virtual bool occlude_box(const Object*, vertex_t& bound_min, vertex_t& bound_max) const = 0;
virtual bool reachable(const Object*) const = 0;
};
class Occlusion {
private:
mutable std::map<const Object*, std::vector<const Object*> > cands;
public:
void finalize(const std::vector<const Object*>&);
light_t get(const Object*, const vertex_t&, const vertex_t&) const;
void getSMPcopy(Occlusion& o) const;
bool enabled() const;
};
class Lights {
private:
typedef struct {
const Light* light;
std::set<const Object*> occluded;
mutable std::map<const Object*, std::vector<const Object*> > can_occlude; // lru
} light_env_t;
std::vector<light_env_t> lights;
Occlusion occlusion;
bool occludes(const Object* src, const Object* occ, const Light* light) const;
static void set_lightmap(void*);
public:
void push(const Light* lo);
void finalize(const std::vector<const Object*>& objects);
void get_light(const Object* o, const vertex_t& hit, const vertex_t* raynrm, const vertex_t& nrm, LightValue&) const;
void getSMPcopy(Lights& o) const;
};