#pragma once
#include "texture.hpp"
/** @brief Base class for any drawable object. */
class Object {
protected:
const box_t bounding;
const Texture* texture;
public:
Object(box_t, const Texture*);
virtual ~Object() = default;
virtual bool intersect(const ray_t& ray, vertex_t& hit, vertex_t& nrm, const Texture*& tex, uv_t& uv) const = 0;
virtual bool intersect(const ray_t& ray, vertex_t& hit, vertex_t& nrm) const = 0;
virtual bool intersect(const ray_t& ray) const = 0;
/** @brief possibly on visible side from given position? */
virtual bool can_intersect(const vertex_t& camera) const = 0;
/** @brief always shadows other volume from given position? */
virtual bool intersect_full(const vertex_t& pos, const box_t& dst) const = 0;
/** @brief maximum bounding volume */
INLINE const box_t& box() const {
return bounding;
}
};
/** @brief Currently the only @ref Object primitive, building the whole scene. */
class SidedAxisPlane final : public Object {
private:
const vertex_t pos;
const vertex_t dir;
const bool positive;
struct {
int n, a, b;
} os{}; ///< null axis offset, other axises
vertex_t nrm{};
INLINE bool intersect(const ray_t& ray, vertex_t& hit) const;
INLINE bool can_intersect(const ray_t& ray) const;
INLINE bool can_intersect_any(const ray_t& ray) const;
public:
SidedAxisPlane(vertex_t pos, vertex_t dir, bool positive, const Texture*);
SidedAxisPlane(ray_t ray, bool positive, const Texture* tex) : SidedAxisPlane(ray.pos, ray.dir, positive, tex){};
bool intersect(const ray_t& ray, vertex_t& hit, vertex_t& nrm, const Texture*& tex, uv_t& uv) const override;
bool intersect(const ray_t& ray, vertex_t& hit, vertex_t& nrm) const override;
bool intersect(const ray_t& ray) const override;
bool can_intersect(const vertex_t& camera) const override;
bool intersect_full(const vertex_t& pos, const box_t& dst) const override;
};