RayMarching  0.0.1
Simple 3D engine based on a ray marching rendering
models3.h
1 #ifndef RAYMARCHING_MODELS3_H
2 #define RAYMARCHING_MODELS3_H
3 #include <cfloat>
4 #include <cmath>
5 #include <memory>
6 #include <Eigen/Dense>
7 #include <Eigen/Geometry>
8 #include <utility>
9 #include "const.h"
10 #include "colors.h"
11 #include "algebra.h"
12 
13 namespace RayMarching {
14 
20  class SDFObject {
21  public:
25  virtual ~SDFObject() = default;
26 
32  [[nodiscard]] virtual double getDist(Eigen::Vector3d const &p) const = 0;
33 
39  [[nodiscard]] virtual color_t getColor(Eigen::Vector3d const &p) const = 0;
40 
46  [[nodiscard]] Line getReflection(const Line& ray) const;
47  };
48 
52  class SDFCombination : public SDFObject {
53  public:
57  enum class SDFOperation {
58  UNION,
59  INTERSECTION,
60  DIFFERENCE
61  };
62  private:
63  const std::unique_ptr<SDFObject> _left;
64  const std::unique_ptr<SDFObject> _right;
65  const SDFOperation _op;
66  protected:
72  [[nodiscard]] std::pair<double, double> getSoloDist(const Eigen::Vector3d &p) const;
73  public:
80  SDFCombination(std::unique_ptr<SDFObject> left, std::unique_ptr<SDFObject> right, SDFOperation op)
81  : _left(std::move(left)), _right(std::move(right)), _op(op) {}
82 
86  ~SDFCombination() override = default;
87 
93  [[nodiscard]] double getDist(const Eigen::Vector3d &p) const override;
94 
100  [[nodiscard]] color_t getColor(const Eigen::Vector3d &p) const override;
101  };
102 
107  class Shape : public SDFObject {
108  protected:
109  Eigen::Vector3d _pos;
111  public:
116  explicit Shape(color_t color = BLACK) : _pos(0), _color(color) {};
117 
123  [[deprecated("TransformataObject is now responsible for the translation")]] explicit Shape(Eigen::Vector3d p, color_t color = BLACK) : _pos(std::move(p)), _color(color) {};
124 
129  [[nodiscard]] virtual Eigen::Vector3d getPos() const { return _pos; };
130 
136  [[nodiscard]] color_t getColor(const Eigen::Vector3d &p) const override { return _color; }
137 
143  };
144 
148  class Sphere : public Shape {
149  private:
150  double _radius;
151  public:
158  explicit Sphere(Eigen::Vector3d p, double r = 0, color_t color = BLACK) : Shape(std::move(p), color), _radius(r) {};
159 
163  ~Sphere() override = default;
164 
170  [[nodiscard]] double getDist(const Eigen::Vector3d &p) const override;
171 
176  [[nodiscard]] double getRadius() const { return _radius; }
177  };
178 
182  class Cube : public Shape {
183  private:
184  Eigen::Vector3d _bound;
185  public:
191  Cube(Eigen::Vector3d p, double bound, color_t color = BLACK) : Shape(std::move(p), color), _bound(bound, bound, bound) {};
192 
196  ~Cube() override = default;
197 
203  [[nodiscard]] double getDist(const Eigen::Vector3d &p) const override;
204 
209  [[nodiscard]] double getBound() const { return _bound.x(); }
210  };
211 
215  class Cylinder : public Shape {
216  private:
217  Eigen::Vector2d _hr;
218  public:
225  Cylinder(Eigen::Vector3d p, double h, double r, color_t color = BLACK) : Shape(std::move(p), color), _hr(h, r) {};
226 
230  ~Cylinder() override = default;
231 
237  [[nodiscard]] double getDist(const Eigen::Vector3d &p) const override;
238  };
239 
244  class TransformataObject : public SDFObject {
245  // TODO TransformataObject doesn't work with SDFCombination
246  // Problem? Transfomata has to be applied for every primitive shape
247  private:
248  std::unique_ptr<SDFObject> _original;
249  double _scale;
250  Eigen::AngleAxisd _rotation;
251  Eigen::AngleAxisd _reverseRotation;
252  Eigen::Vector3d _translation;
253  protected:
254  void applyZeroRotation();
255  public:
260  TransformataObject(std::unique_ptr<SDFObject> object)
261  : _original(std::move(object)), _scale(1), _rotation(), _translation(), _reverseRotation() {}
262 
266  ~TransformataObject() override = default;
267 
268 
275  void rotate(double x, double y, double z);
276 
283  void setRotation(double x, double y, double z);
284 
289  void scale(double s) { _scale *= s; }
290 
295  void setScale(double s) { _scale = s; }
296 
301  [[nodiscard]] double getScale() const { return _scale; }
302 
307  void translate(const Eigen::Vector3d &p) { _translation += p; };
308 
313  void setTranslation(const Eigen::Vector3d &p) { _translation = p; }
314 
319  [[nodiscard]] Eigen::Vector3d getTranslation() const { return _translation; }
320 
326  [[nodiscard]] double getDist(const Eigen::Vector3d &p) const override;
327 
333  [[nodiscard]] color_t getColor(const Eigen::Vector3d &p) const override;
334 
335  };
336 }
337 
338 #endif //RAYMARCHING_MODELS3_H
Cube Shape.
Definition: models3.h:182
~Cube() override=default
Cube(Eigen::Vector3d p, double bound, color_t color=BLACK)
Definition: models3.h:191
double getDist(const Eigen::Vector3d &p) const override
Definition: models3.cpp:58
double getBound() const
Definition: models3.h:209
Cylinder Shape.
Definition: models3.h:215
double getDist(const Eigen::Vector3d &p) const override
Definition: models3.cpp:63
~Cylinder() override=default
Cylinder(Eigen::Vector3d p, double h, double r, color_t color=BLACK)
Definition: models3.h:225
Marching Ray implementation.
Definition: algebra.h:14
SDFObject combining two elements.
Definition: models3.h:52
SDFOperation
Available SDFObject combination.
Definition: models3.h:57
color_t getColor(const Eigen::Vector3d &p) const override
Definition: models3.cpp:45
~SDFCombination() override=default
std::pair< double, double > getSoloDist(const Eigen::Vector3d &p) const
Definition: models3.cpp:26
double getDist(const Eigen::Vector3d &p) const override
Definition: models3.cpp:33
SDFCombination(std::unique_ptr< SDFObject > left, std::unique_ptr< SDFObject > right, SDFOperation op)
Definition: models3.h:80
Virtual class describing abstract shapes.
Definition: models3.h:20
virtual color_t getColor(Eigen::Vector3d const &p) const =0
virtual ~SDFObject()=default
Line getReflection(const Line &ray) const
Definition: models3.cpp:11
virtual double getDist(Eigen::Vector3d const &p) const =0
Abstract Shape description.
Definition: models3.h:107
virtual Eigen::Vector3d getPos() const
Definition: models3.h:129
Shape(Eigen::Vector3d p, color_t color=BLACK)
Definition: models3.h:123
color_t _color
Definition: models3.h:110
color_t getColor(const Eigen::Vector3d &p) const override
Definition: models3.h:136
Shape(color_t color=BLACK)
Definition: models3.h:116
Eigen::Vector3d _pos
Definition: models3.h:109
void setColor(color_t color)
Definition: models3.h:142
Sphere Shape.
Definition: models3.h:148
~Sphere() override=default
double getDist(const Eigen::Vector3d &p) const override
Definition: models3.cpp:54
Sphere(Eigen::Vector3d p, double r=0, color_t color=BLACK)
Definition: models3.h:158
double getRadius() const
Definition: models3.h:176
Class representing SDFObject transformation in space.
Definition: models3.h:244
~TransformataObject() override=default
void rotate(double x, double y, double z)
Definition: models3.cpp:76
color_t getColor(const Eigen::Vector3d &p) const override
Definition: models3.cpp:94
Eigen::Vector3d getTranslation() const
Definition: models3.h:319
void translate(const Eigen::Vector3d &p)
Definition: models3.h:307
double getScale() const
Definition: models3.h:301
void setScale(double s)
Definition: models3.h:295
TransformataObject(std::unique_ptr< SDFObject > object)
Definition: models3.h:260
void scale(double s)
Definition: models3.h:289
void setRotation(double x, double y, double z)
Definition: models3.cpp:85
double getDist(const Eigen::Vector3d &p) const override
Definition: models3.cpp:90
void setTranslation(const Eigen::Vector3d &p)
Definition: models3.h:313
Namespace containing all tools implemented within RayMarching package.
Definition: algebra.h:9
constexpr color_t BLACK
Definition: colors.h:32
3 byte color representation structure
Definition: colors.h:11