primref.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 "default.h"
  18. #include "scene_bezier_curves.h"
  19. namespace embree
  20. {
  21. /*! A primitive reference stores the bounds of the primitive and its ID. */
  22. struct __aligned(32) PrimRef
  23. {
  24. __forceinline PrimRef () {}
  25. #if defined(__AVX__)
  26. __forceinline PrimRef(const PrimRef& v) {
  27. vfloat8::store((float*)this,vfloat8::load((float*)&v));
  28. }
  29. __forceinline void operator=(const PrimRef& v) {
  30. vfloat8::store((float*)this,vfloat8::load((float*)&v));
  31. }
  32. #endif
  33. __forceinline PrimRef (const BBox3fa& bounds, unsigned int geomID, unsigned int primID)
  34. {
  35. lower = bounds.lower; lower.a = geomID;
  36. upper = bounds.upper; upper.a = primID;
  37. }
  38. __forceinline PrimRef (const BBox3fa& bounds, size_t id)
  39. {
  40. #if defined(__X86_64__)
  41. lower = bounds.lower; lower.u = id & 0xFFFFFFFF;
  42. upper = bounds.upper; upper.u = (id >> 32) & 0xFFFFFFFF;
  43. #else
  44. lower = bounds.lower; lower.u = id;
  45. upper = bounds.upper; upper.u = 0;
  46. #endif
  47. }
  48. /*! calculates twice the center of the primitive */
  49. __forceinline const Vec3fa center2() const {
  50. return lower+upper;
  51. }
  52. /*! return the bounding box of the primitive */
  53. __forceinline const BBox3fa bounds() const {
  54. return BBox3fa(lower,upper);
  55. }
  56. /*! size for bin heuristic is 1 */
  57. __forceinline unsigned size() const {
  58. return 1;
  59. }
  60. /*! returns bounds and centroid used for binning */
  61. __forceinline void binBoundsAndCenter(BBox3fa& bounds_o, Vec3fa& center_o) const
  62. {
  63. bounds_o = bounds();
  64. center_o = embree::center2(bounds_o);
  65. }
  66. /*! returns center for binning */
  67. __forceinline Vec3fa binCenter(const AffineSpace3fa& space, void* user) const // only called by hair builder
  68. {
  69. Scene* scene = (Scene*) user;
  70. NativeCurves* mesh = (NativeCurves*) scene->get(geomID());
  71. BBox3fa bounds = mesh->bounds(space,primID());
  72. return embree::center2(bounds);
  73. }
  74. /*! returns bounds and centroid used for binning */
  75. __forceinline void binBoundsAndCenter(BBox3fa& bounds_o, Vec3fa& center_o, const AffineSpace3fa& space, void* user) const // only called by hair builder
  76. {
  77. Scene* scene = (Scene*) user;
  78. NativeCurves* mesh = (NativeCurves*) scene->get(geomID());
  79. BBox3fa bounds = mesh->bounds(space,primID());
  80. bounds_o = bounds;
  81. center_o = embree::center2(bounds);
  82. }
  83. /*! returns the geometry ID */
  84. __forceinline unsigned& geomID() {
  85. return lower.u;
  86. }
  87. __forceinline unsigned geomID() const {
  88. return lower.a;
  89. }
  90. /*! returns the primitive ID */
  91. __forceinline unsigned& primID() {
  92. return upper.u;
  93. }
  94. __forceinline unsigned primID() const {
  95. return upper.a;
  96. }
  97. /*! returns an size_t sized ID */
  98. __forceinline size_t ID() const {
  99. #if defined(__X86_64__)
  100. return size_t(lower.u) + (size_t(upper.u) << 32);
  101. #else
  102. return size_t(lower.u);
  103. #endif
  104. }
  105. /*! special function for operator< */
  106. __forceinline uint64_t ID64() const {
  107. return (((uint64_t)primID()) << 32) + (uint64_t)geomID();
  108. }
  109. /*! allows sorting the primrefs by ID */
  110. friend __forceinline bool operator<(const PrimRef& p0, const PrimRef& p1) {
  111. return p0.ID64() < p1.ID64();
  112. }
  113. /*! Outputs primitive reference to a stream. */
  114. friend __forceinline std::ostream& operator<<(std::ostream& cout, const PrimRef& ref) {
  115. return cout << "{ lower = " << ref.lower << ", upper = " << ref.upper << ", geomID = " << ref.geomID() << ", primID = " << ref.primID() << " }";
  116. }
  117. public:
  118. Vec3fa lower; //!< lower bounds and geomID
  119. Vec3fa upper; //!< upper bounds and primID
  120. };
  121. /*! fast exchange for PrimRefs */
  122. __forceinline void xchg(PrimRef& a, PrimRef& b)
  123. {
  124. #if defined(__AVX__)
  125. const vfloat8 aa = vfloat8::load((float*)&a);
  126. const vfloat8 bb = vfloat8::load((float*)&b);
  127. vfloat8::store((float*)&a,bb);
  128. vfloat8::store((float*)&b,aa);
  129. #else
  130. std::swap(a,b);
  131. #endif
  132. }
  133. }