scene_quad_mesh.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 "geometry.h"
  18. #include "buffer.h"
  19. namespace embree
  20. {
  21. /*! Quad Mesh */
  22. struct QuadMesh : public Geometry
  23. {
  24. /*! type of this geometry */
  25. static const Geometry::Type geom_type = Geometry::QUAD_MESH;
  26. /*! triangle indices */
  27. struct Quad
  28. {
  29. uint32_t v[4];
  30. /*! outputs triangle indices */
  31. __forceinline friend std::ostream &operator<<(std::ostream& cout, const Quad& q) {
  32. return cout << "Quad {" << q.v[0] << ", " << q.v[1] << ", " << q.v[2] << ", " << q.v[3] << " }";
  33. }
  34. };
  35. public:
  36. /*! quad mesh construction */
  37. QuadMesh (Scene* parent, RTCGeometryFlags flags, size_t numQuads, size_t numVertices, size_t numTimeSteps);
  38. /* geometry interface */
  39. public:
  40. void enabling();
  41. void disabling();
  42. void setMask (unsigned mask);
  43. void setBuffer(RTCBufferType type, void* ptr, size_t offset, size_t stride, size_t size);
  44. void* map(RTCBufferType type);
  45. void unmap(RTCBufferType type);
  46. void immutable ();
  47. bool verify ();
  48. void interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats);
  49. // FIXME: implement interpolateN
  50. public:
  51. /*! returns number of quads */
  52. __forceinline size_t size() const {
  53. return quads.size();
  54. }
  55. /*! returns number of vertices */
  56. __forceinline size_t numVertices() const {
  57. return vertices[0].size();
  58. }
  59. /*! returns i'th quad */
  60. __forceinline const Quad& quad(size_t i) const {
  61. return quads[i];
  62. }
  63. /*! returns i'th vertex of itime'th timestep */
  64. __forceinline const Vec3fa vertex(size_t i) const {
  65. return vertices0[i];
  66. }
  67. /*! returns i'th vertex of itime'th timestep */
  68. __forceinline const char* vertexPtr(size_t i) const {
  69. return vertices0.getPtr(i);
  70. }
  71. /*! returns i'th vertex of itime'th timestep */
  72. __forceinline const Vec3fa vertex(size_t i, size_t itime) const {
  73. return vertices[itime][i];
  74. }
  75. /*! returns i'th vertex of itime'th timestep */
  76. __forceinline const char* vertexPtr(size_t i, size_t itime) const {
  77. return vertices[itime].getPtr(i);
  78. }
  79. /*! calculates the bounds of the i'th quad */
  80. __forceinline BBox3fa bounds(size_t i) const
  81. {
  82. const Quad& q = quad(i);
  83. const Vec3fa v0 = vertex(q.v[0]);
  84. const Vec3fa v1 = vertex(q.v[1]);
  85. const Vec3fa v2 = vertex(q.v[2]);
  86. const Vec3fa v3 = vertex(q.v[3]);
  87. return BBox3fa(min(v0,v1,v2,v3),max(v0,v1,v2,v3));
  88. }
  89. /*! calculates the bounds of the i'th quad at the itime'th timestep */
  90. __forceinline BBox3fa bounds(size_t i, size_t itime) const
  91. {
  92. const Quad& q = quad(i);
  93. const Vec3fa v0 = vertex(q.v[0],itime);
  94. const Vec3fa v1 = vertex(q.v[1],itime);
  95. const Vec3fa v2 = vertex(q.v[2],itime);
  96. const Vec3fa v3 = vertex(q.v[3],itime);
  97. return BBox3fa(min(v0,v1,v2,v3),max(v0,v1,v2,v3));
  98. }
  99. /*! check if the i'th primitive is valid at the itime'th timestep */
  100. __forceinline bool valid(size_t i, size_t itime) const {
  101. return valid(i, make_range(itime, itime));
  102. }
  103. /*! check if the i'th primitive is valid between the specified time range */
  104. __forceinline bool valid(size_t i, const range<size_t>& itime_range) const
  105. {
  106. const Quad& q = quad(i);
  107. if (unlikely(q.v[0] >= numVertices())) return false;
  108. if (unlikely(q.v[1] >= numVertices())) return false;
  109. if (unlikely(q.v[2] >= numVertices())) return false;
  110. if (unlikely(q.v[3] >= numVertices())) return false;
  111. for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
  112. {
  113. if (!isvalid(vertex(q.v[0],itime))) return false;
  114. if (!isvalid(vertex(q.v[1],itime))) return false;
  115. if (!isvalid(vertex(q.v[2],itime))) return false;
  116. if (!isvalid(vertex(q.v[3],itime))) return false;
  117. }
  118. return true;
  119. }
  120. /*! calculates the linear bounds of the i'th quad at the itimeGlobal'th time segment */
  121. __forceinline LBBox3fa linearBounds(size_t i, size_t itimeGlobal, size_t numTimeStepsGlobal) const {
  122. return Geometry::linearBounds([&] (size_t itime) { return bounds(i, itime); }, itimeGlobal, numTimeStepsGlobal, numTimeSteps);
  123. }
  124. /*! calculates the build bounds of the i'th primitive, if it's valid */
  125. __forceinline bool buildBounds(size_t i, BBox3fa* bbox = nullptr) const
  126. {
  127. const Quad& q = quad(i);
  128. if (q.v[0] >= numVertices()) return false;
  129. if (q.v[1] >= numVertices()) return false;
  130. if (q.v[2] >= numVertices()) return false;
  131. if (q.v[3] >= numVertices()) return false;
  132. for (size_t t=0; t<numTimeSteps; t++)
  133. {
  134. const Vec3fa v0 = vertex(q.v[0],t);
  135. const Vec3fa v1 = vertex(q.v[1],t);
  136. const Vec3fa v2 = vertex(q.v[2],t);
  137. const Vec3fa v3 = vertex(q.v[3],t);
  138. if (unlikely(!isvalid(v0) || !isvalid(v1) || !isvalid(v2) || !isvalid(v3)))
  139. return false;
  140. }
  141. if (bbox)
  142. *bbox = bounds(i);
  143. return true;
  144. }
  145. /*! calculates the build bounds of the i'th primitive at the itime'th time segment, if it's valid */
  146. __forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
  147. {
  148. const Quad& q = quad(i);
  149. if (unlikely(q.v[0] >= numVertices())) return false;
  150. if (unlikely(q.v[1] >= numVertices())) return false;
  151. if (unlikely(q.v[2] >= numVertices())) return false;
  152. if (unlikely(q.v[3] >= numVertices())) return false;
  153. assert(itime+1 < numTimeSteps);
  154. const Vec3fa a0 = vertex(q.v[0],itime+0); if (unlikely(!isvalid(a0))) return false;
  155. const Vec3fa a1 = vertex(q.v[1],itime+0); if (unlikely(!isvalid(a1))) return false;
  156. const Vec3fa a2 = vertex(q.v[2],itime+0); if (unlikely(!isvalid(a2))) return false;
  157. const Vec3fa a3 = vertex(q.v[3],itime+0); if (unlikely(!isvalid(a3))) return false;
  158. const Vec3fa b0 = vertex(q.v[0],itime+1); if (unlikely(!isvalid(b0))) return false;
  159. const Vec3fa b1 = vertex(q.v[1],itime+1); if (unlikely(!isvalid(b1))) return false;
  160. const Vec3fa b2 = vertex(q.v[2],itime+1); if (unlikely(!isvalid(b2))) return false;
  161. const Vec3fa b3 = vertex(q.v[3],itime+1); if (unlikely(!isvalid(b3))) return false;
  162. /* use bounds of first time step in builder */
  163. bbox = BBox3fa(min(a0,a1,a2,a3),max(a0,a1,a2,a3));
  164. return true;
  165. }
  166. /*! calculates the build bounds of the i'th primitive at the itimeGlobal'th time segment, if it's valid */
  167. __forceinline bool buildBounds(size_t i, size_t itimeGlobal, size_t numTimeStepsGlobal, BBox3fa& bbox) const
  168. {
  169. return Geometry::buildBounds([&] (size_t itime, BBox3fa& bbox) -> bool
  170. {
  171. if (unlikely(!valid(i, itime))) return false;
  172. bbox = bounds(i, itime);
  173. return true;
  174. },
  175. itimeGlobal, numTimeStepsGlobal, numTimeSteps, bbox);
  176. }
  177. public:
  178. APIBuffer<Quad> quads; //!< array of quads
  179. BufferRefT<Vec3fa> vertices0; //!< fast access to first vertex buffer
  180. vector<APIBuffer<Vec3fa>> vertices; //!< vertex array for each timestep
  181. vector<APIBuffer<char>> userbuffers; //!< user buffers
  182. };
  183. }