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
10namespace embree
11{
12 class Scene;
13
14 struct IntersectContext
15 {
16 public:
17 __forceinline IntersectContext(Scene* scene, RTCIntersectContext* user_context)
18 : scene(scene), user(user_context) {}
19
20 __forceinline bool hasContextFilter() const {
21 return user->filter != nullptr;
22 }
23
24 __forceinline bool isCoherent() const {
25 return embree::isCoherent(user->flags);
26 }
27
28 __forceinline bool isIncoherent() const {
29 return embree::isIncoherent(user->flags);
30 }
31
32 public:
33 Scene* scene;
34 RTCIntersectContext* user;
35 };
36
37 template<int M, typename Geometry>
38 __forceinline Vec4vf<M> enlargeRadiusToMinWidth(const IntersectContext* context, const Geometry* geom, const Vec3vf<M>& ray_org, const Vec4vf<M>& v)
39 {
40#if RTC_MIN_WIDTH
41 const vfloat<M> d = length(Vec3vf<M>(v) - ray_org);
42 const vfloat<M> r = clamp(context->user->minWidthDistanceFactor*d, v.w, geom->maxRadiusScale*v.w);
43 return Vec4vf<M>(v.x,v.y,v.z,r);
44#else
45 return v;
46#endif
47 }
48
49 template<typename Geometry>
50 __forceinline Vec3ff enlargeRadiusToMinWidth(const IntersectContext* context, const Geometry* geom, const Vec3fa& ray_org, const Vec3ff& v)
51 {
52#if RTC_MIN_WIDTH
53 const float d = length(Vec3fa(v) - ray_org);
54 const float r = clamp(context->user->minWidthDistanceFactor*d, v.w, geom->maxRadiusScale*v.w);
55 return Vec3ff(v.x,v.y,v.z,r);
56#else
57 return v;
58#endif
59 }
60
61 enum PointQueryType
62 {
63 POINT_QUERY_TYPE_UNDEFINED = 0,
64 POINT_QUERY_TYPE_SPHERE = 1,
65 POINT_QUERY_TYPE_AABB = 2,
66 };
67
68 typedef bool (*PointQueryFunction)(struct RTCPointQueryFunctionArguments* args);
69
70 struct PointQueryContext
71 {
72 public:
73 __forceinline PointQueryContext(Scene* scene,
74 PointQuery* query_ws,
75 PointQueryType query_type,
76 PointQueryFunction func,
77 RTCPointQueryContext* userContext,
78 float similarityScale,
79 void* userPtr)
80 : scene(scene)
81 , query_ws(query_ws)
82 , query_type(query_type)
83 , func(func)
84 , userContext(userContext)
85 , similarityScale(similarityScale)
86 , userPtr(userPtr)
87 , primID(RTC_INVALID_GEOMETRY_ID)
88 , geomID(RTC_INVALID_GEOMETRY_ID)
89 , query_radius(query_ws->radius)
90 {
91 if (query_type == POINT_QUERY_TYPE_AABB) {
92 assert(similarityScale == 0.f);
93 updateAABB();
94 }
95 if (userContext->instStackSize == 0) {
96 assert(similarityScale == 1.f);
97 }
98 }
99
100 public:
101 __forceinline void updateAABB()
102 {
103 if (likely(query_ws->radius == (float)inf || userContext->instStackSize == 0)) {
104 query_radius = Vec3fa(query_ws->radius);
105 return;
106 }
107
108 const AffineSpace3fa m = AffineSpace3fa_load_unaligned((AffineSpace3fa*)userContext->world2inst[userContext->instStackSize-1]);
109 BBox3fa bbox(Vec3fa(-query_ws->radius), Vec3fa(query_ws->radius));
110 bbox = xfmBounds(m, bbox);
111 query_radius = 0.5f * (bbox.upper - bbox.lower);
112 }
113
114public:
115 Scene* scene;
116
117 PointQuery* query_ws; // the original world space point query
118 PointQueryType query_type;
119 PointQueryFunction func;
120 RTCPointQueryContext* userContext;
121 const float similarityScale;
122
123 void* userPtr;
124
125 unsigned int primID;
126 unsigned int geomID;
127
128 Vec3fa query_radius; // used if the query is converted to an AABB internally
129 };
130}
131
132