| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  | // Copyright 2009-2021 Intel Corporation
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  | // SPDX-License-Identifier: Apache-2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "default.h"
 | 
					
						
							|  |  |  | #include "rtcore.h"
 | 
					
						
							|  |  |  | #include "point_query.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace embree | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   class Scene; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct IntersectContext | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     __forceinline IntersectContext(Scene* scene, RTCIntersectContext* user_context) | 
					
						
							|  |  |  |       : scene(scene), user(user_context) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline bool hasContextFilter() const { | 
					
						
							|  |  |  |       return user->filter != nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline bool isCoherent() const { | 
					
						
							|  |  |  |       return embree::isCoherent(user->flags); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     __forceinline bool isIncoherent() const { | 
					
						
							|  |  |  |       return embree::isIncoherent(user->flags); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     Scene* scene; | 
					
						
							|  |  |  |     RTCIntersectContext* user; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template<int M, typename Geometry> | 
					
						
							|  |  |  |       __forceinline Vec4vf<M> enlargeRadiusToMinWidth(const IntersectContext* context, const Geometry* geom, const Vec3vf<M>& ray_org, const Vec4vf<M>& v) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | #if RTC_MIN_WIDTH
 | 
					
						
							|  |  |  |       const vfloat<M> d = length(Vec3vf<M>(v) - ray_org); | 
					
						
							|  |  |  |       const vfloat<M> r = clamp(context->user->minWidthDistanceFactor*d, v.w, geom->maxRadiusScale*v.w); | 
					
						
							|  |  |  |       return Vec4vf<M>(v.x,v.y,v.z,r); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       return v; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename Geometry> | 
					
						
							|  |  |  |     __forceinline Vec3ff enlargeRadiusToMinWidth(const IntersectContext* context, const Geometry* geom, const Vec3fa& ray_org, const Vec3ff& v) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  | #if RTC_MIN_WIDTH
 | 
					
						
							|  |  |  |     const float d = length(Vec3fa(v) - ray_org); | 
					
						
							|  |  |  |     const float r = clamp(context->user->minWidthDistanceFactor*d, v.w, geom->maxRadiusScale*v.w); | 
					
						
							|  |  |  |     return Vec3ff(v.x,v.y,v.z,r); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     return v; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   enum PointQueryType | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     POINT_QUERY_TYPE_UNDEFINED = 0, | 
					
						
							|  |  |  |     POINT_QUERY_TYPE_SPHERE = 1, | 
					
						
							|  |  |  |     POINT_QUERY_TYPE_AABB = 2, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   typedef bool (*PointQueryFunction)(struct RTCPointQueryFunctionArguments* args); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   struct PointQueryContext | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     __forceinline PointQueryContext(Scene* scene,  | 
					
						
							|  |  |  |                                     PointQuery* query_ws,  | 
					
						
							|  |  |  |                                     PointQueryType query_type, | 
					
						
							|  |  |  |                                     PointQueryFunction func,  | 
					
						
							|  |  |  |                                     RTCPointQueryContext* userContext, | 
					
						
							|  |  |  |                                     float similarityScale, | 
					
						
							|  |  |  |                                     void* userPtr) | 
					
						
							|  |  |  |       : scene(scene) | 
					
						
							|  |  |  |       , query_ws(query_ws) | 
					
						
							|  |  |  |       , query_type(query_type) | 
					
						
							|  |  |  |       , func(func) | 
					
						
							|  |  |  |       , userContext(userContext) | 
					
						
							|  |  |  |       , similarityScale(similarityScale) | 
					
						
							|  |  |  |       , userPtr(userPtr)  | 
					
						
							|  |  |  |       , primID(RTC_INVALID_GEOMETRY_ID) | 
					
						
							|  |  |  |       , geomID(RTC_INVALID_GEOMETRY_ID) | 
					
						
							|  |  |  |       , query_radius(query_ws->radius) | 
					
						
							|  |  |  |     {  | 
					
						
							|  |  |  |       if (query_type == POINT_QUERY_TYPE_AABB) { | 
					
						
							|  |  |  |         assert(similarityScale == 0.f); | 
					
						
							|  |  |  |         updateAABB(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (userContext->instStackSize == 0) { | 
					
						
							|  |  |  |         assert(similarityScale == 1.f); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     __forceinline void updateAABB()  | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (likely(query_ws->radius == (float)inf || userContext->instStackSize == 0)) { | 
					
						
							|  |  |  |         query_radius = Vec3fa(query_ws->radius); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const AffineSpace3fa m = AffineSpace3fa_load_unaligned((AffineSpace3fa*)userContext->world2inst[userContext->instStackSize-1]); | 
					
						
							|  |  |  |       BBox3fa bbox(Vec3fa(-query_ws->radius), Vec3fa(query_ws->radius)); | 
					
						
							|  |  |  |       bbox = xfmBounds(m, bbox); | 
					
						
							|  |  |  |       query_radius = 0.5f * (bbox.upper - bbox.lower); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     Scene* scene; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PointQuery* query_ws; // the original world space point query 
 | 
					
						
							|  |  |  |     PointQueryType query_type; | 
					
						
							|  |  |  |     PointQueryFunction func; | 
					
						
							|  |  |  |     RTCPointQueryContext* userContext; | 
					
						
							|  |  |  |     const float similarityScale; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void* userPtr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned int primID; | 
					
						
							|  |  |  |     unsigned int geomID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vec3fa query_radius;  // used if the query is converted to an AABB internally
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |