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
10namespace 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