// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "default.h" #include "ray.h" #include "instance_stack.h" namespace embree { /* Hit structure for K hits */ template struct HitK { /* Default construction does nothing */ __forceinline HitK() {} /* Constructs a hit */ __forceinline HitK(const RTCRayQueryContext* context, const vuint& geomID, const vuint& primID, const vfloat& u, const vfloat& v, const Vec3vf& Ng) : Ng(Ng), u(u), v(v), primID(primID), geomID(geomID) { for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { instID[l] = RTC_INVALID_GEOMETRY_ID; #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) instPrimID[l] = RTC_INVALID_GEOMETRY_ID; #endif } instance_id_stack::copy_UV(context->instID, instID); #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) instance_id_stack::copy_UV(context->instPrimID, instPrimID); #endif } /* Constructs a hit */ __forceinline HitK(const RTCRayQueryContext* context, const vuint& geomID, const vuint& primID, const Vec2vf& uv, const Vec3vf& Ng) : HitK(context,geomID,primID,uv.x,uv.y,Ng) {} /* Returns the size of the hit */ static __forceinline size_t size() { return K; } public: Vec3vf Ng; // geometry normal vfloat u; // barycentric u coordinate of hit vfloat v; // barycentric v coordinate of hit vuint primID; // primitive ID vuint geomID; // geometry ID vuint instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance ID #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) vuint instPrimID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance primitive ID #endif }; /* Specialization for a single hit */ template<> struct __aligned(16) HitK<1> { /* Default construction does nothing */ __forceinline HitK() {} /* Constructs a hit */ __forceinline HitK(const RTCRayQueryContext* context, unsigned int geomID, unsigned int primID, float u, float v, const Vec3fa& Ng) : Ng(Ng.x,Ng.y,Ng.z), u(u), v(v), primID(primID), geomID(geomID) { instance_id_stack::copy_UU(context, context->instID, instID); #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) instance_id_stack::copy_UU(context, context->instPrimID, instPrimID); #endif } /* Constructs a hit */ __forceinline HitK(const RTCRayQueryContext* context, unsigned int geomID, unsigned int primID, const Vec2f& uv, const Vec3fa& Ng) : HitK<1>(context,geomID,primID,uv.x,uv.y,Ng) {} /* Returns the size of the hit */ static __forceinline size_t size() { return 1; } public: Vec3 Ng; // geometry normal float u; // barycentric u coordinate of hit float v; // barycentric v coordinate of hit unsigned int primID; // primitive ID unsigned int geomID; // geometry ID unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance ID #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) unsigned int instPrimID[RTC_MAX_INSTANCE_LEVEL_COUNT]; // instance primitive ID #endif }; /* Shortcuts */ typedef HitK<1> Hit; typedef HitK<4> Hit4; typedef HitK<8> Hit8; typedef HitK<16> Hit16; typedef HitK Hitx; /* Outputs hit to stream */ template __forceinline embree_ostream operator<<(embree_ostream cout, const HitK& ray) { cout << "{ " << embree_endl << " Ng = " << ray.Ng << embree_endl << " u = " << ray.u << embree_endl << " v = " << ray.v << embree_endl << " primID = " << ray.primID << embree_endl << " geomID = " << ray.geomID << embree_endl << " instID ="; for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { cout << " " << ray.instID[l]; } #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) cout << " instPrimID ="; for (unsigned l = 0; l < RTC_MAX_INSTANCE_LEVEL_COUNT; ++l) { cout << " " << ray.instPrimID[l]; } #endif cout << embree_endl; return cout << "}"; } template __forceinline void copyHitToRay(RayHit& ray, const Hit& hit) { ray.Ng = hit.Ng; ray.u = hit.u; ray.v = hit.v; ray.primID = hit.primID; ray.geomID = hit.geomID; instance_id_stack::copy_UU(hit.instID, ray.instID); #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) instance_id_stack::copy_UU(hit.instPrimID, ray.instPrimID); #endif } template __forceinline void copyHitToRay(const vbool& mask, RayHitK& ray, const HitK& hit) { vfloat::storeu(mask,&ray.Ng.x, hit.Ng.x); vfloat::storeu(mask,&ray.Ng.y, hit.Ng.y); vfloat::storeu(mask,&ray.Ng.z, hit.Ng.z); vfloat::storeu(mask,&ray.u, hit.u); vfloat::storeu(mask,&ray.v, hit.v); vuint::storeu(mask,&ray.primID, hit.primID); vuint::storeu(mask,&ray.geomID, hit.geomID); instance_id_stack::copy_VV(hit.instID, ray.instID, mask); #if defined(RTC_GEOMETRY_INSTANCE_ARRAY) instance_id_stack::copy_VV(hit.instPrimID, ray.instPrimID, mask); #endif } }