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 IntersectContext
15   {
16   public:
IntersectContextIntersectContext17     __forceinline IntersectContext(Scene* scene, RTCIntersectContext* user_context)
18       : scene(scene), user(user_context) {}
19 
hasContextFilterIntersectContext20     __forceinline bool hasContextFilter() const {
21       return user->filter != nullptr;
22     }
23 
isCoherentIntersectContext24     __forceinline bool isCoherent() const {
25       return embree::isCoherent(user->flags);
26     }
27 
isIncoherentIntersectContext28     __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>
enlargeRadiusToMinWidth(const IntersectContext * context,const Geometry * geom,const Vec3vf<M> & ray_org,const Vec4vf<M> & v)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>
enlargeRadiusToMinWidth(const IntersectContext * context,const Geometry * geom,const Vec3fa & ray_org,const Vec3ff & v)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:
PointQueryContextPointQueryContext73     __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:
updateAABBPointQueryContext101     __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 
114 public:
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