Path: blob/master/thirdparty/embree/kernels/geometry/curve_intersector_distance.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "../common/ray.h"6#include "curve_intersector_precalculations.h"78namespace embree9{10namespace isa11{12template<typename NativeCurve3fa, int M>13struct DistanceCurveHit14{15__forceinline DistanceCurveHit() {}1617__forceinline DistanceCurveHit(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& T, const int i, const int N,18const NativeCurve3fa& curve3D)19: U(U), V(V), T(T), i(i), N(N), curve3D(curve3D), valid(valid) {}2021__forceinline void finalize()22{23vu = (vfloat<M>(step)+U+vfloat<M>(float(i)))*(1.0f/float(N));24vv = V;25vt = T;26}2728__forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); }29__forceinline float t (const size_t i) const { return vt[i]; }30__forceinline Vec3fa Ng(const size_t i) const {31return curve3D.eval_du(vu[i]);32}3334public:35vfloat<M> U;36vfloat<M> V;37vfloat<M> T;38int i, N;39NativeCurve3fa curve3D;4041public:42vbool<M> valid;43vfloat<M> vu;44vfloat<M> vv;45vfloat<M> vt;46};4748template<typename NativeCurve3fa>49struct DistanceCurveHit<NativeCurve3fa,1>50{51enum { M = 1 };5253__forceinline DistanceCurveHit() {}5455__forceinline DistanceCurveHit(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& T, const int i, const int N,56const NativeCurve3fa& curve3D)57: U(U), V(V), T(T), i(i), N(N), curve3D(curve3D), valid(valid) {}5859__forceinline void finalize()60{61vu = (vfloat<M>(step)+U+vfloat<M>(float(i)))*(1.0f/float(N));62vv = V;63vt = T;64}6566__forceinline Vec2f uv () const { return Vec2f(vu,vv); }67__forceinline float t () const { return vt; }68__forceinline Vec3fa Ng() const { return curve3D.eval_du(vu); }6970public:71vfloat<M> U;72vfloat<M> V;73vfloat<M> T;74int i, N;75NativeCurve3fa curve3D;7677public:78vbool<M> valid;79vfloat<M> vu;80vfloat<M> vv;81vfloat<M> vt;82};8384template<typename NativeCurve3fa, int W = VSIZEX>85struct DistanceCurve1Intersector186{87using vboolx = vbool<W>;88using vintx = vint<W>;89using vfloatx = vfloat<W>;90using Vec4vfx = Vec4vf<W>;9192template<typename Epilog>93__forceinline bool intersect(const CurvePrecalculations1& pre, Ray& ray,94RayQueryContext* context,95const CurveGeometry* geom, const unsigned int primID,96const Vec3ff& v0, const Vec3ff& v1, const Vec3ff& v2, const Vec3ff& v3,97const Epilog& epilog)98{99const int N = geom->tessellationRate;100101/* transform control points into ray space */102const NativeCurve3fa curve3Di(v0,v1,v2,v3);103const NativeCurve3fa curve3D = enlargeRadiusToMinWidth(context,geom,ray.org,curve3Di);104const NativeCurve3fa curve2D = curve3D.xfm_pr(pre.ray_space,ray.org);105106/* evaluate the bezier curve */107vboolx valid = vfloatx(step) < vfloatx(float(N));108const Vec4vfx p0 = curve2D.template eval0<W>(0,N);109const Vec4vfx p1 = curve2D.template eval1<W>(0,N);110111/* approximative intersection with cone */112const Vec4vfx v = p1-p0;113const Vec4vfx w = -p0;114const vfloatx d0 = madd(w.x,v.x,w.y*v.y);115const vfloatx d1 = madd(v.x,v.x,v.y*v.y);116const vfloatx u = clamp(d0*rcp(d1),vfloatx(zero),vfloatx(one));117const Vec4vfx p = madd(u,v,p0);118const vfloatx t = p.z*pre.depth_scale;119const vfloatx d2 = madd(p.x,p.x,p.y*p.y);120const vfloatx r = p.w;121const vfloatx r2 = r*r;122valid &= (d2 <= r2) & (vfloatx(ray.tnear()) <= t) & (t <= vfloatx(ray.tfar));123if (EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR != 0.0f)124valid &= t > float(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR)*r*pre.depth_scale; // ignore self intersections125126/* update hit information */127bool ishit = false;128if (unlikely(any(valid))) {129DistanceCurveHit<NativeCurve3fa,W> hit(valid,u,0.0f,t,0,N,curve3D);130ishit = ishit | epilog(valid,hit);131}132133if (unlikely(W < N))134{135/* process SIMD-size many segments per iteration */136for (int i=W; i<N; i+=W)137{138/* evaluate the bezier curve */139vboolx valid = vintx(i)+vintx(step) < vintx(N);140const Vec4vfx p0 = curve2D.template eval0<W>(i,N);141const Vec4vfx p1 = curve2D.template eval1<W>(i,N);142143/* approximative intersection with cone */144const Vec4vfx v = p1-p0;145const Vec4vfx w = -p0;146const vfloatx d0 = madd(w.x,v.x,w.y*v.y);147const vfloatx d1 = madd(v.x,v.x,v.y*v.y);148const vfloatx u = clamp(d0*rcp(d1),vfloatx(zero),vfloatx(one));149const Vec4vfx p = madd(u,v,p0);150const vfloatx t = p.z*pre.depth_scale;151const vfloatx d2 = madd(p.x,p.x,p.y*p.y);152const vfloatx r = p.w;153const vfloatx r2 = r*r;154valid &= (d2 <= r2) & (vfloatx(ray.tnear()) <= t) & (t <= vfloatx(ray.tfar));155if (EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR != 0.0f)156valid &= t > float(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR)*r*pre.depth_scale; // ignore self intersections157158/* update hit information */159if (unlikely(any(valid))) {160DistanceCurveHit<NativeCurve3fa,W> hit(valid,u,0.0f,t,i,N,curve3D);161ishit = ishit | epilog(valid,hit);162}163}164}165return ishit;166}167};168}169}170171172