gregory_patch_dense.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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 "gregory_patch.h"
  18. namespace embree
  19. {
  20. class __aligned(64) DenseGregoryPatch3fa
  21. {
  22. public:
  23. __forceinline DenseGregoryPatch3fa (const GregoryPatch3fa& patch)
  24. {
  25. for (size_t y=0; y<4; y++)
  26. for (size_t x=0; x<4; x++)
  27. matrix[y][x] = patch.v[y][x];
  28. matrix[0][0].w = patch.f[0][0].x;
  29. matrix[0][1].w = patch.f[0][0].y;
  30. matrix[0][2].w = patch.f[0][0].z;
  31. matrix[0][3].w = 0.0f;
  32. matrix[1][0].w = patch.f[0][1].x;
  33. matrix[1][1].w = patch.f[0][1].y;
  34. matrix[1][2].w = patch.f[0][1].z;
  35. matrix[1][3].w = 0.0f;
  36. matrix[2][0].w = patch.f[1][1].x;
  37. matrix[2][1].w = patch.f[1][1].y;
  38. matrix[2][2].w = patch.f[1][1].z;
  39. matrix[2][3].w = 0.0f;
  40. matrix[3][0].w = patch.f[1][0].x;
  41. matrix[3][1].w = patch.f[1][0].y;
  42. matrix[3][2].w = patch.f[1][0].z;
  43. matrix[3][3].w = 0.0f;
  44. }
  45. __forceinline void extract_f_m(Vec3fa f_m[2][2]) const
  46. {
  47. f_m[0][0] = Vec3fa( matrix[0][0].w, matrix[0][1].w, matrix[0][2].w );
  48. f_m[0][1] = Vec3fa( matrix[1][0].w, matrix[1][1].w, matrix[1][2].w );
  49. f_m[1][1] = Vec3fa( matrix[2][0].w, matrix[2][1].w, matrix[2][2].w );
  50. f_m[1][0] = Vec3fa( matrix[3][0].w, matrix[3][1].w, matrix[3][2].w );
  51. }
  52. __forceinline Vec3fa eval(const float uu, const float vv) const
  53. {
  54. __aligned(64) Vec3fa f_m[2][2]; extract_f_m(f_m);
  55. return GregoryPatch3fa::eval(matrix,f_m,uu,vv);
  56. }
  57. __forceinline Vec3fa normal(const float uu, const float vv) const
  58. {
  59. __aligned(64) Vec3fa f_m[2][2]; extract_f_m(f_m);
  60. return GregoryPatch3fa::normal(matrix,f_m,uu,vv);
  61. }
  62. template<class T>
  63. __forceinline Vec3<T> eval(const T &uu, const T &vv) const
  64. {
  65. Vec3<T> f_m[2][2];
  66. f_m[0][0] = Vec3<T>( matrix[0][0].w, matrix[0][1].w, matrix[0][2].w );
  67. f_m[0][1] = Vec3<T>( matrix[1][0].w, matrix[1][1].w, matrix[1][2].w );
  68. f_m[1][1] = Vec3<T>( matrix[2][0].w, matrix[2][1].w, matrix[2][2].w );
  69. f_m[1][0] = Vec3<T>( matrix[3][0].w, matrix[3][1].w, matrix[3][2].w );
  70. return GregoryPatch3fa::eval_t(matrix,f_m,uu,vv);
  71. }
  72. template<class T>
  73. __forceinline Vec3<T> normal(const T &uu, const T &vv) const
  74. {
  75. Vec3<T> f_m[2][2];
  76. f_m[0][0] = Vec3<T>( matrix[0][0].w, matrix[0][1].w, matrix[0][2].w );
  77. f_m[0][1] = Vec3<T>( matrix[1][0].w, matrix[1][1].w, matrix[1][2].w );
  78. f_m[1][1] = Vec3<T>( matrix[2][0].w, matrix[2][1].w, matrix[2][2].w );
  79. f_m[1][0] = Vec3<T>( matrix[3][0].w, matrix[3][1].w, matrix[3][2].w );
  80. return GregoryPatch3fa::normal_t(matrix,f_m,uu,vv);
  81. }
  82. __forceinline void eval(const float u, const float v,
  83. Vec3fa* P, Vec3fa* dPdu, Vec3fa* dPdv, Vec3fa* ddPdudu, Vec3fa* ddPdvdv, Vec3fa* ddPdudv,
  84. const float dscale = 1.0f) const
  85. {
  86. __aligned(64) Vec3fa f_m[2][2]; extract_f_m(f_m);
  87. if (P) {
  88. *P = GregoryPatch3fa::eval(matrix,f_m,u,v);
  89. }
  90. if (dPdu) {
  91. assert(dPdu); *dPdu = GregoryPatch3fa::eval_du(matrix,f_m,u,v)*dscale;
  92. assert(dPdv); *dPdv = GregoryPatch3fa::eval_dv(matrix,f_m,u,v)*dscale;
  93. }
  94. if (ddPdudu) {
  95. assert(ddPdudu); *ddPdudu = GregoryPatch3fa::eval_dudu(matrix,f_m,u,v)*sqr(dscale);
  96. assert(ddPdvdv); *ddPdvdv = GregoryPatch3fa::eval_dvdv(matrix,f_m,u,v)*sqr(dscale);
  97. assert(ddPdudv); *ddPdudv = GregoryPatch3fa::eval_dudv(matrix,f_m,u,v)*sqr(dscale);
  98. }
  99. }
  100. template<typename vbool, typename vfloat>
  101. __forceinline void eval(const vbool& valid, const vfloat& uu, const vfloat& vv, float* P, float* dPdu, float* dPdv, const float dscale, const size_t dstride, const size_t N) const
  102. {
  103. __aligned(64) Vec3fa f_m[2][2]; extract_f_m(f_m);
  104. GregoryPatch3fa::eval(matrix,f_m,valid,uu,vv,P,dPdu,dPdv,dscale,dstride,N);
  105. }
  106. private:
  107. Vec3fa matrix[4][4]; // f_p/m points are stored in 4th component
  108. };
  109. }