File: FilterIntersect.ih

package info (click to toggle)
ospray 3.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,048 kB
  • sloc: cpp: 80,569; ansic: 951; sh: 805; makefile: 170; python: 69
file content (117 lines) | stat: -rw-r--r-- 3,202 bytes parent folder | download | duplicates (2)
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
// Copyright 2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "Intersect.ih"
#include "Ray.ih"
#include "RayQueryContext.ih"

OSPRAY_BEGIN_ISPC_NAMESPACE

#ifndef OSPRAY_TARGET_SYCL
unmasked void clippingIntersectionFilterV(
    const RTCFilterFunctionNArguments *uniform args);

inline bool filterCall(const RTCIntersectFunctionNArguments *uniform args,
    const RTCHit &rtcHitTemp)
{
  varying int imask;
  varying bool mask = __mask;
  unmasked
  {
    imask = mask ? -1 : 0;
  }

  // call filter intersection callback
  uniform RTCFilterFunctionNArguments filterArgs;
  filterArgs.valid = (int *uniform) & imask;
  filterArgs.geometryUserPtr = args->geometryUserPtr;
  filterArgs.context = args->context;
  filterArgs.ray = (RTCRayN * uniform) args->rayhit;
  filterArgs.hit = (RTCHitN * uniform) & rtcHitTemp;
  filterArgs.N = args->N;
  clippingIntersectionFilterV(&filterArgs);

  // return true if hit has been accepted
  return imask == -1;
}
#endif

inline bool filterIntersectionSingle(
    const RTCIntersectFunctionNArguments *uniform args,
    const Hit &hit,
    const uniform bool isOcclusionTest,
    const uniform bool alwaysReject)
{
  // if there is a hit
  varying Ray *uniform ray = (varying Ray * uniform) args->rayhit;
  if (hit.hit && hit.t > ray->t0 && hit.t <= ray->t) {
    // set a new hit value
    const float tOld = ray->t;
    ray->t = hit.t;

    // prepare temporary hit structure
    RTCHit rtcHitTemp;
    rtcHitTemp.Ng_x = hit.N.x;
    rtcHitTemp.Ng_y = hit.N.y;
    rtcHitTemp.Ng_z = hit.N.z;
    rtcHitTemp.u = hit.u;
    rtcHitTemp.v = 0.f;
    rtcHitTemp.primID = args->primID;
    rtcHitTemp.geomID = args->geomID;
    rtcHitTemp.instID[0] = args->context->instID[0];

    // call filter intersection callback if needed
#ifndef OSPRAY_TARGET_SYCL
    RayQueryContextDefault *uniform ctx =
        (RayQueryContextDefault * uniform) args->context;
    const uniform bool noFilter = ctx->type != RQCT_CLIPPING;
    const bool accept = noFilter || filterCall(args, rtcHitTemp);
#else
    const bool accept = true;
#endif
    if (alwaysReject) {
      // the hit is always rejected
      ray->t = tOld;
    } else {
      if (accept) {
        // hit has been accepted
        if (isOcclusionTest) {
          ray->t = neg_inf;
        } else {
          ray->Ng.x = hit.N.x;
          ray->Ng.y = hit.N.y;
          ray->Ng.z = hit.N.z;

          ray->u = hit.u;
          ray->v = 0.f;

          ray->primID = args->primID;
          ray->geomID = args->geomID;
          ray->instID = args->context->instID[0];
        }
        return true;
      } else {
        // the hit has been rejected in the filter function,
        // restore initial ray dimensions
        ray->t = tOld;
      }
    }
  }

  // no hit or not accepted
  return false;
}

inline bool filterIntersectionBoth(
    const RTCIntersectFunctionNArguments *uniform args,
    const Intersections &isect,
    const uniform bool isOcclusionTest)
{
  if (!filterIntersectionSingle(args, isect.entry, isOcclusionTest, false)) {
    return filterIntersectionSingle(args, isect.exit, isOcclusionTest, false);
  }
  return true;
}
OSPRAY_END_ISPC_NAMESPACE