summaryrefslogtreecommitdiff
path: root/thirdparty/embree/kernels/geometry/intersector_iterators.h
blob: 9cac1cd25ca5c4dfeb74b2b8984bf2661235660f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "../common/scene.h"
#include "../common/ray.h"
#include "../common/point_query.h"
#include "../bvh/node_intersector1.h"
#include "../bvh/node_intersector_packet.h"

namespace embree
{
  namespace isa
  {
    template<typename Intersector>
    struct ArrayIntersector1
    {
      typedef typename Intersector::Primitive Primitive;
      typedef typename Intersector::Precalculations Precalculations;

      template<int N, bool robust>
      static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
      {
        for (size_t i=0; i<num; i++)
          Intersector::intersect(pre,ray,context,prim[i]);
      }

      template<int N, bool robust>
      static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
      {
        for (size_t i=0; i<num; i++) {
          if (Intersector::occluded(pre,ray,context,prim[i]))
            return true;
        }
        return false;
      }
      
      template<int N>
      static __forceinline bool pointQuery(const Accel::Intersectors* This, PointQuery* query, PointQueryContext* context, const Primitive* prim, size_t num, const TravPointQuery<N> &tquery, size_t& lazy_node)
      {
        bool changed = false;
        for (size_t i=0; i<num; i++)
          changed |= Intersector::pointQuery(query, context, prim[i]);
        return changed;
      }

      template<int K>
      static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
      {
      }

      template<int K>
      static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
      {
        return valid;
      }
    };

    template<int K, typename Intersector>
    struct ArrayIntersectorK_1
    {
      typedef typename Intersector::Primitive Primitive;
      typedef typename Intersector::Precalculations Precalculations;

      template<bool robust>
      static __forceinline void intersect(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRayK<K, robust> &tray, size_t& lazy_node)
      {
        for (size_t i=0; i<num; i++) {
          Intersector::intersect(valid,pre,ray,context,prim[i]);
        }
      }

      template<bool robust>
      static __forceinline vbool<K> occluded(const vbool<K>& valid, const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, const TravRayK<K, robust> &tray, size_t& lazy_node)
      {
        vbool<K> valid0 = valid;
        for (size_t i=0; i<num; i++) {
          valid0 &= !Intersector::occluded(valid0,pre,ray,context,prim[i]);
          if (none(valid0)) break;
        }
        return !valid0;
      }

      template<int N, bool robust>
      static __forceinline void intersect(const Accel::Intersectors* This, Precalculations& pre, RayHitK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
      {
        for (size_t i=0; i<num; i++) {
          Intersector::intersect(pre,ray,k,context,prim[i]);
        }
      }

      template<int N, bool robust>
      static __forceinline bool occluded(const Accel::Intersectors* This, Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, const TravRay<N,robust> &tray, size_t& lazy_node)
      {
        for (size_t i=0; i<num; i++) {
          if (Intersector::occluded(pre,ray,k,context,prim[i]))
            return true;
        }
        return false;
      }
    };

    // =============================================================================================

    template<int K, typename IntersectorK>
    struct ArrayIntersectorKStream
    {
      typedef typename IntersectorK::Primitive PrimitiveK;
      typedef typename IntersectorK::Precalculations PrecalculationsK;

      static __forceinline void intersectK(const vbool<K>& valid, const Accel::Intersectors* This, /* PrecalculationsK& pre, */ RayHitK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
      {
        PrecalculationsK pre(valid,ray); // FIXME: might cause trouble

        for (size_t i=0; i<num; i++) {
          IntersectorK::intersect(valid,pre,ray,context,prim[i]);
        }
      }

      static __forceinline vbool<K> occludedK(const vbool<K>& valid, const Accel::Intersectors* This, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
      {
        PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
        vbool<K> valid0 = valid;
        for (size_t i=0; i<num; i++) {
          valid0 &= !IntersectorK::occluded(valid0,pre,ray,context,prim[i]);
          if (none(valid0)) break;
        }
        return !valid0;
      }

      static __forceinline void intersect(const Accel::Intersectors* This, RayHitK<K>& ray, size_t k, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
      {
        PrecalculationsK pre(ray.tnear() <= ray.tfar,ray); // FIXME: might cause trouble
        for (size_t i=0; i<num; i++) {
          IntersectorK::intersect(pre,ray,k,context,prim[i]);
        }
      }

      static __forceinline bool occluded(const Accel::Intersectors* This, RayK<K>& ray, size_t k, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
      {
        PrecalculationsK pre(ray.tnear() <= ray.tfar,ray); // FIXME: might cause trouble
        for (size_t i=0; i<num; i++) {
          if (IntersectorK::occluded(pre,ray,k,context,prim[i]))
            return true;
        }
        return false;
      }

      static __forceinline size_t occluded(const Accel::Intersectors* This, size_t cur_mask, RayK<K>** __restrict__ inputPackets, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
      {
        size_t m_occluded = 0;
        for (size_t i=0; i<num; i++) {
          size_t bits = cur_mask & (~m_occluded);
          for (; bits!=0; )
          {
            const size_t rayID = bscf(bits);
            RayHitK<K> &ray = *inputPackets[rayID / K];
            const size_t k = rayID % K;
            PrecalculationsK pre(ray.tnear() <= ray.tfar,ray); // FIXME: might cause trouble
            if (IntersectorK::occluded(pre,ray,k,context,prim[i]))
            {
              m_occluded |= (size_t)1 << rayID;
              ray.tfar[k] = neg_inf;
            }
          }
        }
        return m_occluded;
      }
    };
  }
}