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
|
// Copyright 2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// ospray
#include "common/Data.ih"
#include "common/DifferentialGeometry.ih"
#include "common/FilterIntersect.ih"
#include "common/Intersect.ih"
#include "common/Ray.ih"
#include "geometry/Geometry.ih"
#include "rkcommon/math/box.ih"
#include "rkcommon/math/vec.ih"
// c++ shared
#include "PlanesShared.h"
OSPRAY_BEGIN_ISPC_NAMESPACE
// The plane can't be truly infinite because Embree has a limit on object size
#define PLANE_MAX_SIZE 1e18f
#define DUMMY_MAX_T 1e38f
export void Planes_bounds(const RTCBoundsFunctionArguments *uniform args)
{
const uniform vec3f lo =
make_vec3f(-PLANE_MAX_SIZE, -PLANE_MAX_SIZE, -PLANE_MAX_SIZE);
const uniform vec3f hi =
make_vec3f(PLANE_MAX_SIZE, PLANE_MAX_SIZE, PLANE_MAX_SIZE);
// use maximum size planes if bounding boxes not provided
Planes *uniform self = (Planes * uniform) args->geometryUserPtr;
box3fa *uniform out = (box3fa * uniform) args->bounds_o;
if (valid(self->bounds)) {
uniform int primID = args->primID;
uniform box3f bbox = get_box3f(self->bounds, primID);
*out = make_box3fa(max(bbox.lower, lo), min(bbox.upper, hi));
} else {
*out = make_box3fa(lo, hi);
}
}
SYCL_EXTERNAL unmasked void Planes_intersect_kernel(
const RTCIntersectFunctionNArguments *uniform args,
const uniform bool isOcclusionTest)
{
// make sure to set the mask
if (!args->valid[programIndex])
return;
args->valid[programIndex] = 0;
// get geometry pointers
Planes *uniform self = (Planes * uniform) args->geometryUserPtr;
uniform unsigned int primID = args->primID;
// this assumes that the args->rayhit is actually a pointer to a varying
// ray!
varying Ray *uniform ray = (varying Ray * uniform) args->rayhit;
// intersect plane with ray
uniform vec4f coeffs = get_vec4f(self->coeffs, primID);
const Hit hit = intersectPlane(ray->org, ray->dir, coeffs);
// do bounding box check if defined
if (valid(self->bounds)) {
uniform box3f bbox = get_box3f(self->bounds, primID);
const Intersections isect = intersectBox(ray->org, ray->dir, bbox);
// discard the intersection if our ray misses bbox completely or
// the intersection is not within bbox extents,
// assumes that (isect.entry.hit == isect.exit.hit)
if (!isect.entry.hit || (hit.t < isect.entry.t) || (hit.t > isect.exit.t))
return;
}
// we are done if first intersection accepted
if (filterIntersectionSingle(args, hit, isOcclusionTest, false)) {
args->valid[programIndex] = -1;
return;
}
// handle plane parallel to ray, which breaks interval logic for clipping
if (!hit.hit) {
const uniform vec3f normal = make_vec3f(coeffs);
if (coeffs.w > dot(ray->org, normal)) { // within clipping half-space?
Hit hitExitDummy;
hitExitDummy.hit = true;
hitExitDummy.t = DUMMY_MAX_T;
hitExitDummy.N = ray->dir;
filterIntersectionSingle(args, hitExitDummy, isOcclusionTest, true);
}
return;
}
// The second implicit plane is needed just for infinite planes
if (valid(self->bounds))
return;
// clipping algorithm works on closed surfaces only,
// so for infinite planes an implicit second plane is tested here,
// it is positioned at the edge of bounding box and its
// normal is oriented in opposite direction to mimic a closed surface
const uniform vec4f coeffsImplicit =
make_vec4f(-coeffs.x, -coeffs.y, -coeffs.z, PLANE_MAX_SIZE);
const Hit hitImplicit = intersectPlane(ray->org, ray->dir, coeffsImplicit);
// we don't want the second plane to be drawn so this intersection is never
// accepted
filterIntersectionSingle(args, hitImplicit, isOcclusionTest, true);
}
export void Planes_intersect(
const struct RTCIntersectFunctionNArguments *uniform args)
{
Planes_intersect_kernel(args, false);
}
export void Planes_occluded(
const struct RTCOccludedFunctionNArguments *uniform args)
{
Planes_intersect_kernel(
(RTCIntersectFunctionNArguments * uniform) args, true);
}
SYCL_EXTERNAL void Planes_postIntersect(const Geometry *uniform,
varying DifferentialGeometry &dg,
const varying Ray &ray,
uniform int64)
{
dg.Ng = dg.Ns = ray.Ng;
}
export void *uniform Planes_postIntersect_addr()
{
return (void *uniform)Planes_postIntersect;
}
OSPRAY_END_ISPC_NAMESPACE
|