1 // Copyright 2009-2021 Intel Corporation 2 // SPDX-License-Identifier: Apache-2.0 3 4 #pragma once 5 6 #include "primitive.h" 7 8 namespace embree 9 { 10 /* Stores the vertices of M triangles in struct of array layout */ 11 template<int M> 12 struct TriangleMvMB 13 { 14 public: 15 struct Type : public PrimitiveType 16 { 17 const char* name() const; 18 size_t sizeActive(const char* This) const; 19 size_t sizeTotal(const char* This) const; 20 size_t getBytes(const char* This) const; 21 }; 22 23 static Type type; 24 25 public: 26 27 /* primitive supports single time segments */ 28 static const bool singleTimeSegment = true; 29 30 /* Returns maximum number of stored triangles */ max_sizeTriangleMvMB31 static __forceinline size_t max_size() { return M; } 32 33 /* Returns required number of primitive blocks for N primitives */ blocksTriangleMvMB34 static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); } 35 36 public: 37 38 /* Default constructor */ TriangleMvMBTriangleMvMB39 __forceinline TriangleMvMB() {} 40 41 /* Construction from vertices and IDs */ TriangleMvMBTriangleMvMB42 __forceinline TriangleMvMB(const Vec3vf<M>& a0, const Vec3vf<M>& a1, 43 const Vec3vf<M>& b0, const Vec3vf<M>& b1, 44 const Vec3vf<M>& c0, const Vec3vf<M>& c1, 45 const vuint<M>& geomIDs, const vuint<M>& primIDs) 46 : v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs) {} 47 48 /* Returns a mask that tells which triangles are valid */ validTriangleMvMB49 __forceinline vbool<M> valid() const { return geomIDs != vuint<M>(-1); } 50 51 /* Returns if the specified triangle is valid */ validTriangleMvMB52 __forceinline bool valid(const size_t i) const { assert(i<M); return geomIDs[i] != -1; } 53 54 /* Returns the number of stored triangles */ sizeTriangleMvMB55 __forceinline size_t size() const { return bsf(~movemask(valid())); } 56 57 /* Returns the geometry IDs */ geomIDTriangleMvMB58 __forceinline vuint<M>& geomID() { return geomIDs; } geomIDTriangleMvMB59 __forceinline const vuint<M>& geomID() const { return geomIDs; } geomIDTriangleMvMB60 __forceinline unsigned int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; } 61 62 /* Returns the primitive IDs */ primIDTriangleMvMB63 __forceinline vuint<M>& primID() { return primIDs; } primIDTriangleMvMB64 __forceinline const vuint<M>& primID() const { return primIDs; } primIDTriangleMvMB65 __forceinline unsigned int primID(const size_t i) const { assert(i<M); return primIDs[i]; } 66 67 /* Calculate the bounds of the triangles at t0 */ bounds0TriangleMvMB68 __forceinline BBox3fa bounds0() const 69 { 70 Vec3vf<M> lower = min(v0,v1,v2); 71 Vec3vf<M> upper = max(v0,v1,v2); 72 const vbool<M> mask = valid(); 73 lower.x = select(mask,lower.x,vfloat<M>(pos_inf)); 74 lower.y = select(mask,lower.y,vfloat<M>(pos_inf)); 75 lower.z = select(mask,lower.z,vfloat<M>(pos_inf)); 76 upper.x = select(mask,upper.x,vfloat<M>(neg_inf)); 77 upper.y = select(mask,upper.y,vfloat<M>(neg_inf)); 78 upper.z = select(mask,upper.z,vfloat<M>(neg_inf)); 79 return BBox3fa(Vec3fa(reduce_min(lower.x),reduce_min(lower.y),reduce_min(lower.z)), 80 Vec3fa(reduce_max(upper.x),reduce_max(upper.y),reduce_max(upper.z))); 81 } 82 83 /* Calculate the bounds of the triangles at t1 */ bounds1TriangleMvMB84 __forceinline BBox3fa bounds1() const 85 { 86 const Vec3vf<M> p0 = v0+dv0; 87 const Vec3vf<M> p1 = v1+dv1; 88 const Vec3vf<M> p2 = v2+dv2; 89 Vec3vf<M> lower = min(p0,p1,p2); 90 Vec3vf<M> upper = max(p0,p1,p2); 91 const vbool<M> mask = valid(); 92 lower.x = select(mask,lower.x,vfloat<M>(pos_inf)); 93 lower.y = select(mask,lower.y,vfloat<M>(pos_inf)); 94 lower.z = select(mask,lower.z,vfloat<M>(pos_inf)); 95 upper.x = select(mask,upper.x,vfloat<M>(neg_inf)); 96 upper.y = select(mask,upper.y,vfloat<M>(neg_inf)); 97 upper.z = select(mask,upper.z,vfloat<M>(neg_inf)); 98 return BBox3fa(Vec3fa(reduce_min(lower.x),reduce_min(lower.y),reduce_min(lower.z)), 99 Vec3fa(reduce_max(upper.x),reduce_max(upper.y),reduce_max(upper.z))); 100 } 101 102 /* Calculate the linear bounds of the primitive */ linearBoundsTriangleMvMB103 __forceinline LBBox3fa linearBounds() const { 104 return LBBox3fa(bounds0(),bounds1()); 105 } 106 107 /* Fill triangle from triangle list */ fillMBTriangleMvMB108 __forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime) 109 { 110 vuint<M> vgeomID = -1, vprimID = -1; 111 Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero; 112 Vec3vf<M> va1 = zero, vb1 = zero, vc1 = zero; 113 114 BBox3fa bounds0 = empty; 115 BBox3fa bounds1 = empty; 116 117 for (size_t i=0; i<M && begin<end; i++, begin++) 118 { 119 const PrimRef& prim = prims[begin]; 120 const unsigned geomID = prim.geomID(); 121 const unsigned primID = prim.primID(); 122 const TriangleMesh* __restrict__ const mesh = scene->get<TriangleMesh>(geomID); 123 const TriangleMesh::Triangle& tri = mesh->triangle(primID); 124 const Vec3fa& a0 = mesh->vertex(tri.v[0],itime+0); bounds0.extend(a0); 125 const Vec3fa& a1 = mesh->vertex(tri.v[0],itime+1); bounds1.extend(a1); 126 const Vec3fa& b0 = mesh->vertex(tri.v[1],itime+0); bounds0.extend(b0); 127 const Vec3fa& b1 = mesh->vertex(tri.v[1],itime+1); bounds1.extend(b1); 128 const Vec3fa& c0 = mesh->vertex(tri.v[2],itime+0); bounds0.extend(c0); 129 const Vec3fa& c1 = mesh->vertex(tri.v[2],itime+1); bounds1.extend(c1); 130 vgeomID [i] = geomID; 131 vprimID [i] = primID; 132 va0.x[i] = a0.x; va0.y[i] = a0.y; va0.z[i] = a0.z; 133 va1.x[i] = a1.x; va1.y[i] = a1.y; va1.z[i] = a1.z; 134 vb0.x[i] = b0.x; vb0.y[i] = b0.y; vb0.z[i] = b0.z; 135 vb1.x[i] = b1.x; vb1.y[i] = b1.y; vb1.z[i] = b1.z; 136 vc0.x[i] = c0.x; vc0.y[i] = c0.y; vc0.z[i] = c0.z; 137 vc1.x[i] = c1.x; vc1.y[i] = c1.y; vc1.z[i] = c1.z; 138 } 139 new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID); 140 return LBBox3fa(bounds0,bounds1); 141 } 142 143 /* Fill triangle from triangle list */ fillMBTriangleMvMB144 __forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range) 145 { 146 vuint<M> vgeomID = -1, vprimID = -1; 147 Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero; 148 Vec3vf<M> va1 = zero, vb1 = zero, vc1 = zero; 149 150 LBBox3fa allBounds = empty; 151 for (size_t i=0; i<M && begin<end; i++, begin++) 152 { 153 const PrimRefMB& prim = prims[begin]; 154 const unsigned geomID = prim.geomID(); 155 const unsigned primID = prim.primID(); 156 const TriangleMesh* const mesh = scene->get<TriangleMesh>(geomID); 157 const range<int> itime_range = mesh->timeSegmentRange(time_range); 158 assert(itime_range.size() == 1); 159 const int ilower = itime_range.begin(); 160 const TriangleMesh::Triangle& tri = mesh->triangle(primID); 161 allBounds.extend(mesh->linearBounds(primID, time_range)); 162 const Vec3fa& a0 = mesh->vertex(tri.v[0],ilower+0); 163 const Vec3fa& a1 = mesh->vertex(tri.v[0],ilower+1); 164 const Vec3fa& b0 = mesh->vertex(tri.v[1],ilower+0); 165 const Vec3fa& b1 = mesh->vertex(tri.v[1],ilower+1); 166 const Vec3fa& c0 = mesh->vertex(tri.v[2],ilower+0); 167 const Vec3fa& c1 = mesh->vertex(tri.v[2],ilower+1); 168 const BBox1f time_range_v(mesh->timeStep(ilower+0),mesh->timeStep(ilower+1)); 169 auto a01 = globalLinear(std::make_pair(a0,a1),time_range_v); 170 auto b01 = globalLinear(std::make_pair(b0,b1),time_range_v); 171 auto c01 = globalLinear(std::make_pair(c0,c1),time_range_v); 172 vgeomID [i] = geomID; 173 vprimID [i] = primID; 174 va0.x[i] = a01.first .x; va0.y[i] = a01.first .y; va0.z[i] = a01.first .z; 175 va1.x[i] = a01.second.x; va1.y[i] = a01.second.y; va1.z[i] = a01.second.z; 176 vb0.x[i] = b01.first .x; vb0.y[i] = b01.first .y; vb0.z[i] = b01.first .z; 177 vb1.x[i] = b01.second.x; vb1.y[i] = b01.second.y; vb1.z[i] = b01.second.z; 178 vc0.x[i] = c01.first .x; vc0.y[i] = c01.first .y; vc0.z[i] = c01.first .z; 179 vc1.x[i] = c01.second.x; vc1.y[i] = c01.second.y; vc1.z[i] = c01.second.z; 180 } 181 new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID); 182 return allBounds; 183 } 184 185 public: 186 Vec3vf<M> v0; // 1st vertex of the triangles 187 Vec3vf<M> v1; // 2nd vertex of the triangles 188 Vec3vf<M> v2; // 3rd vertex of the triangles 189 Vec3vf<M> dv0; // difference vector between time steps t0 and t1 for first vertex 190 Vec3vf<M> dv1; // difference vector between time steps t0 and t1 for second vertex 191 Vec3vf<M> dv2; // difference vector between time steps t0 and t1 for third vertex 192 private: 193 vuint<M> geomIDs; // geometry ID 194 vuint<M> primIDs; // primitive ID 195 }; 196 197 template<int M> 198 typename TriangleMvMB<M>::Type TriangleMvMB<M>::type; 199 200 typedef TriangleMvMB<4> Triangle4vMB; 201 } 202