1 // Copyright 2009-2021 Intel Corporation 2 // SPDX-License-Identifier: Apache-2.0 3 4 #pragma once 5 6 #include "../common/geometry.h" 7 8 namespace embree 9 { 10 static const size_t MAX_PATCH_VALENCE = 16; //!< maximum number of vertices of a patch 11 static const size_t MAX_RING_FACE_VALENCE = 64; //!< maximum number of faces per ring 12 static const size_t MAX_RING_EDGE_VALENCE = 2*64; //!< maximum number of edges per ring 13 14 class CatmullClarkPrecomputedCoefficients 15 { 16 private: 17 18 float table_cos_2PI_div_n[MAX_RING_FACE_VALENCE+1]; 19 20 float* table_limittangent_a[MAX_RING_FACE_VALENCE+1]; 21 float* table_limittangent_b[MAX_RING_FACE_VALENCE+1]; 22 float table_limittangent_c[MAX_RING_FACE_VALENCE+1]; 23 set_cos_2PI_div_n(const size_t n)24 __forceinline float set_cos_2PI_div_n(const size_t n) { 25 if (unlikely(n == 0)) return 1.0f; 26 return cosf(2.0f*float(pi)/(float)n); 27 } 28 set_limittangent_a(const size_t i,const size_t n)29 __forceinline float set_limittangent_a(const size_t i, const size_t n) 30 { 31 if (unlikely(n == 0)) return 1.0f; 32 const float c0 = 1.0f/(float)n * 1.0f / sqrtf(4.0f + cosf(float(pi)/(float)n)*cosf(float(pi)/(float)n)); 33 const float c1 = (1.0f/(float)n + cosf(float(pi)/(float)n) * c0); 34 return cosf(2.0f*float(pi)*(float)i/(float)n) * c1; 35 } 36 set_limittangent_b(const size_t i,const size_t n)37 __forceinline float set_limittangent_b(const size_t i, const size_t n) 38 { 39 if (unlikely(n == 0)) return 1.0f; 40 const float c0 = 1.0f/(float)n * 1.0f / sqrtf(4.0f + cosf(float(pi)/(float)n)*cosf(float(pi)/(float)n)); 41 return cosf((2.0f*float(pi)*i+float(pi))/(float)n) * c0; 42 } 43 set_limittangent_c(const size_t n)44 __forceinline float set_limittangent_c(const size_t n) 45 { 46 if (unlikely(n == 0)) return 1.0f; 47 return 2.0f/16.0f * (5.0f + cosf(2.0f*float(pi)/(float)n) + cosf(float(pi)/(float)n) * sqrtf(18.0f+2.0f*cosf(2.0f*float(pi)/(float)n))); 48 } 49 50 public: 51 cos_2PI_div_n(const size_t n)52 __forceinline float cos_2PI_div_n(const size_t n) 53 { 54 if (likely(n <= MAX_RING_FACE_VALENCE)) 55 return table_cos_2PI_div_n[n]; 56 else 57 return set_cos_2PI_div_n(n); 58 } 59 limittangent_a(const size_t i,const size_t n)60 __forceinline float limittangent_a(const size_t i, const size_t n) 61 { 62 assert(n <= MAX_RING_FACE_VALENCE); 63 assert(i < n); 64 return table_limittangent_a[n][i]; 65 } 66 limittangent_b(const size_t i,const size_t n)67 __forceinline float limittangent_b(const size_t i, const size_t n) 68 { 69 assert(n <= MAX_RING_FACE_VALENCE); 70 assert(i < n); 71 return table_limittangent_b[n][i]; 72 } 73 limittangent_c(const size_t n)74 __forceinline float limittangent_c(const size_t n) 75 { 76 assert(n <= MAX_RING_FACE_VALENCE); 77 return table_limittangent_c[n]; 78 } 79 80 static CatmullClarkPrecomputedCoefficients table; 81 82 CatmullClarkPrecomputedCoefficients(); 83 ~CatmullClarkPrecomputedCoefficients(); 84 }; 85 } 86