Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/curve_intersector_distance.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "../common/ray.h"
7
#include "curve_intersector_precalculations.h"
8
9
namespace embree
10
{
11
namespace isa
12
{
13
template<typename NativeCurve3fa, int M>
14
struct DistanceCurveHit
15
{
16
__forceinline DistanceCurveHit() {}
17
18
__forceinline DistanceCurveHit(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& T, const int i, const int N,
19
const NativeCurve3fa& curve3D)
20
: U(U), V(V), T(T), i(i), N(N), curve3D(curve3D), valid(valid) {}
21
22
__forceinline void finalize()
23
{
24
vu = (vfloat<M>(step)+U+vfloat<M>(float(i)))*(1.0f/float(N));
25
vv = V;
26
vt = T;
27
}
28
29
__forceinline Vec2f uv (const size_t i) const { return Vec2f(vu[i],vv[i]); }
30
__forceinline float t (const size_t i) const { return vt[i]; }
31
__forceinline Vec3fa Ng(const size_t i) const {
32
return curve3D.eval_du(vu[i]);
33
}
34
35
public:
36
vfloat<M> U;
37
vfloat<M> V;
38
vfloat<M> T;
39
int i, N;
40
NativeCurve3fa curve3D;
41
42
public:
43
vbool<M> valid;
44
vfloat<M> vu;
45
vfloat<M> vv;
46
vfloat<M> vt;
47
};
48
49
template<typename NativeCurve3fa>
50
struct DistanceCurveHit<NativeCurve3fa,1>
51
{
52
enum { M = 1 };
53
54
__forceinline DistanceCurveHit() {}
55
56
__forceinline DistanceCurveHit(const vbool<M>& valid, const vfloat<M>& U, const vfloat<M>& V, const vfloat<M>& T, const int i, const int N,
57
const NativeCurve3fa& curve3D)
58
: U(U), V(V), T(T), i(i), N(N), curve3D(curve3D), valid(valid) {}
59
60
__forceinline void finalize()
61
{
62
vu = (vfloat<M>(step)+U+vfloat<M>(float(i)))*(1.0f/float(N));
63
vv = V;
64
vt = T;
65
}
66
67
__forceinline Vec2f uv () const { return Vec2f(vu,vv); }
68
__forceinline float t () const { return vt; }
69
__forceinline Vec3fa Ng() const { return curve3D.eval_du(vu); }
70
71
public:
72
vfloat<M> U;
73
vfloat<M> V;
74
vfloat<M> T;
75
int i, N;
76
NativeCurve3fa curve3D;
77
78
public:
79
vbool<M> valid;
80
vfloat<M> vu;
81
vfloat<M> vv;
82
vfloat<M> vt;
83
};
84
85
template<typename NativeCurve3fa, int W = VSIZEX>
86
struct DistanceCurve1Intersector1
87
{
88
using vboolx = vbool<W>;
89
using vintx = vint<W>;
90
using vfloatx = vfloat<W>;
91
using Vec4vfx = Vec4vf<W>;
92
93
template<typename Epilog>
94
__forceinline bool intersect(const CurvePrecalculations1& pre, Ray& ray,
95
RayQueryContext* context,
96
const CurveGeometry* geom, const unsigned int primID,
97
const Vec3ff& v0, const Vec3ff& v1, const Vec3ff& v2, const Vec3ff& v3,
98
const Epilog& epilog)
99
{
100
const int N = geom->tessellationRate;
101
102
/* transform control points into ray space */
103
const NativeCurve3fa curve3Di(v0,v1,v2,v3);
104
const NativeCurve3fa curve3D = enlargeRadiusToMinWidth(context,geom,ray.org,curve3Di);
105
const NativeCurve3fa curve2D = curve3D.xfm_pr(pre.ray_space,ray.org);
106
107
/* evaluate the bezier curve */
108
vboolx valid = vfloatx(step) < vfloatx(float(N));
109
const Vec4vfx p0 = curve2D.template eval0<W>(0,N);
110
const Vec4vfx p1 = curve2D.template eval1<W>(0,N);
111
112
/* approximative intersection with cone */
113
const Vec4vfx v = p1-p0;
114
const Vec4vfx w = -p0;
115
const vfloatx d0 = madd(w.x,v.x,w.y*v.y);
116
const vfloatx d1 = madd(v.x,v.x,v.y*v.y);
117
const vfloatx u = clamp(d0*rcp(d1),vfloatx(zero),vfloatx(one));
118
const Vec4vfx p = madd(u,v,p0);
119
const vfloatx t = p.z*pre.depth_scale;
120
const vfloatx d2 = madd(p.x,p.x,p.y*p.y);
121
const vfloatx r = p.w;
122
const vfloatx r2 = r*r;
123
valid &= (d2 <= r2) & (vfloatx(ray.tnear()) <= t) & (t <= vfloatx(ray.tfar));
124
if (EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR != 0.0f)
125
valid &= t > float(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR)*r*pre.depth_scale; // ignore self intersections
126
127
/* update hit information */
128
bool ishit = false;
129
if (unlikely(any(valid))) {
130
DistanceCurveHit<NativeCurve3fa,W> hit(valid,u,0.0f,t,0,N,curve3D);
131
ishit = ishit | epilog(valid,hit);
132
}
133
134
if (unlikely(W < N))
135
{
136
/* process SIMD-size many segments per iteration */
137
for (int i=W; i<N; i+=W)
138
{
139
/* evaluate the bezier curve */
140
vboolx valid = vintx(i)+vintx(step) < vintx(N);
141
const Vec4vfx p0 = curve2D.template eval0<W>(i,N);
142
const Vec4vfx p1 = curve2D.template eval1<W>(i,N);
143
144
/* approximative intersection with cone */
145
const Vec4vfx v = p1-p0;
146
const Vec4vfx w = -p0;
147
const vfloatx d0 = madd(w.x,v.x,w.y*v.y);
148
const vfloatx d1 = madd(v.x,v.x,v.y*v.y);
149
const vfloatx u = clamp(d0*rcp(d1),vfloatx(zero),vfloatx(one));
150
const Vec4vfx p = madd(u,v,p0);
151
const vfloatx t = p.z*pre.depth_scale;
152
const vfloatx d2 = madd(p.x,p.x,p.y*p.y);
153
const vfloatx r = p.w;
154
const vfloatx r2 = r*r;
155
valid &= (d2 <= r2) & (vfloatx(ray.tnear()) <= t) & (t <= vfloatx(ray.tfar));
156
if (EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR != 0.0f)
157
valid &= t > float(EMBREE_CURVE_SELF_INTERSECTION_AVOIDANCE_FACTOR)*r*pre.depth_scale; // ignore self intersections
158
159
/* update hit information */
160
if (unlikely(any(valid))) {
161
DistanceCurveHit<NativeCurve3fa,W> hit(valid,u,0.0f,t,i,N,curve3D);
162
ishit = ishit | epilog(valid,hit);
163
}
164
}
165
}
166
return ishit;
167
}
168
};
169
}
170
}
171
172