Path: blob/master/thirdparty/embree/kernels/common/scene_line_segments.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "default.h"6#include "geometry.h"7#include "buffer.h"89namespace embree10{11/*! represents an array of line segments */12struct LineSegments : public Geometry13{14/*! type of this geometry */15static const Geometry::GTypeMask geom_type = Geometry::MTY_CURVE2;1617public:1819/*! line segments construction */20LineSegments (Device* device, Geometry::GType gtype);2122public:23void setMask (unsigned mask);24void setNumTimeSteps (unsigned int numTimeSteps);25void setVertexAttributeCount (unsigned int N);26void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num);27void* getBufferData(RTCBufferType type, unsigned int slot, BufferDataPointerType pointerType);28void updateBuffer(RTCBufferType type, unsigned int slot);29void commit();30bool verify ();31void interpolate(const RTCInterpolateArguments* const args);32void setTessellationRate(float N);33void setMaxRadiusScale(float s);34void addElementsToCount (GeometryCounts & counts) const;35size_t getGeometryDataDeviceByteSize() const;36void convertToDeviceRepresentation(size_t offset, char* data_host, char* data_device) const;3738template<int N>39void interpolate_impl(const RTCInterpolateArguments* const args)40{41unsigned int primID = args->primID;42float u = args->u;43RTCBufferType bufferType = args->bufferType;44unsigned int bufferSlot = args->bufferSlot;45float* P = args->P;46float* dPdu = args->dPdu;47float* ddPdudu = args->ddPdudu;48unsigned int valueCount = args->valueCount;4950/* calculate base pointer and stride */51assert((bufferType == RTC_BUFFER_TYPE_VERTEX && bufferSlot < numTimeSteps) ||52(bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE && bufferSlot <= vertexAttribs.size()));53const char* src = nullptr;54size_t stride = 0;55if (bufferType == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) {56src = vertexAttribs[bufferSlot].getPtr();57stride = vertexAttribs[bufferSlot].getStride();58} else {59src = vertices[bufferSlot].getPtr();60stride = vertices[bufferSlot].getStride();61}6263for (unsigned int i=0; i<valueCount; i+=N)64{65const size_t ofs = i*sizeof(float);66const size_t segment = segments[primID];67const vbool<N> valid = vint<N>((int)i)+vint<N>(step) < vint<N>(int(valueCount));68const vfloat<N> p0 = mem<vfloat<N>>::loadu(valid,(float*)&src[(segment+0)*stride+ofs]);69const vfloat<N> p1 = mem<vfloat<N>>::loadu(valid,(float*)&src[(segment+1)*stride+ofs]);70if (P ) mem<vfloat<N>>::storeu(valid,P+i,lerp(p0,p1,u));71if (dPdu ) mem<vfloat<N>>::storeu(valid,dPdu+i,p1-p0);72if (ddPdudu) mem<vfloat<N>>::storeu(valid,dPdu+i,vfloat<N>(zero));73}74}7576public:7778/*! returns the number of vertices */79__forceinline size_t numVertices() const {80return vertices[0].size();81}8283/*! returns the i'th segment */84__forceinline const unsigned int& segment(size_t i) const {85return segments[i];86}8788#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)89/*! returns the i'th segment */90template<int M>91__forceinline const vuint<M> vsegment(const vuint<M>& i) const {92return segments[i.v];93}94#endif9596/*! returns the segment to the left of the i'th segment */97__forceinline bool segmentLeftExists(size_t i) const {98assert (flags);99return (flags[i] & RTC_CURVE_FLAG_NEIGHBOR_LEFT) != 0;100}101102/*! returns the segment to the right of the i'th segment */103__forceinline bool segmentRightExists(size_t i) const {104assert (flags);105return (flags[i] & RTC_CURVE_FLAG_NEIGHBOR_RIGHT) != 0;106}107108/*! returns i'th vertex of the first time step */109__forceinline Vec3ff vertex(size_t i) const {110return vertices0[i];111}112113/*! returns i'th vertex of the first time step */114__forceinline const char* vertexPtr(size_t i) const {115return vertices0.getPtr(i);116}117118/*! returns i'th normal of the first time step */119__forceinline Vec3fa normal(size_t i) const {120return normals0[i];121}122123/*! returns i'th radius of the first time step */124__forceinline float radius(size_t i) const {125return vertices0[i].w;126}127128/*! returns i'th vertex of itime'th timestep */129__forceinline Vec3ff vertex(size_t i, size_t itime) const {130return vertices[itime][i];131}132133/*! returns i'th vertex of itime'th timestep */134__forceinline const char* vertexPtr(size_t i, size_t itime) const {135return vertices[itime].getPtr(i);136}137138/*! returns i'th normal of itime'th timestep */139__forceinline Vec3fa normal(size_t i, size_t itime) const {140return normals[itime][i];141}142143/*! returns i'th radius of itime'th timestep */144__forceinline float radius(size_t i, size_t itime) const {145return vertices[itime][i].w;146}147148/*! gathers the curve starting with i'th vertex */149__forceinline void gather(Vec3ff& p0, Vec3ff& p1, unsigned int vid) const150{151p0 = vertex(vid+0);152p1 = vertex(vid+1);153}154155#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)156template<int M>157__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, const vuint<M>& vid) const158{159p0 = vertex(vid.v+0);160p1 = vertex(vid.v+1);161}162#endif163164/*! gathers the curve starting with i'th vertex of itime'th timestep */165__forceinline void gather(Vec3ff& p0, Vec3ff& p1, unsigned int vid, size_t itime) const166{167p0 = vertex(vid+0,itime);168p1 = vertex(vid+1,itime);169}170171#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)172template<int M>173__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, const vuint<M>& vid, const vint<M>& itime) const174{175p0 = vertex(vid.v+0,itime.v);176p1 = vertex(vid.v+1,itime.v);177}178#endif179180/*! loads curve vertices for specified time */181__forceinline void gather(Vec3ff& p0, Vec3ff& p1, unsigned int vid, float time) const182{183float ftime;184const size_t itime = timeSegment(time, ftime);185186const float t0 = 1.0f - ftime;187const float t1 = ftime;188Vec3ff a0,a1; gather(a0,a1,vid,itime);189Vec3ff b0,b1; gather(b0,b1,vid,itime+1);190p0 = madd(Vec3ff(t0),a0,t1*b0);191p1 = madd(Vec3ff(t0),a1,t1*b1);192}193194/*! loads curve vertices for specified time for mblur and non-mblur case */195__forceinline void gather_safe(Vec3ff& p0, Vec3ff& p1, unsigned int vid, float time) const196{197if (hasMotionBlur()) gather(p0,p1,vid,time);198else gather(p0,p1,vid);199}200201#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)202template<int M>203__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, const vuint<M>& vid, const vfloat<M>& time) const204{205vfloat<M> ftime;206const vint<M> itime = timeSegment<M>(time, ftime);207208const vfloat<M> t0 = 1.0f - ftime;209const vfloat<M> t1 = ftime;210Vec4vf<M> a0,a1; vgather<M>(a0,a1,vid,itime);211Vec4vf<M> b0,b1; vgather<M>(b0,b1,vid,itime+1);212p0 = madd(Vec4vf<M>(t0),a0,t1*b0);213p1 = madd(Vec4vf<M>(t0),a1,t1*b1);214}215#endif216217/*! gathers the cone curve starting with i'th vertex */218__forceinline void gather(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, unsigned int vid) const219{220gather(p0,p1,vid);221cL = !segmentLeftExists (primID);222cR = !segmentRightExists(primID);223}224225#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)226template<int M>227__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, vbool<M>& cL, vbool<M>& cR, const vuint<M>& primID, const vuint<M>& vid) const228{229vgather<M>(p0,p1,vid);230cL = !segmentLeftExists (primID.v);231cR = !segmentRightExists(primID.v);232}233#endif234235/*! gathers the cone curve starting with i'th vertex of itime'th timestep */236__forceinline void gather(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, size_t vid, size_t itime) const237{238gather(p0,p1,vid,itime);239cL = !segmentLeftExists (primID);240cR = !segmentRightExists(primID);241}242243/*! loads cone curve vertices for specified time */244__forceinline void gather(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, size_t vid, float time) const245{246gather(p0,p1,vid,time);247cL = !segmentLeftExists (primID);248cR = !segmentRightExists(primID);249}250251/*! loads cone curve vertices for specified time for mblur and non-mblur geometry */252__forceinline void gather_safe(Vec3ff& p0, Vec3ff& p1, bool& cL, bool& cR, unsigned int primID, size_t vid, float time) const253{254if (hasMotionBlur()) gather(p0,p1,cL,cR,primID,vid,time);255else gather(p0,p1,cL,cR,primID,vid);256}257258#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)259template<int M>260__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, vbool<M>& cL, vbool<M>& cR, const vuint<M>& primID, const vuint<M>& vid, const vfloat<M>& time) const261{262vgather<M>(p0,p1,vid,time);263cL = !segmentLeftExists (primID.v);264cR = !segmentRightExists(primID.v);265}266#endif267268/*! gathers the curve starting with i'th vertex */269__forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid) const270{271p0 = vertex(vid+0);272p1 = vertex(vid+1);273p2 = segmentLeftExists (primID) ? vertex(vid-1) : Vec3ff(inf);274p3 = segmentRightExists(primID) ? vertex(vid+2) : Vec3ff(inf);275}276277#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)278template<int M>279__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, Vec4vf<M>& p2, Vec4vf<M>& p3, const vuint<M>& primID, const vuint<M>& vid) const280{281p0 = vertex(vid.v+0);282p1 = vertex(vid.v+1);283vbool<M> left = segmentLeftExists (primID.v);284vbool<M> right = segmentRightExists(primID.v);285vuint<M> i2 = select(left, vid-1,vid+0);286vuint<M> i3 = select(right,vid+2,vid+1);287p2 = vertex(i2.v);288p3 = vertex(i3.v);289p2 = select(left, p2,Vec4vf<M>(inf));290p3 = select(right,p3,Vec4vf<M>(inf));291}292#endif293294/*! gathers the curve starting with i'th vertex of itime'th timestep */295__forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid, size_t itime) const296{297p0 = vertex(vid+0,itime);298p1 = vertex(vid+1,itime);299p2 = segmentLeftExists (primID) ? vertex(vid-1,itime) : Vec3ff(inf);300p3 = segmentRightExists(primID) ? vertex(vid+2,itime) : Vec3ff(inf);301}302303#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)304template<int M>305__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, Vec4vf<M>& p2, Vec4vf<M>& p3, const vuint<M>& primID, const vuint<M>& vid, const vint<M>& itime) const306{307p0 = vertex(vid.v+0, itime.v);308p1 = vertex(vid.v+1, itime.v);309vbool<M> left = segmentLeftExists (primID.v);310vbool<M> right = segmentRightExists(primID.v);311vuint<M> i2 = select(left, vid-1,vid+0);312vuint<M> i3 = select(right,vid+2,vid+1);313p2 = vertex(i2.v, itime.v);314p3 = vertex(i3.v, itime.v);315p2 = select(left, p2,Vec4vf<M>(inf));316p3 = select(right,p3,Vec4vf<M>(inf));317}318#endif319320/*! loads curve vertices for specified time */321__forceinline void gather(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid, float time) const322{323float ftime;324const size_t itime = timeSegment(time, ftime);325326const float t0 = 1.0f - ftime;327const float t1 = ftime;328Vec3ff a0,a1,a2,a3; gather(a0,a1,a2,a3,primID,vid,itime);329Vec3ff b0,b1,b2,b3; gather(b0,b1,b2,b3,primID,vid,itime+1);330p0 = madd(Vec3ff(t0),a0,t1*b0);331p1 = madd(Vec3ff(t0),a1,t1*b1);332p2 = madd(Vec3ff(t0),a2,t1*b2);333p3 = madd(Vec3ff(t0),a3,t1*b3);334}335336/*! loads curve vertices for specified time for mblur and non-mblur geometry */337__forceinline void gather_safe(Vec3ff& p0, Vec3ff& p1, Vec3ff& p2, Vec3ff& p3, unsigned int primID, size_t vid, float time) const338{339if (hasMotionBlur()) gather(p0,p1,p2,p3,primID,vid,time);340else gather(p0,p1,p2,p3,primID,vid);341}342343#if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)344template<int M>345__forceinline void vgather(Vec4vf<M>& p0, Vec4vf<M>& p1, Vec4vf<M>& p2, Vec4vf<M>& p3, const vuint<M>& primID, const vuint<M>& vid, const vfloat<M>& time) const346{347vfloat<M> ftime;348const vint<M> itime = timeSegment<M>(time, ftime);349350const vfloat<M> t0 = 1.0f - ftime;351const vfloat<M> t1 = ftime;352Vec4vf<M> a0,a1,a2,a3; vgather<M>(a0,a1,a2,a3,primID,vid,itime);353Vec4vf<M> b0,b1,b2,b3; vgather<M>(b0,b1,b2,b3,primID,vid,itime+1);354p0 = madd(Vec4vf<M>(t0),a0,t1*b0);355p1 = madd(Vec4vf<M>(t0),a1,t1*b1);356p2 = madd(Vec4vf<M>(t0),a2,t1*b2);357p3 = madd(Vec4vf<M>(t0),a3,t1*b3);358}359#endif360361/*! calculates bounding box of i'th line segment */362__forceinline BBox3fa bounds(const Vec3ff& v0, const Vec3ff& v1) const363{364const BBox3ff b = merge(BBox3ff(v0),BBox3ff(v1));365return enlarge((BBox3fa)b,maxRadiusScale*Vec3fa(max(v0.w,v1.w)));366}367368/*! calculates bounding box of i'th line segment */369__forceinline BBox3fa bounds(size_t i) const370{371const unsigned int index = segment(i);372const Vec3ff v0 = vertex(index+0);373const Vec3ff v1 = vertex(index+1);374return bounds(v0,v1);375}376377/*! calculates bounding box of i'th line segment for the itime'th time step */378__forceinline BBox3fa bounds(size_t i, size_t itime) const379{380const unsigned int index = segment(i);381const Vec3ff v0 = vertex(index+0,itime);382const Vec3ff v1 = vertex(index+1,itime);383return bounds(v0,v1);384}385386/*! calculates bounding box of i'th line segment */387__forceinline BBox3fa bounds(const LinearSpace3fa& space, size_t i) const388{389const unsigned int index = segment(i);390const Vec3ff v0 = vertex(index+0);391const Vec3ff v1 = vertex(index+1);392const Vec3ff w0(xfmVector(space,(Vec3fa)v0),v0.w);393const Vec3ff w1(xfmVector(space,(Vec3fa)v1),v1.w);394return bounds(w0,w1);395}396397/*! calculates bounding box of i'th line segment for the itime'th time step */398__forceinline BBox3fa bounds(const LinearSpace3fa& space, size_t i, size_t itime) const399{400const unsigned int index = segment(i);401const Vec3ff v0 = vertex(index+0,itime);402const Vec3ff v1 = vertex(index+1,itime);403const Vec3ff w0(xfmVector(space,(Vec3fa)v0),v0.w);404const Vec3ff w1(xfmVector(space,(Vec3fa)v1),v1.w);405return bounds(w0,w1);406}407408/*! calculates bounding box of i'th segment */409__forceinline BBox3fa bounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const410{411const float r_scale = r_scale0*scale;412const unsigned int index = segment(i);413const Vec3ff v0 = vertex(index+0,itime);414const Vec3ff v1 = vertex(index+1,itime);415const Vec3ff w0(xfmVector(space,(v0-ofs)*Vec3fa(scale)),maxRadiusScale*v0.w*r_scale);416const Vec3ff w1(xfmVector(space,(v1-ofs)*Vec3fa(scale)),maxRadiusScale*v1.w*r_scale);417return bounds(w0,w1);418}419420/*! check if the i'th primitive is valid at the itime'th timestep */421__forceinline bool valid(size_t i, size_t itime) const {422return valid(i, make_range(itime, itime));423}424425/*! check if the i'th primitive is valid between the specified time range */426__forceinline bool valid(size_t i, const range<size_t>& itime_range) const427{428const unsigned int index = segment(i);429if (index+1 >= numVertices()) return false;430431#if !defined(__SYCL_DEVICE_ONLY__)432433for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++)434{435const Vec3ff v0 = vertex(index+0,itime); if (unlikely(!isvalid4(v0))) return false;436const Vec3ff v1 = vertex(index+1,itime); if (unlikely(!isvalid4(v1))) return false;437if (min(v0.w,v1.w) < 0.0f) return false;438}439#endif440441return true;442}443444/*! calculates the linear bounds of the i'th primitive at the itimeGlobal'th time segment */445__forceinline LBBox3fa linearBounds(size_t i, size_t itime) const {446return LBBox3fa(bounds(i,itime+0),bounds(i,itime+1));447}448449/*! calculates the build bounds of the i'th primitive, if it's valid */450__forceinline bool buildBounds(size_t i, BBox3fa* bbox) const451{452if (!valid(i,0)) return false;453*bbox = bounds(i);454return true;455}456457/*! calculates the build bounds of the i'th primitive at the itime'th time segment, if it's valid */458__forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const459{460if (!valid(i,itime+0) || !valid(i,itime+1)) return false;461bbox = bounds(i,itime); // use bounds of first time step in builder462return true;463}464465/*! calculates the linear bounds of the i'th primitive for the specified time range */466__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {467return LBBox3fa([&] (size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);468}469470/*! calculates the linear bounds of the i'th primitive for the specified time range */471__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {472return LBBox3fa([&] (size_t itime) { return bounds(space, primID, itime); }, dt, time_range, fnumTimeSegments);473}474475/*! calculates the linear bounds of the i'th primitive for the specified time range */476__forceinline LBBox3fa linearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {477return LBBox3fa([&] (size_t itime) { return bounds(ofs, scale, r_scale0, space, primID, itime); }, dt, this->time_range, fnumTimeSegments);478}479480/*! calculates the linear bounds of the i'th primitive for the specified time range */481__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const482{483if (!valid(i, timeSegmentRange(time_range))) return false;484bbox = linearBounds(i, time_range);485return true;486}487488/*! get fast access to first vertex buffer */489__forceinline float * getCompactVertexArray () const {490return (float*) vertices0.getPtr();491}492493public:494BufferView<unsigned int> segments; //!< array of line segment indices495BufferView<Vec3ff> vertices0; //!< fast access to first vertex buffer496BufferView<Vec3fa> normals0; //!< fast access to first normal buffer497BufferView<char> flags; //!< start, end flag per segment498Device::vector<BufferView<Vec3ff>> vertices = device; //!< vertex array for each timestep499Device::vector<BufferView<Vec3fa>> normals = device; //!< normal array for each timestep500Device::vector<BufferView<char>> vertexAttribs = device; //!< user buffers501int tessellationRate; //!< tessellation rate for bezier curve502float maxRadiusScale = 1.0; //!< maximal min-width scaling of curve radii503};504505namespace isa506{507struct LineSegmentsISA : public LineSegments508{509LineSegmentsISA (Device* device, Geometry::GType gtype)510: LineSegments(device,gtype) {}511512LinearSpace3fa computeAlignedSpace(const size_t primID) const513{514const Vec3fa dir = normalize(computeDirection(primID));515if (is_finite(dir)) return frame(dir);516else return LinearSpace3fa(one);517}518519LinearSpace3fa computeAlignedSpaceMB(const size_t primID, const BBox1f time_range) const520{521Vec3fa axisz(0,0,1);522Vec3fa axisy(0,1,0);523524const range<int> tbounds = this->timeSegmentRange(time_range);525if (tbounds.size() == 0) return frame(axisz);526527const size_t itime = (tbounds.begin()+tbounds.end())/2;528529const Vec3fa dir = normalize(computeDirection(primID,itime));530if (is_finite(dir)) return frame(dir);531else return LinearSpace3fa(one);532}533534Vec3fa computeDirection(unsigned int primID) const535{536const unsigned vtxID = segment(primID);537const Vec3fa v0 = vertex(vtxID+0);538const Vec3fa v1 = vertex(vtxID+1);539return v1-v0;540}541542Vec3fa computeDirection(unsigned int primID, size_t time) const543{544const unsigned vtxID = segment(primID);545const Vec3fa v0 = vertex(vtxID+0,time);546const Vec3fa v1 = vertex(vtxID+1,time);547return v1-v0;548}549550PrimInfo createPrimRefArray(PrimRef* prims, const range<size_t>& r, size_t k, unsigned int geomID) const551{552PrimInfo pinfo(empty);553for (size_t j=r.begin(); j<r.end(); j++)554{555BBox3fa bounds = empty;556if (!buildBounds(j,&bounds)) continue;557const PrimRef prim(bounds,geomID,unsigned(j));558pinfo.add_center2(prim);559prims[k++] = prim;560}561return pinfo;562}563564PrimInfo createPrimRefArrayMB(mvector<PrimRef>& prims, size_t itime, const range<size_t>& r, size_t k, unsigned int geomID) const565{566PrimInfo pinfo(empty);567for (size_t j=r.begin(); j<r.end(); j++)568{569BBox3fa bounds = empty;570if (!buildBounds(j,itime,bounds)) continue;571const PrimRef prim(bounds,geomID,unsigned(j));572pinfo.add_center2(prim);573prims[k++] = prim;574}575return pinfo;576}577578PrimInfo createPrimRefArrayMB(PrimRef* prims, const BBox1f& time_range, const range<size_t>& r, size_t k, unsigned int geomID) const579{580PrimInfo pinfo(empty);581const BBox1f t0t1 = BBox1f::intersect(getTimeRange(), time_range);582if (t0t1.empty()) return pinfo;583584for (size_t j = r.begin(); j < r.end(); j++) {585LBBox3fa lbounds = empty;586if (!linearBounds(j, t0t1, lbounds))587continue;588const PrimRef prim(lbounds.bounds(), geomID, unsigned(j));589pinfo.add_center2(prim);590prims[k++] = prim;591}592return pinfo;593}594595PrimInfoMB createPrimRefMBArray(mvector<PrimRefMB>& prims, const BBox1f& t0t1, const range<size_t>& r, size_t k, unsigned int geomID) const596{597PrimInfoMB pinfo(empty);598for (size_t j=r.begin(); j<r.end(); j++)599{600if (!valid(j, timeSegmentRange(t0t1))) continue;601const PrimRefMB prim(linearBounds(j,t0t1),this->numTimeSegments(),this->time_range,this->numTimeSegments(),geomID,unsigned(j));602pinfo.add_primref(prim);603prims[k++] = prim;604}605return pinfo;606}607608BBox3fa vbounds(size_t i) const {609return bounds(i);610}611612BBox3fa vbounds(const LinearSpace3fa& space, size_t i) const {613return bounds(space,i);614}615616BBox3fa vbounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const {617return bounds(ofs,scale,r_scale0,space,i,itime);618}619620LBBox3fa vlinearBounds(size_t primID, const BBox1f& time_range) const {621return linearBounds(primID,time_range);622}623624LBBox3fa vlinearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {625return linearBounds(space,primID,time_range);626}627628LBBox3fa vlinearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const {629return linearBounds(ofs,scale,r_scale0,space,primID,time_range);630}631};632}633634DECLARE_ISA_FUNCTION(LineSegments*, createLineSegments, Device* COMMA Geometry::GType);635}636637638