Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/geometry/quad_intersector.h
9905 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
namespace embree
7
{
8
namespace isa
9
{
10
/*! Intersects a ray with a quad with backface culling
11
* enabled. The quad v0,v1,v2,v3 is split into two triangles
12
* v0,v1,v3 and v2,v3,v1. The edge v1,v2 decides which of the two
13
* triangles gets intersected. */
14
template<int N>
15
__forceinline vbool<N> intersect_quad_backface_culling(const vbool<N>& valid0,
16
const Vec3fa& ray_org,
17
const Vec3fa& ray_dir,
18
const float ray_tnear,
19
const float ray_tfar,
20
const Vec3vf<N>& quad_v0,
21
const Vec3vf<N>& quad_v1,
22
const Vec3vf<N>& quad_v2,
23
const Vec3vf<N>& quad_v3,
24
vfloat<N>& u_o,
25
vfloat<N>& v_o,
26
vfloat<N>& t_o)
27
{
28
/* calculate vertices relative to ray origin */
29
vbool<N> valid = valid0;
30
const Vec3vf<N> O = Vec3vf<N>(ray_org);
31
const Vec3vf<N> D = Vec3vf<N>(ray_dir);
32
const Vec3vf<N> va = quad_v0-O;
33
const Vec3vf<N> vb = quad_v1-O;
34
const Vec3vf<N> vc = quad_v2-O;
35
const Vec3vf<N> vd = quad_v3-O;
36
37
const Vec3vf<N> edb = vb-vd;
38
const vfloat<N> WW = dot(cross(vd,edb),D);
39
const Vec3vf<N> v0 = select(WW <= 0.0f,va,vc);
40
const Vec3vf<N> v1 = select(WW <= 0.0f,vb,vd);
41
const Vec3vf<N> v2 = select(WW <= 0.0f,vd,vb);
42
43
/* calculate edges */
44
const Vec3vf<N> e0 = v2-v0;
45
const Vec3vf<N> e1 = v0-v1;
46
47
/* perform edge tests */
48
const vfloat<N> U = dot(cross(v0,e0),D);
49
const vfloat<N> V = dot(cross(v1,e1),D);
50
valid &= max(U,V) <= 0.0f;
51
if (unlikely(none(valid))) return false;
52
53
/* calculate geometry normal and denominator */
54
const Vec3vf<N> Ng = cross(e1,e0);
55
const vfloat<N> den = dot(Ng,D);
56
const vfloat<N> rcpDen = rcp(den);
57
58
/* perform depth test */
59
const vfloat<N> t = rcpDen*dot(v0,Ng);
60
valid &= vfloat<N>(ray_tnear) <= t & t <= vfloat<N>(ray_tfar);
61
if (unlikely(none(valid))) return false;
62
63
/* avoid division by 0 */
64
valid &= den != vfloat<N>(zero);
65
if (unlikely(none(valid))) return false;
66
67
/* update hit information */
68
t_o = t;
69
u_o = U * rcpDen;
70
v_o = V * rcpDen;
71
u_o = select(WW <= 0.0f,u_o,1.0f-u_o);
72
v_o = select(WW <= 0.0f,v_o,1.0f-v_o);
73
return valid;
74
}
75
}
76
}
77
78