ssf_optics.h (2200B)
1 /* Copyright (C) 2016-2018, 2021-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #ifndef SSF_OPTICS_H 17 #define SSF_OPTICS_H 18 19 #include <rsys/double3.h> 20 21 /* Reflect the vector V wrt the normal N. By convention V points outward the 22 * surface. */ 23 static INLINE double* 24 reflect(double res[3], const double V[3], const double N[3]) 25 { 26 double tmp[3]; 27 double cos_V_N; 28 ASSERT(res && V && N); 29 ASSERT(d3_is_normalized(V) && d3_is_normalized(N)); 30 cos_V_N = d3_dot(V, N); 31 d3_muld(tmp, N, 2*cos_V_N); 32 d3_sub(res, tmp, V); 33 return res; 34 } 35 36 /* Refract the vect V wrt the normal N using the relative refractive index eta. 37 * Eta is the refraction index of the outside medium (where N points into) 38 * devided by the refraction index of the inside medium. By convention N and V 39 * points on the same side of the surface. Return res or NULL if the refraction 40 * is impossible. */ 41 static INLINE double* 42 refract(double res[3], const double V[3], const double N[3], const double eta) 43 { 44 double tmp0[3]; 45 double tmp1[3]; 46 double cos_theta_i; 47 double cos_theta_t; 48 double sin2_theta_i; 49 double sin2_theta_t; 50 51 ASSERT(res && V && N); 52 ASSERT(d3_is_normalized(V) && d3_is_normalized(N)); 53 cos_theta_i = d3_dot(V, N); 54 sin2_theta_i = MMAX(0, 1.0 - cos_theta_i*cos_theta_i); 55 sin2_theta_t = eta * eta * sin2_theta_i; 56 if(sin2_theta_t >= 1) return NULL; /* Total reflection */ 57 cos_theta_t = sqrt(1 - sin2_theta_t); 58 59 d3_muld(tmp0, V, eta); 60 d3_muld(tmp1, N, eta * cos_theta_i - cos_theta_t); 61 return d3_sub(res, tmp1, tmp0); 62 } 63 64 #endif /* SSF_OPTICS_H */ 65