1 | // Copyright 2009-2021 Intel Corporation |
2 | // SPDX-License-Identifier: Apache-2.0 |
3 | |
4 | #pragma once |
5 | |
6 | #include "default.h" |
7 | #include "ray.h" |
8 | #include "instance_stack.h" |
9 | |
10 | namespace embree |
11 | { |
12 | /* Hit structure for K hits */ |
13 | template<int K> |
14 | struct HitK |
15 | { |
16 | /* Default construction does nothing */ |
17 | __forceinline HitK() {} |
18 | |
19 | /* Constructs a hit */ |
20 | __forceinline HitK(const RTCIntersectContext* context, const vuint<K>& geomID, const vuint<K>& primID, const vfloat<K>& u, const vfloat<K>& v, const Vec3vf<K>& Ng) |
21 | : Ng(Ng), u(u), v(v), primID(primID), geomID(geomID) |
22 | { |
23 | for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) |
24 | instID[l] = RTC_INVALID_GEOMETRY_ID; |
25 | instance_id_stack::copy_UV<K>(context->instID, instID); |
26 | } |
27 | |
28 | /* Returns the size of the hit */ |
29 | static __forceinline size_t size() { return K; } |
30 | |
31 | public: |
32 | Vec3vf<K> Ng; // geometry normal |
33 | vfloat<K> u; // barycentric u coordinate of hit |
34 | vfloat<K> v; // barycentric v coordinate of hit |
35 | vuint<K> primID; // primitive ID |
36 | vuint<K> geomID; // geometry ID |
37 | vuint<K> instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance ID |
38 | }; |
39 | |
40 | /* Specialization for a single hit */ |
41 | template<> |
42 | struct __aligned(16) HitK<1> |
43 | { |
44 | /* Default construction does nothing */ |
45 | __forceinline HitK() {} |
46 | |
47 | /* Constructs a hit */ |
48 | __forceinline HitK(const RTCIntersectContext* context, unsigned int geomID, unsigned int primID, float u, float v, const Vec3fa& Ng) |
49 | : Ng(Ng.x,Ng.y,Ng.z), u(u), v(v), primID(primID), geomID(geomID) |
50 | { |
51 | instance_id_stack::copy_UU(context->instID, instID); |
52 | } |
53 | |
54 | /* Returns the size of the hit */ |
55 | static __forceinline size_t size() { return 1; } |
56 | |
57 | public: |
58 | Vec3<float> Ng; // geometry normal |
59 | float u; // barycentric u coordinate of hit |
60 | float v; // barycentric v coordinate of hit |
61 | unsigned int primID; // primitive ID |
62 | unsigned int geomID; // geometry ID |
63 | unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance ID |
64 | }; |
65 | |
66 | /* Shortcuts */ |
67 | typedef HitK<1> Hit; |
68 | typedef HitK<4> Hit4; |
69 | typedef HitK<8> Hit8; |
70 | typedef HitK<16> Hit16; |
71 | |
72 | /* Outputs hit to stream */ |
73 | template<int K> |
74 | __forceinline embree_ostream operator<<(embree_ostream cout, const HitK<K>& ray) |
75 | { |
76 | cout << "{ " << embree_endl |
77 | << " Ng = " << ray.Ng << embree_endl |
78 | << " u = " << ray.u << embree_endl |
79 | << " v = " << ray.v << embree_endl |
80 | << " primID = " << ray.primID << embree_endl |
81 | << " geomID = " << ray.geomID << embree_endl |
82 | << " instID =" ; |
83 | for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) |
84 | { |
85 | cout << " " << ray.instID[l]; |
86 | } |
87 | cout << embree_endl; |
88 | return cout << "}" ; |
89 | } |
90 | |
91 | template<typename Hit> |
92 | __forceinline void copyHitToRay(RayHit& ray, const Hit& hit) |
93 | { |
94 | ray.Ng = hit.Ng; |
95 | ray.u = hit.u; |
96 | ray.v = hit.v; |
97 | ray.primID = hit.primID; |
98 | ray.geomID = hit.geomID; |
99 | instance_id_stack::copy_UU(hit.instID, ray.instID); |
100 | } |
101 | |
102 | template<int K> |
103 | __forceinline void copyHitToRay(const vbool<K> &mask, RayHitK<K> &ray, const HitK<K> &hit) |
104 | { |
105 | vfloat<K>::storeu(mask,&ray.Ng.x, hit.Ng.x); |
106 | vfloat<K>::storeu(mask,&ray.Ng.y, hit.Ng.y); |
107 | vfloat<K>::storeu(mask,&ray.Ng.z, hit.Ng.z); |
108 | vfloat<K>::storeu(mask,&ray.u, hit.u); |
109 | vfloat<K>::storeu(mask,&ray.v, hit.v); |
110 | vuint<K>::storeu(mask,&ray.primID, hit.primID); |
111 | vuint<K>::storeu(mask,&ray.geomID, hit.geomID); |
112 | instance_id_stack::copy_VV<K>(hit.instID, ray.instID, mask); |
113 | } |
114 | } |
115 | |