1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "default.h"
7
8namespace 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