diff --git a/include/cglm/call/vec3.h b/include/cglm/call/vec3.h index 34d2cdd..5fec1ed 100644 --- a/include/cglm/call/vec3.h +++ b/include/cglm/call/vec3.h @@ -338,6 +338,10 @@ CGLM_EXPORT void glmc_vec3_reflect(vec3 I, vec3 N, vec3 dest); +CGLM_EXPORT +void +glmc_vec3_faceforward(vec3 N, vec3 I, vec3 Nref, vec3 dest); + #ifdef __cplusplus } #endif diff --git a/include/cglm/struct/vec3.h b/include/cglm/struct/vec3.h index 9763367..95cbcc3 100644 --- a/include/cglm/struct/vec3.h +++ b/include/cglm/struct/vec3.h @@ -77,6 +77,7 @@ CGLM_INLINE vec3s glms_vec3_swizzle(vec3s v, int mask); CGLM_INLINE vec3s glms_vec3_make(float * restrict src); CGLM_INLINE vec3s glms_vec3_reflect(vec3s I, vec3s N); + CGLM_INLINE vec3s glms_vec3_faceforward(vec3s N, vec3s I, vec3s Nref); Convenient: CGLM_INLINE vec3s glms_cross(vec3s a, vec3s b); @@ -1099,4 +1100,12 @@ glms_vec3_(reflect)(vec3s I, vec3s N) { return dest; } +CGLM_INLINE +vec3s +glms_vec3_(faceforward)(vec3s N, vec3s I, vec3s Nref) { + vec3s dest; + glm_vec3_faceforward(N.raw, I.raw, Nref.raw, dest.raw); + return dest; +} + #endif /* cglms_vec3s_h */ diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index 47228cc..79318cf 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -82,6 +82,7 @@ CGLM_INLINE void glm_vec3_make(float * restrict src, vec3 dest); CGLM_INLINE void glm_vec3_reflect(vec3 I, vec3 N, vec3 dest); CGLM_INLINE void glm_vec3_refract(vec3 I, vec3 N, float ior, vec3 dest); + CGLM_INLINE void glm_vec3_faceforward(vec3 N, vec3 I, vec3 Nref, vec3 dest); Convenient: CGLM_INLINE void glm_cross(vec3 a, vec3 b, vec3 d); @@ -1219,4 +1220,26 @@ glm_vec3_reflect(vec3 I, vec3 N, vec3 dest) { glm_vec3_sub(I, temp, dest); } +/*! + * @brief a vector pointing in the same direction as another + * + * orients a vector to point away from a surface as defined by its normal + * + * @param[in] N vector to orient. + * @param[in] I incident vector + * @param[in] Nref reference vector + * @param[out] dest oriented vector, pointing away from the surface. + */ +CGLM_INLINE +void +glm_vec3_faceforward(vec3 N, vec3 I, vec3 Nref, vec3 dest) { + if (glm_vec3_dot(I, Nref) < 0.0f) { + /* N is facing away from I */ + glm_vec3_copy(N, dest); + } else { + /* N is facing towards I, negate it */ + glm_vec3_negate_to(N, dest); + } +} + #endif /* cglm_vec3_h */