htrdr_interface.h (3089B)
1 /* Copyright (C) 2018-2019, 2022-2025 Centre National de la Recherche Scientifique 2 * Copyright (C) 2020-2022 Institut Mines Télécom Albi-Carmaux 3 * Copyright (C) 2022-2025 Institut Pierre-Simon Laplace 4 * Copyright (C) 2022-2025 Institut de Physique du Globe de Paris 5 * Copyright (C) 2018-2025 |Méso|Star> (contact@meso-star.com) 6 * Copyright (C) 2022-2025 Observatoire de Paris 7 * Copyright (C) 2022-2025 Université de Reims Champagne-Ardenne 8 * Copyright (C) 2022-2025 Université de Versaille Saint-Quentin 9 * Copyright (C) 2018-2019, 2022-2025 Université Paul Sabatier 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 23 24 #ifndef HTRDR_INTERFACE_H 25 #define HTRDR_INTERFACE_H 26 27 #include "core/htrdr_materials.h" 28 #include <star/s3d.h> 29 #include <rsys/double3.h> 30 31 /* Forward declaration of external data type */ 32 struct mrumtl; 33 struct s3d_hit; 34 struct ssf_bsdf; 35 struct ssp_rng; 36 37 struct htrdr_interface { 38 struct htrdr_mtl mtl_front; 39 struct htrdr_mtl mtl_back; 40 struct htrdr_mtl mtl_thin; /* != NULL <=> thin material */ 41 }; 42 static const struct htrdr_interface HTRDR_INTERFACE_NULL; 43 44 static INLINE const struct htrdr_mtl* 45 htrdr_interface_fetch_hit_mtl 46 (const struct htrdr_interface* interf, 47 const double dir[3], /* Incoming ray */ 48 const struct s3d_hit* hit) 49 { 50 const struct htrdr_mtl* mtl = NULL; 51 enum { FRONT, BACK }; 52 ASSERT(interf && dir && d3_is_normalized(dir) && hit && !S3D_HIT_NONE(hit)); 53 ASSERT(interf->mtl_front.mrumtl 54 || interf->mtl_back.mrumtl 55 || interf->mtl_thin.mrumtl); 56 57 if(interf->mtl_thin.mrumtl) { 58 mtl = &interf->mtl_thin; 59 } else { 60 double N[3]; 61 int hit_side; 62 d3_normalize(N, d3_set_f3(N, hit->normal)); 63 hit_side = d3_dot(N, dir) < 0 ? FRONT : BACK; 64 65 /* Retrieve the brdf of the material on the *other side* of the hit side */ 66 switch(hit_side) { 67 case BACK: mtl = &interf->mtl_front; break; 68 case FRONT: mtl = &interf->mtl_back; break; 69 default: FATAL("Unreachable code.\n"); break; 70 } 71 72 /* Due to numerical issue the hit side might be wrong and thus the fetched 73 * material might be undefined (e.g. semi-transparent materials). Handle this 74 * issue by fetching the other material. */ 75 if(!mtl->mrumtl) { 76 switch(hit_side) { 77 case BACK: mtl = &interf->mtl_back; break; 78 case FRONT: mtl = &interf->mtl_front; break; 79 default: FATAL("Unreachable code.\n"); break; 80 } 81 } 82 ASSERT(mtl->mrumtl); 83 } 84 85 return mtl; 86 } 87 88 #endif /* HTRDR_INTERFACE_H */ 89