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