Advertisement
Guest User

OpenGL Renderer

a guest
May 21st, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 156.73 KB | None | 0 0
  1. #ifndef AABB_H
  2. #define AABB_H
  3.  
  4. #include <math/Log2Math.h>
  5. #include <array>
  6. #include <vector>
  7. #include <iostream>
  8. #include <limits>
  9. #include <Vertex.h>
  10. #include <math/MathHelpers.h>
  11. #include <ContributionResult.h>
  12.  
  13. namespace Log2
  14. {
  15.   class Mesh;
  16.   class Model;
  17.  
  18.   template<unsigned Dim, typename T>
  19.   class AABB
  20.   {
  21.   public:
  22.     using Vector = Vector<Dim, T>;
  23.     using Matrix = Matrix<Dim + 1, Dim + 1, T>;
  24.     using Type = T;
  25.     static auto constexpr getDim() { return Dim; }
  26.     static const auto NUM_VERTS = 1 << Dim;
  27.     AABB() = default;
  28.     AABB(AABB const & other) = default;
  29.     AABB& operator=(AABB const & other) = default;
  30.     ~AABB() = default;
  31.     AABB(Vector const & min, Vector const & max) :
  32.       _min(min),
  33.       _max(max)
  34.     {}
  35.     explicit AABB(Model const & model)
  36.     {
  37.       for (auto const & m : model.meshes()) {
  38.         unify(m->aabb());
  39.       }
  40.     }
  41.     explicit AABB(Mesh const & mesh) :
  42.       AABB(mesh.vertices().begin(), mesh.vertices().end())
  43.     {
  44.     }
  45.     AABB(Vertex const * begin, Vertex const * const end)
  46.     {
  47.       while (begin != end) {
  48.         update((begin++)->position());
  49.       }
  50.     }
  51.     AABB(AABB const & other, const Matrix & transform)
  52.     {
  53.       ComputeFromTransform<NUM_VERTS - 1>::call(transform, other, *this);
  54.     }
  55.     AABB(Vector const * begin, Vector const * const end)
  56.     {
  57.       while (begin != end) {
  58.         update(*begin++);
  59.       }
  60.     }
  61.     auto const & min() const
  62.     {
  63.       return _min;
  64.     }
  65.     auto const & max() const
  66.     {
  67.       return _max;
  68.     }
  69.     auto & min()
  70.     {
  71.       return _min;
  72.     }
  73.     auto & max()
  74.     {
  75.       return _max;
  76.     }
  77.     auto update(Vector const & vec)
  78.     {
  79.       _min.minimize(vec);
  80.       _max.maximize(vec);
  81.     }
  82.     auto contains(AABB const & other) const
  83.     {
  84.       return _min <= other._min && _max >= other._max;
  85.     }
  86.     auto fullyContains(AABB const & other) const
  87.     {
  88.       return _min < other._min && _max > other._max;
  89.     }
  90.     auto contains(Vector const & p) const
  91.     {
  92.       return _min <= p && _max >= p;
  93.     }
  94.     auto fullyContains(Vector const & p) const
  95.     {
  96.       return _min < p && _max > p;
  97.     }
  98.     auto intersects(AABB const & other) const
  99.     {
  100.       return _max >= other._min && _min <= other._max;
  101.     }
  102.     auto intersects(AABB const & moving, Vector const & v, Vector const & v_inv, T& t_first) const
  103.     {
  104.       t_first = static_cast<T>(0);
  105.       auto t_last = static_cast<T>(1);
  106.       return intersects(moving) || IntersectMoving<>::call(*this, moving, v, v_inv, t_first, t_last);
  107.     }
  108.     template<unsigned i = Dim - 1u>
  109.     struct IntersectMoving
  110.     {
  111.       static auto call(AABB const & a, AABB const & b, Vector const & v, Vector const & v_inv, T& t_first, T& t_last)
  112.       {
  113.         if (v.at<i>() == static_cast<T>(0) && (b._min.at<i>() > a._max.at<i>() || b._max.at<i>() < a._min.at<i>())) {
  114.           return false;
  115.         }
  116.         else if (v.at<i>() < static_cast<T>(0)) {
  117.           if (b._max.at<i>() < a._min.at<i>()) return false;
  118.           if (a._max.at<i>() < b._min.at<i>()) Algorithm::maximize((a._max.at<i>() - b._min.at<i>()) * v_inv.at<i>(), t_first);
  119.           if (b._max.at<i>() > a._min.at<i>()) Algorithm::minimize((a._min.at<i>() - b._max.at<i>()) * v_inv.at<i>(), t_last);
  120.         }
  121.         else {
  122.           if (b._min.at<i>() > a._max.at<i>()) return false;
  123.           if (b._max.at<i>() < a._min.at<i>()) Algorithm::maximize((a._min.at<i>() - b._max.at<i>()) * v_inv.at<i>(), t_first);
  124.           if (a._max.at<i>() > b._min.at<i>()) Algorithm::minimize((a._max.at<i>() - b._min.at<i>()) * v_inv.at<i>(), t_last);
  125.         }
  126.         return t_first <= t_last && IntersectMoving<i - 1u>::call(a, b, v, v_inv, t_first, t_last);
  127.       }
  128.     };
  129.     template<>
  130.     struct IntersectMoving<0>
  131.     {
  132.       static auto call(AABB const & a, AABB const & b, Vector const & v, Vector const & v_inv, T& t_first, T& t_last)
  133.       {
  134.         if (v.at<0>() == static_cast<T>(0) && (b._min.at<0>() > a._max.at<0>() || b._max.at<0>() < a._min.at<0>())) {
  135.           return false;
  136.         }
  137.         else if (v.at<0>() < static_cast<T>(0)) {
  138.           if (b._max.at<0>() < a._min.at<0>()) return false;
  139.           if (a._max.at<0>() < b._min.at<0>()) Algorithm::maximize((a._max.at<0>() - b._min.at<0>()) * v_inv.at<0>(), t_first);
  140.           if (b._max.at<0>() > a._min.at<0>()) Algorithm::minimize((a._min.at<0>() - b._max.at<0>()) * v_inv.at<0>(), t_last);
  141.         }
  142.         else {
  143.           if (b._min.at<0>() > a._max.at<0>()) return false;
  144.           if (b._max.at<0>() < a._min.at<0>()) Algorithm::maximize((a._min.at<0>() - b._max.at<0>()) * v_inv.at<0>(), t_first);
  145.           if (a._max.at<0>() > b._min.at<0>()) Algorithm::minimize((a._max.at<0>() - b._min.at<0>()) * v_inv.at<0>(), t_last);
  146.         }
  147.         return t_first <= t_last;
  148.       }
  149.     };
  150.     auto union_(AABB const & other) const
  151.     {
  152.       return AABB(minimum(_min, other._min), maximum(_max, other._max));
  153.     }
  154.     auto intersection(AABB const & other) const
  155.     {
  156.       return AABB(maximum(_min, other._min), minimum(_max, other._max));
  157.     }
  158.     auto& unify(AABB const & other)
  159.     {
  160.       _min.minimize(other._min);
  161.       _max.maximize(other._max);
  162.       return *this;
  163.     }
  164.     auto& intersect(AABB const & other)
  165.     {
  166.       _min.maximize(other._min);
  167.       _max.minimize(other._max);
  168.       return *this;
  169.     }
  170.     auto valid() const
  171.     {
  172.       return _max >= _min;
  173.     }
  174.     auto minVec(Vector const & p) const
  175.     {
  176.       return _min - p;
  177.     }
  178.     auto maxVec(Vector const & p) const
  179.     {
  180.       return p - _max;
  181.     }
  182.     auto distToBorderForPointInside(Vector const & p) const
  183.     {
  184.       return std::min(minReduce(abs(minVec(p))), minReduce(abs(maxVec(p))));
  185.     }
  186.     auto distToBorder(Vector const & p) const
  187.     {
  188.       return contains(p) ? distToBorderForPointInside(p) : std::sqrt(minSquaredDist(p));
  189.     }
  190.     auto cost(AABB const & other) const
  191.     {
  192.       return union_(other).squaredSize() - squaredSize();
  193.     }
  194.     auto vertices() const
  195.     {
  196.       std::array<Vector, NUM_VERTS> vertices;
  197.       FillArray<NUM_VERTS - 1>::call(*this, vertices);
  198.       return vertices;
  199.     }
  200.     template<unsigned count>
  201.     static auto fromTransform(Vector const * first, Matrix const & transform)
  202.     {
  203.       Vector verts[count];
  204.       FillVerts<count - 1u>::call(first, transform, verts);
  205.       return fromVertices<count>(verts);
  206.     }
  207.     template<unsigned i>
  208.     struct FillVerts
  209.     {
  210.       static auto call(Vector const * first, Matrix const & transform, Vector* res)
  211.       {
  212.         *(res + i) = (transform * (first + i)->toHomogeneous()).homogeneousDivide().reduce<Dim>();
  213.         FillVerts<i - 1u>::call(first, transform, res);
  214.       }
  215.     };
  216.     template<>
  217.     struct FillVerts<0>
  218.     {
  219.       static auto call(Vector const * first, Matrix const & transform, Vector* res)
  220.       {
  221.         *res = (transform * first->toHomogeneous()).homogeneousDivide().reduce<Dim>();
  222.       }
  223.     };
  224.     template<unsigned count>
  225.     static auto fromVertices(Vector const * first)
  226.     {
  227.       AABB ret;
  228.       ComputeFromVertices<count - 1>::call(first, ret);
  229.       return ret;
  230.     }
  231.     auto centerTimesTwo() const
  232.     {
  233.       return _min + _max;
  234.     }
  235.     auto center() const
  236.     {
  237.       return centerTimesTwo() * static_cast<T>(0.5);
  238.     }
  239.     auto center(unsigned const & axis) const
  240.     {
  241.       return (_min[axis] + _max[axis]) * static_cast<T>(0.5);
  242.     }
  243.     template<unsigned axis>
  244.     auto center() const
  245.     {
  246.       return (_min.at<axis>() + _max.at<axis>()) * static_cast<T>(0.5);
  247.     }
  248.     auto extent() const
  249.     {
  250.       return _max - _min;
  251.     }
  252.     auto halfExtent(Vector const & center) const
  253.     {
  254.       return _max - center;
  255.     }
  256.     auto halfExtent() const
  257.     {
  258.       return extent() * static_cast<T>(0.5);
  259.     }
  260.     struct CenterExtent
  261.     {
  262.       Vector _center;
  263.       Vector _halfExtent;
  264.     };
  265.     CenterExtent centerExtent() const
  266.     {
  267.       auto c = center();
  268.       return { c, halfExtent(c) };
  269.     }
  270.     auto size() const
  271.     {
  272.       return extent().length();
  273.     }
  274.     auto squaredSize() const
  275.     {
  276.       return extent().squaredLength();
  277.     }
  278.     auto largerThan(AABB const & other) const
  279.     {
  280.       return squaredSize() > other.squaredSize();
  281.     }
  282.     auto volume() const
  283.     {
  284.       return extent().volume();
  285.     }
  286.     auto closestPoint(Vector const & point) const
  287.     {
  288.       return clamp(point, _min, _max);
  289.     }
  290.     template<unsigned index>
  291.     auto squaredDistToVertex(Vector const & point) const
  292.     {
  293.       static_assert(index < NUM_VERTS, "Invalid index");
  294.       return squaredDistance(point, getVertex<index>());
  295.     }
  296.     auto minSquaredDist(Vector const & point) const
  297.     {
  298.       auto dist = static_cast<T>(0);
  299.       ComputeMinSquaredDist<>::call(*this, point, dist);
  300.       return dist;
  301.     }
  302.     auto maxSquaredDist(Vector const & point) const
  303.     {
  304.       return maxSquaredDist(minVec(point), maxVec(point));
  305.     }
  306.     static_assert(std::numeric_limits<float>::is_iec559, "Division by zero not supported on this platform.");
  307.     template<typename T>
  308.     auto contributes(Vector const & cam_pos, T const & thresh, T const & max_squared_size) const
  309.     {
  310.       return max_squared_size / minSquaredDist(cam_pos) > thresh;
  311.     }
  312.     template<typename T>
  313.     auto contributes(Vector const & cam_pos, T const & thresh) const
  314.     {
  315.       return contributes(cam_pos, thresh, squaredSize());
  316.     }
  317.     template<typename T>
  318.     auto fullyContributes(Vector const & cam_pos, T const & thresh, T const & min_squared_size) const
  319.     {
  320.       return min_squared_size / maxSquaredDist(cam_pos) > thresh;
  321.     }
  322.     template<typename T>
  323.     auto fullyContributes(Vector const & cam_pos, T const & thresh) const
  324.     {
  325.       return fullyContributes(cam_pos, thresh, squaredSize());
  326.     }
  327.     template<typename T>
  328.     ContribResult computeContribution(Vector const & cam_pos, T const & thresh, T const & min_squared_size, T const & max_squared_size) const
  329.     {
  330.       auto min_vec = minVec(cam_pos);
  331.       auto max_vec = maxVec(cam_pos);
  332.       if (max_squared_size / minSquaredDist(cam_pos, min_vec, max_vec) > thresh) {
  333.         return min_squared_size / maxSquaredDist(min_vec, max_vec) > thresh ? ContributionResult::INSIDE : ContributionResult::INTERSECTING;
  334.       }
  335.       return ContributionResult::OUTSIDE;
  336.     }
  337.     auto vertex(unsigned const & index) const
  338.     {
  339.       return Vector(index & 4 ? _min.at<0>() : _max.at<0>(),
  340.         index & 2 ? _min.at<1>() : _max.at<1>(),
  341.         index & 1 ? _min.at<2>() : _max.at<2>());
  342.     }
  343.     template<unsigned index>
  344.     auto vertex() const
  345.     {
  346.       return Vector(index & 4 ? _min.at<0>() : _max.at<0>(),
  347.         index & 2 ? _min.at<1>() : _max.at<1>(),
  348.         index & 1 ? _min.at<2>() : _max.at<2>());
  349.     }
  350.     auto longestAxis() const
  351.     {
  352.       return extent().longestAxis();
  353.     }
  354.     friend auto& operator << (std::ostream& os, AABB const & aabb)
  355.     {
  356.       os << "AABB [ " << aabb.min() << " " << aabb.max() << " ]";
  357.       return os;
  358.     }
  359.     static auto minMemOffset() { return offsetof(AABB, _min); }
  360.     static auto maxMemOffset() { return offsetof(AABB, _max); }
  361.   private:
  362.     Vector _min = std::numeric_limits<T>::max();
  363.     Vector _max = std::numeric_limits<T>::lowest();
  364.  
  365.     template<unsigned index>
  366.     struct ComputeFromTransform
  367.     {
  368.       static auto call(Matrix const & transform, AABB const & other, AABB& res)
  369.       {
  370.         res.update((transform * other.vertex<index>().toHomogeneous()).reduce<Dim>());
  371.         ComputeFromTransform<index - 1>::call(transform, other, res);
  372.       }
  373.     };
  374.     template<>
  375.     struct ComputeFromTransform<0>
  376.     {
  377.       static auto call(Matrix const & transform, AABB const & other, AABB& res)
  378.       {
  379.         res.update((transform * other.vertex<0>().toHomogeneous()).reduce<Dim>());
  380.       }
  381.     };
  382.     template<unsigned index>
  383.     struct FillArray
  384.     {
  385.       static auto call(AABB const & aabb, std::array<Vector, NUM_VERTS>& res)
  386.       {
  387.         res[index] = aabb.vertex<index>();
  388.         FillArray<index - 1>::call(aabb, res);
  389.       }
  390.     };
  391.     template<>
  392.     struct FillArray<0>
  393.     {
  394.       static auto call(AABB const & aabb, std::array<Vector, NUM_VERTS>& res)
  395.       {
  396.         res[0] = aabb.vertex<0>();
  397.       }
  398.     };
  399.     template<unsigned index>
  400.     struct ComputeFromVertices
  401.     {
  402.       static auto call(Vector const * first, AABB& res)
  403.       {
  404.         res.update(*(first + index));
  405.         ComputeFromVertices<index - 1>::call(first, res);
  406.       }
  407.     };
  408.     template<>
  409.     struct ComputeFromVertices<0>
  410.     {
  411.       static auto call(Vector const * first, AABB& res)
  412.       {
  413.         res.update(*first);
  414.       }
  415.     };
  416.     template<unsigned index = Dim - 1>
  417.     struct ComputeMinSquaredDist
  418.     {
  419.       static auto call(AABB const & aabb, Vector const & point, T& dist)
  420.       {
  421.         if (point.at<index>() < aabb._min.at<index>()) {
  422.           dist += MathHelpers::pow<2>(aabb._min.at<index>() - point.at<index>());
  423.         }
  424.         else if (point.at<index>() > aabb._max.at<index>()) {
  425.           dist += MathHelpers::pow<2>(point.at<index>() - aabb._max.at<index>());
  426.         }
  427.         ComputeMinSquaredDist<index - 1>::call(aabb, point, dist);
  428.       }
  429.       static auto call(AABB const & aabb, Vector const & point, Vector const & min_vec, Vector const & max_vec, T& dist)
  430.       {
  431.         if (min_vec.at<index>() > static_cast<T>(0)) {
  432.           dist += MathHelpers::pow<2>(min_vec.at<index>());
  433.         }
  434.         else if (max_vec.at<index>() > static_cast<T>(0)) {
  435.           dist += MathHelpers::pow<2>(max_vec.at<index>());
  436.         }
  437.         ComputeMinSquaredDist<index - 1>::call(aabb, point, min_vec, max_vec, dist);
  438.       }
  439.     };
  440.     template<>
  441.     struct ComputeMinSquaredDist<0>
  442.     {
  443.       static auto call(AABB const & aabb, Vector const & point, T& dist)
  444.       {
  445.         if (point.at<0>() < aabb._min.at<0>()) {
  446.           dist += MathHelpers::pow<2>(aabb._min.at<0>() - point.at<0>());
  447.         }
  448.         else if (point.at<0>() > aabb._max.at<0>()) {
  449.           dist += MathHelpers::pow<2>(point.at<0>() - aabb._max.at<0>());
  450.         }
  451.       }
  452.       static auto call(AABB const & aabb, Vector const & point, Vector const & min_vec, Vector const & max_vec, T& dist)
  453.       {
  454.         if (min_vec.at<0>() > static_cast<T>(0)) {
  455.           dist += MathHelpers::pow<2>(min_vec.at<0>());
  456.         }
  457.         else if (max_vec.at<0>() > static_cast<T>(0)) {
  458.           dist += MathHelpers::pow<2>(max_vec.at<0>());
  459.         }
  460.       }
  461.     };
  462.     auto minSquaredDist(Vector const & point, Vector const & min_vec, Vector const & max_vec) const
  463.     {
  464.       auto dist = static_cast<T>(0);
  465.       ComputeMinSquaredDist<>::call(*this, point, min_vec, max_vec, dist);
  466.       return dist;
  467.     }
  468.     auto maxSquaredDist(Vector const & min_vec, Vector const & max_vec) const
  469.     {
  470.       return maximum(abs(min_vec), abs(max_vec)).squaredLength();
  471.     }
  472.   };
  473.  
  474.   using AABB2f = AABB<2, float>;
  475.   using AABB3f = AABB<3, float>;
  476.   using AABB4f = AABB<4, float>;
  477.  
  478.   using AABB2i = AABB<2, int>;
  479.   using AABB3i = AABB<3, int>;
  480.   using AABB4i = AABB<4, int>;
  481.  
  482.   using AABB2u = AABB<2, unsigned>;
  483.   using AABB3u = AABB<3, unsigned>;
  484.   using AABB4u = AABB<4, unsigned>;
  485. }
  486.  
  487. #endif // !AABB_H
  488.  
  489. #ifndef ALGORITHM_H
  490. #define ALGORITHM_H
  491.  
  492. #include <functional>
  493. #include <type_traits>
  494.  
  495. namespace Log2
  496. {
  497.   class Algorithm
  498.   {
  499.   public:
  500.     Algorithm() = delete;
  501.     template<typename T>
  502.     static auto ptrDiff(T const * const begin, T const * const end)
  503.     {
  504.       return end - begin;
  505.     }
  506.     template<typename T>
  507.     static auto midPtr(T* const begin, long long const & ptr_diff)
  508.     {
  509.       return begin + ptr_diff / 2u;
  510.     }
  511.     template<typename T>
  512.     static auto midPtr(T* const begin, T* const end)
  513.     {
  514.       return midPtr(begin, ptrDiff(begin, end));
  515.     }
  516.     static auto continueSplit(long long const & ptr_diff)
  517.     {
  518.       return ptr_diff > 1u;
  519.     }
  520.     template<typename T>
  521.     static auto continueSplit(T const * const begin, T const * const end)
  522.     {
  523.       return continueSplit(ptrDiff(begin, end));
  524.     }
  525.     template<typename T>
  526.     static auto swap(T& a, T& b)
  527.     {
  528.       auto temp = a;
  529.       a = b;
  530.       b = temp;
  531.     }
  532.     template<typename T, typename Pred>
  533.     static auto partition(T* begin, T const * const end, Pred&& pred)
  534.     {
  535.       auto* mid = begin;
  536.       while (begin != end) {
  537.         if (pred(*begin)) {
  538.           swap(*begin, *mid++);
  539.         }
  540.         ++begin;
  541.       }
  542.       return mid;
  543.     }
  544.     template<typename T>
  545.     static auto isPalindrom(T const * begin, T const * end)
  546.     {
  547.       return isPalindrom(begin, end, std::equal_to<T>());
  548.     }
  549.     template<typename T, typename Pred>
  550.     static auto isPalindrom(T const * begin, T const * end, Pred&& pred)
  551.     {
  552.       auto const * const mid = midPtr(begin, end);
  553.       while (begin != mid && end != mid) {
  554.         if (!pred(*begin++, *(--end))) {
  555.           return false;
  556.         }
  557.       }
  558.       return true;
  559.     }
  560.     template<typename T>
  561.     static auto compare(T const * a, T const * b, size_t len)
  562.     {
  563.       return compare(a, b, len, std::equal_to<T>());
  564.     }
  565.     template<typename T, typename Comp>
  566.     static auto compare(T const * a, T const * b, size_t len, Comp&& comp)
  567.     {
  568.       auto const * const end = a + len;
  569.       while (a != end) {
  570.         if (!comp(*a++, *b++)) {
  571.           return false;
  572.         }
  573.       }
  574.       return true;
  575.     }
  576.     /**
  577.     * Same as partition, but returns the midpoint if the range cannot be split based on pred.
  578.     */
  579.     template<typename T, typename Pred>
  580.     static auto partitionForceSplit(T* const begin, T* const end, Pred&& pred)
  581.     {
  582.       auto* const mid = partition(begin, end, pred);
  583.       return mid == begin || mid == end ? midPtr(begin, end) : mid;
  584.     }
  585.     /**
  586.     * Update peak
  587.     */
  588.     template<typename T, typename Type>
  589.     static void updatePeak(T const & prev_peak_val, Type& peak, T const & val, Type const & data)
  590.     {
  591.       updatePeak(prev_peak_val, peak, val, data, std::less<T>());
  592.     }
  593.     template<typename T, typename Type, typename Compare>
  594.     static void updatePeak(T const & prev_peak_val, Type& peak, T const & val, Type const & data, Compare&& comp)
  595.     {
  596.       if (comp(val, prev_peak_val)) {
  597.         peak = data;
  598.       }
  599.     }
  600.     template<typename T>
  601.     static auto minimize(const T& other, T& out)
  602.     {
  603.       out = std::min(out, other);
  604.     }
  605.     template<typename T>
  606.     static auto maximize(const T& other, T& out)
  607.     {
  608.       out = std::max(out, other);
  609.     }
  610.     template<typename T>
  611.     static auto mergeSort(T* const begin, T* const end)
  612.     {
  613.       mergeSort(begin, end, std::less<T>());
  614.     }
  615.     template<typename T, typename Compare>
  616.     static auto mergeSort(T* const begin, T* const end, Compare&& comp)
  617.     {
  618.       auto ptr_diff = ptrDiff(begin, end);
  619.       if (ptr_diff) {
  620.         auto* temp = new T[ptr_diff];
  621.         mergeSort(begin, end, temp, comp);
  622.         delete[] temp;
  623.       }
  624.     }
  625.     template<typename T>
  626.     static auto copyRange(T const * begin, T const * const end, T* dst)
  627.     {
  628.       copyRangeOverwrite(begin, end, dst);
  629.     }
  630.     template<typename T>
  631.     static auto copyRangeOverwrite(T const * begin, T const * const end, T*& dst)
  632.     {
  633.       while (begin != end) {
  634.         *dst++ = *begin++;
  635.       }
  636.     }
  637.     template<typename T>
  638.     static void quickSortLessEqual(T* const begin, T* const end)
  639.     {
  640.       quickSort(begin, end, std::less_equal<T>());
  641.     }
  642.     template<typename T>
  643.     static void quickSortGreaterEqual(T* const begin, T* const end)
  644.     {
  645.       quickSort(begin, end, std::greater_equal<T>());
  646.     }
  647.     template<typename T>
  648.     struct DefaultVal
  649.     {
  650.       auto const & operator() (T const & t) { return t; }
  651.     };
  652.     template<typename T>
  653.     static auto mean(T const* begin, T const * const end)
  654.     {
  655.       return mean(begin, end, DefaultVal<T>());
  656.     }
  657.     template<typename T, typename GetVal, typename RetVal = float>
  658.     static auto mean(T const* begin, T const * const end, GetVal&& get_val)
  659.     {
  660.       static_assert(std::is_same<RetVal, float>::value || std::is_same<RetVal, double>::value, "RetVal must be float or double");
  661.       auto const denom = static_cast<RetVal>(end - begin);
  662.       auto res = get_val(*begin++) / denom;
  663.       while (begin != end) {
  664.         res += get_val(*begin++) / denom;
  665.       }
  666.       return res;
  667.     }
  668.     template<typename T, unsigned index>
  669.     struct Copy
  670.     {
  671.       static void call(T const * src, T* dst)
  672.       {
  673.         dst[index] = src[index];
  674.         Copy<T, index - 1u>::call(src, dst);
  675.       }
  676.     };
  677.     template<typename T>
  678.     struct Copy<T, 0>
  679.     {
  680.       static void call(T const * src, T* dst)
  681.       {
  682.         *dst = *src;
  683.       }
  684.     };
  685.   private:
  686.     template<typename T, typename Compare>
  687.     static void mergeSort(T* const begin, T* const end, T* temp, Compare&& comp)
  688.     {
  689.       auto ptr_diff = ptrDiff(begin, end);
  690.       if (continueSplit(ptr_diff)) {
  691.         auto * const mid = midPtr(begin, ptr_diff);
  692.         mergeSort(begin, mid, temp, comp);
  693.         mergeSort(mid, end, temp, comp);
  694.         merge(begin, mid, end, temp, comp);
  695.       }
  696.     }
  697.     template<typename T, typename Compare>
  698.     static auto merge(T* begin, T const * const mid, T const * const end, T* temp, Compare&& comp)
  699.     {
  700.       copyRange(begin, end, temp);
  701.       auto* right_temp = temp + ptrDiff(begin, mid);
  702.       auto const * const left_temp_end = right_temp;
  703.       auto const * const right_temp_end = temp + ptrDiff(begin, end);
  704.       mergeResults(temp, right_temp, right_temp_end, begin, comp);
  705.       copyRangeOverwrite(temp, left_temp_end, begin);
  706.       copyRangeOverwrite(right_temp, right_temp_end, begin);
  707.     }
  708.     template<typename T, typename Compare>
  709.     static auto mergeResults(T*& begin, T*& mid, T const * const end, T*& dst, Compare&& comp)
  710.     {
  711.       auto const * const mid_ptr = mid;
  712.       while (begin != mid_ptr && mid != end) {
  713.         *dst++ = comp(*begin, *mid) ? *begin++ : *mid++;
  714.       }
  715.     }
  716.     template<typename T, typename Compare>
  717.     static void quickSort(T* const begin, T* const end, Compare&& comp)
  718.     {
  719.       if (begin < end) {
  720.         auto const pivot = *(end - 1);
  721.         auto* const mid = partition(begin, end, [&](const T& a) {
  722.           return comp(a, pivot);
  723.         });
  724.         quickSort(begin, mid - 1, comp);
  725.         quickSort(mid, end, comp);
  726.       }
  727.     }
  728.   };
  729. }
  730.  
  731. #endif // !ALGORITHM_H
  732.  
  733. #ifndef BOUNDINGVOLUMEHIERARCHY_H
  734. #define BOUNDINGVOLUMEHIERARCHY_H
  735.  
  736. #include <CullingParams.h>
  737. #include <IntersectionTests.h>
  738. #include <Ray.h>
  739. #include <boost/pool/object_pool.hpp>
  740. #include <Algorithm.h>
  741. #include <functional>
  742. #include <Primitive.h>
  743. #include <StackTrivial.h>
  744. #include <CsmTree.h>
  745. #include <BVHNode.h>
  746. #include <BVHNodePool.h>
  747.  
  748. namespace Log2
  749. {
  750.   class BoundingVolumeHierarchy
  751.   {
  752.   public:
  753.     using BV = typename Primitive::BV;
  754.     using Type = typename Primitive::Type;
  755.     using Vector = Vector<BV::getDim(), Type>;
  756.     using Matrix = Matrix<BV::getDim() + 1, BV::getDim() + 1, Type>;
  757.     using Ray = Ray<BV::getDim(), Type>;
  758.     using IntersectRayResult = IntersectRayResult<Type, Matrix>;
  759.     BoundingVolumeHierarchy() = delete;
  760.     BoundingVolumeHierarchy(Primitive * const * begin, Primitive * const * const end) :
  761.       _nodePool(Algorithm::ptrDiff(begin, end))
  762.     {
  763.       StackTrivial<BVHNode::PrimitiveInfo> infos;
  764.       infos.reserve(Algorithm::ptrDiff(begin, end));
  765.       while (begin != end) {
  766.         infos.push_back_unchecked(*begin++);
  767.       }
  768.       _root = _nodePool.createNode(infos);
  769.     }
  770.     BoundingVolumeHierarchy(BoundingVolumeHierarchy const & other) = delete;
  771.     BoundingVolumeHierarchy& operator=(BoundingVolumeHierarchy const & other) = delete;
  772.     BoundingVolumeHierarchy(BoundingVolumeHierarchy&& other) = default;
  773.     BoundingVolumeHierarchy& operator=(BoundingVolumeHierarchy&& other) = default;
  774.     auto cullVisiblePrimitives(CullingParams const & cp, Callback::CbFunc const & on_intersect_frustum, Callback::CbFunc const & on_became_fully_visible, Callback::CbFunc const & on_render) const
  775.     {
  776.       _root->cullVisiblePrimitives(cp, { on_intersect_frustum, on_became_fully_visible, on_render });
  777.     }
  778.     auto cullVisiblePrimitivesWithPlaneMasking(CullingParams const & cp, Callback::CbFunc const & on_intersect_frustum, Callback::CbFunc const & on_became_fully_visible, Callback::CbFunc const & on_render) const
  779.     {
  780.       IntersectedPlanes out(0b11111111);
  781.       _root->cullVisiblePrimitives(cp, out, { on_intersect_frustum, on_became_fully_visible, on_render });
  782.     }
  783.     auto intersectNested(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, std::function<void(Primitive const *)> const & intersect_nested) const
  784.     {
  785.       _root->intersectNested(bv, v, v_inv, min_t_first, intersect_nested);
  786.     }
  787.     auto intersectPrimitives(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, Primitive const *& nearest)
  788.     {
  789.       _root->intersectPrimitives(bv, v, v_inv, min_t_first, nearest);
  790.     }
  791.     auto findNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const
  792.     {
  793.       _root->findNearest(ray_local, ray_world, transform, nearest, nearest_t, nearest_transform);
  794.     }
  795.     auto findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res) const
  796.     {
  797.       _root->findNearestPrecise(ray_local, ray_world, transform, res);
  798.     }
  799.     auto findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive* parent, IntersectRayResult& res, Primitive*& parent_res) const
  800.     {
  801.       _root->findNearestPrecise(ray_local, ray_world, transform, parent, res, parent_res);
  802.     }
  803.     auto findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res, StackTrivial<BVHNode::NodePtr>& stack) const
  804.     {
  805.       stack.push_back(_root);
  806.       while (stack.size()) {
  807.         stack.pop_back()->findNearestPrecise(ray_local, ray_world, transform, res, stack);
  808.       }
  809.     }
  810.     auto findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested) const
  811.     {
  812.       _root->findNearestNested(ray, res, find_nested);
  813.     }
  814.     auto findNearestNested(Ray const & ray, IntersectRayResult& res, StackTrivial<BVHNode::NodePtr>& stack, std::function<void(Primitive*)> const & find_nested) const
  815.     {
  816.       stack.push_back(_root);
  817.       while (stack.size()) {
  818.         stack.pop_back()->findNearestNested(ray, res, find_nested, stack);
  819.       }
  820.     }
  821.     auto queryRange(BV const & bv, Callback::CbFunc const & cb) const
  822.     {
  823.       _root->queryRange(bv, cb);
  824.     }
  825.     auto queryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const
  826.     {
  827.       _root->queryRange(bv, cp, cb);
  828.     }
  829.     auto sizeInBytes() const
  830.     {
  831.       return _root->sizeInBytes();
  832.     }
  833.     auto sizeInKiloBytes() const
  834.     {
  835.       return static_cast<float>(sizeInBytes()) / 1024.f;
  836.     }
  837.     auto sizeInMegaBytes() const
  838.     {
  839.       return sizeInKiloBytes() / 1024.f;
  840.     }
  841.     auto sizeInGigaBytes() const
  842.     {
  843.       return sizeInMegaBytes() / 1024.f;
  844.     }
  845.     auto bv() const
  846.     {
  847.       return _root->getBV();
  848.     }
  849.     auto const & root() const
  850.     {
  851.       return _root;
  852.     }
  853.     auto countNodes(unsigned& internal_nodes, unsigned& leaf_nodes) const
  854.     {
  855.       internal_nodes = 0;
  856.       leaf_nodes = 0;
  857.       _root->countNodes(internal_nodes, leaf_nodes);
  858.     }
  859.     auto insert(Primitive* const & primitive)
  860.     {
  861.       _root->insert(primitive, _root, _nodePool);
  862.     }
  863.     auto minHeight() const
  864.     {
  865.       return _root->minHeight(0);
  866.     }
  867.     auto maxHeight() const
  868.     {
  869.       return _root->maxHeight(0);
  870.     }
  871.     auto averageHeight() const
  872.     {
  873.       unsigned num_internals, num_leafs;
  874.       countNodes(num_internals, num_leafs);
  875.       auto avg_height = 0.f;
  876.       _root->averageHeight(0.f, 1.f / static_cast<float>(num_leafs), avg_height);
  877.       return avg_height;
  878.     }
  879.     auto remove(Primitive* const & primitive)
  880.     {
  881.       bool deleted = false;
  882.       deleted |= _root->remove(primitive, _root, _nodePool, deleted);
  883.       _root->recalculateDirty();
  884.       return deleted;
  885.     }
  886.     auto removeIfDoesNotFit(Primitive* const & primitive, BV const & bv_old)
  887.     {
  888.       bool deleted = false;
  889.       deleted |= _root->removeIfDoesNotFit(primitive, bv_old, nullptr, _root, _root, _nodePool, deleted);
  890.       _root->recalculateDirty();
  891.       return deleted;
  892.     }
  893.     auto reinsertIfDoesNotFit(Primitive* const & primitive, BV const & bv_old)
  894.     {
  895.       if (removeIfDoesNotFit(primitive, bv_old)) {
  896.         insert(primitive);
  897.       }
  898.     }
  899.   private:
  900.     BVHNodePool _nodePool;
  901.     BVHNode* _root;
  902.   };
  903. }
  904.  
  905. #endif
  906.  
  907. #ifndef BVHINTERNALNODE_H
  908. #define BVHINTERNALNODE_H
  909.  
  910. #include <BVHNode.h>
  911. #include <Descendable.h>
  912.  
  913. namespace Log2
  914. {
  915.   class BVHInternalNode : public BVHNode
  916.   {
  917.   public:
  918.     BVHInternalNode(PrimitiveInfo* const begin, PrimitiveInfo* const end, BVHNodePool& node_pool);
  919.     virtual ~BVHInternalNode() = default;
  920.     virtual void cullVisiblePrimitives(CullingParams const & cp, Callback const & cb) const override;
  921.     virtual void cullVisiblePrimitives(CullingParams const & cp, IntersectedPlanes const & in, Callback const & cb) const override;
  922.     virtual void cullContributingPrimitives(CullingParams const & cp, Callback const & cb) const override;
  923.     virtual void cullAllPrimitives(Callback::CbFunc const & on_render) const override;
  924.     virtual size_t sizeInBytes() const override;
  925.     virtual void intersectNested(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, std::function<void(Primitive const *)> const & intersect_nested) const override;
  926.     virtual void intersectPrimitives(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, Primitive const *& nearest) const override;
  927.     virtual void countNodes(unsigned& internal_nodes, unsigned& leaf_nodes) const override;
  928.     virtual void findNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const override;
  929.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res) override;
  930.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive* parent, IntersectRayResult& res, Primitive*& parent_res) override;
  931.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res, StackTrivial<NodePtr>& stack) override;
  932.     virtual void findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested) override;
  933.     virtual void findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested, StackTrivial<NodePtr>& stack) override;
  934.     virtual void queryRange(BV const & bv, Callback::CbFunc const & cb) const override;
  935.     virtual void queryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const override;
  936.     virtual void queryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const override;
  937.     virtual void queryAll(Callback::CbFunc const & cb) const override;
  938.     virtual BV getBV() const override;
  939.     virtual Type minSquaredDist(Vector const & point) const override;
  940.     virtual Type dist(Ray const & ray) const override;
  941.     virtual void destroy(BVHNodePool& pool) override;
  942.     virtual Type cost(BV const & bv) const override;
  943.     virtual void insert(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool) override;
  944.     virtual bool remove(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted) override;
  945.     virtual bool removeIfDoesNotFit(PrimitiveInfo const & info, BV const & bv_old, BVHNode const * parent, BVHNode const * root, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted) override;
  946.     virtual void destroyTree(StackTrivial<PrimitiveInfo>& primitives, BVHNodePool& node_pool) override;
  947.     virtual DirtyInfo recalculateDirty() override;
  948.     virtual size_t minHeight(size_t const & height) const override;
  949.     virtual size_t maxHeight(size_t const & height) const override;
  950.     virtual void averageHeight(float const & height, float const & inv_num_leafs, float& avg_height) const override;
  951.     void insert(PrimitiveInfo const & pi);
  952.     NodePtr& childToDescend(BV const & bv);
  953.     void markAsDirty();
  954.     bool isDirty() const;
  955.     void rebuild(NodePtr& this_ptr, NodePtr child, BVHNodePool& node_pool);
  956.     void collectFromChildren(DirtyInfo const & di);
  957.     virtual void descendVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  958.     virtual void descendVisible(CsmInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  959.     virtual void descendVisible(CsmLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  960.     virtual void descendContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  961.     virtual void descendContributing(CsmInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  962.     virtual void descendContributing(CsmLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  963.     virtual void descendAll(Descendable& other, Callback2::CbFunc const & on_render) override;
  964.     virtual void descendAll(CsmInternalNode& other, Callback2::CbFunc const & on_render) override;
  965.     virtual void descendAll(CsmLeafNode& other, Callback2::CbFunc const & on_render) override;
  966.     void recurseVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb);
  967.     void recurseContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb);
  968.     void recurseAll(Descendable& other, Callback2::CbFunc const & on_render);
  969.   private:
  970.     NodePtr _left, _right;
  971.     BV _bv;
  972.     Type _minSquaredSize, _maxSquaredSize;
  973.     void recurseVisible(CullingParams const & cp, Callback const & cb) const;
  974.     void recurseVisible(CullingParams const & cp, IntersectedPlanes const & ip, Callback const & cb) const;
  975.     void recurseContributing(CullingParams const & cp, Callback const & cb) const;
  976.     void recurseAll(Callback::CbFunc const & on_render) const;
  977.     void recurseNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const;
  978.     void recurseNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res);
  979.     bool largerThan(BVHInternalNode const & other) const;
  980.     void recurseQueryRange(BV const & bv, Callback::CbFunc const & cb) const;
  981.     void recurseQueryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const;
  982.     void recurseQueryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const;
  983.     void recurseQueryAll(Callback::CbFunc const & cb) const;
  984.     void init(PrimitiveInfo const * begin, PrimitiveInfo const * const end);
  985.     bool contributes(CullingParams const & cp) const;
  986.     bool fullyContributes(CullingParams const & cp) const;
  987.     IntersectResult intersectFrustum(CullingParams const & cp) const;
  988.     IntersectResult intersectFrustum(CullingParams const & cp, IntersectedPlanes const & in, IntersectedPlanes& out) const;
  989.     ContribResult computeContribution(CullingParams const & cp) const;
  990.   };
  991. }
  992.  
  993. #endif
  994.  
  995. #ifndef BVHLEAFNODE_H
  996. #define BVHLEAFNODE_H
  997.  
  998. #include <BVHNode.h>
  999. #include <IntersectionTests.h>
  1000.  
  1001. namespace Log2
  1002. {
  1003.   class BVHLeafNode : public BVHNode
  1004.   {
  1005.   public:
  1006.     explicit BVHLeafNode(Primitive* const & primitive);
  1007.     virtual ~BVHLeafNode() = default;
  1008.     virtual void cullVisiblePrimitives(CullingParams const & cp, Callback const & cb) const override;
  1009.     virtual void cullVisiblePrimitives(CullingParams const & cp, IntersectedPlanes const & in, Callback const & cb) const override;
  1010.     virtual void cullContributingPrimitives(CullingParams const & cp, Callback const & cb) const override;
  1011.     virtual void cullAllPrimitives(Callback::CbFunc const & on_render) const override;
  1012.     virtual size_t sizeInBytes() const override;
  1013.     virtual void intersectNested(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, std::function<void(Primitive const *)> const & intersect_nested) const override;
  1014.     virtual void intersectPrimitives(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, Primitive const *& nearest) const override;
  1015.     virtual void countNodes(unsigned& internal_nodes, unsigned& leaf_nodes) const override;
  1016.     virtual void findNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const override;
  1017.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res) override;
  1018.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive* parent, IntersectRayResult& res, Primitive*& parent_res) override;
  1019.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res, StackTrivial<NodePtr>& stack) override;
  1020.     virtual void findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested) override;
  1021.     virtual void findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested, StackTrivial<NodePtr>& stack) override;
  1022.     virtual void queryRange(BV const & bv, Callback::CbFunc const & cb) const override;
  1023.     virtual void queryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const override;
  1024.     virtual void queryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const override;
  1025.     virtual void queryAll(Callback::CbFunc const & cb) const override;
  1026.     virtual BV getBV() const override;
  1027.     virtual Type minSquaredDist(Vector const & point) const override;
  1028.     virtual Type dist(Ray const & ray) const override;
  1029.     virtual void destroy(BVHNodePool& pool) override;
  1030.     virtual Type cost(BV const & bv) const override;
  1031.     virtual void insert(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool) override;
  1032.     virtual bool remove(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted) override;
  1033.     virtual bool removeIfDoesNotFit(PrimitiveInfo const & info, BV const & bv_old, BVHNode const * parent, BVHNode const * root, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted)override;
  1034.     virtual void destroyTree(StackTrivial<PrimitiveInfo>& primitives, BVHNodePool& node_pool) override;
  1035.     virtual DirtyInfo recalculateDirty() override;
  1036.     virtual size_t minHeight(size_t const & height) const override;
  1037.     virtual size_t maxHeight(size_t const & height) const override;
  1038.     virtual void averageHeight(float const & height, float const & inv_num_leafs, float& avg_height) const override;
  1039.     virtual void descendVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  1040.     virtual void descendVisible(CsmInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1041.     virtual void descendVisible(CsmLeafNode& other, CullingParams const & cp, Callback2 const & cb)override;
  1042.     virtual void descendContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  1043.     virtual void descendContributing(CsmInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1044.     virtual void descendContributing(CsmLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1045.     virtual void descendAll(Descendable& other, Callback2::CbFunc const & on_render) override;
  1046.     virtual void descendAll(CsmInternalNode& other, Callback2::CbFunc const & on_render) override;
  1047.     virtual void descendAll(CsmLeafNode& other, Callback2::CbFunc const & on_render) override;
  1048.   private:
  1049.     Primitive * _primitive;
  1050.     bool contributes(CullingParams const & cp) const;
  1051.     IntersectResult intersectFrustum(CullingParams const & cp) const;
  1052.   };
  1053. }
  1054.  
  1055. #endif // !BVHLEAFNODE_H
  1056.  
  1057. #ifndef BVHNODE_H
  1058. #define BVHNODE_H
  1059.  
  1060. #include <Primitive.h>
  1061. #include <math/Log2Math.h>
  1062. #include <Callback.h>
  1063. #include <Descendable.h>
  1064.  
  1065. namespace Log2
  1066. {
  1067.   class CullingParams;
  1068.   class BVHInternalNode;
  1069.   class BVHLeafNode;
  1070.   class BVHNodePool;
  1071.  
  1072.   class Callback;
  1073.  
  1074.   class BVHNode : public Descendable
  1075.   {
  1076.   public:
  1077.     using BV = typename Primitive::BV;
  1078.     using Ray = typename Primitive::Ray;
  1079.     using Matrix = typename Primitive::Matrix;
  1080.     using Type = typename Primitive::Type;
  1081.     static auto const Dim = BV::getDim();
  1082.     using Vector = Vector<Dim, Type>;
  1083.     using IntersectRayResult = IntersectRayResult<Type, Matrix>;
  1084.  
  1085.     class PrimitiveInfo
  1086.     {
  1087.     public:
  1088.       PrimitiveInfo(Primitive* const & p) :
  1089.         _primitive(p),
  1090.         _bv(p->bv()),
  1091.         _squaredSize(p->squaredSize())
  1092.       {
  1093.       }
  1094.       auto const & primitive() const { return _primitive; }
  1095.       auto const & bv() const { return _bv; }
  1096.       auto const & squaredSize() const { return _squaredSize; }
  1097.     private:
  1098.       Primitive* _primitive;
  1099.       BV _bv;
  1100.       Type _squaredSize;
  1101.     };
  1102.     class DirtyInfo
  1103.     {
  1104.  
  1105.     public:
  1106.       DirtyInfo(BV const & bv, Type const & min_squared_size, Type const & max_squared_size) :
  1107.         _bv(bv),
  1108.         _minSquaredSize(min_squared_size),
  1109.         _maxSquaredSize(max_squared_size)
  1110.       {}
  1111.       auto const & bv() const { return _bv; }
  1112.       auto const & minSquaredSize() const { return _minSquaredSize; }
  1113.       auto const & maxSquaredSize() const { return _maxSquaredSize; }
  1114.     private:
  1115.       BV _bv;
  1116.       Type _minSquaredSize;
  1117.       Type _maxSquaredSize;
  1118.     };
  1119.     using NodePtr = BVHNode * ;
  1120.  
  1121.     using CbIntersect = std::function<void(Primitive*, Primitive*)>;
  1122.     BVHNode() = default;
  1123.     virtual ~BVHNode() = default;
  1124.     virtual void cullVisiblePrimitives(CullingParams const & cp, Callback const & cb) const = 0;
  1125.     virtual void cullVisiblePrimitives(CullingParams const & cp, IntersectedPlanes const & in, Callback const & cb) const = 0;
  1126.     virtual void cullContributingPrimitives(CullingParams const & cp, Callback const & cb) const = 0;
  1127.     virtual void cullAllPrimitives(Callback::CbFunc const & on_render) const = 0;
  1128.     virtual size_t sizeInBytes() const = 0;
  1129.     virtual void intersectNested(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, std::function<void(Primitive const *)> const & intersect_nested) const = 0;
  1130.     virtual void intersectPrimitives(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, Primitive const *& nearest) const = 0;
  1131.     virtual void countNodes(unsigned& internal_nodes, unsigned& leaf_nodes) const = 0;
  1132.     virtual void findNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const = 0;
  1133.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res) = 0;
  1134.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive* parent, IntersectRayResult& res, Primitive*& parent_res) = 0;
  1135.     virtual void findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res, StackTrivial<NodePtr>& stack) = 0;
  1136.     virtual void findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested) = 0;
  1137.     virtual void findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested, StackTrivial<NodePtr>& stack) = 0;
  1138.     virtual void queryRange(BV const & bv, Callback::CbFunc const & cb) const = 0;
  1139.     virtual void queryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const = 0;
  1140.     virtual void queryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const = 0;
  1141.     virtual void queryAll(Callback::CbFunc const & cb) const = 0;
  1142.     virtual BV getBV() const = 0;
  1143.     virtual Type minSquaredDist(const Vector& point) const = 0;
  1144.     virtual Type dist(Ray const & ray) const = 0;
  1145.     virtual void destroy(BVHNodePool& pool) = 0;
  1146.     virtual Type cost(BV const & bv) const = 0;
  1147.     virtual void insert(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool) = 0;
  1148.     virtual bool remove(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted) = 0;
  1149.     virtual bool removeIfDoesNotFit(PrimitiveInfo const & info, BV const & bv_old, BVHNode const * parent, BVHNode const * root, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted) = 0;
  1150.     virtual void destroyTree(StackTrivial<PrimitiveInfo>& primitives, BVHNodePool& node_pool) = 0;
  1151.     virtual DirtyInfo recalculateDirty() = 0;
  1152.     virtual size_t minHeight(size_t const & height) const = 0;
  1153.     virtual size_t maxHeight(size_t const & height) const = 0;
  1154.     virtual void averageHeight(float const & height, float const & inv_num_leafs, float& avg_height) const = 0;
  1155.   };
  1156. }
  1157.  
  1158. #endif
  1159.  
  1160. #ifndef BVHNODEPOOL_H
  1161. #define BVHNODEPOOL_H
  1162.  
  1163. #include <boost/pool/object_pool.hpp>
  1164. #include <BVHNode.h>
  1165. #include <BVHLeafNode.h>
  1166. #include <BVHInternalNode.h>
  1167.  
  1168. namespace Log2
  1169. {
  1170.   class BVHNode;
  1171.   class BVHNodePool
  1172.   {
  1173.   public:
  1174.     BVHNodePool(size_t num_primitives);
  1175.     BVHNodePool(BVHNodePool const & other) = delete;
  1176.     BVHNodePool& operator=(BVHNodePool const & other) = delete;
  1177.     BVHNodePool(BVHNodePool&& other) = delete;
  1178.     BVHNodePool& operator=(BVHNodePool&& other) = delete;
  1179.     ~BVHNodePool() = default;
  1180.     BVHNode* createInternalNode(BVHNode::PrimitiveInfo* const begin, BVHNode::PrimitiveInfo* const end);
  1181.     BVHNode* createLeafNode(Primitive* p);
  1182.     BVHNode* createNode(BVHNode::PrimitiveInfo* const begin, BVHNode::PrimitiveInfo* const end);
  1183.     BVHNode* createNode(StackTrivial<BVHNode::PrimitiveInfo>& infos);
  1184.     void destroy(BVHLeafNode* node);
  1185.     void destroy(BVHInternalNode* node);
  1186.   private:
  1187.     boost::object_pool<BVHInternalNode> _internalNodePool;
  1188.     boost::object_pool<BVHLeafNode> _leafNodePool;
  1189.   };
  1190. }
  1191.  
  1192. #endif
  1193.  
  1194. #ifndef CSMINTERNALNODE_H
  1195. #define CSMINTERNALNODE_H
  1196.  
  1197. #include <CsmNode.h>
  1198. #include <Primitive.h>
  1199. #include <Descendable.h>
  1200.  
  1201. namespace Log2
  1202. {
  1203.   class CsmSplit;
  1204.   class CsmNodePool;
  1205.   class CsmTree;
  1206.  
  1207.   class CsmInternalNode : public CsmNode
  1208.   {
  1209.   public:
  1210.     CsmInternalNode(CsmSplit* begin, CsmSplit* end, CsmTree& np, Matrix<4, 4, Type> const & view_matrix_light);
  1211.     ~CsmInternalNode();
  1212.     FrustumPlanes<3, Type> const & frustumPlanes() const;
  1213.     void recurseVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb);
  1214.     void recurseContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb);
  1215.     void recurseAll(Descendable& other, Callback2::CbFunc const & on_render);
  1216.     BV const & bvRender() const;
  1217.     BV const & bvCull() const;
  1218.     virtual void descendVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  1219.     virtual void descendVisible(BVHInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1220.     virtual void descendVisible(BVHLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1221.     virtual void descendContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  1222.     virtual void descendContributing(BVHInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1223.     virtual void descendContributing(BVHLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1224.     virtual void descendAll(Descendable& other, Callback2::CbFunc const & on_render) override;
  1225.     virtual void descendAll(BVHInternalNode& other, Callback2::CbFunc const & on_render) override;
  1226.     virtual void descendAll(BVHLeafNode& other, Callback2::CbFunc const & on_render) override;
  1227.   private:
  1228.     CsmNode* _left;
  1229.     CsmNode* _right;
  1230.     BV _bvRender;
  1231.     BV _bvCull;
  1232.     FrustumPlanes<3, Type> _fp;
  1233.   };
  1234. }
  1235.  
  1236. #endif
  1237.  
  1238. #ifndef CSMLEAFNODE_H
  1239. #define CSMLEAFNODE_H
  1240.  
  1241. #include <CsmNode.h>
  1242. #include <CsmSplit.h>
  1243.  
  1244. namespace Log2
  1245. {
  1246.   class CsmLeafNode : public CsmNode
  1247.   {
  1248.   public:
  1249.     CsmLeafNode(CsmSplit* split);
  1250.     virtual void descendVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  1251.     virtual void descendVisible(BVHInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1252.     virtual void descendVisible(BVHLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1253.     virtual void descendContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb) override;
  1254.     virtual void descendContributing(BVHInternalNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1255.     virtual void descendContributing(BVHLeafNode& other, CullingParams const & cp, Callback2 const & cb) override;
  1256.     virtual void descendAll(Descendable& other, Callback2::CbFunc const & on_render) override;
  1257.     virtual void descendAll(BVHInternalNode& other, Callback2::CbFunc const & on_render) override;
  1258.     virtual void descendAll(BVHLeafNode& other, Callback2::CbFunc const & on_render) override;
  1259.     CsmSplit& split();
  1260.   private:
  1261.     CsmSplit* _split;
  1262.   };
  1263. }
  1264.  
  1265. #endif
  1266.  
  1267. #ifndef CSMNODE_H
  1268. #define CSMNODE_H
  1269.  
  1270. #include <Primitive.h>
  1271. #include <Descendable.h>
  1272.  
  1273. namespace Log2
  1274. {
  1275.   class CsmNode : public Descendable
  1276.   {
  1277.   public:
  1278.  
  1279.     using Type = Primitive::Type;
  1280.     using BV = Primitive::BV;
  1281.   };
  1282. }
  1283.  
  1284. #endif // !CSMNODE_H
  1285.  
  1286. #ifndef CSMSPLIT_H
  1287. #define CSMSPLIT_H
  1288.  
  1289. #include <RenderList.h>
  1290. #include <AABB.h>
  1291. #include <Primitive.h>
  1292. #include <FrustumPlanes.h>
  1293.  
  1294. namespace Log2
  1295. {
  1296.   class CsmSplit
  1297.   {
  1298.     using BV = typename Primitive::BV;
  1299.     using Type = typename Primitive::Type;
  1300.   public:
  1301.     CsmSplit(BV const & bv_light_cull, BV const & bv_light_render, Matrix<4, 4, Type> const & view_matrix_light, Matrix<4, 4, Type>* vp);
  1302.     CsmSplit() = default;
  1303.     CsmSplit(CsmSplit const & other) = default;
  1304.     CsmSplit& operator=(CsmSplit const & other) = default;
  1305.     BV const & bvCull() const;
  1306.     BV const & bvRender() const;
  1307.     Matrix<4, 4, Type> const & vp() const;
  1308.     FrustumPlanes<3, Type> const & frustumPlanes() const;
  1309.     RenderList& renderlist();
  1310.     void set(BV const & bv_light_cull, BV const & bv_light_render, Matrix<4, 4, Type> const & view_matrix_light, Matrix<4, 4, Type>* vp);
  1311.   private:
  1312.     RenderList _rl;
  1313.     BV _bvLightCull;
  1314.     BV _bvLightRender;
  1315.     Matrix<4, 4, Type>* _vp;
  1316.     FrustumPlanes<3, Type> _fp;
  1317.     void init(Matrix<4, 4, Type> const & view_matrix_light);
  1318.   };
  1319. }
  1320.  
  1321. #endif
  1322.  
  1323. #ifndef CSMTREE_H
  1324. #define CSMTREE_H
  1325.  
  1326. #include <CsmSplit.h>
  1327. #include <boost/pool/object_pool.hpp>
  1328. #include <Primitive.h>
  1329. #include <CsmNodePool.h>
  1330.  
  1331. namespace Log2
  1332. {
  1333.   class BoundingVolumeHierarchy;
  1334.   class CsmTree
  1335.   {
  1336.     using BV = typename Primitive::BV;
  1337.     using Type = typename Primitive::Type;
  1338.     class NodePool;
  1339.   public:
  1340.     CsmTree(CsmSplit* begin, CsmSplit* end, Matrix<4, 4, Type> const & view_matrix_light);
  1341.     ~CsmTree();
  1342.     CsmNode* root();
  1343.     void descendVisible(BoundingVolumeHierarchy& bvh, CullingParams const & cp, Callback2 const & cb);
  1344.     CsmNode* createNode(CsmSplit * begin, CsmSplit * end, Matrix<4, 4, Type> const & view_matrix_light);
  1345.   private:
  1346.     CsmNode* createInternalNode(CsmSplit* begin, CsmSplit* end, Matrix<4, 4, Type> const & view_matrix_light);
  1347.     CsmNode* createLeafNode(CsmSplit* cs);
  1348.     CsmNode* _root;
  1349.   };
  1350. }
  1351.  
  1352. #endif
  1353.  
  1354. #ifndef DESCENDABLE_H
  1355. #define DESCENDABLE_H
  1356.  
  1357. #include <Callback.h>
  1358.  
  1359. namespace Log2
  1360. {
  1361.   class BVHInternalNode;
  1362.   class BVHLeafNode;
  1363.   class CsmInternalNode;
  1364.   class CsmLeafNode;
  1365.   class CullingParams;
  1366.   class Descendable
  1367.   {
  1368.   public:
  1369.     virtual void descendVisible(Descendable& other, CullingParams const & cp, Callback2 const & cb) {};
  1370.     virtual void descendVisible(BVHInternalNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1371.     virtual void descendVisible(BVHLeafNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1372.     virtual void descendVisible(CsmInternalNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1373.     virtual void descendVisible(CsmLeafNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1374.     virtual void descendContributing(Descendable& other, CullingParams const & cp, Callback2 const & cb) {};
  1375.     virtual void descendContributing(BVHInternalNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1376.     virtual void descendContributing(BVHLeafNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1377.     virtual void descendContributing(CsmInternalNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1378.     virtual void descendContributing(CsmLeafNode& other, CullingParams const & cp, Callback2 const & cb) {};
  1379.     virtual void descendAll(Descendable& other, Callback2::CbFunc const & cb) {};
  1380.     virtual void descendAll(BVHInternalNode& other, Callback2::CbFunc const & cb) {};
  1381.     virtual void descendAll(BVHLeafNode& other, Callback2::CbFunc const & cb) {};
  1382.     virtual void descendAll(CsmInternalNode& other, Callback2::CbFunc const & cb) {};
  1383.     virtual void descendAll(CsmLeafNode& other, Callback2::CbFunc const & cb) {};
  1384.   };
  1385. }
  1386.  
  1387. #endif
  1388.  
  1389. #ifndef EULERROTATION_H
  1390. #define EULERROTATION_H
  1391.  
  1392. #include <math/MathHelpers.h>
  1393. #include <math/Log2Math.h>
  1394. #include <math/MatVecHelpers.h>
  1395.  
  1396. namespace Log2
  1397. {
  1398.   template<typename T>
  1399.   class EulerRotation
  1400.   {
  1401.   public:
  1402.     EulerRotation() = default;
  1403.     EulerRotation(Vector<3, T> const & radians) : _radians(radians)
  1404.     {}
  1405.     auto rotationX() const
  1406.     {
  1407.       return rotation3Dx(radians().at<0>());
  1408.     }
  1409.     auto rotationY() const
  1410.     {
  1411.       return rotation3Dy(radians().at<1>());
  1412.     }
  1413.     auto rotation() const
  1414.     {
  1415.       return rotationY() * rotationX();
  1416.     }
  1417.     auto right(Matrix<3, 3, T> const & rot) const
  1418.     {
  1419.       return rot * Vector<3, T>(static_cast<T>(-1), static_cast<T>(0), static_cast<T>(0));
  1420.     }
  1421.     auto right() const
  1422.     {
  1423.       return right(rotation());
  1424.     }
  1425.     auto direction(Matrix<3, 3, T> const & rot) const
  1426.     {
  1427.       return rot * Vector<3, T>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(1));
  1428.     }
  1429.     auto direction() const
  1430.     {
  1431.       return direction(rotation());
  1432.     }
  1433.     auto up(Vector<3, T> const & right, Vector<3, T> const & direction) const
  1434.     {
  1435.       return cross(right, direction);
  1436.     }
  1437.     auto up() const
  1438.     {
  1439.       return up(rotation());
  1440.     }
  1441.     auto up(Matrix<3, 3, T> const & rot) const
  1442.     {
  1443.       return up(right(rot), direction(rot));
  1444.     }
  1445.     auto viewMatrix(Vector<3, T> const & pos) const
  1446.     {
  1447.       auto rot = rotation();
  1448.       auto r = right(rot);
  1449.       auto d = direction(rot);
  1450.       return MathHelpers::viewMatrix(pos, r, up(r, d), d);
  1451.     }
  1452.     auto viewMatrix() const
  1453.     {
  1454.       auto rot = rotation();
  1455.       auto r = right(rot);
  1456.       auto d = direction(rot);
  1457.       return MathHelpers::viewMatrix(r, up(r, d), d);
  1458.     }
  1459.     auto viewMatrixInverse(Vector<3, T> const & pos) const
  1460.     {
  1461.       auto rot = rotation();
  1462.       auto r = right(rot);
  1463.       auto d = direction(rot);
  1464.       return MathHelpers::viewMatrixInverse(pos, r, up(r, d), d);
  1465.     }
  1466.     auto const & radians() const
  1467.     {
  1468.       return _radians;
  1469.     }
  1470.     auto degrees() const
  1471.     {
  1472.       return Log2::degrees(_radians);
  1473.     }
  1474.   private:
  1475.     Vector<3, T> _radians = static_cast<T>(0);
  1476.   };
  1477. }
  1478.  
  1479. #endif // !EULERROTATION_H
  1480.  
  1481. #ifndef FIXEDTIMESTEPSYSTEM_H
  1482. #define FIXEDTIMESTEPSYSTEM_H
  1483.  
  1484. #include <memory>
  1485. #include <System.h>
  1486.  
  1487. namespace Log2
  1488. {
  1489.   class Entity;
  1490.  
  1491.   class FixedTimestepSystem : public System
  1492.   {
  1493.   public:
  1494.     FixedTimestepSystem() = default;
  1495.     virtual ~FixedTimestepSystem() = default;
  1496.     virtual bool update() override;
  1497.     virtual void updateSystem() = 0;
  1498.   private:
  1499.     float _acc = 0.f;
  1500.   protected:
  1501.     float const _dt = 1.f / 60.f;
  1502.   };
  1503. }
  1504.  
  1505. #endif
  1506.  
  1507. #ifndef FRUSTUMPLANES_H
  1508. #define FRUSTUMPLANES_H
  1509.  
  1510. #include <math/Log2Math.h>
  1511. #include <array>
  1512. #include <Plane.h>
  1513.  
  1514. namespace Log2
  1515. {
  1516.   template<unsigned Dim, typename T>
  1517.   class FrustumPlanes
  1518.   {
  1519.   public:
  1520.     FrustumPlanes() = default;
  1521.     using Matrix = Matrix<Dim + 1, Dim + 1, T>;
  1522.     static FrustumPlanes create(Matrix const & vp)
  1523.     {
  1524.       FrustumPlanes fp;
  1525.       FillPlanes<Dim * 2u - 1u>::call(fp._planes, vp);
  1526.       return fp;
  1527.     }
  1528.     template<unsigned index>
  1529.     struct FillPlanes
  1530.     {
  1531.       static void call(Plane<Dim, T>* planes, Matrix const & vp)
  1532.       {
  1533.         *(planes + index) = Plane<Dim, T>((vp.row<Dim>() + vp.row<index / 2u>() * static_cast<T>(index % 2 ? -1 : 1)) * static_cast<T>(-1));
  1534.         FillPlanes<index - 1u>::call(planes, vp);
  1535.       }
  1536.     };
  1537.     template<>
  1538.     struct FillPlanes<0>
  1539.     {
  1540.       static void call(Plane<3, T>* planes, Matrix const & vp)
  1541.       {
  1542.         *planes = Plane<3, T>((vp.row<Dim>() + vp.row<0>()) * static_cast<T>(-1));
  1543.       }
  1544.     };
  1545.     FrustumPlanes(FrustumPlanes const & other) = default;
  1546.     FrustumPlanes& operator=(FrustumPlanes const & other) = default;
  1547.     template<unsigned index>
  1548.     auto const & plane() const
  1549.     {
  1550.       return _planes[index];
  1551.     }
  1552.     auto const * begin() const
  1553.     {
  1554.       return _planes;
  1555.     }
  1556.     auto const * end() const
  1557.     {
  1558.       return _planes + 6u;
  1559.     }
  1560.   private:
  1561.     Plane<3, T> _planes [Dim * 2u];
  1562.   };
  1563. }
  1564.  
  1565. #endif // !FRUSTUMPLANES_H
  1566.  
  1567. #ifndef INTERSECTIONTESTS_H
  1568. #define INTERSECTIONTESTS_H
  1569.  
  1570. #include <AABB.h>
  1571. #include <Sphere.h>
  1572. #include <array>
  1573. #include <Ray.h>
  1574. #include <tuple>
  1575. #include <FrustumPlanes.h>
  1576.  
  1577. namespace Log2
  1578. {
  1579.   class Primitive;
  1580.   enum class IntersectionResult
  1581.   {
  1582.     INSIDE, OUTSIDE, INTERSECTING
  1583.   };
  1584.   class IntersectResult
  1585.   {
  1586.   public:
  1587.     IntersectResult(IntersectionResult const & res) : _res(res)
  1588.     {}
  1589.     auto intersecting() const
  1590.     {
  1591.       return _res == IntersectionResult::INTERSECTING;
  1592.     }
  1593.     auto inside() const
  1594.     {
  1595.       return _res == IntersectionResult::INSIDE;
  1596.     }
  1597.     operator bool() const { return _res != IntersectionResult::OUTSIDE; }
  1598.   private:
  1599.     IntersectionResult _res;
  1600.   };
  1601.   static bool intersects(IntersectionResult const & ir)
  1602.   {
  1603.     return ir != IntersectionResult::OUTSIDE;
  1604.   }
  1605.   struct IntersectedPlanes
  1606.   {
  1607.     unsigned char _mask;
  1608.     IntersectedPlanes() : _mask(0u)
  1609.     {}
  1610.     IntersectedPlanes(unsigned char const & mask) : _mask(mask)
  1611.     {
  1612.     }
  1613.     template<unsigned index>
  1614.     void set()
  1615.     {
  1616.       _mask |= 1u << index;
  1617.     }
  1618.     template<unsigned index>
  1619.     auto isSet() const
  1620.     {
  1621.       return (_mask >> index) & 1u;
  1622.     }
  1623.     auto intersects() const
  1624.     {
  1625.       return _mask != 0u;
  1626.     }
  1627.   };
  1628.   template<typename Type, typename Matrix>
  1629.   class IntersectRayResult
  1630.   {
  1631.   public:
  1632.     IntersectRayResult() = default;
  1633.     IntersectRayResult(Type const & z_far) : _nearestT(z_far)
  1634.     {}
  1635.     auto update(Type const & t, Matrix const * nearest_transform, Primitive* nearest)
  1636.     {
  1637.       _nearestT = t;
  1638.       _nearestTransform = nearest_transform;
  1639.       _nearest = nearest;
  1640.     }
  1641.     auto update(typename Ray<3, Type>::IntersectionResult const & res, Matrix const * nearest_transform, Primitive* nearest)
  1642.     {
  1643.       _uv = res.uv();
  1644.       _nearestT = res.t();
  1645.       _nearestTransform = nearest_transform;
  1646.       _nearest = nearest;
  1647.     }
  1648.     operator bool() const { return _nearest != nullptr; }
  1649.     auto const & uv() const
  1650.     {
  1651.       return _uv;
  1652.     }
  1653.     auto const & nearestT() const
  1654.     {
  1655.       return _nearestT;
  1656.     }
  1657.     auto const & nearestTransform() const
  1658.     {
  1659.       return _nearestTransform;
  1660.     }
  1661.     auto* nearest()
  1662.     {
  1663.       return _nearest;
  1664.     }
  1665.   private:
  1666.     Vector<2, Type> _uv;
  1667.     Type _nearestT = std::numeric_limits<Type>::max();
  1668.     Matrix const * _nearestTransform;
  1669.     Primitive* _nearest = nullptr;
  1670.   };
  1671.   template<typename Type>
  1672.   class IntersectRayBVResult
  1673.   {
  1674.   public:
  1675.     IntersectRayBVResult(bool const & intersects, Type const & t) :
  1676.       _intersects(intersects),
  1677.       _t(t)
  1678.     {}
  1679.     operator bool const & () const { return _intersects; }
  1680.     auto const & t() const
  1681.     {
  1682.       return _t;
  1683.     }
  1684.   private:
  1685.     bool _intersects;
  1686.     Type _t;
  1687.   };
  1688.   class IntersectionTests
  1689.   {
  1690.   public:
  1691.     IntersectionTests() = delete;
  1692.     using IR = IntersectionResult;
  1693.     /**
  1694.     * It is assumed that the plane normal defines the outside of the plane.
  1695.     */
  1696.     template<unsigned Dim, typename T>
  1697.     static auto intersectPlane(Plane<Dim, T> const & plane, struct AABB<Dim, T>::CenterExtent const & ce)
  1698.     {
  1699.       auto e = dot(ce._halfExtent, plane.absNormal());
  1700.       auto s = plane.distance(ce._center);
  1701.       if (s > e) {
  1702.         return IR::OUTSIDE;
  1703.       }
  1704.       return s < -e ? IR::INSIDE : IR::INTERSECTING;
  1705.     }
  1706.     template<unsigned Dim, typename T>
  1707.     static auto intersectPlane(Plane<Dim, T> const & plane, Sphere<Dim, T> const & sphere)
  1708.     {
  1709.       auto dist = plane.distance(sphere.center());
  1710.       if (dist > sphere.radius()) {
  1711.         return IR::OUTSIDE;
  1712.       }
  1713.       return dist < -sphere.radius() ? IR::INSIDE : IR::INTERSECTING;
  1714.     }
  1715.     template<unsigned Dim, typename T>
  1716.     static auto outsidePlane(Plane<Dim, T> const & plane, struct AABB<Dim, T>::CenterExtent const & ce)
  1717.     {
  1718.       return plane.distance(ce._center) > dot(ce._halfExtent, plane.absNormal());
  1719.     }
  1720.     template<unsigned Dim, typename T>
  1721.     static auto outsidePlane(Plane<Dim, T> const & plane, Sphere<Dim, T> const & s)
  1722.     {
  1723.       return plane.distance(s.center()) > s.radius();
  1724.     }
  1725.     template<unsigned Dim, typename T>
  1726.     static auto outsideFrustum(AABB<Dim, T> const & aabb, FrustumPlanes<Dim, T> const & fp)
  1727.     {
  1728.       return FrustumCheck<Dim, T, Dim * 2u - 1u>::outside(aabb.centerExtent(), fp);
  1729.     }
  1730.     template<unsigned Dim, typename T>
  1731.     static auto outsideFrustum(Sphere<Dim, T> const & s, FrustumPlanes<Dim, T> const & fp)
  1732.     {
  1733.       return FrustumCheck<Dim, T, Dim * 2u - 1u>::outside(s, fp);
  1734.     }
  1735.     template<unsigned Dim, typename T>
  1736.     static auto intersectFrustum(AABB<Dim, T> const & aabb, FrustumPlanes<Dim, T> const & fp)
  1737.     {
  1738.       bool intersecting = false;
  1739.       return IntersectResult(FrustumCheck<Dim, T, Dim * 2u - 1u>::call(aabb.centerExtent(), fp, intersecting));
  1740.     }
  1741.     template<unsigned Dim, typename T>
  1742.     static auto intersectFrustum(AABB<Dim, T> const & aabb, FrustumPlanes<Dim, T> const & fp, IntersectedPlanes const & in, IntersectedPlanes& out)
  1743.     {
  1744.       return IntersectResult(FrustumCheck<Dim, T, Dim * 2u - 1u>::call(aabb.centerExtent(), fp, in, out));
  1745.     }
  1746.     template<unsigned Dim, typename T, unsigned index>
  1747.     struct FrustumCheck
  1748.     {
  1749.       static IR call(struct AABB<Dim, T>::CenterExtent const & ce, FrustumPlanes<Dim, T> const & fp, bool& intersecting)
  1750.       {
  1751.         auto result = intersectPlane(fp.plane<index>(), ce);
  1752.         if (result == IR::OUTSIDE) {
  1753.           return IR::OUTSIDE;
  1754.         }
  1755.         intersecting = intersecting || result == IR::INTERSECTING;
  1756.         return FrustumCheck<Dim, T, index - 1u>::call(ce, fp, intersecting);
  1757.       }
  1758.       static IR call(Sphere<Dim, T> const & s, FrustumPlanes<Dim, T> const & fp, bool& intersecting)
  1759.       {
  1760.         auto result = intersectPlane(fp.plane<index>(), s);
  1761.         if (result == IR::OUTSIDE) {
  1762.           return IR::OUTSIDE;
  1763.         }
  1764.         intersecting = intersecting || result == IR::INTERSECTING;
  1765.         return FrustumCheck<Dim, T, index - 1u>::call(s, fp, intersecting);
  1766.       }
  1767.       static IR call(struct AABB<Dim, T>::CenterExtent const & ce, FrustumPlanes<Dim, T> const & fp, IntersectedPlanes const & in, IntersectedPlanes & out)
  1768.       {
  1769.         if (in.isSet<index>()) {
  1770.           auto result = intersectPlane(fp.plane<index>(), ce);
  1771.           if (result == IR::OUTSIDE) {
  1772.             return IR::OUTSIDE;
  1773.           }
  1774.           else if (result == IR::INTERSECTING) {
  1775.             out.set<index>();
  1776.           }
  1777.         }
  1778.         return FrustumCheck<Dim, T, index - 1u>::call(ce, fp, in, out);
  1779.       }
  1780.       static bool outside(struct AABB<Dim, T>::CenterExtent const & ce, FrustumPlanes<Dim, T> const & fp)
  1781.       {
  1782.         return outsidePlane(fp.plane<index>(), ce) || FrustumCheck<Dim, T, index - 1u>::outside(ce, fp);
  1783.       }
  1784.       static bool outside(Sphere<Dim, T> const & s, FrustumPlanes<Dim, T> const & fp)
  1785.       {
  1786.         return outsidePlane(fp.plane<index>(), s) || FrustumCheck<Dim, T, index - 1u>::outside(s, fp);
  1787.       }
  1788.     };
  1789.     template<unsigned Dim, typename T>
  1790.     struct FrustumCheck<Dim, T, 0>
  1791.     {
  1792.       static IR call(struct AABB<Dim, T>::CenterExtent const & ce, FrustumPlanes<Dim, T> const & fp, bool& intersecting)
  1793.       {
  1794.         auto result = intersectPlane(fp.plane<0>(), ce);
  1795.         if (result == IR::OUTSIDE) {
  1796.           return IR::OUTSIDE;
  1797.         }
  1798.         return intersecting || result == IR::INTERSECTING ? IR::INTERSECTING : IR::INSIDE;
  1799.       }
  1800.       static IR call(Sphere<Dim, T> const & s, FrustumPlanes<Dim, T> const & fp, bool& intersecting)
  1801.       {
  1802.         auto result = intersectPlane(fp.plane<0>(), s);
  1803.         if (result == IR::OUTSIDE) {
  1804.           return IR::OUTSIDE;
  1805.         }
  1806.         return intersecting || result == IR::INTERSECTING ? IR::INTERSECTING : IR::INSIDE;
  1807.       }
  1808.       static IR call(struct AABB<Dim, T>::CenterExtent const & ce, FrustumPlanes<Dim, T> const & fp, IntersectedPlanes const & in, IntersectedPlanes & out)
  1809.       {
  1810.         if (in.isSet<0>()) {
  1811.           auto result = intersectPlane(fp.plane<0>(), ce);
  1812.           if (result == IR::OUTSIDE) {
  1813.             return IR::OUTSIDE;
  1814.           }
  1815.           else if (result == IR::INTERSECTING) {
  1816.             out.set<0>();
  1817.           }
  1818.         }
  1819.         return out.intersects() ? IR::INTERSECTING : IR::INSIDE;
  1820.       }
  1821.       static bool outside(struct AABB<Dim, T>::CenterExtent const & ce, FrustumPlanes<Dim, T> const & fp)
  1822.       {
  1823.         return outsidePlane(fp.plane<0>(), ce);
  1824.       }
  1825.       static bool outside(Sphere<Dim, T> const & s, FrustumPlanes<Dim, T> const & fp)
  1826.       {
  1827.         return outsidePlane(fp.plane<0>(), s);
  1828.       }
  1829.     };
  1830.     template<unsigned Dim, typename T>
  1831.     static auto intersectFrustum(Sphere<Dim, T> const & sphere, FrustumPlanes<Dim, T> const & fp)
  1832.     {
  1833.       bool intersecting = false;
  1834.       return FrustumCheck<Dim, T, Dim * 2u - 1u>::call(sphere, fp, intersecting);
  1835.     }
  1836.  
  1837.     template<unsigned Dim, typename T>
  1838.     static IntersectRayBVResult<T> intersectRay(AABB<Dim, T> const & aabb, Ray<Dim, T> const & ray)
  1839.     {
  1840.       auto t1 = (aabb.min() - ray.origin()) * ray.invDir();
  1841.       auto t2 = (aabb.max() - ray.origin()) * ray.invDir();
  1842.       auto t_min = maxReduce(minimum(t1, t2));
  1843.       auto t_max = minReduce(maximum(t1, t2));
  1844.       return { t_min <= t_max && t_max >= static_cast<T>(0), t_min };
  1845.     }
  1846.     template<unsigned Dim, typename T>
  1847.     static auto continueSearch(AABB<Dim, T> const & aabb, Ray<Dim, T> const & ray, T const & nearest_dist)
  1848.     {
  1849.       auto result = intersectRay(aabb, ray);
  1850.       return result && result.t() < nearest_dist;
  1851.     }
  1852.     template<typename T, unsigned Dim, typename Matrix>
  1853.     static auto continueSearch(AABB<Dim, T> const & aabb, Ray<Dim, T> const & ray, IntersectRayResult<T, Matrix> const & res)
  1854.     {
  1855.       return continueSearch(aabb, ray, res.nearestT());
  1856.     }
  1857.     template<typename T, unsigned Dim, typename Matrix>
  1858.     static auto continueSearch(AABB<Dim, T> const & aabb_local, Ray<Dim, T> const & ray_local, Ray<Dim, T> const & ray_world,
  1859.       Matrix const & mat, T const & nearest_dist)
  1860.     {
  1861.       auto result = intersectRay(aabb_local, ray_local);
  1862.       return result && distance(ray_world.origin(), MathHelpers::transformPoint(mat, ray_local.pos(result.t()))) < nearest_dist;
  1863.     }
  1864.     template<typename T, unsigned Dim, typename Matrix>
  1865.     static auto continueSearch(AABB<Dim, T> const & aabb_local, Ray<Dim, T> const & ray_local, Ray<Dim, T> const & ray_world,
  1866.       Matrix const & mat, IntersectRayResult<T, Matrix> const & res)
  1867.     {
  1868.       return continueSearch(aabb_local, ray_local, ray_world, mat, res.nearestT());
  1869.     }
  1870.   };
  1871. }
  1872.  
  1873. #endif // !INTERSECTIONTESTS_H
  1874.  
  1875. #ifndef LIGHT_H
  1876. #define LIGHT_H
  1877.  
  1878. #include "math/Log2Math.h"
  1879. #include "Mesh.h"
  1880. #include <memory>
  1881. #include <StackTrivial.h>
  1882. #include <EulerRotation.h>
  1883. #include <CsmSplit.h>
  1884.  
  1885. namespace Log2
  1886. {
  1887.   class Light
  1888.   {
  1889.   public:
  1890.     Light(Vec3f const & color);
  1891.     Vec3f const & intensity() const;
  1892.     void setIntensity(Vec3f const & i);
  1893.   protected:
  1894.     Vec3f _intensity = Vec3f(1.f);
  1895.   };
  1896.  
  1897.   class DirectionalLight : public Light
  1898.   {
  1899.   public:
  1900.     DirectionalLight(Vec3f const & color, Vec3f const & euler_radians);
  1901.     float _ambientPower = 0.3f;
  1902.     template<typename T>
  1903.     auto csmSplits(T const & aspect_ratio, T const & near_plane, T const & fov_degrees, Matrix<4, 4, T> const & view_matrix_inverse,
  1904.       T const & shadow_map_size, StackTrivial<T> const & frustum_splits, CsmSplit* splits, Matrix<4, 4, T>* vp)
  1905.     {
  1906.       auto view_matrix_light = viewMatrix();
  1907.       for (auto ptr = frustum_splits.begin(); ptr != frustum_splits.end(); ptr++) {
  1908.         auto vp_inverse = view_matrix_inverse * inverse(MathHelpers::projectionMatrixPerspective<T>(fov_degrees, aspect_ratio, ptr == frustum_splits.begin() ? near_plane : *(ptr - 1), *ptr));
  1909.         auto cube_ndc = MathHelpers::cubeNDC<T>();
  1910.         AABB<3, T> aabb_light(AABB<3, T>::fromTransform<cube_ndc.size()>(cube_ndc.data(), view_matrix_light * vp_inverse));
  1911.         auto units_per_texel = (aabb_light.max() - aabb_light.min()) / shadow_map_size;
  1912.         aabb_light.min() = floor(aabb_light.min() / units_per_texel) * units_per_texel;
  1913.         aabb_light.max() = floor(aabb_light.max() / units_per_texel) * units_per_texel;
  1914.         AABB<3, T> aabb_light_cull = aabb_light;
  1915.         aabb_light_cull.min().at<2>() -= _maxShadowCastDistance;
  1916.         (splits++)->set(aabb_light_cull, aabb_light, view_matrix_light, vp++);
  1917.       }
  1918.     }
  1919.     Mat4f viewMatrix() const;
  1920.     Vec3f direction() const;
  1921.     Vec3f const & eulerRadians() const;
  1922.     Vec3f eulerDegrees() const;
  1923.     void setEulerRadians(Vec3f const & euler_radians);
  1924.     void setEulerDegrees(Vec3f const & euler_degrees);
  1925.     void setMaxShadowCastDistance(float const & distance);
  1926.     float const & getMaxShadowCastDistance() const;
  1927.   private:
  1928.     EulerRotation<float> _er;
  1929.     float _maxShadowCastDistance = 1000.f;
  1930.   };
  1931. }
  1932.  
  1933. #endif
  1934.  
  1935. #ifndef MESH_H
  1936. #define MESH_H
  1937.  
  1938. #include <vector>
  1939. #include <array>
  1940. #include <memory>
  1941. #include <functional>
  1942. #include <Vertex.h>
  1943. #include <AABB.h>
  1944. #include <Sphere.h>
  1945. #include <BoundingVolumeHierarchy.h>
  1946. #include <Triangle.h>
  1947. #include <StackTrivial.h>
  1948. #include <boost/pool/object_pool.hpp>
  1949.  
  1950. namespace Log2
  1951. {
  1952.   class Material;
  1953.  
  1954.   class Mesh
  1955.   {
  1956.   public:
  1957.     using Type = Primitive::Type;
  1958.     Mesh() = default;
  1959.     Mesh(StackTrivial<Vertex>&& vertices, StackTrivial<unsigned int>&& indices, std::shared_ptr<Material> const * materials, unsigned int material_index);
  1960.     StackTrivial<Vertex> const & vertices() const;
  1961.     StackTrivial<unsigned int> const & indices() const;
  1962.     void setVertices(StackTrivial<Vertex>&& vertices);
  1963.     void setIndices(StackTrivial<unsigned>&& indices);
  1964.     unsigned const & materialIndex() const;
  1965.     AABB3f const & aabb() const;
  1966.     Sphere3f const & sphere() const;
  1967.     void setMaterialIndex(unsigned const & material_index);
  1968.     void setMaterial(std::shared_ptr<Material> const & material);
  1969.     std::shared_ptr<Material> const & material() const;
  1970.     struct Proxy;
  1971.     using Ray = typename BoundingVolumeHierarchy::Ray;
  1972.     BoundingVolumeHierarchy * bvh();
  1973.     void triangles(Vertex* vertices, boost::object_pool<Triangle>& tri_pool, StackTrivial<Primitive*>& triangles) const;
  1974.     std::shared_ptr<BoundingVolumeHierarchy> getTransformedBVH(Matrix<4, 4, Type> const & transform,
  1975.       Matrix<3, 3, Type> const & m_inv_transpose, boost::object_pool<Triangle>& tri_pool, StackTrivial<Vertex>& vertices) const;
  1976.     void calculateTangentSpace();
  1977.   private:
  1978.     StackTrivial<Vertex> _vertices;
  1979.     StackTrivial<unsigned int> _indices;
  1980.     boost::object_pool<Triangle> _trianglePool;
  1981.     unsigned int _materialIndex;
  1982.     std::shared_ptr<Material> _material;
  1983.     AABB3f _aabb;
  1984.     Sphere3f _sphere;
  1985.     std::unique_ptr<BoundingVolumeHierarchy> _bvh;
  1986.     void init();
  1987.   };
  1988. }
  1989.  
  1990. #endif
  1991.  
  1992. #ifndef PLANE_H
  1993. #define PLANE_H
  1994.  
  1995. #include <math/Log2Math.h>
  1996.  
  1997. namespace Log2
  1998. {
  1999.   template<unsigned Dim, typename T>
  2000.   class Plane
  2001.   {
  2002.   public:
  2003.     Plane() = default;
  2004.     Plane(Vector<Dim, T> const & normal, T const & bias) :
  2005.       _normal(normal),
  2006.       _bias(bias)
  2007.     {
  2008.       normalize();
  2009.     }
  2010.     explicit Plane(Vector<Dim + 1, T> const & normal_bias) :
  2011.       _normal(normal_bias.reduce<Dim>()),
  2012.       _bias(normal_bias[Dim])
  2013.     {
  2014.       normalize();
  2015.     }
  2016.     auto normalize()
  2017.     {
  2018.       auto inv_len = static_cast<T>(1) / _normal.length();
  2019.       _normal *= inv_len;
  2020.       _bias *= inv_len;
  2021.     }
  2022.     auto const & normal() const
  2023.     {
  2024.       return _normal;
  2025.     }
  2026.     auto const & bias() const
  2027.     {
  2028.       return _bias;
  2029.     }
  2030.     auto normalBias() const
  2031.     {
  2032.       return Vector<Dim + 1, T>(_normal, _bias);
  2033.     }
  2034.     auto distance(Vector<Dim, T> const & point) const
  2035.     {
  2036.       return dot(point, _normal) + _bias;
  2037.     }
  2038.     auto absNormal() const
  2039.     {
  2040.       return abs(_normal);
  2041.     }
  2042.   private:
  2043.     Vector<Dim, T> _normal;
  2044.     T _bias;
  2045.   };
  2046.  
  2047.   using Plane2f = Plane<2, float>;
  2048.   using Plane3f = Plane<3, float>;
  2049.  
  2050.   using Plane2d = Plane<2, double>;
  2051.   using Plane3d = Plane<3, double>;
  2052. }
  2053.  
  2054. #endif
  2055.  
  2056. #ifndef TRIANGLE_H
  2057. #define TRIANGLE_H  
  2058.  
  2059. #include <Primitive.h>
  2060. #include <vector>
  2061. #include <Vertex.h>
  2062.  
  2063. namespace Log2
  2064. {
  2065.   class Particle;
  2066.   class Triangle : public Primitive
  2067.   {
  2068.   public:
  2069.     Triangle() = default;
  2070.     Triangle(Vec3u const & indices, Vertex* vertices) :
  2071.       _indices(indices),
  2072.       _vertices(vertices)
  2073.     {
  2074.     }
  2075.     Triangle& operator=(Triangle const & other) = default;
  2076.     template<unsigned index>
  2077.     auto vertex() const
  2078.     {
  2079.       static_assert(index <= 2, "Invalid index");
  2080.       return _vertices[_indices[index]].position();
  2081.     }
  2082.     template<unsigned index>
  2083.     auto normal() const
  2084.     {
  2085.       static_assert(index <= 2, "Invalid index");
  2086.       return _vertices[_indices[index]].normal();
  2087.     }
  2088.     auto center() const
  2089.     {
  2090.       return interpolatePos(static_cast<Type>(1.0 / 3.0));
  2091.     }
  2092.     auto centerNormal() const
  2093.     {
  2094.       return interpolateNormal(static_cast<Type>(1.0 / 3.0));
  2095.     }
  2096.     Vector<3, Type> interpolatePos(Vector<2, Type> const & uv) const
  2097.     {
  2098.       return interpolateBary(uv, vertex<0>(), vertex<1>(), vertex<2>());
  2099.     }
  2100.     virtual Vector<3, Type> interpolateNormal(Vector<2, Type> const & uv) const override
  2101.     {
  2102.       return interpolateBary(uv, normal<0>(), normal<1>(), normal<2>());
  2103.     }
  2104.     virtual Vector<2, Type> barycentric(Vector<3, Type> const & p)
  2105.     {
  2106.       return barycentric(vertex<0>(), vertex<1>(), vertex<2>(), p);
  2107.     }
  2108.     template<unsigned Dim>
  2109.     static auto barycentric(Vector<Dim, Type> const & p0, Vector<Dim, Type> const & p1, Vector<Dim, Type> const & p2, Vector<Dim, Type> const & p)
  2110.     {
  2111.       auto e0 = p1 - p0;
  2112.       auto e1 = p2 - p0;
  2113.       auto one_over_a = static_cast<Type>(1) / triAreaTimesTwo(e0, e1);
  2114.       return Vector<2, Type>(triAreaTimesTwo(p - p0, e1), triAreaTimesTwo(e0, p - p1)) * one_over_a;
  2115.     }
  2116.  
  2117.     std::array<Vec3f, 3u> getVertices() const
  2118.     {
  2119.       return { vertex<0>(), vertex<1>(), vertex<2>() };
  2120.     }
  2121.     virtual BV bv() const override;
  2122.     virtual Type squaredSize() const override;
  2123.     Ray::IntersectionResult intersectRay(Ray const & ray, Vector<3, Type> const & p0, Vector<3, Type> const & p1, Vector<3, Type> const & p2);
  2124.     virtual Ray::IntersectionResult intersectRay(Ray const & ray_local, Ray const & ray_world, Matrix const & mat) override;
  2125.     virtual Ray::IntersectionResult intersectRay(Ray const & ray) override;
  2126.     virtual Ray::IntersectionResult intersectRay(Ray const & ray, Matrix const & matrix) override;
  2127.     virtual void debugTriangle(Vector<4, Type>* _debugTriangle, Matrix const & transform) const override;
  2128.     virtual Triangle* toTriangle() override;
  2129.   private:
  2130.     Vec3u _indices;
  2131.     Vertex* _vertices;
  2132.   };
  2133. }
  2134.  
  2135. #endif
  2136.  
  2137. #ifndef VERTEX_H
  2138. #define VERTEX_H
  2139.  
  2140. #include <math/Log2Math.h>
  2141.  
  2142. namespace Log2
  2143. {
  2144.   struct CompressedNormal
  2145.   {
  2146.     int _x : 10;
  2147.     int _y : 10;
  2148.     int _z : 10;
  2149.     int _w : 2;
  2150.     CompressedNormal() = default;
  2151.     explicit CompressedNormal(Vec3f const & normal)
  2152.     {
  2153.       Vec3i compressed(normal.normalize() * 511.f);
  2154.       _x = compressed.at<0>();
  2155.       _y = compressed.at<1>();
  2156.       _z = compressed.at<2>();
  2157.       _w = 1;
  2158.     }
  2159.     explicit CompressedNormal(Vec3f const & tangent, int const & handedness)
  2160.     {
  2161.       Vec3i compressed(tangent.normalize() * 511.f);
  2162.       _x = compressed.at<0>();
  2163.       _y = compressed.at<1>();
  2164.       _z = compressed.at<2>();
  2165.       _w = handedness;
  2166.     }
  2167.     auto uncompress() const
  2168.     {
  2169.       return Vec3f(Vec3i(_x, _y, _z)) / 511.f;
  2170.     }
  2171.     auto const & w() const
  2172.     {
  2173.       return _w;
  2174.     }
  2175.   };
  2176.   class Vertex
  2177.   {
  2178.   public:
  2179.     Vertex() = default;
  2180.     Vertex(Vec3f const & position) :
  2181.       _position(position)
  2182.     {
  2183.     }
  2184.     Vertex(Vec3f const & position, CompressedNormal const & normal) :
  2185.       _position(position),
  2186.       _normal(normal)
  2187.     {
  2188.     }
  2189.     Vertex(Vec3f const & position, Vec2f const & uv) :
  2190.       _position(position),
  2191.       _uv(uv)
  2192.     {
  2193.     }
  2194.     Vertex(Vec3f const & position, CompressedNormal const & normal, Vec2f const & uv) :
  2195.       _position(position),
  2196.       _normal(normal),
  2197.       _uv(uv)
  2198.     {
  2199.     }
  2200.     Vertex(Vec3f const & position, CompressedNormal const & normal, Vec2f const & uv, CompressedNormal const & tangent) :
  2201.       _position(position),
  2202.       _normal(normal),
  2203.       _uv(uv),
  2204.       _tangent(tangent)
  2205.     {
  2206.     }
  2207.     auto const & position() const
  2208.     {
  2209.       return _position;
  2210.     }
  2211.     auto normal() const
  2212.     {
  2213.       return _normal.uncompress();
  2214.     }
  2215.     auto const & uv() const
  2216.     {
  2217.       return _uv;
  2218.     }
  2219.     auto tangent() const
  2220.     {
  2221.       return _tangent.uncompress();
  2222.     }
  2223.     auto bitangent() const
  2224.     {
  2225.       return cross(normal(), tangent()) * static_cast<float>(_tangent.w());
  2226.     }
  2227.     auto setPosition(Vec3f const & position)
  2228.     {
  2229.       _position = position;
  2230.     }
  2231.     auto setNormal(CompressedNormal const & normal)
  2232.     {
  2233.       _normal = normal;
  2234.     }
  2235.     auto setNormal(Vec3f const & normal)
  2236.     {
  2237.       _normal = CompressedNormal(normal);
  2238.     }
  2239.     auto setUV(Vec2f const & uv)
  2240.     {
  2241.       _uv = uv;
  2242.     }
  2243.     auto setTangent(CompressedNormal const & tangent)
  2244.     {
  2245.       _tangent = tangent;
  2246.     }
  2247.     auto setTangent(Vec3f const & tangent)
  2248.     {
  2249.       _tangent = CompressedNormal(tangent);
  2250.     }
  2251.     auto set(Vec3f const & t, int const & handedness, Vec3f const & n)
  2252.     {
  2253.       setTangent(CompressedNormal(t, handedness));
  2254.       setNormal(n);
  2255.     }
  2256.     static size_t positionMemOffset()
  2257.     {
  2258.       return offsetof(Vertex, _position);
  2259.     }
  2260.     static size_t normalMemOffset()
  2261.     {
  2262.       return offsetof(Vertex, _normal);
  2263.     }
  2264.     static size_t uvMemOffset()
  2265.     {
  2266.       return offsetof(Vertex, _uv);
  2267.     }
  2268.     static size_t tangentMemOffset()
  2269.     {
  2270.       return offsetof(Vertex, _tangent);
  2271.     }
  2272.   private:
  2273.     Vec3f _position;
  2274.     CompressedNormal _normal = CompressedNormal(0.f);
  2275.     Vec2f _uv;
  2276.     CompressedNormal _tangent = CompressedNormal(0.f);
  2277.   };
  2278.  
  2279.   class VertexUncompressed
  2280.   {
  2281.   public:
  2282.     auto addTangent(Vec3f const & t)
  2283.     {
  2284.       _t = normalize(_t + t);
  2285.     }
  2286.     auto addBitangent(Vec3f const & b)
  2287.     {
  2288.       _b = normalize(_b + b);
  2289.     }
  2290.     auto addNormal(Vec3f const & n)
  2291.     {
  2292.       _n = normalize(_n + n);
  2293.     }
  2294.     auto add(Vec3f const & t, Vec3f const & b, Vec3f const & n)
  2295.     {
  2296.       addTangent(t);
  2297.       addBitangent(b);
  2298.       addNormal(n);
  2299.     }
  2300.     auto const & tangent() const
  2301.     {
  2302.       return _t;
  2303.     }
  2304.     auto const & bitangent() const
  2305.     {
  2306.       return _b;
  2307.     }
  2308.     auto const & normal() const
  2309.     {
  2310.       return _n;
  2311.     }
  2312.     auto const & t() const
  2313.     {
  2314.       return tangent();
  2315.     }
  2316.     auto const & b() const
  2317.     {
  2318.       return bitangent();
  2319.     }
  2320.     auto const & n() const
  2321.     {
  2322.       return normal();
  2323.     }
  2324.   private:
  2325.     Vec3f _t = 0.f;
  2326.     Vec3f _b = 0.f;
  2327.     Vec3f _n = 0.f;
  2328.   };
  2329. }
  2330.  
  2331. #endif
  2332.  
  2333. #ifndef PHYSICSCAMERACONTROLLER_H
  2334. #define PHYSICSCAMERACONTROLLER_H
  2335.  
  2336. #include <memory>
  2337. #include <math/Log2Math.h>
  2338. #include <FixedTimestepSystem.h>
  2339. #include <Primitive.h>
  2340.  
  2341. namespace Log2
  2342. {
  2343.   class Camera;
  2344.   class BoundingVolumeHierarchy;
  2345.  
  2346.   class PhysicsCameraController : public FixedTimestepSystem
  2347.   {
  2348.   private:
  2349.     using Type = Primitive::Type;
  2350.     using Vector = Vector<3, Type>;
  2351.   public:
  2352.     PhysicsCameraController(Camera* const & camera, BoundingVolumeHierarchy*& bvh);
  2353.     virtual ~PhysicsCameraController() = default;
  2354.     virtual void updateSystem() override;
  2355.     virtual unsigned getID() override;
  2356.     virtual const char* getName() override;
  2357.     void setAcceleration(Vector const & dir, Type const & amount);
  2358.     void setAngularAcceleration(Vector const & aa);
  2359.     Camera * const & getCamera() const;
  2360.     void setCamera(Camera * const & camera);
  2361.     void setDamping(Type const & damping);
  2362.     Vector const & gravity() const;
  2363.     void setGravity(Vector const & gravity);
  2364.     bool const & collisions() const;
  2365.     void setCollisions(bool const & collisions);
  2366.   private:
  2367.     Camera* _c;
  2368.     Vector _acceleration = static_cast<Type>(0);
  2369.     Vector _velocity = static_cast<Type>(0);
  2370.     Type _damp = DAMP_DEFAULT;
  2371.     Vector _angularAcceleration = static_cast<Type>(0);
  2372.     Vector _angularVelocity = static_cast<Type>(0);
  2373.     Vector _gravity = static_cast<Type>(0);
  2374.     BoundingVolumeHierarchy*& _bvh;
  2375.     bool _collisions = true;
  2376.     static constexpr const Type DAMP_DEFAULT = static_cast<Type>(0.95);
  2377.     static constexpr const Type DAMP_INTERIOR = static_cast<Type>(0.7);
  2378.   };
  2379. }
  2380.  
  2381. #endif
  2382.  
  2383. #ifndef MATHHELPERS_H
  2384. #define MATHHELPERS_H
  2385.  
  2386. #include <math/Log2Math.h>
  2387. #define GLM_ENABLE_EXPERIMENTAL
  2388. #include <glm/gtc/matrix_transform.hpp>
  2389. #include <array>
  2390.  
  2391. namespace Log2
  2392. {
  2393.   template<unsigned Dim, typename T>
  2394.   class AABB;
  2395.   class MathHelpers
  2396.   {
  2397.   public:
  2398.     template<typename T>
  2399.     static auto cubeNDC()
  2400.     {
  2401.       std::array<Vector<3, T>, 8> ret;
  2402.       FillCubeNDC<T>::call(ret.data());
  2403.       return ret;
  2404.     }
  2405.     template<typename T, unsigned i = 7>
  2406.     struct FillCubeNDC
  2407.     {
  2408.       static void call(Vector<3, T>* res)
  2409.       {
  2410.         *(res + i) = Vector<3, T>(i & 4 ? -static_cast<T>(1) : static_cast<T>(1), i & 2 ? -static_cast<T>(1) : static_cast<T>(1), i & 1 ? -static_cast<T>(1) : static_cast<T>(1));
  2411.         FillCubeNDC<T, i - 1u>::call(res);
  2412.       }
  2413.     };
  2414.     template<typename T>
  2415.     struct FillCubeNDC<T, 0>
  2416.     {
  2417.       static void call(Vector<3, T>* res)
  2418.       {
  2419.         *res = Vector<3, T>(0 & 4 ? -static_cast<T>(1) : static_cast<T>(1), 0 & 2 ? -static_cast<T>(1) : static_cast<T>(1), 0 & 1 ? -static_cast<T>(1) : static_cast<T>(1));
  2420.       }
  2421.     };
  2422.     template<typename T>
  2423.     static auto projectionMatrixPerspective(T const & fov_degrees, T const & aspect_ratio, T const & z_near, T const & z_far)
  2424.     {
  2425.       using Vec = Vector<4, T>;
  2426.       auto const t = tan(radians(fov_degrees) * static_cast<T>(0.5));
  2427.       auto const sx = static_cast<T>(1) / (aspect_ratio * t);
  2428.       auto const sy = static_cast<T>(1) / t;
  2429.       auto const sz = static_cast<T>(1) / (z_far - z_near);
  2430.       return Matrix<4, 4, T>({ Vec(sx, static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
  2431.         Vec(static_cast<T>(0), sy, static_cast<T>(0), static_cast<T>(0)),
  2432.         Vec(static_cast<T>(0), static_cast<T>(0), (z_far + z_near) * sz, static_cast<T>(1)),
  2433.         Vec(static_cast<T>(0), static_cast<T>(0), -(static_cast<T>(2) * z_far * z_near) * sz, static_cast<T>(0)) });
  2434.     }
  2435.     template<typename T>
  2436.     static auto projectionMatrixOrtho(AABB<3, T> const & aabb)
  2437.     {
  2438.       auto const c = aabb.centerTimesTwo() * static_cast<T>(-1);
  2439.       auto const e = Vector<3, T>(static_cast<T>(1)) / aabb.extent();
  2440.       return Matrix<4, 4, T>({ Vector<4, T>(static_cast<T>(2) * e.at<0>(), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)),
  2441.         Vector<4, T>(static_cast<T>(0), static_cast<T>(2) * e.at<1>(), static_cast<T>(0), static_cast<T>(0)),
  2442.         Vector<4, T>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(2) * e.at<2>(), static_cast<T>(0)),
  2443.         Vector<4, T>(c * e, static_cast<T>(1)) });
  2444.     }
  2445.     template<typename T>
  2446.     static auto viewMatrix(Vector<3, T> const & pos, Vector<3, T> const & right, Vector<3, T> const & up, Vector<3, T> const & direction)
  2447.     {
  2448.       return Matrix<4, 4, T>({ Vector<4, T>(right.at<0>(), up.at<0>(), direction.at<0>(), static_cast<T>(0)),
  2449.         Vector<4, T>(right.at<1>(), up.at<1>(), direction.at<1>(), static_cast<T>(0)),
  2450.         Vector<4, T>(right.at<2>(), up.at<2>(), direction.at<2>(), static_cast<T>(0)),
  2451.         Vector<4, T>(-dot(right, pos), -dot(up, pos), -dot(direction, pos), static_cast<T>(1)) });
  2452.     }
  2453.     template<typename T>
  2454.     static auto viewMatrixInverse(Vector<3, T> const & pos, Vector<3, T> const & right, Vector<3, T> const & up, Vector<3, T> const & direction)
  2455.     {
  2456.       return Matrix<4, 4, T>({ Vector<4, T>(right, static_cast<T>(0)),
  2457.         Vector<4, T>(up, static_cast<T>(0)),
  2458.         Vector<4, T>(direction, static_cast<T>(0)),
  2459.         Vector<4, T>(pos, static_cast<T>(1)) });
  2460.     }
  2461.     template<typename T>
  2462.     static auto viewMatrix(Vector<3, T> const & right, Vector<3, T> const & up, Vector<3, T> const & direction)
  2463.     {
  2464.       return Matrix<4, 4, T>({ Vector<4, T>(right.at<0>(), up.at<0>(), direction.at<0>(), static_cast<T>(0)),
  2465.         Vector<4, T>(right.at<1>(), up.at<1>(), direction.at<1>(), static_cast<T>(0)),
  2466.         Vector<4, T>(right.at<2>(), up.at<2>(), direction.at<2>(), static_cast<T>(0)),
  2467.         Vector<4, T>(static_cast<T>(0), static_cast<T>(0), static_cast<T>(0), static_cast<T>(1)) });
  2468.     }
  2469.     template<typename T>
  2470.     static auto hash(Vector<2, T> const & p, Vector<3, T> const & seed = Vector<3, T>(static_cast<T>(24.33), static_cast<T>(52.23), static_cast<T>(14721.28)))
  2471.     {
  2472.       return fract(std::sin(dot(p, seed.xy())) * seed.z());
  2473.     }
  2474.     template<typename T>
  2475.     static auto valueNoise(Vector<2, T> const & p, Vector<3, T> const & seed = Vector<3, T>(static_cast<T>(24.33), static_cast<T>(52.23), static_cast<T>(14721.28)))
  2476.     {
  2477.       auto start = floor(p);
  2478.       auto end = start + static_cast<T>(1);
  2479.       auto weights = smoothstep(start, end, p);
  2480.       return lerp(lerp(hash(start, seed), hash(Vector<2, T>(end.x(), start.y()), seed), weights.x()), lerp(hash(Vector<2, T>(start.x(), end.y()), seed), hash(end, seed), weights.x()), weights.y());
  2481.     }
  2482.     template<typename T>
  2483.     static auto hash(T const & p)
  2484.     {
  2485.       return fract(std::sin(p) * static_cast<T>(14721.28));
  2486.     }
  2487.     template<typename T>
  2488.     static auto valueNoise(T const & p)
  2489.     {
  2490.       auto start = std::floor(p);
  2491.       auto end = start + static_cast<T>(1);
  2492.       return lerp(hash(start), hash(end), smoothstep(start, end, p));
  2493.     }
  2494.     template<typename T>
  2495.     static auto fract(T val)
  2496.     {
  2497.       return val - std::floor(val);
  2498.     }
  2499.     template<typename T>
  2500.     static auto elementsPerThread(T const & num_elements, T const & num_threads)
  2501.     {
  2502.       return static_cast<T>(std::ceil(static_cast<float>(num_elements) / static_cast<float>(num_threads)));
  2503.     }
  2504.     template <typename T, unsigned index>
  2505.     struct ComputePow
  2506.     {
  2507.       static auto call(const T& base)
  2508.       {
  2509.         return base * ComputePow<T, index - 1>::call(base);
  2510.       }
  2511.     };
  2512.     template <typename T>
  2513.     struct ComputePow<T, 0>
  2514.     {
  2515.       static auto call(const T& base)
  2516.       {
  2517.         return base;
  2518.       }
  2519.     };
  2520.     template <unsigned exponent, typename T>
  2521.     static auto pow(T const & base)
  2522.     {
  2523.       return exponent ? ComputePow<T, exponent - 1>::call(base) : static_cast<T>(1);
  2524.     }
  2525.     template<unsigned Dim, typename T>
  2526.     static auto transformVector(Matrix<Dim + 1, Dim + 1, T> const & mat, Vector<Dim, T> const & vec)
  2527.     {
  2528.       return transform<Dim, T, 0>(mat, vec);
  2529.     }
  2530.     template<unsigned Dim, typename T>
  2531.     static auto transformPoint(Matrix<Dim + 1, Dim + 1, T> const & mat, Vector<Dim, T> const & point)
  2532.     {
  2533.       return transform<Dim, T, 1>(mat, point);
  2534.     }
  2535.     template<unsigned Dim, typename T, unsigned Hom>
  2536.     static auto transform(Matrix<Dim + 1, Dim + 1, T> const & mat, Vector<Dim, T> const & v)
  2537.     {
  2538.       return (mat * Vector<Dim + 1, T>(v, static_cast<T>(Hom))).reduce<Dim>();
  2539.     }
  2540.     template<unsigned Dim, typename T>
  2541.     static auto transformReduce(Matrix<Dim + 1, Dim + 1, T> const & mat, Vector<Dim, T> const & v)
  2542.     {
  2543.       return Matrix<Dim, Dim, T>(mat) * v;
  2544.     }
  2545.   };
  2546. }
  2547.  
  2548. #endif
  2549.  
  2550. #include <BVHInternalNode.h>
  2551. #include <CullingParams.h>
  2552. #include <BVHNodePool.h>
  2553. #include <StackTrivial.h>
  2554. #include <BVHLeafNode.h>
  2555. #include <CsmInternalNode.h>
  2556. #include <CsmLeafNode.h>
  2557.  
  2558. namespace Log2
  2559. {
  2560.   void BVHInternalNode::init(PrimitiveInfo const * begin, PrimitiveInfo const * const end)
  2561.   {
  2562.     while (begin != end) {
  2563.       insert(*begin++);
  2564.     }
  2565.   }
  2566.   bool BVHInternalNode::contributes(CullingParams const & cp) const
  2567.   {
  2568.     return _bv.contributes(cp.camPos(), cp.thresh(), _maxSquaredSize);
  2569.   }
  2570.   bool BVHInternalNode::fullyContributes(CullingParams const & cp) const
  2571.   {
  2572.     return _bv.fullyContributes(cp.camPos(), cp.thresh(), _minSquaredSize);
  2573.   }
  2574.   IntersectResult BVHInternalNode::intersectFrustum(CullingParams const & cp) const
  2575.   {
  2576.     return IntersectionTests::intersectFrustum(_bv, cp.frustumPlanes());
  2577.   }
  2578.   IntersectResult BVHInternalNode::intersectFrustum(CullingParams const & cp, IntersectedPlanes const & in, IntersectedPlanes& out) const
  2579.   {
  2580.     return IntersectionTests::intersectFrustum(_bv, cp.frustumPlanes(), in, out);
  2581.   }
  2582.   ContribResult BVHInternalNode::computeContribution(CullingParams const & cp) const
  2583.   {
  2584.     return _bv.computeContribution(cp.camPos(), cp.thresh(), _minSquaredSize, _maxSquaredSize);
  2585.   }
  2586.   BVHInternalNode::BVHInternalNode(PrimitiveInfo* const begin, PrimitiveInfo* const end, BVHNodePool& np)
  2587.     : BVHNode(),
  2588.     _bv(begin->bv()),
  2589.     _minSquaredSize(begin->squaredSize()),
  2590.     _maxSquaredSize(begin->squaredSize())
  2591.   {
  2592.     init(begin + 1u, end);
  2593.     auto const axis = _bv.longestAxis();
  2594.     auto const bv_center = _bv.center(axis);
  2595.     auto* const mid = Algorithm::partitionForceSplit(begin, end, [&axis, &bv_center](PrimitiveInfo const & p) {
  2596.       return p.bv().center(axis) < bv_center;
  2597.     });
  2598.     _left = np.createNode(begin, mid);
  2599.     _right = np.createNode(mid, end);
  2600.   }
  2601.   void BVHInternalNode::recurseVisible(CullingParams const & cp, Callback const & cb) const
  2602.   {
  2603.     _left->cullVisiblePrimitives(cp, cb);
  2604.     _right->cullVisiblePrimitives(cp, cb);
  2605.   }
  2606.   void BVHInternalNode::recurseVisible(CullingParams const & cp, IntersectedPlanes const & ip, Callback const & cb) const
  2607.   {
  2608.     _left->cullVisiblePrimitives(cp, ip, cb);
  2609.     _right->cullVisiblePrimitives(cp, ip, cb);
  2610.   }
  2611.   void BVHInternalNode::recurseContributing(CullingParams const & cp, Callback const & cb) const
  2612.   {
  2613.     _left->cullContributingPrimitives(cp, cb);
  2614.     _right->cullContributingPrimitives(cp, cb);
  2615.   }
  2616.   void BVHInternalNode::recurseAll(Callback::CbFunc const & on_render) const
  2617.   {
  2618.     _left->cullAllPrimitives(on_render);
  2619.     _right->cullAllPrimitives(on_render);
  2620.   }
  2621.   void BVHInternalNode::cullVisiblePrimitives(CullingParams const & cp, Callback const & cb) const
  2622.   {
  2623.     if (contributes(cp)) {
  2624.       if (auto const result = intersectFrustum(cp)) {
  2625.         result.intersecting() ? recurseVisible(cp, cb) : recurseContributing(cp, cb);
  2626.       }
  2627.     }
  2628.   }
  2629.   void BVHInternalNode::cullVisiblePrimitives(CullingParams const & cp, IntersectedPlanes const & in, Callback const & cb) const
  2630.   {
  2631.     if (contributes(cp)) {
  2632.       IntersectedPlanes out;
  2633.       if (auto const result = intersectFrustum(cp, in, out)) {
  2634.         result.intersecting() ? recurseVisible(cp, out, cb) : recurseContributing(cp, cb);
  2635.       }
  2636.     }
  2637.   }
  2638.   void BVHInternalNode::cullContributingPrimitives(CullingParams const & cp, Callback const & cb) const
  2639.   {
  2640.     if (auto const result = computeContribution(cp)) {
  2641.       result.intersecting() ? recurseContributing(cp, cb) : recurseAll(cb.onRender());
  2642.     }
  2643.   }
  2644.   void BVHInternalNode::cullAllPrimitives(Callback::CbFunc const & on_render) const
  2645.   {
  2646.     recurseAll(on_render);
  2647.   }
  2648.   size_t BVHInternalNode::sizeInBytes() const
  2649.   {
  2650.     return sizeof *this + _left->sizeInBytes() + _right->sizeInBytes();
  2651.   }
  2652.   void BVHInternalNode::intersectNested(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, std::function<void(Primitive const *)> const & intersect_nested) const
  2653.   {
  2654.     Type t_first;
  2655.     if (_bv.intersects(bv, v, v_inv, t_first) && t_first < min_t_first) {
  2656.       _left->intersectNested(bv, v, v_inv, min_t_first, intersect_nested);
  2657.       _right->intersectNested(bv, v, v_inv, min_t_first, intersect_nested);
  2658.     }
  2659.   }
  2660.   void BVHInternalNode::intersectPrimitives(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, Primitive const *& nearest) const
  2661.   {
  2662.     Type t_first;
  2663.     if (_bv.intersects(bv, v, v_inv, t_first) && t_first < min_t_first) {
  2664.       _left->intersectPrimitives(bv, v, v_inv, min_t_first, nearest);
  2665.       _right->intersectPrimitives(bv, v, v_inv, min_t_first, nearest);
  2666.     }
  2667.   }
  2668.   void BVHInternalNode::countNodes(unsigned& internal_nodes, unsigned& leaf_nodes) const
  2669.   {
  2670.     _left->countNodes(++internal_nodes, leaf_nodes);
  2671.     _right->countNodes(internal_nodes, leaf_nodes);
  2672.   }
  2673.  
  2674.   void BVHInternalNode::recurseNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const
  2675.   {
  2676.     _left->findNearest(ray_local, ray_world, transform, nearest, nearest_t, nearest_transform);
  2677.     _right->findNearest(ray_local, ray_world, transform, nearest, nearest_t, nearest_transform);
  2678.   }
  2679.   void BVHInternalNode::recurseNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res)
  2680.   {
  2681.     _left->findNearestPrecise(ray_local, ray_world, transform, res);
  2682.     _right->findNearestPrecise(ray_local, ray_world, transform, res);
  2683.   }
  2684.  
  2685.   void BVHInternalNode::findNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const
  2686.   {
  2687.     if (IntersectionTests::continueSearch(_bv, ray_local, ray_world, *transform, nearest_t)) {
  2688.       recurseNearest(ray_local, ray_world, transform, nearest, nearest_t, nearest_transform);
  2689.     }
  2690.   }
  2691.   void BVHInternalNode::findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res)
  2692.   {
  2693.     if (IntersectionTests::continueSearch(_bv, ray_local, ray_world, *transform, res)) {
  2694.       recurseNearestPrecise(ray_local, ray_world, transform, res);
  2695.     }
  2696.   }
  2697.   void BVHInternalNode::findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive* parent, IntersectRayResult& res, Primitive*& parent_res)
  2698.   {
  2699.     if (IntersectionTests::continueSearch(_bv, ray_local, ray_world, *transform, res)) {
  2700.       _left->findNearestPrecise(ray_local, ray_world, transform, parent, res, parent_res);
  2701.       _right->findNearestPrecise(ray_local, ray_world, transform, parent, res, parent_res);
  2702.     }
  2703.   }
  2704.   void BVHInternalNode::findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res, StackTrivial<NodePtr>& stack)
  2705.   {
  2706.     if (IntersectionTests::continueSearch(_bv, ray_local, ray_world, *transform, res)) {
  2707.       stack.push_back(_right);
  2708.       stack.push_back(_left);
  2709.     }
  2710.   }
  2711.   void BVHInternalNode::findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested)
  2712.   {
  2713.     if (IntersectionTests::continueSearch(_bv, ray, res)) {
  2714.       NodePtr nodes[2] = { _left, _right };
  2715.       if (_right->dist(ray) < _left->dist(ray)) {
  2716.         Algorithm::swap(*nodes, *(nodes + 1u));
  2717.       }
  2718.       (*nodes)->findNearestNested(ray, res, find_nested);
  2719.       (*(nodes + 1u))->findNearestNested(ray, res, find_nested);
  2720.     }
  2721.   }
  2722.   void BVHInternalNode::findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested, StackTrivial<NodePtr>& stack)
  2723.   {
  2724.     if (IntersectionTests::continueSearch(_bv, ray, res)) {
  2725.       stack.push_back(_right);
  2726.       stack.push_back(_left);
  2727.       if (_right->dist(ray) < _left->dist(ray)) {
  2728.         Algorithm::swap(stack.back(), *(&stack.back() - 1u));
  2729.       }
  2730.     }
  2731.   }
  2732.   bool BVHInternalNode::largerThan(BVHInternalNode const & other) const
  2733.   {
  2734.     return _bv.largerThan(other._bv);
  2735.   }
  2736.   void BVHInternalNode::recurseQueryRange(BV const & bv, Callback::CbFunc const & cb) const
  2737.   {
  2738.     _left->queryRange(bv, cb);
  2739.     _right->queryRange(bv, cb);
  2740.   }
  2741.   void BVHInternalNode::recurseQueryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const
  2742.   {
  2743.     _left->queryRange(bv, cp, cb);
  2744.     _right->queryRange(bv, cp, cb);
  2745.   }
  2746.   void BVHInternalNode::recurseQueryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const
  2747.   {
  2748.     _left->queryContributing(cp, cb);
  2749.     _right->queryContributing(cp, cb);
  2750.   }
  2751.   void BVHInternalNode::recurseQueryAll(Callback::CbFunc const & cb) const
  2752.   {
  2753.     _left->queryAll(cb);
  2754.     _right->queryAll(cb);
  2755.   }
  2756.   void BVHInternalNode::queryRange(BV const & bv, Callback::CbFunc const & cb) const
  2757.   {
  2758.     if (bv.contains(_bv)) {
  2759.       recurseQueryAll(cb);
  2760.     }
  2761.     else if (bv.intersects(_bv)) {
  2762.       recurseQueryRange(bv, cb);
  2763.     }
  2764.   }
  2765.   void BVHInternalNode::queryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const
  2766.   {
  2767.     if (contributes(cp)) {
  2768.       if (bv.contains(_bv)) {
  2769.         recurseQueryContributing(cp, cb);
  2770.       }
  2771.       else if (bv.intersects(_bv)) {
  2772.         recurseQueryRange(bv, cp, cb);
  2773.       }
  2774.     }
  2775.   }
  2776.   void BVHInternalNode::queryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const
  2777.   {
  2778.     if (auto const result = computeContribution(cp)) {
  2779.       result.intersecting() ? recurseQueryContributing(cp, cb) : recurseQueryAll(cb);
  2780.     }
  2781.   }
  2782.   void BVHInternalNode::queryAll(Callback::CbFunc const & cb) const
  2783.   {
  2784.     recurseQueryAll(cb);
  2785.   }
  2786.   BVHInternalNode::BV BVHInternalNode::getBV() const
  2787.   {
  2788.     return _bv;
  2789.   }
  2790.   BVHInternalNode::Type BVHInternalNode::minSquaredDist(Vector const & point) const
  2791.   {
  2792.     return _bv.minSquaredDist(point);
  2793.   }
  2794.   BVHInternalNode::Type BVHInternalNode::dist(Ray const & ray) const
  2795.   {
  2796.     return minSquaredDist(ray.origin());
  2797.   }
  2798.   void BVHInternalNode::destroy(BVHNodePool& pool)
  2799.   {
  2800.     pool.destroy(this);
  2801.   }
  2802.   BVHInternalNode::Type BVHInternalNode::cost(BV const & bv) const
  2803.   {
  2804.     return _bv.cost(bv);
  2805.   }
  2806.   void BVHInternalNode::insert(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool)
  2807.   {
  2808.     insert(info);
  2809.     auto& child = childToDescend(info.bv());
  2810.     child->insert(info, child, node_pool);
  2811.   }
  2812.   bool BVHInternalNode::remove(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted)
  2813.   {
  2814.     bool dirty = false;
  2815.     if (_bv.intersects(info.bv())) {
  2816.       bool deleted_left = false;
  2817.       dirty = dirty || _left->remove(info, _left, node_pool, deleted_left);
  2818.       bool deleted_right = false;
  2819.       dirty = dirty || _right->remove(info, _right, node_pool, deleted_right);
  2820.       if (deleted_left) {
  2821.         rebuild(this_ptr, _right, node_pool);
  2822.       }
  2823.       else if (deleted_right) {
  2824.         rebuild(this_ptr, _left, node_pool);
  2825.       }
  2826.     }
  2827.     if (dirty) {
  2828.       markAsDirty();
  2829.     }
  2830.     return dirty;
  2831.   }
  2832.   bool BVHInternalNode::removeIfDoesNotFit(PrimitiveInfo const & info, BV const & bv_old, BVHNode const * parent, BVHNode const * root, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted)
  2833.   {
  2834.     bool dirty = false;
  2835.     if (_bv.intersects(bv_old)) {
  2836.       bool deleted_left = false;
  2837.       dirty = dirty || _left->removeIfDoesNotFit(info, bv_old, this, root, _left, node_pool, deleted_left);
  2838.       bool deleted_right = false;
  2839.       dirty = dirty || _right->removeIfDoesNotFit(info, bv_old, this, root, _right, node_pool, deleted_right);
  2840.       if (deleted_left) {
  2841.         rebuild(this_ptr, _right, node_pool);
  2842.       }
  2843.       else if (deleted_right) {
  2844.         rebuild(this_ptr, _left, node_pool);
  2845.       }
  2846.     }
  2847.     if (dirty) {
  2848.       markAsDirty();
  2849.     }
  2850.     return dirty;
  2851.   }
  2852.   void BVHInternalNode::destroyTree(StackTrivial<PrimitiveInfo>& primitives, BVHNodePool& node_pool)
  2853.   {
  2854.     _left->destroyTree(primitives, node_pool);
  2855.     _right->destroyTree(primitives, node_pool);
  2856.     destroy(node_pool);
  2857.   }
  2858.   BVHInternalNode::DirtyInfo BVHInternalNode::recalculateDirty()
  2859.   {
  2860.     if (isDirty()) {
  2861.       collectFromChildren(_left->recalculateDirty());
  2862.       collectFromChildren(_right->recalculateDirty());
  2863.     }
  2864.     return { _bv, _minSquaredSize, _maxSquaredSize };
  2865.   }
  2866.   size_t BVHInternalNode::minHeight(size_t const & height) const
  2867.   {
  2868.     return std::min(_left->minHeight(height + 1u), _right->minHeight(height + 1u));
  2869.   }
  2870.   size_t BVHInternalNode::maxHeight(size_t const & height) const
  2871.   {
  2872.     return std::max(_left->maxHeight(height + 1u), _right->maxHeight(height + 1u));
  2873.   }
  2874.   void BVHInternalNode::averageHeight(float const & height, float const & inv_num_leafs, float& avg_height) const
  2875.   {
  2876.     _left->averageHeight(height + 1.f, inv_num_leafs, avg_height);
  2877.     _right->averageHeight(height + 1.f, inv_num_leafs, avg_height);
  2878.   }
  2879.   void BVHInternalNode::insert(BVHInternalNode::PrimitiveInfo const & pi)
  2880.   {
  2881.     _bv.unify(pi.bv());
  2882.     Algorithm::minimize(pi.squaredSize(), _minSquaredSize);
  2883.     Algorithm::maximize(pi.squaredSize(), _maxSquaredSize);
  2884.   }
  2885.   BVHInternalNode::NodePtr& BVHInternalNode::childToDescend(BV const & bv)
  2886.   {
  2887.     return _left->cost(bv) < _right->cost(bv) ? _left : _right;
  2888.   }
  2889.   void BVHInternalNode::markAsDirty()
  2890.   {
  2891.     _bv = BV();
  2892.     _minSquaredSize = std::numeric_limits<Type>::max();
  2893.     _maxSquaredSize = std::numeric_limits<Type>::lowest();
  2894.   }
  2895.   bool BVHInternalNode::isDirty() const
  2896.   {
  2897.     return _maxSquaredSize == std::numeric_limits<Type>::lowest();
  2898.   }
  2899.   void BVHInternalNode::rebuild(NodePtr& this_ptr, NodePtr child, BVHNodePool& node_pool)
  2900.   {
  2901.     StackTrivial<PrimitiveInfo> infos;
  2902.     child->destroyTree(infos, node_pool);
  2903.     this_ptr = node_pool.createNode(infos);
  2904.     destroy(node_pool);
  2905.   }
  2906.   void BVHInternalNode::collectFromChildren(DirtyInfo const & di)
  2907.   {
  2908.     _bv.unify(di.bv());
  2909.     Algorithm::minimize(di.minSquaredSize(), _minSquaredSize);
  2910.     Algorithm::maximize(di.maxSquaredSize(), _maxSquaredSize);
  2911.   }
  2912.   void BVHInternalNode::descendVisible(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  2913.   {
  2914.     other.descendVisible(*this, cp, cb);
  2915.   }
  2916.   void BVHInternalNode::descendVisible(CsmInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  2917.   {
  2918.     if (contributes(cp)) {
  2919.       if (auto const result = IntersectionTests::intersectFrustum(_bv, other.frustumPlanes())) {
  2920.         if (result.intersecting()) {
  2921.           _bv.largerThan(other.bvRender()) ? recurseVisible(other, cp, cb) : other.recurseVisible(*this, cp, cb);
  2922.         }
  2923.         else {
  2924.           _bv.largerThan(other.bvRender()) ? recurseContributing(other, cp, cb) : other.recurseContributing(*this, cp, cb);
  2925.         }
  2926.       }
  2927.     }
  2928.   }
  2929.   void BVHInternalNode::descendVisible(CsmLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  2930.   {
  2931.     if (contributes(cp)) {
  2932.       if (auto const result = IntersectionTests::intersectFrustum(_bv, other.split().frustumPlanes())) {
  2933.         result.intersecting() ? recurseVisible(other, cp, cb) : recurseContributing(other, cp, cb);
  2934.       }
  2935.     }
  2936.   }
  2937.   void BVHInternalNode::descendContributing(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  2938.   {
  2939.     other.descendContributing(*this, cp, cb);
  2940.   }
  2941.   void BVHInternalNode::descendContributing(CsmInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  2942.   {
  2943.     if (auto const result = computeContribution(cp)) {
  2944.       if (result.intersecting()) {
  2945.         _bv.largerThan(other.bvRender()) ? recurseContributing(other, cp, cb) : other.recurseContributing(*this, cp, cb);
  2946.       }
  2947.       else {
  2948.         descendAll(other, cb.onRender());
  2949.       }
  2950.     }
  2951.   }
  2952.   void BVHInternalNode::descendContributing(CsmLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  2953.   {
  2954.     if (auto const result = computeContribution(cp)) {
  2955.       result.intersecting() ? recurseContributing(other, cp, cb) : descendAll(other, cb.onRender());
  2956.     }
  2957.   }
  2958.   void BVHInternalNode::descendAll(Descendable & other, Callback2::CbFunc const & on_render)
  2959.   {
  2960.     other.descendAll(*this, on_render);
  2961.   }
  2962.   void BVHInternalNode::descendAll(CsmInternalNode & other, Callback2::CbFunc const & on_render)
  2963.   {
  2964.     recurseAll(other, on_render);
  2965.   }
  2966.   void BVHInternalNode::descendAll(CsmLeafNode & other, Callback2::CbFunc const & on_render)
  2967.   {
  2968.     recurseAll(other, on_render);
  2969.   }
  2970.   void BVHInternalNode::recurseVisible(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  2971.   {
  2972.     _left->descendVisible(other, cp, cb);
  2973.     _right->descendVisible(other, cp, cb);
  2974.   }
  2975.   void BVHInternalNode::recurseContributing(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  2976.   {
  2977.     _left->descendContributing(other, cp, cb);
  2978.     _right->descendContributing(other, cp, cb);
  2979.   }
  2980.   void BVHInternalNode::recurseAll(Descendable & other, Callback2::CbFunc const & on_render)
  2981.   {
  2982.     _left->descendAll(other, on_render);
  2983.     _right->descendAll(other, on_render);
  2984.   }
  2985. }
  2986.  
  2987. #include <BVHLeafNode.h>
  2988. #include <BVHInternalNode.h>
  2989. #include <BVHNodePool.h>
  2990. #include <StackTrivial.h>
  2991. #include <CullingParams.h>
  2992. #include <CsmInternalNode.h>
  2993. #include <CsmLeafNode.h>
  2994.  
  2995. namespace Log2
  2996. {
  2997.   BVHLeafNode::BVHLeafNode(Primitive* const & primitive)
  2998.     : BVHNode(),
  2999.     _primitive(primitive)
  3000.   {
  3001.   }
  3002.   void BVHLeafNode::cullVisiblePrimitives(CullingParams const & cp, Callback const & cb) const
  3003.   {
  3004.     cb.onIntersectFrustum()(_primitive);
  3005.   }
  3006.   void BVHLeafNode::cullVisiblePrimitives(CullingParams const & cp, IntersectedPlanes const & in, Callback const & cb) const
  3007.   {
  3008.     cb.onIntersectFrustum()(_primitive);
  3009.   }
  3010.   void BVHLeafNode::cullContributingPrimitives(CullingParams const & cp, Callback const & cb) const
  3011.   {
  3012.     cb.onBecameFullyVisible()(_primitive);
  3013.   }
  3014.   void BVHLeafNode::cullAllPrimitives(Callback::CbFunc const & on_render) const
  3015.   {
  3016.     on_render(_primitive);
  3017.   }
  3018.   size_t BVHLeafNode::sizeInBytes() const
  3019.   {
  3020.     return sizeof *this;
  3021.   }
  3022.   void BVHLeafNode::intersectNested(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, std::function<void(Primitive const *)> const & intersect_nested) const
  3023.   {
  3024.     Type t_first;
  3025.     if (getBV().intersects(bv, v, v_inv, t_first) && t_first < min_t_first) {
  3026.       intersect_nested(_primitive);
  3027.     }
  3028.   }
  3029.   void BVHLeafNode::intersectPrimitives(BV const & bv, Vector const & v, Vector const & v_inv, Type& min_t_first, Primitive const *& nearest) const
  3030.   {
  3031.     Type t_first;
  3032.     if (getBV().intersects(bv, v, v_inv, t_first) && t_first < min_t_first) {
  3033.       min_t_first = t_first;
  3034.       nearest = _primitive;
  3035.     }
  3036.   }
  3037.   void BVHLeafNode::countNodes(unsigned& internal_nodes, unsigned& leaf_nodes) const
  3038.   {
  3039.     ++leaf_nodes;
  3040.   }
  3041.   void BVHLeafNode::findNearest(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive const *& nearest, Type& nearest_t, Matrix const *& nearest_transform) const
  3042.   {
  3043.     if (auto const result = IntersectionTests::intersectRay(getBV(), ray_local)) {
  3044.       auto const t_world = distance(ray_world.origin(), MathHelpers::transformPoint(*transform, ray_local.pos(result.t())));
  3045.       if (t_world < nearest_t) {
  3046.         nearest = _primitive;
  3047.         nearest_t = t_world;
  3048.         nearest_transform = transform;
  3049.       }
  3050.     }
  3051.   }
  3052.   void BVHLeafNode::findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res)
  3053.   {
  3054.     if (IntersectionTests::continueSearch(getBV(), ray_local, ray_world, *transform, res)) {
  3055.       if (auto const result = _primitive->intersectRay(ray_local, ray_world, *transform)) {
  3056.         if (result.t() < res.nearestT()) {
  3057.           res.update(result, transform, _primitive);
  3058.         }
  3059.       }
  3060.     }
  3061.   }
  3062.   void BVHLeafNode::findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, Primitive* parent, IntersectRayResult& res, Primitive*& parent_res)
  3063.   {
  3064.     if (IntersectionTests::continueSearch(getBV(), ray_local, ray_world, *transform, res)) {
  3065.       if (auto const result = _primitive->intersectRay(ray_local, ray_world, *transform)) {
  3066.         if (result.t() < res.nearestT()) {
  3067.           res.update(result, transform, _primitive);
  3068.           parent_res = parent;
  3069.         }
  3070.       }
  3071.     }
  3072.   }
  3073.   void BVHLeafNode::findNearestPrecise(Ray const & ray_local, Ray const & ray_world, Matrix const * transform, IntersectRayResult& res, StackTrivial<NodePtr>& stack)
  3074.   {
  3075.     findNearestPrecise(ray_local, ray_world, transform, res);
  3076.   }
  3077.   void BVHLeafNode::findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested)
  3078.   {
  3079.     find_nested(_primitive);
  3080.   }
  3081.   void BVHLeafNode::findNearestNested(Ray const & ray, IntersectRayResult& res, std::function<void(Primitive*)> const & find_nested, StackTrivial<NodePtr>& stack)
  3082.   {
  3083.     findNearestNested(ray, res, find_nested);
  3084.   }
  3085.   void BVHLeafNode::queryRange(BV const & bv, Callback::CbFunc const & cb) const
  3086.   {
  3087.     if (bv.intersects(getBV())) {
  3088.       cb(_primitive);
  3089.     }
  3090.   }
  3091.   void BVHLeafNode::queryRange(BV const & bv, CullingParams const & cp, Callback::CbFunc const & cb) const
  3092.   {
  3093.     if (contributes(cp) && bv.intersects(getBV())) {
  3094.       cb(_primitive);
  3095.     }
  3096.   }
  3097.   void BVHLeafNode::queryContributing(CullingParams const & cp, Callback::CbFunc const & cb) const
  3098.   {
  3099.     if (contributes(cp)) {
  3100.       cb(_primitive);
  3101.     }
  3102.   }
  3103.   void BVHLeafNode::queryAll(Callback::CbFunc const & cb) const
  3104.   {
  3105.     cb(_primitive);
  3106.   }
  3107.   BVHLeafNode::BV BVHLeafNode::getBV() const
  3108.   {
  3109.     return _primitive->bv();
  3110.   }
  3111.   BVHLeafNode::Type BVHLeafNode::minSquaredDist(Vector const & point) const
  3112.   {
  3113.     return getBV().minSquaredDist(point);
  3114.   }
  3115.   BVHLeafNode::Type BVHLeafNode::dist(Ray const & ray) const
  3116.   {
  3117.     return minSquaredDist(ray.origin());
  3118.   }
  3119.   void BVHLeafNode::destroy(BVHNodePool& pool)
  3120.   {
  3121.     pool.destroy(this);
  3122.   }
  3123.   BVHLeafNode::Type BVHLeafNode::cost(BV const & bv) const
  3124.   {
  3125.     return getBV().cost(bv);
  3126.   }
  3127.   void BVHLeafNode::insert(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool)
  3128.   {
  3129.     PrimitiveInfo infos[2] = { info, _primitive };
  3130.     this_ptr = node_pool.createNode(infos, infos + 2);
  3131.     destroy(node_pool);
  3132.   }
  3133.   bool BVHLeafNode::remove(PrimitiveInfo const & info, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted)
  3134.   {
  3135.     deleted = info.primitive() == _primitive;
  3136.     if (deleted) {
  3137.       destroy(node_pool);
  3138.     }
  3139.     return deleted;
  3140.   }
  3141.   bool BVHLeafNode::removeIfDoesNotFit(PrimitiveInfo const & info, BV const & bv_old, BVHNode const * parent, BVHNode const * root, NodePtr& this_ptr, BVHNodePool& node_pool, bool& deleted)
  3142.   {
  3143.     deleted = this != root && info.primitive() == _primitive && !parent->getBV().contains(info.bv());
  3144.     if (deleted) {
  3145.       destroy(node_pool);
  3146.     }
  3147.     return deleted;
  3148.   }
  3149.   void BVHLeafNode::destroyTree(StackTrivial<PrimitiveInfo>& primitives, BVHNodePool& node_pool)
  3150.   {
  3151.     primitives.push_back(_primitive);
  3152.     destroy(node_pool);
  3153.   }
  3154.   BVHLeafNode::DirtyInfo BVHLeafNode::recalculateDirty()
  3155.   {
  3156.     return { _primitive->bv(), _primitive->squaredSize(), _primitive->squaredSize() };
  3157.   }
  3158.   size_t BVHLeafNode::minHeight(size_t const & height) const
  3159.   {
  3160.     return height;
  3161.   }
  3162.   size_t BVHLeafNode::maxHeight(size_t const & height) const
  3163.   {
  3164.     return height;
  3165.   }
  3166.   void BVHLeafNode::averageHeight(float const & height, float const & inv_num_leafs, float& avg_height) const
  3167.   {
  3168.     avg_height += height * inv_num_leafs;
  3169.   }
  3170.   void BVHLeafNode::descendVisible(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3171.   {
  3172.     other.descendVisible(*this, cp, cb);
  3173.   }
  3174.   void BVHLeafNode::descendVisible(CsmInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  3175.   {
  3176.     if (contributes(cp)) {
  3177.       if (auto const result = IntersectionTests::intersectFrustum(getBV(), other.frustumPlanes())) {
  3178.         result.intersecting() ? other.recurseVisible(*this, cp, cb) : other.recurseContributing(*this, cp, cb);
  3179.       }
  3180.     }
  3181.   }
  3182.   void BVHLeafNode::descendVisible(CsmLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  3183.   {
  3184.     cb.onIntersectFrustum()(_primitive, other.split().renderlist());
  3185.   }
  3186.   void BVHLeafNode::descendContributing(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3187.   {
  3188.     other.descendContributing(*this, cp, cb);
  3189.   }
  3190.   void BVHLeafNode::descendContributing(CsmInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  3191.   {
  3192.     if (contributes(cp)) {
  3193.       other.recurseContributing(*this, cp, cb);
  3194.     }
  3195.   }
  3196.   void BVHLeafNode::descendContributing(CsmLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  3197.   {
  3198.     cb.onBecameFullyVisible()(_primitive, other.split().renderlist());
  3199.   }
  3200.   void BVHLeafNode::descendAll(Descendable & other, Callback2::CbFunc const & on_render)
  3201.   {
  3202.     other.descendAll(*this, on_render);
  3203.   }
  3204.   void BVHLeafNode::descendAll(CsmInternalNode & other, Callback2::CbFunc const & on_render)
  3205.   {
  3206.     other.recurseAll(*this, on_render);
  3207.   }
  3208.   void BVHLeafNode::descendAll(CsmLeafNode & other, Callback2::CbFunc const & on_render)
  3209.   {
  3210.     on_render(_primitive, other.split().renderlist());
  3211.   }
  3212.   bool BVHLeafNode::contributes(CullingParams const & cp) const
  3213.   {
  3214.     return getBV().contributes(cp.camPos(), cp.thresh());
  3215.   }
  3216.   IntersectResult BVHLeafNode::intersectFrustum(CullingParams const & cp) const
  3217.   {
  3218.     return IntersectionTests::intersectFrustum(getBV(), cp.frustumPlanes());
  3219.   }
  3220. }
  3221.  
  3222. #include <CsmInternalNode.h>
  3223. #include <CsmNodePool.h>
  3224. #include <CsmSplit.h>
  3225. #include <CsmNode.h>
  3226. #include <BVHInternalNode.h>
  3227. #include <BVHLeafNode.h>
  3228. #include <CsmTree.h>
  3229.  
  3230. namespace Log2
  3231. {
  3232.   CsmInternalNode::CsmInternalNode(CsmSplit * const begin, CsmSplit * const end, CsmTree & np, Matrix<4, 4, Type> const & view_matrix_light) :
  3233.     _bvCull(begin->bvCull()),
  3234.     _bvRender(begin->bvRender())
  3235.   {
  3236.     for (auto const * ptr = begin + 1u; ptr != end; ) {
  3237.       _bvCull.unify(ptr->bvCull());
  3238.       _bvRender.unify(ptr->bvRender());
  3239.       ++ptr;
  3240.     }
  3241.     _fp = FrustumPlanes<3, Type>::create(MathHelpers::projectionMatrixOrtho(_bvCull) * view_matrix_light);
  3242.     auto axis = _bvRender.longestAxis();
  3243.     auto center = _bvRender.center(axis);
  3244.     auto* const mid = Algorithm::partitionForceSplit(begin, end, [&axis, &center](CsmSplit const & split) {
  3245.       return split.bvRender().center(axis) < center;
  3246.     });
  3247.     _left = np.createNode(begin, mid, view_matrix_light);
  3248.     _right = np.createNode(mid, end, view_matrix_light);
  3249.   }
  3250.   CsmInternalNode::~CsmInternalNode()
  3251.   {
  3252.     delete _left;
  3253.     delete _right;
  3254.   }
  3255.   FrustumPlanes<3, CsmInternalNode::Type> const & CsmInternalNode::frustumPlanes() const
  3256.   {
  3257.     return _fp;
  3258.   }
  3259.   void CsmInternalNode::recurseVisible(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3260.   {
  3261.     _left->descendVisible(other, cp, cb);
  3262.     _right->descendVisible(other, cp, cb);
  3263.   }
  3264.   void CsmInternalNode::recurseContributing(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3265.   {
  3266.     _left->descendContributing(other, cp, cb);
  3267.     _right->descendContributing(other, cp, cb);
  3268.   }
  3269.   void CsmInternalNode::recurseAll(Descendable & other, Callback2::CbFunc const & on_render)
  3270.   {
  3271.     _left->descendAll(other, on_render);
  3272.     _right->descendAll(other, on_render);
  3273.   }
  3274.   CsmInternalNode::BV const & CsmInternalNode::bvRender() const
  3275.   {
  3276.     return _bvRender;
  3277.   }
  3278.   CsmInternalNode::BV const & CsmInternalNode::bvCull() const
  3279.   {
  3280.     return _bvCull;
  3281.   }
  3282.   void CsmInternalNode::descendVisible(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3283.   {
  3284.     other.descendVisible(*this, cp, cb);
  3285.   }
  3286.   void CsmInternalNode::descendVisible(BVHInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  3287.   {
  3288.     other.descendVisible(*this, cp, cb);
  3289.   }
  3290.   void CsmInternalNode::descendVisible(BVHLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  3291.   {
  3292.     other.descendVisible(*this, cp, cb);
  3293.   }
  3294.   void CsmInternalNode::descendContributing(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3295.   {
  3296.     other.descendContributing(*this, cp, cb);
  3297.   }
  3298.   void CsmInternalNode::descendContributing(BVHInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  3299.   {
  3300.     other.descendContributing(*this, cp, cb);
  3301.   }
  3302.   void CsmInternalNode::descendContributing(BVHLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  3303.   {
  3304.     other.descendContributing(*this, cp, cb);
  3305.   }
  3306.   void CsmInternalNode::descendAll(Descendable & other, Callback2::CbFunc const & on_render)
  3307.   {
  3308.     other.descendAll(*this, on_render);
  3309.   }
  3310.   void CsmInternalNode::descendAll(BVHInternalNode & other, Callback2::CbFunc const & on_render)
  3311.   {
  3312.     other.descendAll(*this, on_render);
  3313.   }
  3314.   void CsmInternalNode::descendAll(BVHLeafNode & other, Callback2::CbFunc const & on_render)
  3315.   {
  3316.     other.descendAll(*this, on_render);
  3317.   }
  3318. }
  3319.  
  3320. #include <CsmLeafNode.h>
  3321. #include <BVHInternalNode.h>
  3322. #include <BVHLeafNode.h>
  3323.  
  3324. namespace Log2
  3325. {
  3326.   CsmLeafNode::CsmLeafNode(CsmSplit * split) :
  3327.     _split(split)
  3328.   {
  3329.   }
  3330.   void CsmLeafNode::descendVisible(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3331.   {
  3332.     other.descendVisible(*this, cp, cb);
  3333.   }
  3334.   void CsmLeafNode::descendVisible(BVHInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  3335.   {
  3336.     other.descendVisible(*this, cp, cb);
  3337.   }
  3338.   void CsmLeafNode::descendVisible(BVHLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  3339.   {
  3340.     other.descendVisible(*this, cp, cb);
  3341.   }
  3342.   void CsmLeafNode::descendContributing(Descendable & other, CullingParams const & cp, Callback2 const & cb)
  3343.   {
  3344.     other.descendContributing(*this, cp, cb);
  3345.   }
  3346.   void CsmLeafNode::descendContributing(BVHInternalNode & other, CullingParams const & cp, Callback2 const & cb)
  3347.   {
  3348.     other.descendContributing(*this, cp, cb);
  3349.   }
  3350.   void CsmLeafNode::descendContributing(BVHLeafNode & other, CullingParams const & cp, Callback2 const & cb)
  3351.   {
  3352.     other.descendContributing(*this, cp, cb);
  3353.   }
  3354.   void CsmLeafNode::descendAll(Descendable & other, Callback2::CbFunc const & on_render)
  3355.   {
  3356.     other.descendAll(*this, on_render);
  3357.   }
  3358.   void CsmLeafNode::descendAll(BVHInternalNode & other, Callback2::CbFunc const & on_render)
  3359.   {
  3360.     other.descendAll(*this, on_render);
  3361.   }
  3362.   void CsmLeafNode::descendAll(BVHLeafNode & other, Callback2::CbFunc const & on_render)
  3363.   {
  3364.     other.descendAll(*this, on_render);
  3365.   }
  3366.   CsmSplit& CsmLeafNode::split()
  3367.   {
  3368.     return *_split;
  3369.   }
  3370. }
  3371.  
  3372. #include <CsmSplit.h>
  3373.  
  3374. namespace Log2
  3375. {
  3376.   CsmSplit::CsmSplit(BV const & bv_light_cull, BV const & bv_light_render, Matrix<4, 4, Type> const & view_matrix_light, Matrix<4, 4, Type>* vp) :
  3377.     _bvLightCull(bv_light_cull),
  3378.     _bvLightRender(bv_light_render),
  3379.     _vp(vp)
  3380.   {
  3381.     init(view_matrix_light);
  3382.   }
  3383.   CsmSplit::BV const & CsmSplit::bvCull() const
  3384.   {
  3385.     return _bvLightCull;
  3386.   }
  3387.   CsmSplit::BV const & CsmSplit::bvRender() const
  3388.   {
  3389.     return _bvLightRender;
  3390.   }
  3391.   Matrix<4, 4, CsmSplit::Type> const & CsmSplit::vp() const
  3392.   {
  3393.     return *_vp;
  3394.   }
  3395.   FrustumPlanes<3, CsmSplit::Type> const & CsmSplit::frustumPlanes() const
  3396.   {
  3397.     return _fp;
  3398.   }
  3399.   RenderList & CsmSplit::renderlist()
  3400.   {
  3401.     return _rl;
  3402.   }
  3403.   void CsmSplit::set(BV const & bv_light_cull, BV const & bv_light_render, Matrix<4, 4, Type> const & view_matrix_light, Matrix<4, 4, Type>* vp)
  3404.   {
  3405.     _bvLightCull = bv_light_cull;
  3406.     _bvLightRender = bv_light_render;
  3407.     _vp = vp;
  3408.     init(view_matrix_light);
  3409.   }
  3410.   void CsmSplit::init(Matrix<4, 4, Type> const & view_matrix_light)
  3411.   {
  3412.     *_vp = MathHelpers::projectionMatrixOrtho(_bvLightCull) * view_matrix_light;
  3413.     _fp = FrustumPlanes<3, Type>::create(*_vp);
  3414.   }
  3415. }
  3416.  
  3417. #include <CsmTree.h>
  3418. #include <BoundingVolumeHierarchy.h>
  3419. #include <CsmInternalNode.h>
  3420. #include <CsmLeafNode.h>
  3421.  
  3422. namespace Log2
  3423. {
  3424.   CsmTree::CsmTree(CsmSplit * begin, CsmSplit * end, Matrix<4, 4, Type> const & view_matrix_light)
  3425.   {
  3426.     _root = createNode(begin, end, view_matrix_light);
  3427.   }
  3428.   CsmTree::~CsmTree()
  3429.   {
  3430.     delete _root;
  3431.   }
  3432.   CsmNode * CsmTree::root()
  3433.   {
  3434.     return _root;
  3435.   }
  3436.   void CsmTree::descendVisible(BoundingVolumeHierarchy& bvh, CullingParams const & cp, Callback2 const & cb)
  3437.   {
  3438.     _root->descendVisible(*bvh.root(), cp, cb);
  3439.   }
  3440.   CsmNode * CsmTree::createNode(CsmSplit * begin, CsmSplit * end, Matrix<4, 4, Type> const & view_matrix_light)
  3441.   {
  3442.     return Algorithm::continueSplit(begin, end) ? createInternalNode(begin, end, view_matrix_light) : createLeafNode(begin);
  3443.   }
  3444.   CsmNode * CsmTree::createInternalNode(CsmSplit * begin, CsmSplit * end, Matrix<4, 4, Type> const & view_matrix_light)
  3445.   {
  3446.     return new CsmInternalNode(begin, end, *this, view_matrix_light);
  3447.   }
  3448.   CsmNode * CsmTree::createLeafNode(CsmSplit * cs)
  3449.   {
  3450.     return new CsmLeafNode(cs);
  3451.   }
  3452. }
  3453.  
  3454. #include <FixedTimestepSystem.h>
  3455. #include <GameTimer.h>
  3456. #include <iostream>
  3457.  
  3458. namespace Log2
  3459. {
  3460.   bool FixedTimestepSystem::update()
  3461.   {
  3462.     _acc += _gameTimer->getDeltaTimeSeconds();
  3463.     bool did_update = false;
  3464.     while (_acc >= _dt) {
  3465.       updateSystem();
  3466.       _acc -= _dt;
  3467.       did_update = true;
  3468.     }
  3469.     return did_update;
  3470.   }
  3471. }
  3472.  
  3473. #define GLM_ENABLE_EXPERIMENTAL
  3474. #include "Mesh.h"
  3475. #include <fstream>
  3476. #include <sstream>
  3477. #include <iostream>
  3478. #include <glm/gtx/string_cast.hpp>
  3479. #include <AABB.h>
  3480. #include <math/Log2Math.h>
  3481.  
  3482. namespace Log2
  3483. {
  3484.   Mesh::Mesh(StackTrivial<Vertex>&& vertices, StackTrivial<unsigned int>&& indices, std::shared_ptr<Material> const * materials, unsigned int material_index) :
  3485.     _vertices(std::move(vertices)),
  3486.     _indices(std::move(indices)),
  3487.     _material(*(materials + material_index)),
  3488.     _materialIndex(material_index)
  3489.   {
  3490.     init();
  3491.   }
  3492.   StackTrivial<Vertex> const & Mesh::vertices() const
  3493.   {
  3494.     return _vertices;
  3495.   }
  3496.   StackTrivial<unsigned int> const & Mesh::indices() const
  3497.   {
  3498.     return _indices;
  3499.   }
  3500.   void Mesh::setVertices(StackTrivial<Vertex>&& vertices)
  3501.   {
  3502.     _vertices = std::move(vertices);
  3503.     init();
  3504.   }
  3505.   void Mesh::setIndices(StackTrivial<unsigned>&& indices)
  3506.   {
  3507.     _indices = std::move(indices);
  3508.     init();
  3509.   }
  3510.   unsigned const & Mesh::materialIndex() const
  3511.   {
  3512.     return _materialIndex;
  3513.   }
  3514.   AABB3f const & Mesh::aabb() const
  3515.   {
  3516.     return _aabb;
  3517.   }
  3518.   Sphere3f const & Mesh::sphere() const
  3519.   {
  3520.     return _sphere;
  3521.   }
  3522.   void Mesh::setMaterialIndex(unsigned const & material_index)
  3523.   {
  3524.     _materialIndex = material_index;
  3525.   }
  3526.   void Mesh::setMaterial(std::shared_ptr<Material> const & material)
  3527.   {
  3528.     _material = material;
  3529.   }
  3530.   std::shared_ptr<Material> const & Mesh::material() const
  3531.   {
  3532.     return _material;
  3533.   }
  3534.   BoundingVolumeHierarchy * Mesh::bvh()
  3535.   {
  3536.     return _bvh.get();
  3537.   }
  3538.  
  3539.   void Mesh::triangles(Vertex * vertices, boost::object_pool<Triangle>& tri_pool, StackTrivial<Primitive*>& triangles) const
  3540.   {
  3541.     triangles.reserveToFit(_indices.size() / 3u);
  3542.     auto const * begin = _indices.begin();
  3543.     auto const * end = _indices.end();
  3544.     while (begin != end) {
  3545.       triangles.push_back_unchecked(new (tri_pool.malloc()) Triangle(Vec3u(*begin, *(begin + 1), *(begin + 2)), vertices));
  3546.       begin += 3;
  3547.     }
  3548.   }
  3549.  
  3550.   std::shared_ptr<BoundingVolumeHierarchy> Mesh::getTransformedBVH(Matrix<4, 4, Type> const & transform,
  3551.     Matrix<3, 3, Type> const & m_inv_transpose, boost::object_pool<Triangle>& tri_pool, StackTrivial<Vertex>& vertices) const
  3552.   {
  3553.     vertices.clear();
  3554.     vertices.reserve(_vertices.size());
  3555.     for (auto const * ptr = _vertices.begin(); ptr != _vertices.end();) {
  3556.       vertices.push_back_unchecked(Vertex(MathHelpers::transformPoint(transform, ptr->position()), CompressedNormal(m_inv_transpose * ptr->normal()), ptr->uv(),
  3557.         CompressedNormal(m_inv_transpose * ptr->tangent())));
  3558.       ++ptr;
  3559.     }
  3560.     StackTrivial<Primitive*> tris;
  3561.     triangles(vertices.begin(), tri_pool, tris);
  3562.     return std::make_shared<BoundingVolumeHierarchy>(tris.begin(), tris.end());
  3563.   }
  3564.  
  3565.   void Mesh::calculateTangentSpace()
  3566.   {
  3567.     auto * const s = new VertexUncompressed[_vertices.size()]();
  3568.     for (auto const * index = _indices.begin(); index != _indices.end(); index += 3) {
  3569.       auto& v0 = _vertices[*index];
  3570.       auto& v1 = _vertices[*(index + 1)];
  3571.       auto& v2 = _vertices[*(index + 2)];
  3572.       auto const & uv0 = v0.uv();
  3573.       auto const & uv1 = v1.uv();
  3574.       auto const & uv2 = v2.uv();
  3575.       auto const s1 = uv1.u() - uv0.u();
  3576.       auto const t1 = uv1.v() - uv0.v();
  3577.       auto const s2 = uv2.u() - uv0.u();
  3578.       auto const t2 = uv2.v() - uv0.v();
  3579.       auto const one_over_det = s1 * t2 - t1 * s2;
  3580.       auto const e1 = v1.position() - v0.position();
  3581.       auto const e2 = v2.position() - v0.position();
  3582.       auto t = (e1 * t2 - e2 * t1) * one_over_det;
  3583.       auto b = (e2 * s1 - e1 * s2) * one_over_det;
  3584.       auto n = cross(e1, e2);
  3585.       s[*index].add(t, b, n);
  3586.       s[*(index + 1)].add(t, b, n);
  3587.       s[*(index + 2)].add(t, b, n);
  3588.     }
  3589.     auto* ptr = s;
  3590.     for (auto& v : _vertices) {
  3591.       v.set(ptr->t() - ptr->n() * dot(ptr->n(), ptr->t()), dot(cross(ptr->t(), ptr->b()), ptr->n()) < 0.f ? -1 : 1, ptr->n());
  3592.       ++ptr;
  3593.     }
  3594.     delete[] s;
  3595.   }
  3596.  
  3597.   void Mesh::init()
  3598.   {
  3599.     calculateTangentSpace();
  3600.     _aabb = AABB3f(*this);
  3601.     _sphere = Sphere3f(*this);
  3602.     StackTrivial<Primitive*> tris;
  3603.     triangles(_vertices.begin(), _trianglePool, tris);
  3604.     _bvh = std::make_unique<BoundingVolumeHierarchy>(tris.begin(), tris.end());
  3605.   }
  3606. }
  3607.  
  3608. #include <Triangle.h>
  3609. #include <Camera.h>
  3610. #include <physics/Particle.h>
  3611.  
  3612. namespace Log2
  3613. {
  3614.   Triangle::BV Triangle::bv() const
  3615.   {
  3616.     return BV::fromVertices<3>(getVertices().data());
  3617.   }
  3618.   Triangle::Type Triangle::squaredSize() const
  3619.   {
  3620.     return bv().squaredSize();
  3621.   }
  3622.   Triangle::Ray::IntersectionResult Triangle::intersectRay(Ray const & ray, Vector<3, Type> const & p0, Vector<3, Type> const & p1, Vector<3, Type> const & p2)
  3623.   {
  3624.     Ray::IntersectionResult res;
  3625.     auto e1 = p1 - p0;
  3626.     auto e2 = p2 - p0;
  3627.     auto d = ray.dir();
  3628.     auto det_a = e1.x() * (-d.z() * e2.y() + d.y() * e2.z()) - e2.x() * (-d.z() * e1.y() + d.y() * e1.z()) - d.x() * (e1.y() * e2.z() - e2.y() * e1.z());
  3629.     if (det_a <= -std::numeric_limits<Type>::epsilon() || det_a >= std::numeric_limits<Type>::epsilon()) {
  3630.       auto one_over_det = static_cast<Type>(1) / det_a;
  3631.       auto s = ray.origin() - p0;
  3632.       res.setU(dot(Vector<3, Type>(-d.z() * e2.y() + d.y() * e2.z(), d.z() * e2.x() - d.x() * e2.z(), -d.y() * e2.x() + d.x() * e2.y()), s) * one_over_det);
  3633.       if (res.uv().validU()) {
  3634.         res.setV(dot(Vector<3, Type>(d.z() * e1.y() - d.y() * e1.z(), -d.z() * e1.x() + d.x() * e1.z(), d.y() * e1.x() - d.x() * e1.y()), s) * one_over_det);
  3635.         if (res.uv().validVW()) {
  3636.           res.setT(dot(Vector<3, Type>(e1.y() * e2.z() - e2.y() * e1.z(), -e1.x() * e2.z() + e2.x() * e1.z(), e1.x() * e2.y() - e2.x() * e1.y()), s) * one_over_det);
  3637.           return res;
  3638.         }
  3639.       }
  3640.     }
  3641.     return res;
  3642.   }
  3643.   Triangle::Ray::IntersectionResult Triangle::intersectRay(Ray const & ray_local, Ray const & ray_world, Matrix const & mat)
  3644.   {
  3645.     if (auto res = intersectRay(ray_local)) {
  3646.       res.setT(distance(ray_world.origin(), MathHelpers::transformPoint(mat, ray_local.pos(res.t()))));
  3647.       return res;
  3648.     }
  3649.     return Triangle::Ray::IntersectionResult();
  3650.   }
  3651.   Triangle::Ray::IntersectionResult Triangle::intersectRay(Ray const & ray)
  3652.   {
  3653.     return intersectRay(ray, vertex<0>(), vertex<1>(), vertex<2>());
  3654.   }
  3655.   Triangle::Ray::IntersectionResult Triangle::intersectRay(Ray const & ray, Matrix const & mat)
  3656.   {
  3657.     return intersectRay(ray, MathHelpers::transformPoint(mat, vertex<0>()), MathHelpers::transformPoint(mat, vertex<1>()), MathHelpers::transformPoint(mat, vertex<2>()));
  3658.   }
  3659.   void Triangle::debugTriangle(Vector<4, Type> * _debugTriangle, Matrix const & transform) const
  3660.   {
  3661.     *_debugTriangle++ = transform * vertex<0>().toHomogeneous();
  3662.     *_debugTriangle++ = transform * vertex<1>().toHomogeneous();
  3663.     *_debugTriangle = transform * vertex<2>().toHomogeneous();
  3664.   }
  3665.   Triangle * Triangle::toTriangle()
  3666.   {
  3667.     return this;
  3668.   }
  3669. }
  3670.  
  3671. #include <opengl/GLSLShaderGenerator.h>
  3672. #include <GraphicsSettings.h>
  3673. #include <Flags.h>
  3674. #include <iostream>
  3675.  
  3676. namespace Log2
  3677. {
  3678.   GLSLShaderGenerator::GLSLShaderGenerator() :
  3679.     _compositeVertexSource(std::string(vertexFileComposite), GL_VERTEX_SHADER)
  3680.   {
  3681.     _windParamString = "uniform float " + std::string(time) + "; \n\
  3682. uniform vec3 " + std::string(bbMin) + "; // AABB min xz\n\
  3683. uniform vec3 " + std::string(bbMax) + "; // AABB max xz\n" + std::string(noiseCodeGLSL());
  3684.  
  3685.     _springParticleDataStr = "layout (std430, binding = " + str(bufferBindingSpringSkinnedInitPos) + ") readonly buffer init_pos_buffer \n\
  3686. { \n\
  3687.  vec4 init_pos[]; \n\
  3688. };\n\
  3689. layout(std430, binding = " + str(bufferBindingSpringSkinnedPos) + ") readonly buffer pos_buffer \n\
  3690. { \n\
  3691.  vec4 pos[]; \n\
  3692. };\n";
  3693.   }
  3694.   GLShaderSource GLSLShaderGenerator::createMeshVertexShaderSource(unsigned const & flags, GraphicsSettings const & gs)const
  3695.   {
  3696.     std::string key = "vs";
  3697.     if (flags & MeshRenderFlag::MR_SPRING_SKINNED) {
  3698.       key += "_spring_skinned";
  3699.     }
  3700.     key += ".glsl";
  3701.     GLShaderSource src;
  3702.     src._key = key;
  3703.     src._source = createMeshVertexSource(flags, gs);
  3704.     src._type = GL_VERTEX_SHADER;
  3705.     return src;
  3706.   }
  3707.   GLShaderSource GLSLShaderGenerator::createMeshFragmentShaderSource(unsigned const & flags, GraphicsSettings const & gs)const
  3708.   {
  3709.     std::string key = "fs";
  3710.     if (flags & MeshRenderFlag::MR_DIFFUSE_MAP) {
  3711.       key += "_albedo";
  3712.     }
  3713.     if (flags & MeshRenderFlag::MR_NORMAL_MAP) {
  3714.       key += "_normal";
  3715.       if (flags & MeshRenderFlag::MR_HEIGHT_MAP) {
  3716.         key += "_parallax";
  3717.       }
  3718.     }
  3719.     if (flags & MeshRenderFlag::MR_ALPHA_MAP) {
  3720.       key += "_alpha";
  3721.     }
  3722.     if (flags & MeshRenderFlag::MR_REFLECTIVE) {
  3723.       key += "_reflective";
  3724.     }
  3725.     if (gs.screenSpaceReflections()) {
  3726.       key += "_ssr";
  3727.     }
  3728.     if (gs.shadows() || gs.shadowsPCF()) {
  3729.       key += "_shadows";
  3730.     }
  3731.     if (gs.shadowsPCF()) {
  3732.       key += "_pcf";
  3733.     }
  3734.     if (gs.softShadows()) {
  3735.       key += "_soft_shadows";
  3736.     }
  3737.     if (gs.gammaEnabled()) {
  3738.       key += "_gamma";
  3739.     }
  3740.     key += ".glsl";
  3741.     GLShaderSource src;
  3742.     src._key = key;
  3743.     src._source = createMeshFragmentSource(flags, gs);
  3744.     src._type = GL_FRAGMENT_SHADER;
  3745.     return src;
  3746.   }
  3747.   GLShaderSource GLSLShaderGenerator::createMeshVertexShaderDepthSource(unsigned const & flags, GraphicsSettings const & gs)const
  3748.   {
  3749.     std::string key = "vs_depth";
  3750.     if (flags & MeshRenderFlag::MR_SPRING_SKINNED) {
  3751.       key += "_spring_skinned";
  3752.     }
  3753.     key += ".glsl";
  3754.     GLShaderSource src;
  3755.     src._key = key;
  3756.     src._source = createMeshVertexDepthSource(flags, gs);
  3757.     src._type = GL_VERTEX_SHADER;
  3758.     return src;
  3759.   }
  3760.   GLShaderSource GLSLShaderGenerator::createMeshFragmentShaderDepthSource(unsigned const & flags, GraphicsSettings const & gs)const
  3761.   {
  3762.     std::string key = "fs_depth";
  3763.     if (flags & MeshRenderFlag::MR_ALPHA_MAP) {
  3764.       key += "_alpha";
  3765.     }
  3766.     key += ".glsl";
  3767.     GLShaderSource src;
  3768.     src._key = key;
  3769.     src._source = createMeshFragmentDepthSource(flags, gs);
  3770.     src._type = GL_FRAGMENT_SHADER;
  3771.     return src;
  3772.   }
  3773.   void GLSLShaderGenerator::createCompositeShaderSource(GraphicsSettings const & gs, GLShaderSource& vertex_src, GLShaderSource& fragment_src, bool god_rays)const
  3774.   {
  3775.     vertex_src = _compositeVertexSource;
  3776.     std::string key = "fs_composite";
  3777.     if (gs.depthOfField()) {
  3778.       key += "_dof";
  3779.     }
  3780.     if (gs.exposureEnabled()) {
  3781.       key += "_exposure";
  3782.     }
  3783.     if (gs.gammaEnabled()) {
  3784.       key += "_gamma";
  3785.     }
  3786.     if (god_rays) {
  3787.       key += "_god_rays";
  3788.     }
  3789.     if (gs.bloom()) {
  3790.       key += "_bloom";
  3791.     }
  3792.     key += ".glsl";
  3793.     fragment_src._key = key;
  3794.     fragment_src._source = createCompositeShaderSource(gs, god_rays);
  3795.     fragment_src._type = GL_FRAGMENT_SHADER;
  3796.   }
  3797.   void GLSLShaderGenerator::createBlurShaderSource(GraphicsSettings const & gs, GLShaderSource & vertex_src, GLShaderSource & fragment_src)const
  3798.   {
  3799.     vertex_src = _compositeVertexSource;
  3800.     fragment_src._source = "#version 330 \n\
  3801. layout(location = 0) out vec3 fragmentColor;\n\
  3802. in vec2 uv;\n\
  3803. uniform sampler2D " + std::string(toBlurSampler) + ";\n\
  3804. uniform vec2 " + std::string(texelSize) + ";\n";
  3805.     fragment_src._source += blurSource(gs.blurWeights(gs.blurRadius(), gs.blurSigma()));
  3806.     fragment_src._source += "void main()\n\
  3807. {\n\
  3808.  fragmentColor = vec3(0.f);\n\
  3809.  for (int i = -" + str(gs.blurRadius()) + "; i <= " + str(gs.blurRadius()) + "; i++){\n\
  3810.    fragmentColor += texture(" + std::string(toBlurSampler) + ", uv + i * " + std::string(texelSize) + ").rgb * blur_weights[i + " + str(gs.blurRadius()) + "];\n\
  3811.  }\n\
  3812. }\n";
  3813.     fragment_src._key = "fs_blur";
  3814.     fragment_src._type = GL_FRAGMENT_SHADER;
  3815.   }
  3816.   void GLSLShaderGenerator::createSSRShaderSource(const GraphicsSettings & gs, GLShaderSource & vertex_src, GLShaderSource & fragment_src)const
  3817.   {
  3818.     vertex_src = _compositeVertexSource;
  3819.     fragment_src._source = "#version 330 \n\
  3820. layout(location = 0) out vec3 fragmentColor;\n\
  3821. in vec2 uv;\n\
  3822. uniform sampler2D " + std::string(lightingSampler) + ";\n\
  3823. uniform sampler2D " + std::string(viewSpaceNormalsSampler) + ";\n\
  3824. uniform sampler2D " + std::string(depthSampler) + ";\n\
  3825. uniform mat4 " + std::string(projectionMatrixInverse) + "; // Inverse projection matrix\n\
  3826. uniform mat4 " + std::string(projectionMatrix) + "; // Projection matrix\n\
  3827. uniform vec4 " + std::string(projectionMatrixInverseThirdRow) + "; // Third row of inverse projection matrix\n\
  3828. uniform vec4 " + std::string(projectionMatrixInverseFourthRow) + "; // Fourth row of inverse projection matrix\n\
  3829. void main()\n\
  3830. {\n\
  3831.  vec3 normal_view = textureLod(" + std::string(viewSpaceNormalsSampler) + ", uv, 0.f).xyz;\n\
  3832.  if (normal_view != vec3(0.f)) {\n\
  3833.    vec4 pos_view_h = " + std::string(projectionMatrixInverse) + " * vec4(vec3(uv, texture(" + std::string(depthSampler) + ", uv).r) * 2.f - 1.f, 1.f);\n\
  3834.    vec3 pos_view = pos_view_h.xyz / pos_view_h.w;\n\
  3835.    vec3 ray_dir = reflect(normalize(pos_view), normal_view);\n\
  3836.    vec3 ray = ray_dir * max(-pos_view.z * " + str(gs.SSRRayLenScale()) + "f, " + str(gs.SSRMinRayLen()) + ");\n\
  3837.    vec3 delta = ray / " + str(gs.SSRSteps()) + "f;\n\
  3838.    vec3 ray_pos_view = pos_view + delta;\n\
  3839.    for (float i = 0.f; i < " + str(gs.SSRSteps()) + "f; i++, ray_pos_view += delta) {\n\
  3840.      vec4 ray_pos_h = " + std::string(projectionMatrix) + " * vec4(ray_pos_view, 1.f);\n\
  3841.      vec2 ray_pos_ndc = ray_pos_h.xy / ray_pos_h.w;\n\
  3842.      vec2 uv = ray_pos_ndc * 0.5f + 0.5f;\n\
  3843.      vec4 comp_ndc = vec4(vec3(uv, texture(" + std::string(depthSampler) + ", uv).r) * 2.f - 1.f, 1.f);\n\
  3844.      float comp_depth = dot(comp_ndc, " + std::string(projectionMatrixInverseThirdRow) + ") / dot(comp_ndc, " + std::string(projectionMatrixInverseFourthRow) + ");\n\
  3845.      if (ray_pos_view.z > comp_depth) { // Intersection found, the ray traveled behind the depth buffer. \n\
  3846.        float sign;\n\
  3847.        for (uint i = 0u; i < " + str(gs.SSRBinarySteps()) + "u; i++, delta *= 0.5f, ray_pos_view += delta * sign) { // Binary search refinement\n\
  3848.          ray_pos_h = " + std::string(projectionMatrix) + " * vec4(ray_pos_view, 1.f);\n\
  3849.          ray_pos_ndc = ray_pos_h.xy / ray_pos_h.w;\n\
  3850.          uv = ray_pos_ndc * 0.5f + 0.5f;\n\
  3851.          vec4 comp_ndc = vec4(vec3(uv, texture(" + std::string(depthSampler) + ", uv).r) * 2.f - 1.f, 1.f);\n\
  3852.          float comp_depth = dot(comp_ndc, " + std::string(projectionMatrixInverseThirdRow) + ") / dot(comp_ndc, " + std::string(projectionMatrixInverseFourthRow) + ");\n\
  3853.          sign = ray_pos_view.z > comp_depth ? -1.f : 1.f;\n\
  3854.        }\n\
  3855.        fragmentColor = textureLod(" + std::string(lightingSampler) + ", uv, 0.f).rgb;\n\
  3856.        return;\n\
  3857.      }\n\
  3858.    }\n\
  3859.  }\n\
  3860.  fragmentColor = textureLod(" + std::string(lightingSampler) + ", uv, 0.f).rgb;\n\
  3861. }\n";
  3862.     fragment_src._key = "fs_ssr";
  3863.     fragment_src._type = GL_FRAGMENT_SHADER;
  3864.   }
  3865.   void GLSLShaderGenerator::createGodRayShaderSource(const GraphicsSettings& gs, GLShaderSource & vertex_src, GLShaderSource & fragment_src) const
  3866.   {
  3867.     vertex_src = _compositeVertexSource;
  3868.     fragment_src._source = "#version 330\n\
  3869. layout(location = 0) out vec3 fragmentColor;\n\
  3870. uniform sampler2D " + std::string(lightingSampler) + ";\n\
  3871. uniform sampler2D " + std::string(depthSampler) + ";\n\
  3872. uniform vec2 " + std::string(lightPosUV) + ";\n\
  3873. in vec2 uv;\n\
  3874. void main()\n\
  3875. {\n\
  3876.  fragmentColor = vec3(0.f);\n\
  3877.  vec2 delta = (" + std::string(lightPosUV) + " - uv) / " + str(gs.godRaySteps()) + ";\n\
  3878.  vec2 tex_coord = uv;\n\
  3879.  float decay = 1.f;\n\
  3880.  for (float i = 0.f; i < " + str(gs.godRaySteps()) + "; i++, tex_coord += delta, decay *= " + str(gs.godRayDecay()) + ") { \n\
  3881.    fragmentColor += decay * texture(" + std::string(lightingSampler) + ", tex_coord).rgb * float(texture(" + std::string(depthSampler) + ", tex_coord).r == 1.f);\n\
  3882.  }\n\
  3883.  fragmentColor /= " + str(gs.godRaySteps()) + ";\n\
  3884. }\n";
  3885.     fragment_src._key = "fs_god_ray";
  3886.     fragment_src._type = GL_FRAGMENT_SHADER;
  3887.   }
  3888.   void GLSLShaderGenerator::createBrightnessShaderSource(const GraphicsSettings & gs, GLShaderSource & vertex_src, GLShaderSource & fragment_src) const
  3889.   {
  3890.     vertex_src = _compositeVertexSource;
  3891.     fragment_src._source = "#version 330\n\
  3892. layout (location = 0) out vec3 fragmentColor;\n\
  3893. uniform sampler2D " + std::string(lightingSampler) + ";\n\
  3894. in vec2 uv;\n\
  3895. void main() \n\
  3896. {\n\
  3897.  vec3 col = texture(" + std::string(lightingSampler) + ", uv).rgb; \n\
  3898.  fragmentColor = col * smoothstep(0.85f, 1.f, dot(col, vec3(0.2126f, 0.7152f, 0.0722f)));\n\
  3899. }";
  3900.     fragment_src._type = GL_FRAGMENT_SHADER;
  3901.   }
  3902.   std::string GLSLShaderGenerator::createMeshVertexSource(unsigned const & flags, GraphicsSettings const & gs) const
  3903.   {
  3904.     std::string version = (flags & MR_SPRING_SKINNED) ? "450" : "330";
  3905.     std::string shader_src;
  3906.     shader_src += "#version " + version + "\n\
  3907. layout(location = 0) in vec3 position;\n\
  3908. layout(location = 1) in vec3 normal;\n\
  3909. layout(location = 2) in vec2 uv;\n\
  3910. layout(location = 3) in vec4 tangent;\n\
  3911. layout (location = 4) in uvec4 p_indices;\n\
  3912. layout(location = 5) in vec4 weights;\n\
  3913. // Shader constants\n\
  3914. uniform mat4 VP; \n\
  3915. // Model constants\n\
  3916. uniform mat4 " + std::string(modelMatrix) + ";\n\
  3917. out vec3 pos_world;\n\
  3918. out vec3 normal_local;\n\
  3919. out vec2 uv_out;\n\
  3920. out vec4 tangent_local;\n";
  3921.     if (flags & MeshRenderFlag::MR_SPRING_SKINNED) {
  3922.       shader_src += _springParticleDataStr;
  3923.     }
  3924.     if (gs.depthPrepassEnabled()) {
  3925.       shader_src += "invariant gl_Position; \n";
  3926.     }
  3927.     shader_src += "void main()\n\
  3928. {\n";
  3929.     if (flags & MeshRenderFlag::MR_SPRING_SKINNED) {
  3930.       shader_src += "    vec3 offs = vec3(0.f);\n\
  3931.        for (uint i = 0; i < 4; i++) { \n\
  3932.          offs += (pos[p_indices[i]].xyz - init_pos[p_indices[i]].xyz) * weights[i]; \n\
  3933.        }\n";
  3934.       shader_src += "  pos_world = (" + std::string(modelMatrix) + " * vec4(position + offs, 1.f)).xyz;\n";
  3935.     }
  3936.     else {
  3937.       shader_src += "  pos_world = (" + std::string(modelMatrix) + " * vec4(position, 1.f)).xyz;\n";
  3938.     }
  3939.     shader_src += "  gl_Position = VP * vec4(pos_world, 1.f);\n\
  3940.  normal_local = normal;\n\
  3941.  uv_out = uv;\n\
  3942.  tangent_local = tangent;\n";
  3943.     shader_src += "}\n";
  3944.     return shader_src;
  3945.   }
  3946.   std::string GLSLShaderGenerator::createMeshVertexDepthSource(unsigned const & flags, GraphicsSettings const  & gs) const
  3947.   {
  3948.     std::string version = (flags & MR_SPRING_SKINNED) ? "450" : "330";
  3949.     std::string shader_src = "#version " + version + "\n\
  3950. layout(location = 0) in vec3 position;\n\
  3951. layout(location = 2) in vec2 uv;\n\
  3952. layout(location = 5) in uvec4 p_indices; \n\
  3953. layout(location = 6) in vec4 weights; \n";
  3954.     if (gs.depthPrepassEnabled()) {
  3955.       shader_src += "invariant gl_Position; \n";
  3956.     }
  3957.     shader_src += "uniform mat4 " + std::string(modelMatrix) + ";\n";
  3958.     shader_src += "uniform mat4 " + std::string(viewProjectionMatrix) + "; \n";
  3959.     shader_src += _windParamString;
  3960.     shader_src += "out vec2 uv_out;\n";
  3961.     if (flags & MR_SPRING_SKINNED) {
  3962.       shader_src += _springParticleDataStr;
  3963.     }
  3964.     shader_src += "void main()\n\
  3965. {\n";
  3966.     if (flags & MR_SPRING_SKINNED) {
  3967.       shader_src += "    vec3 offs = vec3(0.f);\n\
  3968.        for (uint i = 0; i < 4; i++) { \n\
  3969.          offs += (pos[p_indices[i]].xyz - init_pos[p_indices[i]].xyz) * weights[i]; \n\
  3970.        }\n";
  3971.       shader_src += "  vec4 pos_world = " + std::string(modelMatrix) + " * vec4(position + offs, 1.f);\n";
  3972.     }
  3973.     else {
  3974.       shader_src += "  vec4 pos_world = " + std::string(modelMatrix) + " * vec4(position, 1.f);\n";
  3975.     }
  3976.     shader_src += "  gl_Position = " + std::string(viewProjectionMatrix) + " * pos_world;\n";
  3977.     shader_src += "  uv_out = uv;\n\
  3978. }\n";
  3979.     return shader_src;
  3980.   }
  3981.   std::string GLSLShaderGenerator::createMeshFragmentSource(unsigned const & flags, GraphicsSettings const & gs) const
  3982.   {
  3983.     std::string version = "330";
  3984.     bool tangent_space = (flags & MR_NORMAL_MAP) || (flags & MR_HEIGHT_MAP);
  3985.     std::string shader_src = "#version " + version + " \n\
  3986. layout(location = 0) out vec3 fragmentColor;\n";
  3987.     unsigned rt_index = 1;
  3988.     if (gs.screenSpaceReflections()) {
  3989.       shader_src += "layout(location = " + str(rt_index) + ") out vec3 viewSpaceNormal; \n";
  3990.       rt_index++;
  3991.     }
  3992.     shader_src += "in vec3 pos_world;\n\
  3993. in vec2 uv_out;\n\
  3994. uniform vec3 " + std::string(diffuseColor) + ";\n\
  3995. uniform sampler2D " + std::string(diffuseSampler) + ";\n\
  3996. uniform sampler2D " + std::string(alphaSampler) + ";\n\
  3997. uniform sampler2D " + std::string(normalSampler) + ";\n\
  3998. uniform sampler2D " + std::string(heightSampler) + ";\n\
  3999. uniform float " + std::string(parallaxHeightScale) + "; // Parallax ray scale\n\
  4000. uniform float " + std::string(shadowMapBias) + "; // Shadow map bias\n\
  4001. uniform float " + std::string(parallaxMinSteps) + "; // Parallax min steps\n\
  4002. uniform float " + std::string(parallaxMaxSteps) + "; // Parallax max steps\n\
  4003. uniform float " + std::string(parallaxBinarySearchSteps) + "; // Parallax binary search steps\n\
  4004. uniform vec3 " + std::string(lightDirWorld) + "; // light direction world space\n\
  4005. uniform vec3 " + std::string(cameraPositionWorld) + "; // camera position world space\n\
  4006. uniform vec3 " + std::string(lightIntensity) + "; // light intensity\n\
  4007. uniform mat4 " + std::string(worldToLightMatrices) + " [" + str(gs.frustumSplits().size()) + "]; // world space to light space\n\
  4008. uniform float " + std::string(frustumSplits) + " [" + str(gs.frustumSplits().size()) + "]; // frustum_splits\n\
  4009. uniform int " + std::string(numfrustumSplits) + "; // num frustum splits\n";
  4010.     shader_src += (gs.shadowsPCF() ? "uniform sampler2DArrayShadow " : "uniform sampler2DArray ") + std::string(shadowSampler) + ";\n";
  4011.     shader_src += "// Material constants\n\
  4012. uniform float " + std::string(ambientConstant) + ";\n\
  4013. uniform float " + std::string(diffuseConstant) + ";\n\
  4014. uniform float " + std::string(specularConstant) + ";\n\
  4015. uniform float " + std::string(specularExponent) + ";\n\
  4016. uniform float " + std::string(gamma) + ";\n\
  4017. uniform mat3 " + std::string(modelMatrixTransposeInverse) + ";\n\
  4018. uniform mat3 " + std::string(viewMatrixOrtho) + ";\n\
  4019. uniform vec4 " + std::string(viewMatrixThirdRow) + ";\n\
  4020. in vec3 normal_local;\n\
  4021. in vec4 tangent_local;\n";
  4022.     shader_src += blurSource(gs.blurWeights2D(gs.shadowBlurRadius(), gs.shadowBlurSigma()));
  4023.     shader_src += "void main()\n\
  4024. {\n\
  4025.  vec2 uv = uv_out;\n";
  4026.     if (tangent_space) {
  4027.       shader_src += "  vec3 bitangent_local = tangent_local.w * cross(normal_local, tangent_local.xyz);\n"; // Handedness is stored in the w coordinate of the tangent vector.
  4028.       shader_src += "  mat3 world_to_tangent = mat3(normalize(" + std::string(modelMatrixTransposeInverse) + " * vec3(tangent_local.x, bitangent_local.x, normal_local.x)), normalize(" + std::string(modelMatrixTransposeInverse) + " * vec3(tangent_local.y, bitangent_local.y, normal_local.y)), normalize(" + std::string(modelMatrixTransposeInverse) + " * vec3(tangent_local.z, bitangent_local.z, normal_local.z)));\n";
  4029.     }
  4030.     shader_src += "  vec3 e =" + std::string(tangent_space ? " world_to_tangent *" : "") + " normalize(" + std::string(cameraPositionWorld) + " - pos_world); \n";
  4031.     if ((flags & MR_NORMAL_MAP) && (flags & MR_HEIGHT_MAP)) {
  4032.       if (!gs.reliefMapping()) {
  4033.         shader_src += "  uv -= e.xy / e.z * (1.f - textureLod(" + std::string(heightSampler) + ", uv, 0.f).r) * " + std::string(parallaxHeightScale) + "; \n";
  4034.       }
  4035.       else {
  4036.         shader_src += "  float steps = mix(" + std::string(parallaxMaxSteps) + ", " + std::string(parallaxMinSteps) + ", clamp(dot(vec3(0.f, 0.f, 1.f), e), 0.f, 1.f));\n\
  4037.  vec2 ray = e.xy * " + std::string(parallaxHeightScale) + ";\n\
  4038.  vec2 delta = ray / steps;\n\
  4039.  float layer_delta = 1.f / steps;\n\
  4040.  float layer_depth = 1.f - layer_delta;\n\
  4041.  uv -= delta;\n\
  4042.  for (float i = 0.f; i < steps; i++, uv -= delta, layer_depth -= layer_delta) {\n\
  4043.    if(textureLod(" + std::string(heightSampler) + ", uv, 0.f).r > layer_depth){\n\
  4044.      delta *= 0.5f;\n\
  4045.      layer_delta *= 0.5f;\n\
  4046.      uv += delta;\n\
  4047.      layer_depth += layer_delta;\n\
  4048.      for (float i = 0.f, sign; i < " + std::string(parallaxBinarySearchSteps) + "; i++, uv += delta * sign, layer_depth += layer_delta * sign){\n\
  4049.        sign = (textureLod(" + std::string(heightSampler) + ", uv, 0.f).r > layer_depth) ? 1.f : -1.f;\n\
  4050.        delta *= 0.5f;\n\
  4051.        layer_delta *= 0.5f;\n\
  4052.      }\n\
  4053.      break;\n\
  4054.    }\n\
  4055.  }\n";
  4056.       }
  4057.     }
  4058.     if (flags & MeshRenderFlag::MR_ALPHA_MAP) {
  4059.       shader_src += "  if (texture(" + std::string(alphaSampler) + ", uv).r < 0.5f) {\n\
  4060.    discard;\n\
  4061.    return;\n\
  4062.  }\n";
  4063.     }
  4064.     shader_src += "  vec3 l = " + std::string((tangent_space ? "world_to_tangent *" : "")) + std::string(lightDirWorld) + ";\n";
  4065.   //  std::string normal_str = "normal_world";
  4066.     if (flags & MeshRenderFlag::MR_NORMAL_MAP) {
  4067.       shader_src += "  vec3 n = normalize((texture(" + std::string(normalSampler) + ", uv).xyz * 2.f - 1.f));\n";
  4068.     }
  4069.     else {
  4070.       shader_src += "  vec3 n = normalize(" + std::string(modelMatrixTransposeInverse) + " * normal_local);\n";
  4071.     }
  4072.     shader_src += "  float diffuse = max(dot(l, n), 0.f);\n\
  4073.  float specular = pow(max(dot(normalize(e + l), n), 0.f), " + std::string(specularExponent) + ");\n";
  4074.  
  4075.     if (flags & MeshRenderFlag::MR_DIFFUSE_MAP) {
  4076.       shader_src += "  vec3 albedo = texture(" + std::string(diffuseSampler) + ", uv).rgb;\n";
  4077.     }
  4078.     else {
  4079.       shader_src += "  vec3 albedo = " + std::string(diffuseColor) + ";\n";
  4080.     }
  4081.     if (gs.gammaEnabled()) {
  4082.       shader_src += "  albedo = pow(albedo, vec3(" + std::string(gamma) + "));\n";
  4083.     }
  4084.     if (gs.shadows() || gs.shadowsPCF()) {
  4085.       shader_src += "  int index = " + std::string(numfrustumSplits) + "-1;\n\
  4086.  for (int i = " + std::string(numfrustumSplits) + "-2; i >= 0; i--) {\n\
  4087.    index -= int(dot(" + std::string(viewMatrixThirdRow) + ", vec4(pos_world, 1.f)) < " + std::string(frustumSplits) + "[i]);\n\
  4088.  }\n";
  4089.       shader_src += "  vec4 shadow_coord = " + std::string(worldToLightMatrices) + "[index] * vec4(pos_world, 1.f);\n\
  4090.  shadow_coord.xyz /= shadow_coord.w;\n\
  4091.  shadow_coord = shadow_coord * 0.5f + 0.5f;\n";
  4092.       // shadow_coord.z -= " + std::string(shadowMapBias()) + ";\n";
  4093.       if (!gs.shadowsPCF()) {
  4094.         shader_src += "  if (all(greaterThanEqual(shadow_coord.xyz, vec3(0.f))) && all(lessThanEqual(shadow_coord.xyz, vec3(1.f)))) {\n  ";
  4095.       }
  4096.       if (gs.softShadows()) {
  4097.         auto rad = str(gs.shadowBlurRadius());
  4098.         shader_src += "  float light_factor = 1.f;\n\
  4099.  vec2 offs = 1.f / textureSize(" + std::string(shadowSampler) + ", 0).xy;\n\
  4100.  for (int u = -" + rad + "; u <= " + rad + "; u++) {\n\
  4101.    for(int v = -" + rad + "; v <= " + rad + "; v++) {\n\
  4102.      light_factor -= texture(" + std::string(shadowSampler) + ", vec4(shadow_coord.xy + vec2(u, v) * offs, index, shadow_coord.z)) * blur_weights[((v + " + rad + ") * " + rad + ") + u + " + rad + "];\n\
  4103.  }\n\
  4104. }\n";
  4105.       }
  4106.       else {
  4107.         shader_src += std::string("  float light_factor = 1.f - ") + (gs.shadowsPCF() ? "texture(" + std::string(shadowSampler) + ", vec4(shadow_coord.xy, index, shadow_coord.z))" : "float(shadow_coord.z > texture(" + std::string(shadowSampler) + ", vec3(shadow_coord.xy, index)).r)") + ";\n";
  4108.       }
  4109.       shader_src += "  specular *= light_factor;\n\
  4110.  diffuse *= light_factor;\n";
  4111.       if (!gs.shadowsPCF()) {
  4112.         shader_src += "  }\n";
  4113.       }
  4114.     }
  4115.     shader_src += "  fragmentColor = " + std::string(lightIntensity) + " * albedo * (" + std::string(ambientConstant) + " + " + std::string(diffuseConstant) + " * diffuse + " + std::string(specularConstant) + " * specular);\n";
  4116.     if (gs.screenSpaceReflections()) {
  4117.       if (flags & MR_REFLECTIVE) {
  4118.         shader_src += "  mat3 mv_inverse = " + std::string(viewMatrixOrtho) + " * " + std::string(modelMatrixTransposeInverse) + ";\n";
  4119.         if (tangent_space) {
  4120.           shader_src += "  mat3 tangent_to_view = mat3(normalize(mv_inverse * tangent_local.xyz), normalize(mv_inverse * bitangent_local), normalize(mv_inverse * normal_local));\n\
  4121.  viewSpaceNormal = normalize(tangent_to_view * n);\n";
  4122.         }
  4123.         else {
  4124.           shader_src += "  viewSpaceNormal = normalize(mv_inverse * normal_local);\n";
  4125.         }
  4126.       }
  4127.       else {
  4128.         shader_src += "  viewSpaceNormal = vec3(0.f);\n";
  4129.       }
  4130.     }
  4131.     shader_src += "}\n";
  4132.     return shader_src;
  4133.   }
  4134.   std::string GLSLShaderGenerator::createMeshFragmentDepthSource(unsigned const & flags, GraphicsSettings const & gs) const
  4135.   {
  4136.     std::string shader_src = "#version 330\n\
  4137. in vec2 uv_out;\n";
  4138.     if (flags & MR_ALPHA_MAP) {
  4139.       shader_src += "uniform sampler2D " + std::string(alphaSampler) + ";\n";
  4140.     }
  4141.     shader_src += "void main()\n\
  4142. {\n";
  4143.     if (flags & MR_ALPHA_MAP) {
  4144.       shader_src += "  if (texture(" + std::string(alphaSampler) + ", uv_out).r < 0.5f){\n\
  4145.    discard;\n\
  4146.  }\n";
  4147.     }
  4148.     shader_src += "}";
  4149.     return shader_src;
  4150.   }
  4151.   std::string GLSLShaderGenerator::createCompositeShaderSource(GraphicsSettings const & gs, bool const & god_rays) const
  4152.   {
  4153.     std::string shader_src = "#version 330\n\
  4154. layout(location = 0) out vec3 fragmentColor;\n\
  4155. uniform sampler2D " + std::string(lightingSampler) + ";\n\
  4156. uniform sampler2D " + std::string(depthSampler) + ";\n\
  4157. uniform sampler2D " + std::string(dofSampler) + ";\n\
  4158. uniform sampler2D " + std::string(godRaySampler) + ";\n\
  4159. uniform sampler2D " + std::string(bloomSampler) + ";\n\
  4160. uniform vec4 " + std::string(projectionMatrixInverseThirdRow) + ";\n\
  4161. uniform vec4 " + std::string(projectionMatrixInverseFourthRow) + ";\n\
  4162. uniform vec3 " + godRayIntensity + ";\n\
  4163. uniform float " + std::string(maxMipLevel) + ";\n\
  4164. in vec2 uv;\n\
  4165. void main()\n\
  4166. {\n\
  4167.  fragmentColor = textureLod(" + std::string(lightingSampler) + ", uv, 0.f).rgb;\n";
  4168.     if (gs.depthOfField()) {
  4169.       shader_src += "  vec4 pos_ndc = vec4(vec3(uv, texture(" + std::string(depthSampler) + ", uv).r) * 2.f - 1.f, 1.f);\n\
  4170.  float depth_view = dot(" + std::string(projectionMatrixInverseThirdRow) + ", pos_ndc) / dot(" + std::string(projectionMatrixInverseFourthRow) + ", pos_ndc);\n\
  4171.  vec3 blur_color = texture(" + std::string(dofSampler) + ", uv).rgb;\n\
  4172.  if (depth_view >= " + str(gs.dofCenter()) + "){\n\
  4173.    fragmentColor = mix(fragmentColor, blur_color, smoothstep(" + str(gs.dofCenter()) + ", " + str(gs.dofFar()) + ", depth_view));\n\
  4174.  }\n\
  4175.  else {\n\
  4176.    fragmentColor = mix(blur_color, fragmentColor, smoothstep(" + str(gs.dofNear()) + ", " + str(gs.dofCenter()) + ", depth_view));\n\
  4177.  }\n";
  4178.     }
  4179.     if (gs.autoExposure()) {
  4180.       shader_src += "  float scene_brightness = dot(textureLod(" + std::string(lightingSampler) + ", vec2(0.5f), " + std::string(maxMipLevel) + ").rgb , vec3(0.2126f, 0.7152f, 0.0722f));\n";
  4181.     }
  4182.     if (god_rays) {
  4183.       shader_src += "  fragmentColor += texture(" + std::string(godRaySampler) + ", uv).rgb * " + godRayIntensity + ";\n";
  4184.     }
  4185.     if (gs.bloom()) {
  4186.       shader_src += "  fragmentColor += texture(" + std::string(bloomSampler) + ", uv).rgb" + (gs.autoExposure() ? " * (1.f - smoothstep(0.f, " + str(gs.refBrightness()) + ", scene_brightness))" : "") + ";\n";
  4187.     }
  4188.     if (gs.exposureEnabled()) {
  4189.       shader_src += "  fragmentColor *= " + str(gs.exposure()) + (gs.autoExposure() ? " * clamp(0.25f / scene_brightness, 0.5f, 3.f)" : "") + ";\n";
  4190.     }
  4191.     shader_src += "  fragmentColor /= 1.f + fragmentColor;\n";
  4192.     if (gs.gammaEnabled()) {
  4193.       shader_src += "  fragmentColor = pow(fragmentColor, vec3(" + str(1.f / gs.gamma()) + "));\n";
  4194.     }
  4195.     return shader_src + "}\n";
  4196.   }
  4197.   std::string GLSLShaderGenerator::blurSource(StackTrivial<float> const & weights) const
  4198.   {
  4199.     std::string res = "  const float blur_weights[" + str(weights.size()) + "] = float[](";
  4200.     for (auto* ptr = weights.begin(); ptr != weights.end(); ptr++) {
  4201.       res += str(*ptr);
  4202.       res += ptr == weights.end() - 1u ? ");\n" : ",";
  4203.     }
  4204.     return res;
  4205.   }
  4206. }
  4207.  
  4208. #include <physics/PhysicsCameraController.h>
  4209. #include <GameTimer.h>
  4210. #include <Camera.h>
  4211. #include <iostream>
  4212. #include <BoundingVolumeHierarchy.h>
  4213. #include <Triangle.h>
  4214. #include <set>
  4215.  
  4216. namespace Log2
  4217. {
  4218.   PhysicsCameraController::PhysicsCameraController(Camera* const & camera, BoundingVolumeHierarchy*& bvh) :
  4219.     _c(camera),
  4220.     _bvh(bvh)
  4221.   {
  4222.   }
  4223.   void PhysicsCameraController::updateSystem()
  4224.   {
  4225.     setDamping(DAMP_DEFAULT);
  4226.     auto const v_new = _velocity + ((_acceleration + _gravity) * _dt);
  4227.     auto const v_constant = v_new * _dt;
  4228.     auto p2 = _c->pos() + v_constant;
  4229.     if (_collisions) {
  4230.       auto v_inv = Vector(static_cast<Type>(1)) / v_constant;
  4231.       auto min_t_first = std::numeric_limits<Type>::max();
  4232.       Primitive const * nearest = nullptr;
  4233.       _bvh->intersectNested(_c->collisionShape(), v_constant, v_inv, min_t_first, [this, &min_t_first, &nearest, &v_constant, &v_inv](Primitive const * imr) {
  4234.         boost::object_pool<Triangle> tri_pool;
  4235.         StackTrivial<Vertex> vertices;
  4236.         imr->getTransformedBVH(tri_pool, vertices)->intersectPrimitives(_c->collisionShape(), v_constant, v_inv, min_t_first, nearest);
  4237.         setDamping(DAMP_INTERIOR);
  4238.       });
  4239.       _c->setPosition(nearest ? lerp(_c->pos(), p2, min_t_first) : p2);
  4240.     }
  4241.     else {
  4242.       _c->setPosition(p2);
  4243.     }
  4244.     _velocity = v_new * _damp;
  4245.     _angularVelocity += _angularAcceleration * _dt;
  4246.     _c->setEulerRadians(_c->eulerRadians() - _angularVelocity * _dt);
  4247.     _angularVelocity *= DAMP_DEFAULT;
  4248.   }
  4249.   unsigned PhysicsCameraController::getID()
  4250.   {
  4251.     return 0;
  4252.   }
  4253.   const char * PhysicsCameraController::getName()
  4254.   {
  4255.     return "PhysicsCameraController";
  4256.   }
  4257.   void PhysicsCameraController::setAcceleration(Vector const & dir, Type const & amount)
  4258.   {
  4259.     _acceleration = dir.length() > static_cast<Type>(0) ? normalize(dir) * amount : static_cast<Type>(0);
  4260.   }
  4261.   void PhysicsCameraController::setAngularAcceleration(Vector const & aa)
  4262.   {
  4263.     _angularAcceleration = aa;
  4264.   }
  4265.   Camera* const & PhysicsCameraController::getCamera() const
  4266.   {
  4267.     return _c;
  4268.   }
  4269.   void PhysicsCameraController::setCamera(Camera* const & camera)
  4270.   {
  4271.     _c = camera;
  4272.   }
  4273.   void PhysicsCameraController::setDamping(Type const & damping)
  4274.   {
  4275.     _damp = damping;
  4276.   }
  4277.   PhysicsCameraController::Vector const & PhysicsCameraController::gravity() const
  4278.   {
  4279.     return _gravity;
  4280.   }
  4281.   void PhysicsCameraController::setGravity(Vector const & gravity)
  4282.   {
  4283.     _gravity = gravity;
  4284.   }
  4285.   bool const & PhysicsCameraController::collisions() const
  4286.   {
  4287.     return _collisions;
  4288.   }
  4289.   void PhysicsCameraController::setCollisions(bool const & collisions)
  4290.   {
  4291.     _collisions = collisions;
  4292.   }
  4293. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement