/* * Copyright 2018, Blender Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include // clang-format off #include "kernel/kernel_compat_cpu.h" #include "kernel/split/kernel_split_data_types.h" #include "kernel/kernel_globals.h" // clang-format on #include "util/util_vector.h" CCL_NAMESPACE_BEGIN struct CCLIntersectContext { typedef enum { RAY_REGULAR = 0, RAY_SHADOW_ALL = 1, RAY_LOCAL = 2, RAY_SSS = 3, RAY_VOLUME_ALL = 4, } RayType; KernelGlobals *kg; RayType type; /* for shadow rays */ Intersection *isect_s; int max_hits; int num_hits; /* for SSS Rays: */ LocalIntersection *local_isect; int local_object_id; uint *lcg_state; CCLIntersectContext(KernelGlobals *kg_, RayType type_) { kg = kg_; type = type_; max_hits = 1; num_hits = 0; isect_s = NULL; local_isect = NULL; local_object_id = -1; lcg_state = NULL; } }; class IntersectContext { public: IntersectContext(CCLIntersectContext *ctx) { rtcInitIntersectContext(&context); userRayExt = ctx; } RTCIntersectContext context; CCLIntersectContext *userRayExt; }; ccl_device_inline void kernel_embree_setup_ray(const Ray &ray, RTCRay &rtc_ray, const uint visibility) { rtc_ray.org_x = ray.P.x; rtc_ray.org_y = ray.P.y; rtc_ray.org_z = ray.P.z; rtc_ray.dir_x = ray.D.x; rtc_ray.dir_y = ray.D.y; rtc_ray.dir_z = ray.D.z; rtc_ray.tnear = 0.0f; rtc_ray.tfar = ray.t; rtc_ray.time = ray.time; rtc_ray.mask = visibility; } ccl_device_inline void kernel_embree_setup_rayhit(const Ray &ray, RTCRayHit &rayhit, const uint visibility) { kernel_embree_setup_ray(ray, rayhit.ray, visibility); rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID; rayhit.hit.primID = RTC_INVALID_GEOMETRY_ID; } ccl_device_inline void kernel_embree_convert_hit(KernelGlobals *kg, const RTCRay *ray, const RTCHit *hit, Intersection *isect) { bool is_hair = hit->geomID & 1; isect->u = is_hair ? hit->u : 1.0f - hit->v - hit->u; isect->v = is_hair ? hit->v : hit->u; isect->t = ray->tfar; isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z); if (hit->instID[0] != RTC_INVALID_GEOMETRY_ID) { RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData( rtcGetGeometry(kernel_data.bvh.scene, hit->instID[0])); isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)); isect->object = hit->instID[0] / 2; } else { isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData( rtcGetGeometry(kernel_data.bvh.scene, hit->geomID)); isect->object = OBJECT_NONE; } isect->type = kernel_tex_fetch(__prim_type, isect->prim); } ccl_device_inline void kernel_embree_convert_sss_hit(KernelGlobals *kg, const RTCRay *ray, const RTCHit *hit, Intersection *isect, int local_object_id) { isect->u = 1.0f - hit->v - hit->u; isect->v = hit->u; isect->t = ray->tfar; isect->Ng = make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z); RTCScene inst_scene = (RTCScene)rtcGetGeometryUserData( rtcGetGeometry(kernel_data.bvh.scene, local_object_id * 2)); isect->prim = hit->primID + (intptr_t)rtcGetGeometryUserData(rtcGetGeometry(inst_scene, hit->geomID)); isect->object = local_object_id; isect->type = kernel_tex_fetch(__prim_type, isect->prim); } CCL_NAMESPACE_END