Path: blob/master/thirdparty/embree/kernels/geometry/pointi.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 PointMi11{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:23/* primitive supports multiple time segments */24static const bool singleTimeSegment = false;2526/* Returns maximum number of stored line segments */27static __forceinline size_t max_size()28{29return M;30}3132/* Returns required number of primitive blocks for N line segments */33static __forceinline size_t blocks(size_t N)34{35return (N + max_size() - 1) / max_size();36}3738/* Returns required number of bytes for N line segments */39static __forceinline size_t bytes(size_t N)40{41return blocks(N) * sizeof(PointMi);42}4344public:45/* Default constructor */46__forceinline PointMi() {}4748/* Construction from vertices and IDs */49__forceinline PointMi(const vuint<M>& geomIDs, const vuint<M>& primIDs, Geometry::GType gtype, uint32_t numPrimitives)50: gtype((unsigned char)gtype),51numPrimitives(numPrimitives),52sharedGeomID(geomIDs[0]),53primIDs(primIDs)54{55assert(all(vuint<M>(geomID()) == geomIDs));56}5758/* Returns a mask that tells which line segments are valid */59__forceinline vbool<M> valid() const {60return vint<M>(step) < vint<M>(numPrimitives);61}6263/* Returns if the specified line segment is valid */64__forceinline bool valid(const size_t i) const65{66assert(i < M);67return i < numPrimitives;68}6970/* Returns the number of stored line segments */71__forceinline size_t size() const {72return numPrimitives;73}7475__forceinline unsigned int geomID(unsigned int i = 0) const {76return sharedGeomID;77}7879__forceinline vuint<M>& primID() {80return primIDs;81}82__forceinline const vuint<M>& primID() const {83return primIDs;84}85__forceinline unsigned int primID(const size_t i) const {86assert(i < M);87return primIDs[i];88}8990/* gather the line segments */91__forceinline void gather(Vec4vf<M>& p0, const Points* geom) const;92__forceinline void gather(Vec4vf<M>& p0, Vec3vf<M>& n0, const Points* geom) const;9394__forceinline void gatheri(Vec4vf<M>& p0, const Points* geom, const int itime) const;95__forceinline void gatheri(Vec4vf<M>& p0, Vec3vf<M>& n0, const Points* geom, const int itime) const;9697__forceinline void gather(Vec4vf<M>& p0, const Points* geom, float time) const;98__forceinline void gather(Vec4vf<M>& p0, Vec3vf<M>& n0, const Points* geom, float time) const;99100/* Calculate the bounds of the line segments */101__forceinline const BBox3fa bounds(const Scene* scene, size_t itime = 0) const102{103BBox3fa bounds = empty;104for (size_t i = 0; i < M && valid(i); i++) {105const Points* geom = scene->get<Points>(geomID(i));106bounds.extend(geom->bounds(primID(i),itime));107}108return bounds;109}110111/* Calculate the linear bounds of the primitive */112__forceinline LBBox3fa linearBounds(const Scene* scene, size_t itime) {113return LBBox3fa(bounds(scene, itime + 0), bounds(scene, itime + 1));114}115116__forceinline LBBox3fa linearBounds(const Scene* const scene, size_t itime, size_t numTimeSteps)117{118LBBox3fa allBounds = empty;119for (size_t i = 0; i < M && valid(i); i++) {120const Points* geom = scene->get<Points>(geomID(i));121allBounds.extend(geom->linearBounds(primID(i), itime, numTimeSteps));122}123return allBounds;124}125126__forceinline LBBox3fa linearBounds(const Scene* const scene, const BBox1f time_range)127{128LBBox3fa allBounds = empty;129for (size_t i = 0; i < M && valid(i); i++) {130const Points* geom = scene->get<Points>(geomID((unsigned int)i));131allBounds.extend(geom->linearBounds(primID(i), time_range));132}133return allBounds;134}135136/* Fill line segment from line segment list */137template<typename PrimRefT>138__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)139{140Geometry::GType gty = scene->get(prims[begin].geomID())->getType();141vuint<M> geomID, primID;142vuint<M> v0;143const PrimRefT* prim = &prims[begin];144145int numPrimitives = 0;146for (size_t i = 0; i < M; i++) {147if (begin < end) {148geomID[i] = prim->geomID();149primID[i] = prim->primID();150begin++;151numPrimitives++;152} else {153assert(i);154if (i > 0) {155geomID[i] = geomID[i - 1];156primID[i] = primID[i - 1];157}158}159if (begin < end)160prim = &prims[begin]; // FIXME: remove this line161}162new (this) PointMi(geomID, primID, gty, numPrimitives); // FIXME: use non temporal store163}164165template<typename BVH, typename Allocator>166__forceinline static typename BVH::NodeRef createLeaf(BVH* bvh,167const PrimRef* prims,168const range<size_t>& set,169const Allocator& alloc)170{171size_t start = set.begin();172size_t items = PointMi::blocks(set.size());173size_t numbytes = PointMi::bytes(set.size());174PointMi* accel = (PointMi*)alloc.malloc1(numbytes, M * sizeof(float));175for (size_t i = 0; i < items; i++) {176accel[i].fill(prims, start, set.end(), bvh->scene);177}178return bvh->encodeLeaf((char*)accel, items);179};180181__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)182{183fill(prims, begin, end, scene);184return linearBounds(scene, itime);185}186187__forceinline LBBox3fa fillMB(188const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)189{190fill(prims, begin, end, scene);191return linearBounds(scene, time_range);192}193194template<typename BVH, typename SetMB, typename Allocator>195__forceinline static typename BVH::NodeRecordMB4D createLeafMB(BVH* bvh, const SetMB& prims, const Allocator& alloc)196{197size_t start = prims.object_range.begin();198size_t end = prims.object_range.end();199size_t items = PointMi::blocks(prims.object_range.size());200size_t numbytes = PointMi::bytes(prims.object_range.size());201PointMi* accel = (PointMi*)alloc.malloc1(numbytes, M * sizeof(float));202const typename BVH::NodeRef node = bvh->encodeLeaf((char*)accel, items);203204LBBox3fa bounds = empty;205for (size_t i = 0; i < items; i++)206bounds.extend(accel[i].fillMB(prims.prims->data(), start, end, bvh->scene, prims.time_range));207208return typename BVH::NodeRecordMB4D(node, bounds, prims.time_range);209};210211/*! output operator */212friend __forceinline embree_ostream operator<<(embree_ostream cout, const PointMi& point)213{214return cout << "Point" << M << "i {" << point.geomID() << ", " << point.primID() << "}";215}216217public:218unsigned char gtype;219unsigned char numPrimitives;220unsigned int sharedGeomID;221222private:223vuint<M> primIDs; // primitive ID224};225226template<>227__forceinline void PointMi<4>::gather(Vec4vf4& p0, const Points* geom) const228{229const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));230const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));231const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));232const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));233transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);234}235236template<>237__forceinline void PointMi<4>::gather(Vec4vf4& p0, Vec3vf4& n0, const Points* geom) const238{239const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));240const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));241const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));242const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));243transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);244const vfloat4 b0 = vfloat4(geom->normal(primID(0)));245const vfloat4 b1 = vfloat4(geom->normal(primID(1)));246const vfloat4 b2 = vfloat4(geom->normal(primID(2)));247const vfloat4 b3 = vfloat4(geom->normal(primID(3)));248transpose(b0, b1, b2, b3, n0.x, n0.y, n0.z);249}250251template<>252__forceinline void PointMi<4>::gatheri(Vec4vf4& p0, const Points* geom, const int itime) const253{254const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));255const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));256const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));257const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));258transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);259}260261template<>262__forceinline void PointMi<4>::gatheri(Vec4vf4& p0, Vec3vf4& n0, const Points* geom, const int itime) const263{264const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));265const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));266const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));267const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));268transpose(a0, a1, a2, a3, p0.x, p0.y, p0.z, p0.w);269const vfloat4 b0 = vfloat4(geom->normal((size_t)primID(0), (size_t)itime));270const vfloat4 b1 = vfloat4(geom->normal((size_t)primID(1), (size_t)itime));271const vfloat4 b2 = vfloat4(geom->normal((size_t)primID(2), (size_t)itime));272const vfloat4 b3 = vfloat4(geom->normal((size_t)primID(3), (size_t)itime));273transpose(b0, b1, b2, b3, n0.x, n0.y, n0.z);274}275276template<>277__forceinline void PointMi<4>::gather(Vec4vf4& p0, const Points* geom, float time) const278{279float ftime;280const int itime = geom->timeSegment(time, ftime);281282Vec4vf4 a0; gatheri(a0, geom, itime);283Vec4vf4 b0; gatheri(b0, geom, itime + 1);284p0 = lerp(a0, b0, vfloat4(ftime));285}286287template<>288__forceinline void PointMi<4>::gather(Vec4vf4& p0, Vec3vf4& n0, const Points* geom, float time) const289{290float ftime;291const int itime = geom->timeSegment(time, ftime);292293Vec4vf4 a0, b0;294Vec3vf4 norm0, norm1;295gatheri(a0, norm0, geom, itime);296gatheri(b0, norm1, geom, itime + 1);297p0 = lerp(a0, b0, vfloat4(ftime));298n0 = lerp(norm0, norm1, vfloat4(ftime));299}300301#if defined(__AVX__)302303template<>304__forceinline void PointMi<8>::gather(Vec4vf8& p0, const Points* geom) const305{306const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));307const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));308const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));309const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));310const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4)));311const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5)));312const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6)));313const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7)));314transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);315}316317template<>318__forceinline void PointMi<8>::gather(Vec4vf8& p0, Vec3vf8& n0, const Points* geom) const319{320const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0)));321const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1)));322const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2)));323const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3)));324const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4)));325const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5)));326const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6)));327const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7)));328transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);329const vfloat4 b0 = vfloat4(geom->normal(primID(0)));330const vfloat4 b1 = vfloat4(geom->normal(primID(1)));331const vfloat4 b2 = vfloat4(geom->normal(primID(2)));332const vfloat4 b3 = vfloat4(geom->normal(primID(3)));333const vfloat4 b4 = vfloat4(geom->normal(primID(4)));334const vfloat4 b5 = vfloat4(geom->normal(primID(5)));335const vfloat4 b6 = vfloat4(geom->normal(primID(6)));336const vfloat4 b7 = vfloat4(geom->normal(primID(7)));337transpose(b0, b1, b2, b3, b4, b5, b6, b7, n0.x, n0.y, n0.z);338}339340template<>341__forceinline void PointMi<8>::gatheri(Vec4vf8& p0, const Points* geom, const int itime) const342{343const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));344const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));345const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));346const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));347const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4), itime));348const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5), itime));349const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6), itime));350const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7), itime));351transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);352}353354template<>355__forceinline void PointMi<8>::gatheri(Vec4vf8& p0, Vec3vf8& n0, const Points* geom, const int itime) const356{357const vfloat4 a0 = vfloat4::loadu(geom->vertexPtr(primID(0), itime));358const vfloat4 a1 = vfloat4::loadu(geom->vertexPtr(primID(1), itime));359const vfloat4 a2 = vfloat4::loadu(geom->vertexPtr(primID(2), itime));360const vfloat4 a3 = vfloat4::loadu(geom->vertexPtr(primID(3), itime));361const vfloat4 a4 = vfloat4::loadu(geom->vertexPtr(primID(4), itime));362const vfloat4 a5 = vfloat4::loadu(geom->vertexPtr(primID(5), itime));363const vfloat4 a6 = vfloat4::loadu(geom->vertexPtr(primID(6), itime));364const vfloat4 a7 = vfloat4::loadu(geom->vertexPtr(primID(7), itime));365transpose(a0, a1, a2, a3, a4, a5, a6, a7, p0.x, p0.y, p0.z, p0.w);366const vfloat4 b0 = vfloat4(geom->normal((size_t)primID(0), (size_t)itime));367const vfloat4 b1 = vfloat4(geom->normal((size_t)primID(1), (size_t)itime));368const vfloat4 b2 = vfloat4(geom->normal((size_t)primID(2), (size_t)itime));369const vfloat4 b3 = vfloat4(geom->normal((size_t)primID(3), (size_t)itime));370const vfloat4 b4 = vfloat4(geom->normal((size_t)primID(4), (size_t)itime));371const vfloat4 b5 = vfloat4(geom->normal((size_t)primID(5), (size_t)itime));372const vfloat4 b6 = vfloat4(geom->normal((size_t)primID(6), (size_t)itime));373const vfloat4 b7 = vfloat4(geom->normal((size_t)primID(7), (size_t)itime));374transpose(b0, b1, b2, b3, b4, b5, b6, b7, n0.x, n0.y, n0.z);375}376377template<>378__forceinline void PointMi<8>::gather(Vec4vf8& p0, const Points* geom, float time) const379{380float ftime;381const int itime = geom->timeSegment(time, ftime);382383Vec4vf8 a0;384gatheri(a0, geom, itime);385Vec4vf8 b0;386gatheri(b0, geom, itime + 1);387p0 = lerp(a0, b0, vfloat8(ftime));388}389390template<>391__forceinline void PointMi<8>::gather(Vec4vf8& p0, Vec3vf8& n0, const Points* geom, float time) const392{393float ftime;394const int itime = geom->timeSegment(time, ftime);395396Vec4vf8 a0, b0;397Vec3vf8 norm0, norm1;398gatheri(a0, norm0, geom, itime);399gatheri(b0, norm1, geom, itime + 1);400p0 = lerp(a0, b0, vfloat8(ftime));401n0 = lerp(norm0, norm1, vfloat8(ftime));402}403#endif404405template<int M>406typename PointMi<M>::Type PointMi<M>::type;407408typedef PointMi<4> Point4i;409typedef PointMi<8> Point8i;410411} // namespace embree412413414