Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/common/context.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "default.h"
7
#include "rtcore.h"
8
#include "point_query.h"
9
10
namespace embree
11
{
12
class Scene;
13
14
struct RayQueryContext
15
{
16
public:
17
18
__forceinline RayQueryContext(Scene* scene, RTCRayQueryContext* user_context, RTCIntersectArguments* args)
19
: scene(scene), user(user_context), args(args) {}
20
21
__forceinline RayQueryContext(Scene* scene, RTCRayQueryContext* user_context, RTCOccludedArguments* args)
22
: scene(scene), user(user_context), args((RTCIntersectArguments*)args) {}
23
24
__forceinline bool hasContextFilter() const {
25
return args->filter != nullptr;
26
}
27
28
RTCFilterFunctionN getFilter() const {
29
return args->filter;
30
}
31
32
RTCIntersectFunctionN getIntersectFunction() const {
33
return args->intersect;
34
}
35
36
RTCOccludedFunctionN getOccludedFunction() const {
37
return (RTCOccludedFunctionN) args->intersect;
38
}
39
40
__forceinline bool isCoherent() const {
41
return embree::isCoherent(args->flags);
42
}
43
44
__forceinline bool isIncoherent() const {
45
return embree::isIncoherent(args->flags);
46
}
47
48
__forceinline bool enforceArgumentFilterFunction() const {
49
return args->flags & RTC_RAY_QUERY_FLAG_INVOKE_ARGUMENT_FILTER;
50
}
51
52
#if RTC_MIN_WIDTH
53
__forceinline float getMinWidthDistanceFactor() const {
54
return args->minWidthDistanceFactor;
55
}
56
#endif
57
58
public:
59
Scene* scene = nullptr;
60
RTCRayQueryContext* user = nullptr;
61
RTCIntersectArguments* args = nullptr;
62
};
63
64
template<int M, typename Geometry>
65
__forceinline Vec4vf<M> enlargeRadiusToMinWidth(const RayQueryContext* context, const Geometry* geom, const Vec3vf<M>& ray_org, const Vec4vf<M>& v)
66
{
67
#if RTC_MIN_WIDTH
68
const vfloat<M> d = length(Vec3vf<M>(v) - ray_org);
69
const vfloat<M> r = clamp(context->getMinWidthDistanceFactor()*d, v.w, geom->maxRadiusScale*v.w);
70
return Vec4vf<M>(v.x,v.y,v.z,r);
71
#else
72
return v;
73
#endif
74
}
75
76
template<typename Geometry>
77
__forceinline Vec3ff enlargeRadiusToMinWidth(const RayQueryContext* context, const Geometry* geom, const Vec3fa& ray_org, const Vec3ff& v)
78
{
79
#if RTC_MIN_WIDTH
80
const float d = length(Vec3fa(v) - ray_org);
81
const float r = clamp(context->getMinWidthDistanceFactor()*d, v.w, geom->maxRadiusScale*v.w);
82
return Vec3ff(v.x,v.y,v.z,r);
83
#else
84
return v;
85
#endif
86
}
87
88
template<typename Geometry>
89
__forceinline Vec3ff enlargeRadiusToMinWidth(const RayQueryContext* context, const Geometry* geom, const Vec3fa& ray_org, const Vec4f& v) {
90
return enlargeRadiusToMinWidth(context,geom,ray_org,Vec3ff(v.x,v.y,v.z,v.w));
91
}
92
93
enum PointQueryType
94
{
95
POINT_QUERY_TYPE_UNDEFINED = 0,
96
POINT_QUERY_TYPE_SPHERE = 1,
97
POINT_QUERY_TYPE_AABB = 2,
98
};
99
100
typedef bool (*PointQueryFunction)(struct RTCPointQueryFunctionArguments* args);
101
102
struct PointQueryContext
103
{
104
public:
105
__forceinline PointQueryContext(Scene* scene,
106
PointQuery* query_ws,
107
PointQueryType query_type,
108
PointQueryFunction func,
109
RTCPointQueryContext* userContext,
110
float similarityScale,
111
void* userPtr)
112
: scene(scene)
113
, tstate(nullptr)
114
, query_ws(query_ws)
115
, query_type(query_type)
116
, func(func)
117
, userContext(userContext)
118
, similarityScale(similarityScale)
119
, userPtr(userPtr)
120
, primID(RTC_INVALID_GEOMETRY_ID)
121
, geomID(RTC_INVALID_GEOMETRY_ID)
122
, query_radius(query_ws->radius)
123
{
124
update();
125
}
126
127
public:
128
__forceinline void update()
129
{
130
if (query_type == POINT_QUERY_TYPE_AABB) {
131
assert(similarityScale == 0.f);
132
updateAABB();
133
}
134
else{
135
query_radius = Vec3fa(query_ws->radius * similarityScale);
136
}
137
if (userContext->instStackSize == 0) {
138
assert(similarityScale == 1.f);
139
}
140
}
141
142
__forceinline void updateAABB()
143
{
144
if (likely(query_ws->radius == (float)inf || userContext->instStackSize == 0)) {
145
query_radius = Vec3fa(query_ws->radius);
146
return;
147
}
148
149
const AffineSpace3fa m = AffineSpace3fa_load_unaligned((AffineSpace3fa*)userContext->world2inst[userContext->instStackSize-1]);
150
BBox3fa bbox(Vec3fa(-query_ws->radius), Vec3fa(query_ws->radius));
151
bbox = xfmBounds(m, bbox);
152
query_radius = 0.5f * (bbox.upper - bbox.lower);
153
}
154
155
public:
156
Scene* scene;
157
void* tstate;
158
159
PointQuery* query_ws; // the original world space point query
160
PointQueryType query_type;
161
PointQueryFunction func;
162
RTCPointQueryContext* userContext;
163
float similarityScale;
164
165
void* userPtr;
166
167
unsigned int primID;
168
unsigned int geomID;
169
170
Vec3fa query_radius; // used if the query is converted to an AABB internally
171
};
172
}
173
174
175