linei.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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 "primitive.h"
  18. namespace embree
  19. {
  20. template <int M>
  21. struct LineMi
  22. {
  23. typedef Vec3<vfloat<M>> Vec3vfM;
  24. /* Virtual interface to query information about the line segment type */
  25. struct Type : public PrimitiveType
  26. {
  27. Type();
  28. size_t size(const char* This) const;
  29. };
  30. static Type type;
  31. public:
  32. /* Returns maximal number of stored line segments */
  33. static __forceinline size_t max_size() { return M; }
  34. /* Returns required number of primitive blocks for N line segments */
  35. static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); }
  36. public:
  37. /* Default constructor */
  38. __forceinline LineMi() { }
  39. /* Construction from vertices and IDs */
  40. __forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs)
  41. : v0(v0), geomIDs(geomIDs), primIDs(primIDs) {}
  42. /* Returns a mask that tells which line segments are valid */
  43. __forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
  44. /* Returns a mask that tells which line segments are valid */
  45. template<int Mx>
  46. __forceinline vbool<Mx> valid() const { return vint<Mx>(primIDs) != vint<Mx>(-1); }
  47. /* Returns if the specified line segment is valid */
  48. __forceinline bool valid(const size_t i) const { assert(i<M); return primIDs[i] != -1; }
  49. /* Returns the number of stored line segments */
  50. __forceinline size_t size() const { return __bsf(~movemask(valid())); }
  51. /* Returns the geometry IDs */
  52. __forceinline vint<M> geomID() const { return geomIDs; }
  53. __forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
  54. /* Returns the primitive IDs */
  55. __forceinline vint<M> primID() const { return primIDs; }
  56. __forceinline int primID(const size_t i) const { assert(i<M); return primIDs[i]; }
  57. /* gather the line segments */
  58. __forceinline void gather(Vec4<vfloat<M>>& p0,
  59. Vec4<vfloat<M>>& p1,
  60. const Scene* scene) const;
  61. __forceinline void gather(Vec4<vfloat<M>>& p0,
  62. Vec4<vfloat<M>>& p1,
  63. const LineSegments* geom0,
  64. const LineSegments* geom1,
  65. const LineSegments* geom2,
  66. const LineSegments* geom3,
  67. const vint<M>& itime) const;
  68. __forceinline void gather(Vec4<vfloat<M>>& p0,
  69. Vec4<vfloat<M>>& p1,
  70. const Scene* scene,
  71. float time) const;
  72. /* Calculate the bounds of the line segments */
  73. __forceinline const BBox3fa bounds(const Scene* scene, size_t itime = 0) const
  74. {
  75. BBox3fa bounds = empty;
  76. for (size_t i=0; i<M && valid(i); i++)
  77. {
  78. const LineSegments* geom = scene->get<LineSegments>(geomID(i));
  79. const Vec3fa& p0 = geom->vertex(v0[i]+0,itime);
  80. const Vec3fa& p1 = geom->vertex(v0[i]+1,itime);
  81. BBox3fa b = merge(BBox3fa(p0),BBox3fa(p1));
  82. b = enlarge(b,Vec3fa(max(p0.w,p1.w)));
  83. bounds.extend(b);
  84. }
  85. return bounds;
  86. }
  87. /* Calculate the linear bounds of the primitive */
  88. __forceinline LBBox3fa linearBounds(const Scene* scene, size_t itime) {
  89. return LBBox3fa(bounds(scene,itime+0), bounds(scene,itime+1));
  90. }
  91. __forceinline LBBox3fa linearBounds(const Scene *const scene, size_t itime, size_t numTimeSteps) {
  92. LBBox3fa allBounds = empty;
  93. for (size_t i=0; i<M && valid(i); i++)
  94. {
  95. const LineSegments* geom = scene->get<LineSegments>(geomID(i));
  96. allBounds.extend(geom->linearBounds(primID(i), itime, numTimeSteps));
  97. }
  98. return allBounds;
  99. }
  100. /* Fill line segment from line segment list */
  101. __forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
  102. {
  103. vint<M> geomID, primID;
  104. vint<M> v0;
  105. const PrimRef* prim = &prims[begin];
  106. for (size_t i=0; i<M; i++)
  107. {
  108. const LineSegments* geom = scene->get<LineSegments>(prim->geomID());
  109. if (begin<end) {
  110. geomID[i] = prim->geomID();
  111. primID[i] = prim->primID();
  112. v0[i] = geom->segment(prim->primID());
  113. begin++;
  114. } else {
  115. assert(i);
  116. if (i>0) {
  117. geomID[i] = geomID[i-1];
  118. primID[i] = -1;
  119. v0[i] = v0[i-1];
  120. }
  121. }
  122. if (begin<end) prim = &prims[begin];
  123. }
  124. new (this) LineMi(v0,geomID,primID); // FIXME: use non temporal store
  125. }
  126. /* Fill line segment from line segment list */
  127. __forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, size_t numTimeSteps)
  128. {
  129. fill(prims,begin,end,scene);
  130. return linearBounds(scene,itime,numTimeSteps);
  131. }
  132. /* Updates the primitive */
  133. __forceinline BBox3fa update(LineSegments* geom)
  134. {
  135. BBox3fa bounds = empty;
  136. for (size_t i=0; i<M && valid(i); i++)
  137. {
  138. const Vec3fa& p0 = geom->vertex(v0[i]+0);
  139. const Vec3fa& p1 = geom->vertex(v0[i]+1);
  140. BBox3fa b = merge(BBox3fa(p0),BBox3fa(p1));
  141. b = enlarge(b,Vec3fa(max(p0.w,p1.w)));
  142. bounds.extend(b);
  143. }
  144. return bounds;
  145. }
  146. /*! output operator */
  147. friend __forceinline std::ostream& operator<<(std::ostream& cout, const LineMi& line) {
  148. return cout << "Line" << M << "i {" << line.v0 << ", " << line.geomIDs << ", " << line.primIDs << "}";
  149. }
  150. public:
  151. vint<M> v0; // index of start vertex
  152. vint<M> geomIDs; // geometry ID
  153. vint<M> primIDs; // primitive ID
  154. };
  155. template<>
  156. __forceinline void LineMi<4>::gather(Vec4vf4& p0,
  157. Vec4vf4& p1,
  158. const Scene* scene) const
  159. {
  160. const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0]);
  161. const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
  162. const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
  163. const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
  164. const vfloat4 a0 = vfloat4::loadu(geom0->vertexPtr(v0[0]));
  165. const vfloat4 a1 = vfloat4::loadu(geom1->vertexPtr(v0[1]));
  166. const vfloat4 a2 = vfloat4::loadu(geom2->vertexPtr(v0[2]));
  167. const vfloat4 a3 = vfloat4::loadu(geom3->vertexPtr(v0[3]));
  168. transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
  169. const vfloat4 b0 = vfloat4::loadu(geom0->vertexPtr(v0[0]+1));
  170. const vfloat4 b1 = vfloat4::loadu(geom1->vertexPtr(v0[1]+1));
  171. const vfloat4 b2 = vfloat4::loadu(geom2->vertexPtr(v0[2]+1));
  172. const vfloat4 b3 = vfloat4::loadu(geom3->vertexPtr(v0[3]+1));
  173. transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
  174. }
  175. template<>
  176. __forceinline void LineMi<4>::gather(Vec4vf4& p0,
  177. Vec4vf4& p1,
  178. const LineSegments* geom0,
  179. const LineSegments* geom1,
  180. const LineSegments* geom2,
  181. const LineSegments* geom3,
  182. const vint4& itime) const
  183. {
  184. const vfloat4 a0 = vfloat4::loadu(geom0->vertexPtr(v0[0],itime[0]));
  185. const vfloat4 a1 = vfloat4::loadu(geom1->vertexPtr(v0[1],itime[1]));
  186. const vfloat4 a2 = vfloat4::loadu(geom2->vertexPtr(v0[2],itime[2]));
  187. const vfloat4 a3 = vfloat4::loadu(geom3->vertexPtr(v0[3],itime[3]));
  188. transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);
  189. const vfloat4 b0 = vfloat4::loadu(geom0->vertexPtr(v0[0]+1,itime[0]));
  190. const vfloat4 b1 = vfloat4::loadu(geom1->vertexPtr(v0[1]+1,itime[1]));
  191. const vfloat4 b2 = vfloat4::loadu(geom2->vertexPtr(v0[2]+1,itime[2]));
  192. const vfloat4 b3 = vfloat4::loadu(geom3->vertexPtr(v0[3]+1,itime[3]));
  193. transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);
  194. }
  195. template<>
  196. __forceinline void LineMi<4>::gather(Vec4vf4& p0,
  197. Vec4vf4& p1,
  198. const Scene* scene,
  199. float time) const
  200. {
  201. const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0]);
  202. const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
  203. const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
  204. const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
  205. const vfloat4 numTimeSegments(geom0->fnumTimeSegments, geom1->fnumTimeSegments, geom2->fnumTimeSegments, geom3->fnumTimeSegments);
  206. vfloat4 ftime;
  207. const vint4 itime = getTimeSegment(vfloat4(time), numTimeSegments, ftime);
  208. Vec4vf4 a0,a1;
  209. gather(a0,a1,geom0,geom1,geom2,geom3,itime);
  210. Vec4vf4 b0,b1;
  211. gather(b0,b1,geom0,geom1,geom2,geom3,itime+1);
  212. p0 = lerp(a0,b0,ftime);
  213. p1 = lerp(a1,b1,ftime);
  214. }
  215. template<int M>
  216. typename LineMi<M>::Type LineMi<M>::type;
  217. typedef LineMi<4> Line4i;
  218. }