The spica renderer
bounds3d_detail.h
1 #ifdef _MSC_VER
2 #pragma once
3 #endif
4 
5 #ifndef _SPICA_BOUND3D_DETAIL_H_
6 #define _SPICA_BOUND3D_DETAIL_H_
7 
8 #include "ray.h"
9 
10 namespace spica {
11 
12 template <class T>
13 Bounds3_<T>::Bounds3_()
14  : posMin_{}
15  , posMax_{} {
16  T minNum = std::numeric_limits<T>::lowest();
17  T maxNum = std::numeric_limits<T>::max();
18  posMin_ = Point3_<T>{ maxNum, maxNum, maxNum };
19  posMax_ = Point3_<T>{ minNum, minNum, minNum };
20 }
21 
22 template <class T>
23 Bounds3_<T>::Bounds3_(const Point3_<T>& posMin, const Point3_<T>& posMax)
24  : posMin_{ posMin }
25  , posMax_{ posMax } {
26 }
27 
28 template <class T>
29 Bounds3_<T>::Bounds3_(const Bounds3_<T>& b)
30  : posMin_{ b.posMin_ }
31  , posMax_{ b.posMax_ } {
32 }
33 
34 template <class T>
35 Bounds3_<T>::~Bounds3_() {
36 }
37 
38 template <class T>
39 Bounds3_<T>& Bounds3_<T>::operator=(const Bounds3_<T>& b) {
40  this->posMin_ = b.posMin_;
41  this->posMax_ = b.posMax_;
42  return *this;
43 }
44 
45 template <class T>
46 bool Bounds3_<T>::operator==(const Bounds3_<T>& b) const {
47  return posMin_ == b.posMin_ && posMax_ == b.posMax_;
48 }
49 
50 template <class T>
51 bool Bounds3_<T>::operator!=(const Bounds3_<T>& b) const {
52  return posMin_ != b.posMin_ || posMax_ != b.posMax_;
53 }
54 
55 template <class T>
57  Vector3_<T> diff = posMax_ - posMin_;
58  if (diff.x() >= diff.y() && diff.x() >= diff.z()) return 0;
59  if (diff.y() >= diff.z()) return 1;
60  return 2;
61 }
62 
63 template <class T>
64 bool Bounds3_<T>::intersect(const Ray& ray, double* tNear, double* tFar) const {
65  double t0 = 0.0, t1 = ray.maxDist();
66  for (int i = 0; i < 3; i++) {
67  double tt0 = (posMin_[i] - ray.org()[i]) * ray.invdir()[i];
68  double tt1 = (posMax_[i] - ray.org()[i]) * ray.invdir()[i];
69  if (tt0 > tt1) std::swap(tt0, tt1);
70 
71  t0 = std::max(t0, tt0);
72  t1 = std::min(t1, tt1);
73  if (t0 > t1) return false;
74  }
75 
76  if (tNear) *tNear = t0;
77  if (tFar) *tFar = t1;
78  return true;
79 }
80 
81 template <class T>
83  Point3_<T> posMin = Point3_<T>::minimum(b1.posMin(), b2.posMin());
84  Point3_<T> posMax = Point3_<T>::maximum(b1.posMax(), b2.posMax());
85  return Bounds3_<T>{ posMin, posMax };
86 }
87 
88 template <class T>
89 void Bounds3_<T>::merge(const Bounds3_<T>& b) {
90  posMin_ = Point3_<T>::minimum(posMin_, b.posMin_);
91  posMax_ = Point3_<T>::maximum(posMax_, b.posMax_);
92 }
93 
94 template <class T>
95 void Bounds3_<T>::merge(const Point3_<T>& p) {
96  posMin_ = Point3_<T>::minimum(p, posMin_);
97  posMax_ = Point3_<T>::maximum(p, posMax_);
98 }
99 
100 template <class T>
101 bool Bounds3_<T>::inside(const Point3_<T>& p) const {
102  return (posMin_.x() < p.x() && p.x() < posMax_.x() &&
103  posMin_.x() < p.y() && p.x() < posMax_.y() &&
104  posMin_.x() < p.z() && p.x() < posMax_.z());
105 }
106 
107 template <class T>
108 T Bounds3_<T>::area() const {
109  Vector3_<T> diff = posMax_ - posMin_;
110  const double xy = std::abs(diff.x() * diff.y());
111  const double yz = std::abs(diff.y() * diff.z());
112  const double zx = std::abs(diff.z() * diff.x());
113  return 2.0 * (xy + yz + zx);
114 }
115 
116 } // namespace spica
117 
118 #endif // _SPICA_BOUND3D_DETAIL_H_
bool intersect(const Ray &ray, double *tNear=nullptr, double *tFar=nullptr) const
Intersection test.
Definition: bounds3d_detail.h:64
T z() const
Get z.
Definition: vector3d.h:106
T x() const
Get x.
Definition: vector3d.h:98
int maximumExtent() const
Maximum extent: return 0 -> x, 1 -> y, 2 -> z.
Definition: bounds3d_detail.h:56
Ray class.
Definition: ray.h:24
Three-dimensional vector.
Definition: core.hpp:56
Definition: bounds3d.h:16
T y() const
Get y.
Definition: vector3d.h:102
Definition: core.hpp:68