Path: blob/master/thirdparty/embree/kernels/common/scene_points.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "buffer.h"6#include "default.h"7#include "geometry.h"89namespace embree10{11/*! represents an array of points */12struct Points : public Geometry13{14/*! type of this geometry */15static const Geometry::GTypeMask geom_type = Geometry::MTY_POINTS;1617public:18/*! line segments construction */19Points(Device* device, Geometry::GType gtype);2021public:22void setMask(unsigned mask);23void setNumTimeSteps(unsigned int numTimeSteps);24void setVertexAttributeCount(unsigned int N);25void setBuffer(RTCBufferType type,26unsigned int slot,27RTCFormat format,28const Ref<Buffer>& buffer,29size_t offset,30size_t stride,31unsigned int num);32void* getBufferData(RTCBufferType type, unsigned int slot, BufferDataPointerType pointerType);33void updateBuffer(RTCBufferType type, unsigned int slot);34void commit();35bool verify();36void setMaxRadiusScale(float s);37void addElementsToCount (GeometryCounts & counts) const;38size_t getGeometryDataDeviceByteSize() const;39void convertToDeviceRepresentation(size_t offset, char* data_host, char* data_device) const;4041public:42/*! returns the number of vertices */43__forceinline size_t numVertices() const {44return vertices[0].size();45}4647/*! returns i'th vertex of the first time step */48__forceinline Vec3ff vertex(size_t i) const {49return vertices0[i];50}5152/*! returns i'th vertex of the first time step */53__forceinline const char* vertexPtr(size_t i) const {54return vertices0.getPtr(i);55}5657/*! returns i'th normal of the first time step */58__forceinline Vec3fa normal(size_t i) const {59return normals0[i];60}6162/*! returns i'th radius of the first time step */63__forceinline float radius(size_t i) const {64return vertices0[i].w;65}6667/*! returns i'th vertex of itime'th timestep */68__forceinline Vec3ff vertex(size_t i, size_t itime) const {69return vertices[itime][i];70}7172/*! returns i'th vertex of for specified time */73__forceinline Vec3ff vertex(size_t i, float time) const74{75float ftime;76const size_t itime = timeSegment(time, ftime);77const float t0 = 1.0f - ftime;78const float t1 = ftime;79Vec3ff v0 = vertex(i, itime+0);80Vec3ff v1 = vertex(i, itime+1);81return madd(Vec3ff(t0),v0,t1*v1);82}8384/*! returns i'th vertex of for specified time */85__forceinline Vec3ff vertex_safe(size_t i, float time) const86{87if (hasMotionBlur()) return vertex(i,time);88else return vertex(i);89}9091/*! returns i'th vertex of itime'th timestep */92__forceinline const char* vertexPtr(size_t i, size_t itime) const {93return vertices[itime].getPtr(i);94}9596/*! returns i'th normal of itime'th timestep */97__forceinline Vec3fa normal(size_t i, size_t itime) const {98return normals[itime][i];99}100101/*! returns i'th normal of for specified time */102__forceinline Vec3fa normal(size_t i, float time) const103{104float ftime;105const size_t itime = timeSegment(time, ftime);106const float t0 = 1.0f - ftime;107const float t1 = ftime;108Vec3fa n0 = normal(i, itime+0);109Vec3fa n1 = normal(i, itime+1);110return madd(Vec3fa(t0),n0,t1*n1);111}112113/*! returns i'th normal of for specified time */114__forceinline Vec3fa normal_safe(size_t i, float time) const115{116if (hasMotionBlur()) return normal(i,time);117else return normal(i);118}119120/*! returns i'th radius of itime'th timestep */121__forceinline float radius(size_t i, size_t itime) const {122return vertices[itime][i].w;123}124125/*! returns i'th radius of for specified time */126__forceinline float radius(size_t i, float time) const127{128float ftime;129const size_t itime = timeSegment(time, ftime);130const float t0 = 1.0f - ftime;131const float t1 = ftime;132float r0 = radius(i, itime+0);133float r1 = radius(i, itime+1);134return madd(t0,r0,t1*r1);135}136137/*! returns i'th radius of for specified time */138__forceinline float radius_safe(size_t i, float time) const139{140if (hasMotionBlur()) return radius(i,time);141else return radius(i);142}143144/*! calculates bounding box of i'th line segment */145__forceinline BBox3fa bounds(const Vec3ff& v0) const {146return enlarge(BBox3fa(v0), maxRadiusScale*Vec3fa(v0.w));147}148149/*! calculates bounding box of i'th line segment */150__forceinline BBox3fa bounds(size_t i) const151{152const Vec3ff v0 = vertex(i);153return bounds(v0);154}155156/*! calculates bounding box of i'th line segment for the itime'th time step */157__forceinline BBox3fa bounds(size_t i, size_t itime) const158{159const Vec3ff v0 = vertex(i, itime);160return bounds(v0);161}162163/*! calculates bounding box of i'th line segment */164__forceinline BBox3fa bounds(const LinearSpace3fa& space, size_t i) const165{166const Vec3ff v0 = vertex(i);167const Vec3ff w0(xfmVector(space, (Vec3fa)v0), v0.w);168return bounds(w0);169}170171/*! calculates bounding box of i'th line segment for the itime'th time step */172__forceinline BBox3fa bounds(const LinearSpace3fa& space, size_t i, size_t itime) const173{174const Vec3ff v0 = vertex(i, itime);175const Vec3ff w0(xfmVector(space, (Vec3fa)v0), v0.w);176return bounds(w0);177}178179/*! check if the i'th primitive is valid at the itime'th timestep */180__forceinline bool valid(size_t i, size_t itime) const {181return valid(i, make_range(itime, itime));182}183184/*! check if the i'th primitive is valid between the specified time range */185__forceinline bool valid(size_t i, const range<size_t>& itime_range) const186{187const unsigned int index = (unsigned int)i;188if (index >= numVertices())189return false;190191for (size_t itime = itime_range.begin(); itime <= itime_range.end(); itime++) {192const Vec3ff v0 = vertex(index + 0, itime);193if (unlikely(!isvalid4(v0)))194return false;195if (v0.w < 0.0f)196return false;197}198return true;199}200201/*! calculates the linear bounds of the i'th primitive at the itimeGlobal'th time segment */202__forceinline LBBox3fa linearBounds(size_t i, size_t itime) const {203return LBBox3fa(bounds(i, itime + 0), bounds(i, itime + 1));204}205206/*! calculates the build bounds of the i'th primitive, if it's valid */207__forceinline bool buildBounds(size_t i, BBox3fa* bbox) const208{209if (!valid(i, 0))210return false;211*bbox = bounds(i);212return true;213}214215/*! calculates the build bounds of the i'th primitive at the itime'th time segment, if it's valid */216__forceinline bool buildBounds(size_t i, size_t itime, BBox3fa& bbox) const217{218if (!valid(i, itime + 0) || !valid(i, itime + 1))219return false;220bbox = bounds(i, itime); // use bounds of first time step in builder221return true;222}223224/*! calculates the linear bounds of the i'th primitive for the specified time range */225__forceinline LBBox3fa linearBounds(size_t primID, const BBox1f& dt) const {226return LBBox3fa([&](size_t itime) { return bounds(primID, itime); }, dt, time_range, fnumTimeSegments);227}228229/*! calculates the linear bounds of the i'th primitive for the specified time range */230__forceinline LBBox3fa linearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& dt) const {231return LBBox3fa([&](size_t itime) { return bounds(space, primID, itime); }, dt, time_range, fnumTimeSegments);232}233234/*! calculates the linear bounds of the i'th primitive for the specified time range */235__forceinline bool linearBounds(size_t i, const BBox1f& time_range, LBBox3fa& bbox) const236{237if (!valid(i, timeSegmentRange(time_range))) return false;238bbox = linearBounds(i, time_range);239return true;240}241242/*! get fast access to first vertex buffer */243__forceinline float * getCompactVertexArray () const {244return (float*) vertices0.getPtr();245}246247__forceinline float projectedPrimitiveArea(const size_t i) const {248const float R = radius(i);249return 1 + 2*M_PI*R*R;250}251252public:253BufferView<Vec3ff> vertices0; //!< fast access to first vertex buffer254BufferView<Vec3fa> normals0; //!< fast access to first normal buffer255Device::vector<BufferView<Vec3ff>> vertices = device; //!< vertex array for each timestep256Device::vector<BufferView<Vec3fa>> normals = device; //!< normal array for each timestep257Device::vector<BufferView<char>> vertexAttribs = device; //!< user buffers258float maxRadiusScale = 1.0; //!< maximal min-width scaling of curve radii259};260261namespace isa262{263struct PointsISA : public Points264{265PointsISA(Device* device, Geometry::GType gtype) : Points(device, gtype) {}266267Vec3fa computeDirection(unsigned int primID) const268{269return Vec3fa(1, 0, 0);270}271272Vec3fa computeDirection(unsigned int primID, size_t time) const273{274return Vec3fa(1, 0, 0);275}276277PrimInfo createPrimRefArray(PrimRef* prims, const range<size_t>& r, size_t k, unsigned int geomID) const278{279PrimInfo pinfo(empty);280for (size_t j = r.begin(); j < r.end(); j++) {281BBox3fa bounds = empty;282if (!buildBounds(j, &bounds))283continue;284const PrimRef prim(bounds, geomID, unsigned(j));285pinfo.add_center2(prim);286prims[k++] = prim;287}288return pinfo;289}290291PrimInfo createPrimRefArrayMB(mvector<PrimRef>& prims, size_t itime, const range<size_t>& r, size_t k, unsigned int geomID) const292{293PrimInfo pinfo(empty);294for (size_t j = r.begin(); j < r.end(); j++) {295BBox3fa bounds = empty;296if (!buildBounds(j, itime, bounds))297continue;298const PrimRef prim(bounds, geomID, unsigned(j));299pinfo.add_center2(prim);300prims[k++] = prim;301}302return pinfo;303}304305PrimInfo createPrimRefArrayMB(PrimRef* prims, const BBox1f& time_range, const range<size_t>& r, size_t k, unsigned int geomID) const306{307PrimInfo pinfo(empty);308const BBox1f t0t1 = BBox1f::intersect(getTimeRange(), time_range);309if (t0t1.empty()) return pinfo;310311for (size_t j = r.begin(); j < r.end(); j++) {312LBBox3fa lbounds = empty;313if (!linearBounds(j, t0t1, lbounds))314continue;315const PrimRef prim(lbounds.bounds(), geomID, unsigned(j));316pinfo.add_center2(prim);317prims[k++] = prim;318}319return pinfo;320}321322PrimInfoMB createPrimRefMBArray(mvector<PrimRefMB>& prims,323const BBox1f& t0t1,324const range<size_t>& r,325size_t k,326unsigned int geomID) const327{328PrimInfoMB pinfo(empty);329for (size_t j = r.begin(); j < r.end(); j++) {330if (!valid(j, timeSegmentRange(t0t1)))331continue;332const PrimRefMB prim(linearBounds(j, t0t1), this->numTimeSegments(), this->time_range, this->numTimeSegments(), geomID, unsigned(j));333pinfo.add_primref(prim);334prims[k++] = prim;335}336return pinfo;337}338339BBox3fa vbounds(size_t i) const340{341return bounds(i);342}343344BBox3fa vbounds(const LinearSpace3fa& space, size_t i) const345{346return bounds(space, i);347}348349LBBox3fa vlinearBounds(size_t primID, const BBox1f& time_range) const350{351return linearBounds(primID, time_range);352}353354LBBox3fa vlinearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const355{356return linearBounds(space, primID, time_range);357}358};359} // namespace isa360361DECLARE_ISA_FUNCTION(Points*, createPoints, Device* COMMA Geometry::GType);362} // namespace embree363364365