1 | // Copyright 2009-2021 Intel Corporation |
2 | // SPDX-License-Identifier: Apache-2.0 |
3 | |
4 | #pragma once |
5 | |
6 | #include "default.h" |
7 | |
8 | namespace embree |
9 | { |
10 | /* Point query structure for closest point query */ |
11 | template<int K> |
12 | struct RTC_ALIGN(16) PointQueryK |
13 | { |
14 | /* Default construction does nothing */ |
15 | __forceinline PointQueryK() {} |
16 | |
17 | /* Constructs a ray from origin, direction, and ray segment. Near |
18 | * has to be smaller than far */ |
19 | __forceinline PointQueryK(const Vec3vf<K>& p, const vfloat<K>& radius = inf, const vfloat<K>& time = zero) |
20 | : p(p), time(time), radius(radius) {} |
21 | |
22 | /* Returns the size of the ray */ |
23 | static __forceinline size_t size() { return K; } |
24 | |
25 | /* Calculates if this is a valid ray that does not cause issues during traversal */ |
26 | __forceinline vbool<K> valid() const |
27 | { |
28 | const vbool<K> vx = (abs(p.x) <= vfloat<K>(FLT_LARGE)); |
29 | const vbool<K> vy = (abs(p.y) <= vfloat<K>(FLT_LARGE)); |
30 | const vbool<K> vz = (abs(p.z) <= vfloat<K>(FLT_LARGE)); |
31 | const vbool<K> vn = radius >= vfloat<K>(0); |
32 | const vbool<K> vf = abs(time) < vfloat<K>(inf); |
33 | return vx & vy & vz & vn & vf; |
34 | } |
35 | |
36 | __forceinline void get(PointQueryK<1>* ray) const; |
37 | __forceinline void get(size_t i, PointQueryK<1>& ray) const; |
38 | __forceinline void set(const PointQueryK<1>* ray); |
39 | __forceinline void set(size_t i, const PointQueryK<1>& ray); |
40 | |
41 | Vec3vf<K> p; // location of the query point |
42 | vfloat<K> time; // time for motion blur |
43 | vfloat<K> radius; // radius for the point query |
44 | }; |
45 | |
46 | /* Specialization for a single point query */ |
47 | template<> |
48 | struct RTC_ALIGN(16) PointQueryK<1> |
49 | { |
50 | /* Default construction does nothing */ |
51 | __forceinline PointQueryK() {} |
52 | |
53 | /* Constructs a ray from origin, direction, and ray segment. Near |
54 | * has to be smaller than far */ |
55 | __forceinline PointQueryK(const Vec3fa& p, float radius = inf, float time = zero) |
56 | : p(p), time(time), radius(radius) {} |
57 | |
58 | /* Calculates if this is a valid ray that does not cause issues during traversal */ |
59 | __forceinline bool valid() const { |
60 | return all(le_mask(abs(Vec3fa(p)), Vec3fa(FLT_LARGE)) & le_mask(Vec3fa(0.f), Vec3fa(radius))) && abs(time) < float(inf); |
61 | } |
62 | |
63 | Vec3f p; |
64 | float time; |
65 | float radius; |
66 | }; |
67 | |
68 | /* Converts point query packet to single point query */ |
69 | template<int K> |
70 | __forceinline void PointQueryK<K>::get(PointQueryK<1>* query) const |
71 | { |
72 | for (size_t i = 0; i < K; i++) // FIXME: use SIMD transpose |
73 | { |
74 | query[i].p.x = p.x[i]; |
75 | query[i].p.y = p.y[i]; |
76 | query[i].p.z = p.z[i]; |
77 | query[i].time = time[i]; |
78 | query[i].radius = radius[i]; |
79 | } |
80 | } |
81 | |
82 | /* Extracts a single point query out of a point query packet*/ |
83 | template<int K> |
84 | __forceinline void PointQueryK<K>::get(size_t i, PointQueryK<1>& query) const |
85 | { |
86 | query.p.x = p.x[i]; |
87 | query.p.y = p.y[i]; |
88 | query.p.z = p.z[i]; |
89 | query.radius = radius[i]; |
90 | query.time = time[i]; |
91 | } |
92 | |
93 | /* Converts single point query to point query packet */ |
94 | template<int K> |
95 | __forceinline void PointQueryK<K>::set(const PointQueryK<1>* query) |
96 | { |
97 | for (size_t i = 0; i < K; i++) |
98 | { |
99 | p.x[i] = query[i].p.x; |
100 | p.y[i] = query[i].p.y; |
101 | p.z[i] = query[i].p.z; |
102 | radius[i] = query[i].radius; |
103 | time[i] = query[i].time; |
104 | } |
105 | } |
106 | |
107 | /* inserts a single point query into a point query packet element */ |
108 | template<int K> |
109 | __forceinline void PointQueryK<K>::set(size_t i, const PointQueryK<1>& query) |
110 | { |
111 | p.x[i] = query.p.x; |
112 | p.y[i] = query.p.y; |
113 | p.z[i] = query.p.z; |
114 | radius[i] = query.radius; |
115 | time[i] = query.time; |
116 | } |
117 | |
118 | /* Shortcuts */ |
119 | typedef PointQueryK<1> PointQuery; |
120 | typedef PointQueryK<4> PointQuery4; |
121 | typedef PointQueryK<8> PointQuery8; |
122 | typedef PointQueryK<16> PointQuery16; |
123 | struct PointQueryN; |
124 | |
125 | /* Outputs point query to stream */ |
126 | template<int K> |
127 | __forceinline embree_ostream operator <<(embree_ostream cout, const PointQueryK<K>& query) |
128 | { |
129 | cout << "{ " << embree_endl |
130 | << " p = " << query.p << embree_endl |
131 | << " r = " << query.radius << embree_endl |
132 | << " time = " << query.time << embree_endl |
133 | << "}" ; |
134 | return cout; |
135 | } |
136 | } |
137 | |