trianglei.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. /* Stores M triangles from an indexed face set */
  21. template <int M>
  22. struct TriangleMi
  23. {
  24. typedef Vec3<vfloat<M>> Vec3vfM;
  25. /* Virtual interface to query information about the triangle type */
  26. struct Type : public PrimitiveType
  27. {
  28. Type();
  29. size_t size(const char* This) const;
  30. };
  31. static Type type;
  32. public:
  33. /* Returns maximal number of stored triangles */
  34. static __forceinline size_t max_size() { return M; }
  35. /* Returns required number of primitive blocks for N primitives */
  36. static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); }
  37. public:
  38. /* Default constructor */
  39. __forceinline TriangleMi() { }
  40. /* Construction from vertices and IDs */
  41. __forceinline TriangleMi(const vint<M>& v0, const vint<M>& v1, const vint<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
  42. : v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
  43. /* Returns a mask that tells which triangles are valid */
  44. __forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
  45. /* Returns if the specified triangle is valid */
  46. __forceinline bool valid(const size_t i) const { assert(i<M); return primIDs[i] != -1; }
  47. /* Returns the number of stored triangles */
  48. __forceinline size_t size() const { return __bsf(~movemask(valid())); }
  49. /* Returns the geometry IDs */
  50. __forceinline vint<M> geomID() const { return geomIDs; }
  51. __forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
  52. /* Returns the primitive IDs */
  53. __forceinline vint<M> primID() const { return primIDs; }
  54. __forceinline int primID(const size_t i) const { assert(i<M); return primIDs[i]; }
  55. /* gather the triangles */
  56. __forceinline void gather(Vec3<vfloat<M>>& p0, Vec3<vfloat<M>>& p1, Vec3<vfloat<M>>& p2, const Scene* const scene) const;
  57. /* Non temporal store */
  58. __forceinline static void store_nt(TriangleMi* dst, const TriangleMi& src)
  59. {
  60. vint<M>::store_nt(&dst->v0,src.v0);
  61. vint<M>::store_nt(&dst->v1,src.v1);
  62. vint<M>::store_nt(&dst->v2,src.v2);
  63. vint<M>::store_nt(&dst->geomIDs,src.geomIDs);
  64. vint<M>::store_nt(&dst->primIDs,src.primIDs);
  65. }
  66. /* Fill triangle from triangle list */
  67. __forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
  68. {
  69. vint<M> geomID = -1, primID = -1;
  70. vint<M> v0 = zero, v1 = zero, v2 = zero;
  71. const PrimRef* prim = &prims[begin];
  72. for (size_t i=0; i<M; i++)
  73. {
  74. const TriangleMesh* mesh = scene->get<TriangleMesh>(prim->geomID());
  75. const TriangleMesh::Triangle& tri = mesh->triangle(prim->primID());
  76. if (begin<end) {
  77. geomID[i] = prim->geomID();
  78. primID[i] = prim->primID();
  79. int* base = (int*) mesh->vertexPtr(tri.v[0]);
  80. v0[i] = tri.v[0];
  81. v1[i] = int(size_t((int*)mesh->vertexPtr(tri.v[1])-base));
  82. v2[i] = int(size_t((int*)mesh->vertexPtr(tri.v[2])-base));
  83. begin++;
  84. } else {
  85. assert(i);
  86. if (i > 0) {
  87. geomID[i] = geomID[0];
  88. primID[i] = -1;
  89. v0[i] = 0;
  90. v1[i] = 0;
  91. v2[i] = 0;
  92. }
  93. }
  94. if (begin<end) prim = &prims[begin];
  95. }
  96. new (this) TriangleMi(v0,v1,v2,geomID,primID); // FIXME: use non temporal store
  97. }
  98. /* Updates the primitive */
  99. __forceinline BBox3fa update(TriangleMesh* mesh)
  100. {
  101. BBox3fa bounds = empty;
  102. for (size_t i=0; i<M; i++)
  103. {
  104. if (primID(i) == -1) break;
  105. const unsigned primId = primID(i);
  106. const TriangleMesh::Triangle& tri = mesh->triangle(primId);
  107. const Vec3fa p0 = mesh->vertex(tri.v[0]);
  108. const Vec3fa p1 = mesh->vertex(tri.v[1]);
  109. const Vec3fa p2 = mesh->vertex(tri.v[2]);
  110. bounds.extend(merge(BBox3fa(p0),BBox3fa(p1),BBox3fa(p2)));
  111. }
  112. return bounds;
  113. }
  114. public:
  115. vint<M> v0; // index to 1st vertex
  116. vint<M> v1; // offset to 2nd vertex
  117. vint<M> v2; // offset to 3rd vertex
  118. vint<M> geomIDs; // geometry ID of mesh
  119. vint<M> primIDs; // primitive ID of primitive inside mesh
  120. };
  121. template<>
  122. __forceinline void TriangleMi<4>::gather(Vec3vf4& p0, Vec3vf4& p1, Vec3vf4& p2, const Scene* const scene) const
  123. {
  124. const bool samegeom = all(geomIDs == vint4(geomIDs[0]));
  125. if (likely(samegeom))
  126. {
  127. const TriangleMesh* mesh = scene->get<TriangleMesh>(geomIDs[0]);
  128. const int* base0 = (const int*) mesh->vertexPtr(v0[0]);
  129. const int* base1 = (const int*) mesh->vertexPtr(v0[1]);
  130. const int* base2 = (const int*) mesh->vertexPtr(v0[2]);
  131. const int* base3 = (const int*) mesh->vertexPtr(v0[3]);
  132. const vfloat4 a0 = vfloat4::loadu(base0 ), a1 = vfloat4::loadu(base1 ), a2 = vfloat4::loadu(base2 ), a3 = vfloat4::loadu(base3 );
  133. const vfloat4 b0 = vfloat4::loadu(base0+v1[0]), b1 = vfloat4::loadu(base1+v1[1]), b2 = vfloat4::loadu(base2+v1[2]), b3 = vfloat4::loadu(base3+v1[3]);
  134. const vfloat4 c0 = vfloat4::loadu(base0+v2[0]), c1 = vfloat4::loadu(base1+v2[1]), c2 = vfloat4::loadu(base2+v2[2]), c3 = vfloat4::loadu(base3+v2[3]);
  135. transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z);
  136. transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z);
  137. transpose(c0,c1,c2,c3,p2.x,p2.y,p2.z);
  138. }
  139. else
  140. {
  141. const int* base0 = (const int*) scene->get<TriangleMesh>(geomIDs[0])->vertexPtr(v0[0]);
  142. const int* base1 = (const int*) scene->get<TriangleMesh>(geomIDs[1])->vertexPtr(v0[1]);
  143. const int* base2 = (const int*) scene->get<TriangleMesh>(geomIDs[2])->vertexPtr(v0[2]);
  144. const int* base3 = (const int*) scene->get<TriangleMesh>(geomIDs[3])->vertexPtr(v0[3]);
  145. const vfloat4 a0 = vfloat4::loadu(base0 ), a1 = vfloat4::loadu(base1 ), a2 = vfloat4::loadu(base2 ), a3 = vfloat4::loadu(base3 );
  146. const vfloat4 b0 = vfloat4::loadu(base0+v1[0]), b1 = vfloat4::loadu(base1+v1[1]), b2 = vfloat4::loadu(base2+v1[2]), b3 = vfloat4::loadu(base3+v1[3]);
  147. const vfloat4 c0 = vfloat4::loadu(base0+v2[0]), c1 = vfloat4::loadu(base1+v2[1]), c2 = vfloat4::loadu(base2+v2[2]), c3 = vfloat4::loadu(base3+v2[3]);
  148. transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z);
  149. transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z);
  150. transpose(c0,c1,c2,c3,p2.x,p2.y,p2.z);
  151. }
  152. }
  153. template<int M>
  154. typename TriangleMi<M>::Type TriangleMi<M>::type;
  155. typedef TriangleMi<4> Triangle4i;
  156. }