| 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(src: context->instID, tgt: 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(src: hit.instID, tgt: 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 | |