catmullclark_coefficients.h 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // ======================================================================== //
  2. // Copyright 2009-2017 Intel Corporation //
  3. // //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); //
  5. // you may not use this file except in compliance with the License. //
  6. // You may obtain a copy of the License at //
  7. // //
  8. // http://www.apache.org/licenses/LICENSE-2.0 //
  9. // //
  10. // Unless required by applicable law or agreed to in writing, software //
  11. // distributed under the License is distributed on an "AS IS" BASIS, //
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
  13. // See the License for the specific language governing permissions and //
  14. // limitations under the License. //
  15. // ======================================================================== //
  16. #pragma once
  17. #include "../common/geometry.h"
  18. namespace embree
  19. {
  20. static const size_t MAX_PATCH_VALENCE = 16; //!< maximal number of vertices of a patch
  21. static const size_t MAX_RING_FACE_VALENCE = 32; //!< maximal number of faces per ring
  22. static const size_t MAX_RING_EDGE_VALENCE = 2*32; //!< maximal number of edges per ring
  23. class CatmullClarkPrecomputedCoefficients
  24. {
  25. private:
  26. float table_cos_2PI_div_n[MAX_RING_FACE_VALENCE+1];
  27. float* table_limittangent_a[MAX_RING_FACE_VALENCE+1];
  28. float* table_limittangent_b[MAX_RING_FACE_VALENCE+1];
  29. float table_limittangent_c[MAX_RING_FACE_VALENCE+1];
  30. __forceinline float set_cos_2PI_div_n(const size_t n) {
  31. if (unlikely(n == 0)) return 1.0f;
  32. return cosf(2.0f*float(pi)/(float)n);
  33. }
  34. __forceinline float set_limittangent_a(const size_t i, const size_t n)
  35. {
  36. if (unlikely(n == 0)) return 1.0f;
  37. const float c0 = 1.0f/(float)n * 1.0f / sqrtf(4.0f + cosf(float(pi)/(float)n)*cosf(float(pi)/(float)n));
  38. const float c1 = (1.0f/(float)n + cosf(float(pi)/(float)n) * c0);
  39. return cosf(2.0f*float(pi)*(float)i/(float)n) * c1;
  40. }
  41. __forceinline float set_limittangent_b(const size_t i, const size_t n)
  42. {
  43. if (unlikely(n == 0)) return 1.0f;
  44. const float c0 = 1.0f/(float)n * 1.0f / sqrtf(4.0f + cosf(float(pi)/(float)n)*cosf(float(pi)/(float)n));
  45. return cosf((2.0f*float(pi)*i+float(pi))/(float)n) * c0;
  46. }
  47. __forceinline float set_limittangent_c(const size_t n)
  48. {
  49. if (unlikely(n == 0)) return 1.0f;
  50. 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)));
  51. }
  52. public:
  53. __forceinline float cos_2PI_div_n(const size_t n)
  54. {
  55. if (likely(n <= MAX_RING_FACE_VALENCE))
  56. return table_cos_2PI_div_n[n];
  57. else
  58. return set_cos_2PI_div_n(n);
  59. }
  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. __forceinline float limittangent_b(const size_t i, const size_t n)
  67. {
  68. assert(n <= MAX_RING_FACE_VALENCE);
  69. assert(i < n);
  70. return table_limittangent_b[n][i];
  71. }
  72. __forceinline float limittangent_c(const size_t n)
  73. {
  74. assert(n <= MAX_RING_FACE_VALENCE);
  75. return table_limittangent_c[n];
  76. }
  77. static CatmullClarkPrecomputedCoefficients table;
  78. CatmullClarkPrecomputedCoefficients();
  79. ~CatmullClarkPrecomputedCoefficients();
  80. };
  81. }