scene_line_segments.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 "geometry.h"
  19. #include "buffer.h"
  20. namespace embree
  21. {
  22. /*! represents an array of line segments */
  23. struct LineSegments : public Geometry
  24. {
  25. /*! type of this geometry */
  26. static const Geometry::Type geom_type = Geometry::LINE_SEGMENTS;
  27. public:
  28. /*! line segments construction */
  29. LineSegments (Scene* parent, RTCGeometryFlags flags, size_t numPrimitives, size_t numVertices, size_t numTimeSteps);
  30. public:
  31. void enabling();
  32. void disabling();
  33. void setMask (unsigned mask);
  34. void setBuffer(RTCBufferType type, void* ptr, size_t offset, size_t stride, size_t size);
  35. void* map(RTCBufferType type);
  36. void unmap(RTCBufferType type);
  37. void immutable ();
  38. bool verify ();
  39. 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);
  40. // FIXME: implement interpolateN
  41. public:
  42. /*! returns number of line segments */
  43. __forceinline size_t size() const {
  44. return segments.size();
  45. }
  46. /*! returns the number of vertices */
  47. __forceinline size_t numVertices() const {
  48. return vertices[0].size();
  49. }
  50. /*! returns the i'th segment */
  51. __forceinline const unsigned int& segment(size_t i) const {
  52. return segments[i];
  53. }
  54. /*! returns i'th vertex of the first time step */
  55. __forceinline Vec3fa vertex(size_t i) const {
  56. return vertices0[i];
  57. }
  58. /*! returns i'th vertex of the first time step */
  59. __forceinline const char* vertexPtr(size_t i) const {
  60. return vertices0.getPtr(i);
  61. }
  62. /*! returns i'th radius of the first time step */
  63. __forceinline float radius(size_t i) const {
  64. return vertices0[i].w;
  65. }
  66. /*! returns i'th vertex of itime'th timestep */
  67. __forceinline Vec3fa vertex(size_t i, size_t itime) const {
  68. return vertices[itime][i];
  69. }
  70. /*! returns i'th vertex of itime'th timestep */
  71. __forceinline const char* vertexPtr(size_t i, size_t itime) const {
  72. return vertices[itime].getPtr(i);
  73. }
  74. /*! returns i'th radius of itime'th timestep */
  75. __forceinline float radius(size_t i, size_t itime) const {
  76. return vertices[itime][i].w;
  77. }
  78. /*! calculates bounding box of i'th line segment */
  79. __forceinline BBox3fa bounds(size_t i) const
  80. {
  81. const unsigned int index = segment(i);
  82. const float r0 = radius(index+0);
  83. const float r1 = radius(index+1);
  84. const Vec3fa v0 = vertex(index+0);
  85. const Vec3fa v1 = vertex(index+1);
  86. const BBox3fa b = merge(BBox3fa(v0),BBox3fa(v1));
  87. return enlarge(b,Vec3fa(max(r0,r1)));
  88. }
  89. /*! calculates bounding box of i'th line segment for the itime'th time step */
  90. __forceinline BBox3fa bounds(size_t i, size_t itime) const
  91. {
  92. const unsigned int index = segment(i);
  93. const float r0 = radius(index+0,itime);
  94. const float r1 = radius(index+1,itime);
  95. const Vec3fa v0 = vertex(index+0,itime);
  96. const Vec3fa v1 = vertex(index+1,itime);
  97. const BBox3fa b = merge(BBox3fa(v0),BBox3fa(v1));
  98. return enlarge(b,Vec3fa(max(r0,r1)));
  99. }
  100. /*! check if the i'th primitive is valid at the itime'th timestep */
  101. __forceinline bool valid(size_t i, size_t itime) const {
  102. return valid(i, make_range(itime, itime));
  103. }
  104. /*! check if the i'th primitive is valid between the specified time range */
  105. __forceinline bool valid(size_t i, const range<size_t>& itime_range) const
  106. {
  107. const unsigned int index = segment(i);
  108. if (index+1 >= numVertices()) return false;
  109. for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)
  110. {
  111. const Vec3fa v0 = vertex(index+0,itime); if (unlikely(!isvalid((vfloat4)v0))) return false;
  112. const Vec3fa v1 = vertex(index+1,itime); if (unlikely(!isvalid((vfloat4)v1))) return false;
  113. if (min(v0.w,v1.w) < 0.0f) return false;
  114. }
  115. return true;
  116. }
  117. /*! calculates the linear bounds of the i'th primitive at the itimeGlobal'th time segment */
  118. __forceinline LBBox3fa linearBounds(size_t i, size_t itimeGlobal, size_t numTimeStepsGlobal) const
  119. {
  120. return Geometry::linearBounds([&] (size_t itime) { return bounds(i, itime); },
  121. itimeGlobal, numTimeStepsGlobal, numTimeSteps);
  122. }
  123. /*! calculates the build bounds of the i'th primitive, if it's valid */
  124. __forceinline bool buildBounds(size_t i, BBox3fa* bbox) const
  125. {
  126. if (!valid(i,0)) return false;
  127. *bbox = bounds(i);
  128. return true;
  129. }
  130. /*! calculates the build bounds of the i'th primitive at the itime'th time segment, if it's valid */
  131. __forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const
  132. {
  133. if (!valid(i,itime+0) || !valid(i,itime+1)) return false;
  134. bbox = bounds(i,itime); // use bounds of first time step in builder
  135. return true;
  136. }
  137. /*! calculates the build bounds of the i'th primitive at the itimeGlobal'th time segment, if it's valid */
  138. __forceinline bool buildBounds(size_t i, size_t itimeGlobal, size_t numTimeStepsGlobal, BBox3fa& bbox) const
  139. {
  140. return Geometry::buildBounds([&] (size_t itime, BBox3fa& bbox) -> bool
  141. {
  142. if (unlikely(!valid(i, itime))) return false;
  143. bbox = bounds(i, itime);
  144. return true;
  145. },
  146. itimeGlobal, numTimeStepsGlobal, numTimeSteps, bbox);
  147. }
  148. public:
  149. APIBuffer<unsigned int> segments; //!< array of line segment indices
  150. BufferRefT<Vec3fa> vertices0; //!< fast access to first vertex buffer
  151. vector<APIBuffer<Vec3fa>> vertices; //!< vertex array for each timestep
  152. vector<APIBuffer<char>> userbuffers; //!< user buffers
  153. };
  154. }