File: World.ispc

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 (103 lines) | stat: -rw-r--r-- 3,334 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
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "World.ih"

OSPRAY_BEGIN_ISPC_NAMESPACE

#ifndef OSPRAY_TARGET_SYCL
unmasked void clippingIntersectionFilterV(
    const RTCFilterFunctionNArguments *uniform args)
{
  // Set execution mask
  uniform int *uniform valid = args->valid;
  if (!valid[programIndex])
    return;

  // Get pointer to the intersection context
  RayQueryContextClipping *uniform context =
      (RayQueryContextClipping * uniform) args->context;

  // We skip this intersection to collect all remaining intersections
  valid[programIndex] = 0;

  // Skip if array is full
  if (context->hitsCount >= CLIPPING_HITS_MAX_COUNT)
    return;

  // Get ray and hit
  varying Ray *uniform ray = (varying Ray * uniform) args->ray;
  varying const RTCHit *uniform hit = (varying const RTCHit *uniform)args->hit;

  // Prepare clipping normal
  vec3f Nc;
  {
    // The postIntersect function needs the hit part of the Ray structure to be
    // initialized. Making a ray copy here is quite costly. That is why just
    // the necessary ray fields are set here.
    DifferentialGeometry dg;
    ray->Ng = make_vec3f(hit->Ng_x, hit->Ng_y, hit->Ng_z);
    ray->u = hit->u;
    ray->v = hit->v;
    ray->primID = hit->primID;
    ray->geomID = hit->geomID;

    // We need to call postIntersect on clipping geometry
    foreach_unique (instID in hit->instID[0]) {
      // Call postIntersect to get shading normal
      Instance *uniform instance = *(context->world->instances + instID);
      Instance_postIntersect(
          instance, NULL, dg, *ray, DG_NG | DG_NS, true, *context->super.ffh);

      // Use geometry normal for clipping
      // but use shading normal to check if inversion is needed
      Nc = (dot(dg.Ns, dg.Ng) > 0.f) ? ray->Ng : neg(ray->Ng);
    }

    // Restore IDs initial values
    ray->primID = RTC_INVALID_GEOMETRY_ID;
    ray->geomID = RTC_INVALID_GEOMETRY_ID;
  }

  // Based on clipping normal vector decide if the ray is
  // entering clipping geometry (set positive hit value) or exiting clipping
  // geometry (set negative hit value)
  const bool exitsClipping = (dot(ray->dir, Nc) > 0.f);
  ClippingHit cHit;
  cHit.t = (exitsClipping) ? -ray->t : ray->t;
  cHit.primID = hit->primID;
  cHit.geomID = hit->geomID;
  cHit.instID = hit->instID[0];

  // Some geometry types (e.g. curves, subdivisions)
  // may give more than 2 intersections, we have to filter them out
  for (uint32 i = 0; i < context->hitsCount; i++) {
    if ((context->hits[i].primID == cHit.primID)
        && (context->hits[i].geomID == cHit.geomID)
        && (context->hits[i].instID == cHit.instID)
        && floatUlpCompare(context->hits[i].t, cHit.t, 512))
      return;
  }

  // Now we know that this intersection will be taken into account,
  // so we can update clipping depth correction value accordingly
  if (exitsClipping) {
    context->corrClippingDepth--;
  } else {
    context->corrClippingDepth++;
  }

  // Insert hit value into sorted array
  for (uint32 i = 0; i < context->hitsCount; i++) {
    if (abs(context->hits[i].t) > abs(cHit.t)) {
      const ClippingHit tmp = context->hits[i];
      context->hits[i] = cHit;
      cHit = tmp;
    }
  }
  context->hits[context->hitsCount] = cHit;
  context->hitsCount++;
}
#endif

OSPRAY_END_ISPC_NAMESPACE