File: Isosurfaces.ispc

package info (click to toggle)
ospray 3.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 10,040 kB
  • sloc: cpp: 80,569; ansic: 951; sh: 805; makefile: 171; python: 69
file content (142 lines) | stat: -rw-r--r-- 3,785 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
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
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "common/FeatureFlagsEnum.h"
#ifdef OSPRAY_ENABLE_VOLUMES

// ospray
#include "common/FilterIntersect.ih"
#include "common/Ray.ih"
#include "common/World.ih"
#include "geometry/Geometry.ih"
#include "rkcommon/math/box.ih"
#include "rkcommon/math/vec.ih"
#include "volume/Volume.ih"
// c++ shared
#include "IsosurfacesShared.h"

OSPRAY_BEGIN_ISPC_NAMESPACE

int Isosurfaces_primID(const Isosurfaces *uniform self, const float isovalue)
{
  for (uniform int i = 0; i < self->super.numPrimitives; ++i) {
    if (isovalue == self->isovalues[i]) {
      return i;
    }
  }
  return -1;
}

export void Isosurfaces_bounds(const RTCBoundsFunctionArguments *uniform args)
{
  uniform Isosurfaces *uniform self =
      (uniform Isosurfaces * uniform) args->geometryUserPtr;

  box3fa *uniform out = (box3fa * uniform) args->bounds_o;
  *out = make_box3fa(self->volume->boundingBox);
}

SYCL_EXTERNAL void Isosurfaces_postIntersect(const Geometry *uniform geometry,
    varying DifferentialGeometry &dg,
    const varying Ray &ray,
    uniform int64 flags,
    const uniform FeatureFlagsHandler &ffh)
{
  Isosurfaces *uniform self = (Isosurfaces * uniform) geometry;

  if (flags & (DG_NS | DG_NG))
    dg.Ng = dg.Ns =
        Volume_getGradient(self->volume, ray.Ng /* actually local hit */, ffh);

  // convert ray-space epsilon (in ray.u) to object-/world-space using max(dir)
  // instead of costly length; the error is at most sqrt(3)~1.7, quite
  // acceptable for eps
  dg.epsilon = reduce_max(abs(ray.dir)) * ray.u;
}

SYCL_EXTERNAL void unmasked Isosurfaces_intersect_kernel(
    const RTCIntersectFunctionNArguments *uniform args,
    const uniform bool isOcclusionTest,
    const uniform FeatureFlagsHandler &ffh)
{
  // make sure to set the mask
  if (!args->valid[programIndex]) {
    return;
  }

  const uniform FeatureFlags ff = getFeatureFlags(ffh);

  args->valid[programIndex] = 0;

  Isosurfaces *uniform self = (Isosurfaces * uniform) args->geometryUserPtr;

  // this assumes that the args->rayhit is actually a pointer to a varying ray!
  varying Ray *uniform ray = (varying Ray * uniform) args->rayhit;

  VKLHitIterator iterator;
  vkl_range1f tRange;
  tRange.lower = ray->t0;
  tRange.upper = ray->t;
  float time = 0.f;
  // do not use alloca: it prevents inlining and thus optimization
  // wrt. "template arg" isOcclusionTest, alloca also not supported on GPU
  uniform uint8 hitIteratorBuffer[VKL_MAX_HIT_ITERATOR_SIZE];

  iterator = vklInitHitIteratorV(&self->vklHitContext,
      (varying vkl_vec3f *)&ray->org,
      (varying vkl_vec3f *)&ray->dir,
      &tRange,
#ifndef OSPRAY_TARGET_SYCL
      &
#endif
      time,
      hitIteratorBuffer
#ifdef OSPRAY_TARGET_SYCL
      ,
      ff.volume
#endif
  );

  VKLHit hit;
  bool gotHit = vklIterateHitV(iterator,
      &hit
#ifdef OSPRAY_TARGET_SYCL
      ,
      ff.volume
#endif
  );
  if (!gotHit)
    return;

  Hit hitFilter;
  hitFilter.hit = true;
  hitFilter.t = hit.t;
  // Transport hit point in *volume local coords* to postIntersect
  hitFilter.N = ray->org + ray->dir * hit.t;
  // Transport epsilon to postIntersect
  hitFilter.u = hit.epsilon;
  bool accept =
      filterIntersectionSingle(args, hitFilter, isOcclusionTest, false);
  if (!accept)
    return;

  args->valid[programIndex] = -1;

  if (isOcclusionTest) {
    ray->t = neg_inf;
  } else {
    ray->instID = args->context->instID[0];
    ray->geomID = args->geomID;
    ray->primID = Isosurfaces_primID(self, hit.sample);
    ray->t = hitFilter.t;
    ray->u = hitFilter.u;
    ray->Ng = hitFilter.N;
  }
}

export void *uniform Isosurfaces_postIntersect_addr()
{
  return (void *uniform)Isosurfaces_postIntersect;
}

OSPRAY_END_ISPC_NAMESPACE
#endif