Path: blob/master/thirdparty/embree/kernels/geometry/linei.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "primitive.h"67namespace embree8{9template<int M>10struct LineMi11{12/* Virtual interface to query information about the line segment type */13struct Type : public PrimitiveType14{15const char* name() const;16size_t sizeActive(const char* This) const;17size_t sizeTotal(const char* This) const;18size_t getBytes(const char* This) const;19};20static Type type;2122public:2324/* primitive supports multiple time segments */25static const bool singleTimeSegment = false;2627/* Returns maximum number of stored line segments */28static __forceinline size_t max_size() { return M; }2930/* Returns required number of primitive blocks for N line segments */31static __forceinline size_t blocks(size_t N) { return (N+max_size()-1)/max_size(); }3233/* Returns required number of bytes for N line segments */34static __forceinline size_t bytes(size_t N) { return blocks(N)*sizeof(LineMi); }3536public:3738/* Default constructor */39__forceinline LineMi() { }4041/* Construction from vertices and IDs */42__forceinline LineMi(const vuint<M>& v0, unsigned short leftExists, unsigned short rightExists, const vuint<M>& geomIDs, const vuint<M>& primIDs, Geometry::GType gtype)43: gtype((unsigned char)gtype), m((unsigned char)popcnt(vuint<M>(primIDs) != vuint<M>(-1))), sharedGeomID(geomIDs[0]), leftExists (leftExists), rightExists(rightExists), v0(v0), primIDs(primIDs)44{45assert(all(vuint<M>(geomID()) == geomIDs));46}4748/* Returns a mask that tells which line segments are valid */49__forceinline vbool<M> valid() const { return primIDs != vuint<M>(-1); }5051/* Returns if the specified line segment is valid */52__forceinline bool valid(const size_t i) const { assert(i<M); return primIDs[i] != -1; }5354/* Returns the number of stored line segments */55__forceinline size_t size() const { return bsf(~movemask(valid())); }5657/* Returns the geometry IDs */58//template<class T>59//static __forceinline T unmask(T &index) { return index & 0x3fffffff; }6061__forceinline unsigned int geomID(unsigned int i = 0) const { return sharedGeomID; }62//__forceinline vuint<M> geomID() { return unmask(geomIDs); }63//__forceinline const vuint<M> geomID() const { return unmask(geomIDs); }64//__forceinline unsigned int geomID(const size_t i) const { assert(i<M); return unmask(geomIDs[i]); }6566/* Returns the primitive IDs */67__forceinline vuint<M>& primID() { return primIDs; }68__forceinline const vuint<M>& primID() const { return primIDs; }69__forceinline unsigned int primID(const size_t i) const { assert(i<M); return primIDs[i]; }7071/* gather the line segments */72__forceinline void gather(Vec4vf<M>& p0,73Vec4vf<M>& p1,74const LineSegments* geom) const;7576__forceinline void gatheri(Vec4vf<M>& p0,77Vec4vf<M>& p1,78const LineSegments* geom,79const int itime) const;8081__forceinline void gather(Vec4vf<M>& p0,82Vec4vf<M>& p1,83const LineSegments* geom,84float time) const;8586/* gather the line segments with lateral info */87__forceinline void gather(Vec4vf<M>& p0,88Vec4vf<M>& p1,89Vec4vf<M>& pL,90Vec4vf<M>& pR,91const LineSegments* geom) const;9293__forceinline void gatheri(Vec4vf<M>& p0,94Vec4vf<M>& p1,95Vec4vf<M>& pL,96Vec4vf<M>& pR,97const LineSegments* geom,98const int itime) const;99100__forceinline void gather(Vec4vf<M>& p0,101Vec4vf<M>& p1,102Vec4vf<M>& pL,103Vec4vf<M>& pR,104const LineSegments* geom,105float time) const;106107__forceinline void gather(Vec4vf<M>& p0,108Vec4vf<M>& p1,109vbool<M>& cL,110vbool<M>& cR,111const LineSegments* geom) const;112113__forceinline void gatheri(Vec4vf<M>& p0,114Vec4vf<M>& p1,115vbool<M>& cL,116vbool<M>& cR,117const LineSegments* geom,118const int itime) const;119120__forceinline void gather(Vec4vf<M>& p0,121Vec4vf<M>& p1,122vbool<M>& cL,123vbool<M>& cR,124const LineSegments* geom,125float time) const;126127/* Calculate the bounds of the line segments */128__forceinline const BBox3fa bounds(const Scene* scene, size_t itime = 0) const129{130BBox3fa bounds = empty;131for (size_t i=0; i<M && valid(i); i++)132{133const LineSegments* geom = scene->get<LineSegments>(geomID(i));134const Vec3ff& p0 = geom->vertex(v0[i]+0,itime);135const Vec3ff& p1 = geom->vertex(v0[i]+1,itime);136BBox3fa b = merge(BBox3fa(p0),BBox3fa(p1));137b = enlarge(b,Vec3fa(max(p0.w,p1.w)));138bounds.extend(b);139}140return bounds;141}142143/* Calculate the linear bounds of the primitive */144__forceinline LBBox3fa linearBounds(const Scene* scene, size_t itime) {145return LBBox3fa(bounds(scene,itime+0), bounds(scene,itime+1));146}147148__forceinline LBBox3fa linearBounds(const Scene *const scene, size_t itime, size_t numTimeSteps) {149LBBox3fa allBounds = empty;150for (size_t i=0; i<M && valid(i); i++)151{152const LineSegments* geom = scene->get<LineSegments>(geomID(i));153allBounds.extend(geom->linearBounds(primID(i), itime, numTimeSteps));154}155return allBounds;156}157158__forceinline LBBox3fa linearBounds(const Scene *const scene, const BBox1f time_range)159{160LBBox3fa allBounds = empty;161for (size_t i=0; i<M && valid(i); i++)162{163const LineSegments* geom = scene->get<LineSegments>(geomID((unsigned int)i));164allBounds.extend(geom->linearBounds(primID(i), time_range));165}166return allBounds;167}168169/* Fill line segment from line segment list */170template<typename PrimRefT>171__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)172{173Geometry::GType gty = scene->get(prims[begin].geomID())->getType();174vuint<M> geomID, primID;175vuint<M> v0;176unsigned short leftExists = 0;177unsigned short rightExists = 0;178const PrimRefT* prim = &prims[begin];179180for (size_t i=0; i<M; i++)181{182const LineSegments* geom = scene->get<LineSegments>(prim->geomID());183if (begin<end) {184geomID[i] = prim->geomID();185primID[i] = prim->primID();186v0[i] = geom->segment(prim->primID());187leftExists |= geom->segmentLeftExists(primID[i]) << i;188rightExists |= geom->segmentRightExists(primID[i]) << i;189begin++;190} else {191assert(i);192if (i>0) {193geomID[i] = geomID[i-1];194primID[i] = -1;195v0[i] = v0[i-1];196}197}198if (begin<end) prim = &prims[begin]; // FIXME: remove this line199}200new (this) LineMi(v0,leftExists,rightExists,geomID,primID,gty); // FIXME: use non temporal store201}202203template<typename BVH, typename Allocator>204__forceinline static typename BVH::NodeRef createLeaf (BVH* bvh, const PrimRef* prims, const range<size_t>& set, const Allocator& alloc)205{206size_t start = set.begin();207size_t items = LineMi::blocks(set.size());208size_t numbytes = LineMi::bytes(set.size());209LineMi* accel = (LineMi*) alloc.malloc1(numbytes,M*sizeof(float));210for (size_t i=0; i<items; i++) {211accel[i].fill(prims,start,set.end(),bvh->scene);212}213return bvh->encodeLeaf((char*)accel,items);214};215216__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)217{218fill(prims,begin,end,scene);219return linearBounds(scene,itime);220}221222__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)223{224fill(prims,begin,end,scene);225return linearBounds(scene,time_range);226}227228template<typename BVH, typename SetMB, typename Allocator>229__forceinline static typename BVH::NodeRecordMB4D createLeafMB(BVH* bvh, const SetMB& prims, const Allocator& alloc)230{231size_t start = prims.begin();232size_t end = prims.end();233size_t items = LineMi::blocks(prims.size());234size_t numbytes = LineMi::bytes(prims.size());235LineMi* accel = (LineMi*) alloc.malloc1(numbytes,M*sizeof(float));236const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel,items);237238LBBox3fa bounds = empty;239for (size_t i=0; i<items; i++)240bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range));241242return typename BVH::NodeRecordMB4D(node,bounds,prims.time_range);243};244245/* Updates the primitive */246__forceinline BBox3fa update(LineSegments* geom)247{248BBox3fa bounds = empty;249for (size_t i=0; i<M && valid(i); i++)250{251const Vec3ff& p0 = geom->vertex(v0[i]+0);252const Vec3ff& p1 = geom->vertex(v0[i]+1);253BBox3fa b = merge(BBox3fa(p0),BBox3fa(p1));254b = enlarge(b,Vec3fa(max(p0.w,p1.w)));255bounds.extend(b);256}257return bounds;258}259260/*! output operator */261friend __forceinline embree_ostream operator<<(embree_ostream cout, const LineMi& line) {262return cout << "Line" << M << "i {" << line.v0 << ", " << line.geomID() << ", " << line.primID() << "}";263}264265public:266unsigned char gtype;267unsigned char m;268unsigned int sharedGeomID;269unsigned short leftExists, rightExists;270vuint<M> v0; // index of start vertex271private:272vuint<M> primIDs; // primitive ID273};274275template<>276__forceinline void LineMi<4>::gather(Vec4vf4& p0,277Vec4vf4& p1,278const LineSegments* geom) const279{280const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));281const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));282const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));283const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));284transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);285286const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));287const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));288const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));289const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));290transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);291}292293template<>294__forceinline void LineMi<4>::gatheri(Vec4vf4& p0,295Vec4vf4& p1,296const LineSegments* geom,297const int itime) const298{299const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));300const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));301const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));302const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));303transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);304305const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));306const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));307const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));308const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));309transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);310}311312template<>313__forceinline void LineMi<4>::gather(Vec4vf4& p0,314Vec4vf4& p1,315const LineSegments* geom,316float time) const317{318float ftime;319const int itime = geom->timeSegment(time, ftime);320321Vec4vf4 a0,a1;322gatheri(a0,a1,geom,itime);323Vec4vf4 b0,b1;324gatheri(b0,b1,geom,itime+1);325p0 = lerp(a0,b0,vfloat4(ftime));326p1 = lerp(a1,b1,vfloat4(ftime));327}328329template<>330__forceinline void LineMi<4>::gather(Vec4vf4& p0,331Vec4vf4& p1,332vbool4& cL,333vbool4& cR,334const LineSegments* geom) const335{336gather(p0,p1,geom);337cL = !vbool4(leftExists);338cR = !vbool4(rightExists);339}340341template<>342__forceinline void LineMi<4>::gatheri(Vec4vf4& p0,343Vec4vf4& p1,344vbool4& cL,345vbool4& cR,346const LineSegments* geom,347const int itime) const348{349gatheri(p0,p1,geom,itime);350cL = !vbool4(leftExists);351cR = !vbool4(rightExists);352}353354template<>355__forceinline void LineMi<4>::gather(Vec4vf4& p0,356Vec4vf4& p1,357vbool4& cL,358vbool4& cR,359const LineSegments* geom,360float time) const361{362float ftime;363const int itime = geom->timeSegment(time, ftime);364365Vec4vf4 a0,a1;366gatheri(a0,a1,geom,itime);367Vec4vf4 b0,b1;368gatheri(b0,b1,geom,itime+1);369p0 = lerp(a0,b0,vfloat4(ftime));370p1 = lerp(a1,b1,vfloat4(ftime));371cL = !vbool4(leftExists);372cR = !vbool4(rightExists);373}374375template<>376__forceinline void LineMi<4>::gather(Vec4vf4& p0,377Vec4vf4& p1,378Vec4vf4& pL,379Vec4vf4& pR,380const LineSegments* geom) const381{382const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));383const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));384const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));385const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));386transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);387388const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));389const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));390const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));391const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));392transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);393394const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1)) : vfloat4(inf);395const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1)) : vfloat4(inf);396const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1)) : vfloat4(inf);397const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1)) : vfloat4(inf);398transpose(l0,l1,l2,l3,pL.x,pL.y,pL.z,pL.w);399400const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2)) : vfloat4(inf);401const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2)) : vfloat4(inf);402const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2)) : vfloat4(inf);403const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2)) : vfloat4(inf);404transpose(r0,r1,r2,r3,pR.x,pR.y,pR.z,pR.w);405}406407template<>408__forceinline void LineMi<4>::gatheri(Vec4vf4& p0,409Vec4vf4& p1,410Vec4vf4& pL,411Vec4vf4& pR,412const LineSegments* geom,413const int itime) const414{415const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));416const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));417const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));418const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));419transpose(a0,a1,a2,a3,p0.x,p0.y,p0.z,p0.w);420421const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));422const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));423const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));424const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));425transpose(b0,b1,b2,b3,p1.x,p1.y,p1.z,p1.w);426427const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1,itime)) : vfloat4(inf);428const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1,itime)) : vfloat4(inf);429const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1,itime)) : vfloat4(inf);430const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1,itime)) : vfloat4(inf);431transpose(l0,l1,l2,l3,pL.x,pL.y,pL.z,pL.w);432433const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2,itime)) : vfloat4(inf);434const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2,itime)) : vfloat4(inf);435const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2,itime)) : vfloat4(inf);436const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2,itime)) : vfloat4(inf);437transpose(r0,r1,r2,r3,pR.x,pR.y,pR.z,pR.w);438}439440template<>441__forceinline void LineMi<4>::gather(Vec4vf4& p0,442Vec4vf4& p1,443Vec4vf4& pL,444Vec4vf4& pR,445const LineSegments* geom,446float time) const447{448float ftime;449const int itime = geom->timeSegment(time, ftime);450451Vec4vf4 a0,a1,aL,aR;452gatheri(a0,a1,aL,aR,geom,itime);453Vec4vf4 b0,b1,bL,bR;454gatheri(b0,b1,bL,bR,geom,itime+1);455p0 = lerp(a0,b0,vfloat4(ftime));456p1 = lerp(a1,b1,vfloat4(ftime));457pL = lerp(aL,bL,vfloat4(ftime));458pR = lerp(aR,bR,vfloat4(ftime));459460pL = select(vboolf4(leftExists), pL, Vec4vf4(inf));461pR = select(vboolf4(rightExists), pR, Vec4vf4(inf));462}463464#if defined(__AVX__)465466template<>467__forceinline void LineMi<8>::gather(Vec4vf8& p0,468Vec4vf8& p1,469const LineSegments* geom) const470{471const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));472const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));473const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));474const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));475const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4]));476const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5]));477const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6]));478const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7]));479transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);480481const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));482const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));483const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));484const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));485const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1));486const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1));487const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1));488const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1));489transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);490}491492template<>493__forceinline void LineMi<8>::gatheri(Vec4vf8& p0,494Vec4vf8& p1,495const LineSegments* geom,496const int itime) const497{498const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));499const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));500const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));501const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));502const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4],itime));503const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5],itime));504const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6],itime));505const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7],itime));506transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);507508const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));509const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));510const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));511const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));512const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1,itime));513const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1,itime));514const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1,itime));515const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1,itime));516transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);517}518519template<>520__forceinline void LineMi<8>::gather(Vec4vf8& p0,521Vec4vf8& p1,522const LineSegments* geom,523float time) const524{525float ftime;526const int itime = geom->timeSegment(time, ftime);527528Vec4vf8 a0,a1;529gatheri(a0,a1,geom,itime);530Vec4vf8 b0,b1;531gatheri(b0,b1,geom,itime+1);532p0 = lerp(a0,b0,vfloat8(ftime));533p1 = lerp(a1,b1,vfloat8(ftime));534}535536template<>537__forceinline void LineMi<8>::gather(Vec4vf8& p0,538Vec4vf8& p1,539Vec4vf8& pL,540Vec4vf8& pR,541const LineSegments* geom) const542{543const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0]));544const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1]));545const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2]));546const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3]));547const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4]));548const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5]));549const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6]));550const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7]));551transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);552553const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1));554const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1));555const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1));556const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1));557const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1));558const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1));559const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1));560const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1));561transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);562563const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1)) : vfloat4(inf);564const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1)) : vfloat4(inf);565const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1)) : vfloat4(inf);566const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1)) : vfloat4(inf);567const vfloat4 l4 = (leftExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]-1)) : vfloat4(inf);568const vfloat4 l5 = (leftExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]-1)) : vfloat4(inf);569const vfloat4 l6 = (leftExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]-1)) : vfloat4(inf);570const vfloat4 l7 = (leftExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]-1)) : vfloat4(inf);571transpose(l0,l1,l2,l3,l4,l5,l6,l7,pL.x,pL.y,pL.z,pL.w);572573const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2)) : vfloat4(inf);574const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2)) : vfloat4(inf);575const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2)) : vfloat4(inf);576const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2)) : vfloat4(inf);577const vfloat4 r4 = (rightExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]+2)) : vfloat4(inf);578const vfloat4 r5 = (rightExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]+2)) : vfloat4(inf);579const vfloat4 r6 = (rightExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]+2)) : vfloat4(inf);580const vfloat4 r7 = (rightExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]+2)) : vfloat4(inf);581transpose(r0,r1,r2,r3,r4,r5,r6,r7,pR.x,pR.y,pR.z,pR.w);582}583584template<>585__forceinline void LineMi<8>::gatheri(Vec4vf8& p0,586Vec4vf8& p1,587Vec4vf8& pL,588Vec4vf8& pR,589const LineSegments* geom,590const int itime) const591{592const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(v0[0],itime));593const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(v0[1],itime));594const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(v0[2],itime));595const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(v0[3],itime));596const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(v0[4],itime));597const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(v0[5],itime));598const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(v0[6],itime));599const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(v0[7],itime));600transpose(a0,a1,a2,a3,a4,a5,a6,a7,p0.x,p0.y,p0.z,p0.w);601602const vfloat4 b0 = vfloat4::loadu(geom->vertexPtr(v0[0]+1,itime));603const vfloat4 b1 = vfloat4::loadu(geom->vertexPtr(v0[1]+1,itime));604const vfloat4 b2 = vfloat4::loadu(geom->vertexPtr(v0[2]+1,itime));605const vfloat4 b3 = vfloat4::loadu(geom->vertexPtr(v0[3]+1,itime));606const vfloat4 b4 = vfloat4::loadu(geom->vertexPtr(v0[4]+1,itime));607const vfloat4 b5 = vfloat4::loadu(geom->vertexPtr(v0[5]+1,itime));608const vfloat4 b6 = vfloat4::loadu(geom->vertexPtr(v0[6]+1,itime));609const vfloat4 b7 = vfloat4::loadu(geom->vertexPtr(v0[7]+1,itime));610transpose(b0,b1,b2,b3,b4,b5,b6,b7,p1.x,p1.y,p1.z,p1.w);611612const vfloat4 l0 = (leftExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]-1,itime)) : vfloat4(inf);613const vfloat4 l1 = (leftExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]-1,itime)) : vfloat4(inf);614const vfloat4 l2 = (leftExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]-1,itime)) : vfloat4(inf);615const vfloat4 l3 = (leftExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]-1,itime)) : vfloat4(inf);616const vfloat4 l4 = (leftExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]-1,itime)) : vfloat4(inf);617const vfloat4 l5 = (leftExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]-1,itime)) : vfloat4(inf);618const vfloat4 l6 = (leftExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]-1,itime)) : vfloat4(inf);619const vfloat4 l7 = (leftExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]-1,itime)) : vfloat4(inf);620transpose(l0,l1,l2,l3,l4,l5,l6,l7,pL.x,pL.y,pL.z,pL.w);621622const vfloat4 r0 = (rightExists & (1<<0)) ? vfloat4::loadu(geom->vertexPtr(v0[0]+2,itime)) : vfloat4(inf);623const vfloat4 r1 = (rightExists & (1<<1)) ? vfloat4::loadu(geom->vertexPtr(v0[1]+2,itime)) : vfloat4(inf);624const vfloat4 r2 = (rightExists & (1<<2)) ? vfloat4::loadu(geom->vertexPtr(v0[2]+2,itime)) : vfloat4(inf);625const vfloat4 r3 = (rightExists & (1<<3)) ? vfloat4::loadu(geom->vertexPtr(v0[3]+2,itime)) : vfloat4(inf);626const vfloat4 r4 = (rightExists & (1<<4)) ? vfloat4::loadu(geom->vertexPtr(v0[4]+2,itime)) : vfloat4(inf);627const vfloat4 r5 = (rightExists & (1<<5)) ? vfloat4::loadu(geom->vertexPtr(v0[5]+2,itime)) : vfloat4(inf);628const vfloat4 r6 = (rightExists & (1<<6)) ? vfloat4::loadu(geom->vertexPtr(v0[6]+2,itime)) : vfloat4(inf);629const vfloat4 r7 = (rightExists & (1<<7)) ? vfloat4::loadu(geom->vertexPtr(v0[7]+2,itime)) : vfloat4(inf);630transpose(r0,r1,r2,r3,r4,r5,r6,r7,pR.x,pR.y,pR.z,pR.w);631}632633template<>634__forceinline void LineMi<8>::gather(Vec4vf8& p0,635Vec4vf8& p1,636Vec4vf8& pL,637Vec4vf8& pR,638const LineSegments* geom,639float time) const640{641float ftime;642const int itime = geom->timeSegment(time, ftime);643644Vec4vf8 a0,a1,aL,aR;645gatheri(a0,a1,aL,aR,geom,itime);646Vec4vf8 b0,b1,bL,bR;647gatheri(b0,b1,bL,bR,geom,itime+1);648p0 = lerp(a0,b0,vfloat8(ftime));649p1 = lerp(a1,b1,vfloat8(ftime));650pL = lerp(aL,bL,vfloat8(ftime));651pR = lerp(aR,bR,vfloat8(ftime));652653pL = select(vboolf4(leftExists), pL, Vec4vf8(inf));654pR = select(vboolf4(rightExists), pR, Vec4vf8(inf));655}656657template<>658__forceinline void LineMi<8>::gather(Vec4vf8& p0,659Vec4vf8& p1,660vbool8& cL,661vbool8& cR,662const LineSegments* geom) const663{664gather(p0,p1,geom);665cL = !vbool8(leftExists);666cR = !vbool8(rightExists);667}668669template<>670__forceinline void LineMi<8>::gatheri(Vec4vf8& p0,671Vec4vf8& p1,672vbool8& cL,673vbool8& cR,674const LineSegments* geom,675const int itime) const676{677gatheri(p0,p1,geom,itime);678cL = !vbool8(leftExists);679cR = !vbool8(rightExists);680}681682template<>683__forceinline void LineMi<8>::gather(Vec4vf8& p0,684Vec4vf8& p1,685vbool8& cL,686vbool8& cR,687const LineSegments* geom,688float time) const689{690float ftime;691const int itime = geom->timeSegment(time, ftime);692693Vec4vf8 a0,a1;694gatheri(a0,a1,geom,itime);695Vec4vf8 b0,b1;696gatheri(b0,b1,geom,itime+1);697p0 = lerp(a0,b0,vfloat8(ftime));698p1 = lerp(a1,b1,vfloat8(ftime));699cL = !vbool8(leftExists);700cR = !vbool8(rightExists);701}702703#endif704705template<int M>706typename LineMi<M>::Type LineMi<M>::type;707708typedef LineMi<4> Line4i;709typedef LineMi<8> Line8i;710}711712713