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