| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- // ======================================================================== //
- // Copyright 2009-2017 Intel Corporation //
- // //
- // Licensed under the Apache License, Version 2.0 (the "License"); //
- // you may not use this file except in compliance with the License. //
- // You may obtain a copy of the License at //
- // //
- // http://www.apache.org/licenses/LICENSE-2.0 //
- // //
- // Unless required by applicable law or agreed to in writing, software //
- // distributed under the License is distributed on an "AS IS" BASIS, //
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
- // See the License for the specific language governing permissions and //
- // limitations under the License. //
- // ======================================================================== //
- #pragma once
- #include "default.h"
- namespace embree
- {
- class Scene;
- /*! Base class all geometries are derived from */
- class Geometry
- {
- friend class Scene;
- public:
- /*! type of geometry */
- enum Type { TRIANGLE_MESH = 1, USER_GEOMETRY = 2, BEZIER_CURVES = 4, SUBDIV_MESH = 8, INSTANCE = 16, QUAD_MESH = 32, LINE_SEGMENTS = 64 };
- public:
-
- /*! Geometry constructor */
- Geometry (Scene* scene, Type type, size_t numPrimitives, size_t numTimeSteps, RTCGeometryFlags flags);
- /*! Geometry destructor */
- virtual ~Geometry();
- /*! updates intersection filter function counts in scene */
- void updateIntersectionFilters(bool enable);
- public:
- /*! tests if geometry is enabled */
- __forceinline bool isEnabled() const { return numPrimitives && enabled; }
- /*! tests if geometry is disabled */
- __forceinline bool isDisabled() const { return !isEnabled(); }
- /*! tests if geomery is used by any instance (including world space instance) */
- __forceinline bool isUsed() const { return used; }
- /*! tests if geometry is used by any non-world space instance */
- __forceinline bool isInstanced() const { return used-enabled; }
- /*! tests if geometry is modified */
- __forceinline bool isModified() const { return numPrimitives && modified; }
- /*! clears modified flag */
- __forceinline void clearModified() { modified = false; }
- /*! test if this is a static geometry */
- __forceinline bool isStatic() const { return flags == RTC_GEOMETRY_STATIC; }
- /*! test if this is a deformable geometry */
- __forceinline bool isDeformable() const { return flags == RTC_GEOMETRY_DEFORMABLE; }
- /*! test if this is a dynamic geometry */
- __forceinline bool isDynamic() const { return flags == RTC_GEOMETRY_DYNAMIC; }
- /*! returns geometry type */
- __forceinline Type getType() const { return type; }
- /*! returns number of primitives */
- __forceinline size_t size() const { return numPrimitives; }
- /*! sets the number of primitives */
- __forceinline void setNumPrimitives(size_t numPrimitives_in)
- {
- if ((ssize_t)numPrimitives_in == -1) return;
- if (numPrimitives_in == numPrimitives) return;
- numPrimitives = numPrimitives_in;
- numPrimitivesChanged = true;
- }
- /*! for all geometries */
- public:
- /*! Enable geometry. */
- virtual void enable ();
- /*! Update geometry. */
- virtual void update ();
- /*! Update geometry buffer. */
- virtual void updateBuffer (RTCBufferType type) {
- update(); // update everything for geometries not supporting this call
- }
-
- /*! Disable geometry. */
- virtual void disable ();
- /*! Free buffers that are unused */
- virtual void immutable () {}
- /*! Verify the geometry */
- virtual bool verify () { return true; }
- /*! called if geometry is switching from disabled to enabled state */
- virtual void enabling() = 0;
- /*! called if geometry is switching from enabled to disabled state */
- virtual void disabling() = 0;
- /*! called before every build */
- virtual void preCommit();
- /*! called after every build */
- virtual void postCommit();
- /*! sets constant tessellation rate for the geometry */
- virtual void setTessellationRate(float N) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set user data pointer. */
- virtual void setUserData (void* ptr);
-
- /*! Get user data pointer. */
- __forceinline void* getUserData() const {
- return userPtr;
- }
- /*! interpolates user data to the specified u/v location */
- virtual void interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! interpolates user data to the specified u/v locations */
- virtual void interpolateN(const void* valid_i, const unsigned* primIDs, const float* u, const float* v, size_t numUVs,
- RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats);
- /*! for subdivision surfaces only */
- public:
- virtual void setSubdivisionMode (unsigned topologyID, RTCSubdivisionMode mode) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- virtual void setIndexBuffer(RTCBufferType vertexBuffer, RTCBufferType indexBuffer) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! for triangle meshes and bezier curves only */
- public:
- /*! Sets ray mask. */
- virtual void setMask (unsigned mask) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Maps specified buffer. */
- virtual void* map(RTCBufferType type) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- return nullptr;
- }
- /*! Unmap specified buffer. */
- virtual void unmap(RTCBufferType type) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Sets specified buffer. */
- virtual void setBuffer(RTCBufferType type, void* ptr, size_t offset, size_t stride, size_t size) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set displacement function. */
- virtual void setDisplacementFunction (RTCDisplacementFunc filter, RTCBounds* bounds) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set displacement function. */
- virtual void setDisplacementFunction2 (RTCDisplacementFunc2 filter, RTCBounds* bounds) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set intersection filter function for single rays. */
- virtual void setIntersectionFilterFunction (RTCFilterFunc filter, bool ispc = false);
-
- /*! Set intersection filter function for ray packets of size 4. */
- virtual void setIntersectionFilterFunction4 (RTCFilterFunc4 filter4, bool ispc = false);
-
- /*! Set intersection filter function for ray packets of size 8. */
- virtual void setIntersectionFilterFunction8 (RTCFilterFunc8 filter8, bool ispc = false);
-
- /*! Set intersection filter function for ray packets of size 16. */
- virtual void setIntersectionFilterFunction16 (RTCFilterFunc16 filter16, bool ispc = false);
- /*! Set intersection filter function for ray packets of size N. */
- virtual void setIntersectionFilterFunctionN (RTCFilterFuncN filterN);
- /*! Set occlusion filter function for single rays. */
- virtual void setOcclusionFilterFunction (RTCFilterFunc filter, bool ispc = false);
-
- /*! Set occlusion filter function for ray packets of size 4. */
- virtual void setOcclusionFilterFunction4 (RTCFilterFunc4 filter4, bool ispc = false);
-
- /*! Set occlusion filter function for ray packets of size 8. */
- virtual void setOcclusionFilterFunction8 (RTCFilterFunc8 filter8, bool ispc = false);
-
- /*! Set occlusion filter function for ray packets of size 16. */
- virtual void setOcclusionFilterFunction16 (RTCFilterFunc16 filter16, bool ispc = false);
- /*! Set occlusion filter function for ray packets of size N. */
- virtual void setOcclusionFilterFunctionN (RTCFilterFuncN filterN);
- /*! for instances only */
- public:
-
- /*! Sets transformation of the instance */
- virtual void setTransform(const AffineSpace3fa& transform, size_t timeStep) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! for user geometries only */
- public:
- /*! Set bounds function. */
- virtual void setBoundsFunction (RTCBoundsFunc bounds) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set bounds function. */
- virtual void setBoundsFunction2 (RTCBoundsFunc2 bounds, void* userPtr) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set bounds function. */
- virtual void setBoundsFunction3 (RTCBoundsFunc3 bounds, void* userPtr) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set intersect function for single rays. */
- virtual void setIntersectFunction (RTCIntersectFunc intersect, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set intersect function for ray packets of size 4. */
- virtual void setIntersectFunction4 (RTCIntersectFunc4 intersect4, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set intersect function for ray packets of size 8. */
- virtual void setIntersectFunction8 (RTCIntersectFunc8 intersect8, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set intersect function for ray packets of size 16. */
- virtual void setIntersectFunction16 (RTCIntersectFunc16 intersect16, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set intersect function for streams of single rays. */
- virtual void setIntersectFunction1Mp (RTCIntersectFunc1Mp intersect) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set intersect function for ray packets of size N. */
- virtual void setIntersectFunctionN (RTCIntersectFuncN intersect) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set occlusion function for single rays. */
- virtual void setOccludedFunction (RTCOccludedFunc occluded, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set occlusion function for ray packets of size 4. */
- virtual void setOccludedFunction4 (RTCOccludedFunc4 occluded4, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set occlusion function for ray packets of size 8. */
- virtual void setOccludedFunction8 (RTCOccludedFunc8 occluded8, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
-
- /*! Set occlusion function for ray packets of size 16. */
- virtual void setOccludedFunction16 (RTCOccludedFunc16 occluded16, bool ispc = false) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set occlusion function for streams of single rays. */
- virtual void setOccludedFunction1Mp (RTCOccludedFunc1Mp occluded) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! Set occlusion function for ray packets of size N. */
- virtual void setOccludedFunctionN (RTCOccludedFuncN occluded) {
- throw_RTCError(RTC_INVALID_OPERATION,"operation not supported for this geometry");
- }
- /*! returns number of time segments */
- __forceinline unsigned numTimeSegments () const {
- return numTimeSteps-1;
- }
- public:
- __forceinline bool hasIntersectionFilter1() const { return (hasIntersectionFilterMask & (HAS_FILTER1 | HAS_FILTERN)) != 0; }
- __forceinline bool hasOcclusionFilter1 () const { return (hasOcclusionFilterMask & (HAS_FILTER1 | HAS_FILTERN)) != 0; }
- template<typename simd> __forceinline bool hasIntersectionFilter() const;
- template<typename simd> __forceinline bool hasOcclusionFilter() const;
- template<typename simd> __forceinline bool hasISPCIntersectionFilter() const;
- template<typename simd> __forceinline bool hasISPCOcclusionFilter() const;
- public:
- /*! calculates the linear bounds of a primitive at the itimeGlobal'th time segment */
- template<typename BoundsFunc>
- __forceinline static LBBox3fa linearBounds(const BoundsFunc& bounds, size_t itimeGlobal, size_t numTimeStepsGlobal, size_t numTimeSteps)
- {
- if (numTimeStepsGlobal == numTimeSteps)
- {
- const BBox3fa bounds0 = bounds(itimeGlobal+0);
- const BBox3fa bounds1 = bounds(itimeGlobal+1);
- return LBBox3fa(bounds0, bounds1);
- }
- const int timeSegments = int(numTimeSteps-1);
- const int timeSegmentsGlobal = int(numTimeStepsGlobal-1);
- const float invTimeSegmentsGlobal = rcp(float(timeSegmentsGlobal));
- const int itimeScaled = int(itimeGlobal) * timeSegments;
- const int itime0 = itimeScaled / timeSegmentsGlobal;
- const int rtime0 = itimeScaled % timeSegmentsGlobal;
- const float ftime0 = float(rtime0) * invTimeSegmentsGlobal;
- const int rtime1 = rtime0 + timeSegments;
- if (rtime1 <= timeSegmentsGlobal)
- {
- const BBox3fa b0 = bounds(itime0+0);
- const BBox3fa b1 = bounds(itime0+1);
- const float ftime1 = float(rtime1) * invTimeSegmentsGlobal;
- return LBBox3fa(lerp(b0, b1, ftime0), lerp(b0, b1, ftime1));
- }
- const BBox3fa b0 = bounds(itime0+0);
- const BBox3fa b1 = bounds(itime0+1);
- const BBox3fa b2 = bounds(itime0+2);
- const float ftime1 = float(rtime1-timeSegmentsGlobal) * invTimeSegmentsGlobal;
- BBox3fa bounds0 = lerp(b0, b1, ftime0);
- BBox3fa bounds1 = lerp(b1, b2, ftime1);
- const BBox3fa b1Lerp = lerp(bounds0, bounds1, float(timeSegmentsGlobal-rtime0) * rcp(float(timeSegments)));
- bounds0.lower = min(bounds0.lower, bounds0.lower - (b1Lerp.lower - b1.lower));
- bounds1.lower = min(bounds1.lower, bounds1.lower - (b1Lerp.lower - b1.lower));
- bounds0.upper = max(bounds0.upper, bounds0.upper + (b1.upper - b1Lerp.upper));
- bounds1.upper = max(bounds1.upper, bounds1.upper + (b1.upper - b1Lerp.upper));
- return LBBox3fa(bounds0, bounds1);
- }
- /*! calculates the linear bounds of a primitive at the itimeGlobal'th time segment, if it's valid */
- template<typename BoundsFunc>
- __forceinline static bool linearBounds(const BoundsFunc& bounds, size_t itimeGlobal, size_t numTimeStepsGlobal, size_t numTimeSteps, LBBox3fa& lbbox)
- {
- if (numTimeStepsGlobal == numTimeSteps)
- {
- BBox3fa bounds0; if (unlikely(!bounds(itimeGlobal+0, bounds0))) return false;
- BBox3fa bounds1; if (unlikely(!bounds(itimeGlobal+1, bounds1))) return false;
- lbbox = LBBox3fa(bounds0, bounds1);
- return true;
- }
- const int timeSegments = int(numTimeSteps-1);
- const int timeSegmentsGlobal = int(numTimeStepsGlobal-1);
- const float invTimeSegmentsGlobal = rcp(float(timeSegmentsGlobal));
- const int itimeScaled = int(itimeGlobal) * timeSegments;
- const int itime0 = itimeScaled / timeSegmentsGlobal;
- const int rtime0 = itimeScaled % timeSegmentsGlobal;
- const float ftime0 = float(rtime0) * invTimeSegmentsGlobal;
- const int rtime1 = rtime0 + timeSegments;
- if (rtime1 <= timeSegmentsGlobal)
- {
- BBox3fa b0; if (unlikely(!bounds(itime0+0, b0))) return false;
- BBox3fa b1; if (unlikely(!bounds(itime0+1, b1))) return false;
- const float ftime1 = float(rtime1) * invTimeSegmentsGlobal;
- lbbox = LBBox3fa(lerp(b0, b1, ftime0), lerp(b0, b1, ftime1));
- return true;
- }
- BBox3fa b0; if (unlikely(!bounds(itime0+0, b0))) return false;
- BBox3fa b1; if (unlikely(!bounds(itime0+1, b1))) return false;
- BBox3fa b2; if (unlikely(!bounds(itime0+2, b2))) return false;
- const float ftime1 = float(rtime1-timeSegmentsGlobal) * invTimeSegmentsGlobal;
- BBox3fa bounds0 = lerp(b0, b1, ftime0);
- BBox3fa bounds1 = lerp(b1, b2, ftime1);
- const BBox3fa b1Lerp = lerp(bounds0, bounds1, float(timeSegmentsGlobal-rtime0) * rcp(float(timeSegments)));
- bounds0.lower = min(bounds0.lower, bounds0.lower - (b1Lerp.lower - b1.lower));
- bounds1.lower = min(bounds1.lower, bounds1.lower - (b1Lerp.lower - b1.lower));
- bounds0.upper = max(bounds0.upper, bounds0.upper + (b1.upper - b1Lerp.upper));
- bounds1.upper = max(bounds1.upper, bounds1.upper + (b1.upper - b1Lerp.upper));
- lbbox = LBBox3fa(bounds0, bounds1);
- return true;
- }
- /*! calculates the build bounds of a primitive at the itimeGlobal'th time segment, if it's valid */
- template<typename BoundsFunc>
- __forceinline static bool buildBounds(const BoundsFunc& bounds, size_t itimeGlobal, size_t numTimeStepsGlobal, size_t numTimeSteps, BBox3fa& bbox)
- {
- LBBox3fa lbbox;
- if (!linearBounds(bounds, itimeGlobal, numTimeStepsGlobal, numTimeSteps, lbbox))
- return false;
- bbox = 0.5f * (lbbox.bounds0 + lbbox.bounds1);
- return true;
- }
- /*! checks if a primitive is valid at the itimeGlobal'th time segment */
- template<typename ValidFunc>
- __forceinline static bool validLinearBounds(const ValidFunc& valid, size_t itimeGlobal, size_t numTimeStepsGlobal, size_t numTimeSteps)
- {
- if (numTimeStepsGlobal == numTimeSteps)
- {
- if (unlikely(!valid(itimeGlobal+0))) return false;
- if (unlikely(!valid(itimeGlobal+1))) return false;
- return true;
- }
- const int timeSegments = int(numTimeSteps-1);
- const int timeSegmentsGlobal = int(numTimeStepsGlobal-1);
- const int itimeScaled = int(itimeGlobal) * timeSegments;
- const int itime0 = itimeScaled / timeSegmentsGlobal;
- const int rtime0 = itimeScaled % timeSegmentsGlobal;
- const int rtime1 = rtime0 + timeSegments;
- if (rtime1 <= timeSegmentsGlobal)
- {
- if (unlikely(!valid(itime0+0))) return false;
- if (unlikely(!valid(itime0+1))) return false;
- return true;
- }
- if (unlikely(!valid(itime0+0))) return false;
- if (unlikely(!valid(itime0+1))) return false;
- if (unlikely(!valid(itime0+2))) return false;
- return true;
- }
- public:
- Scene* parent; //!< pointer to scene this mesh belongs to
- unsigned id; //!< internal geometry ID
- Type type; //!< geometry type
- size_t numPrimitives; //!< number of primitives of this geometry
- bool numPrimitivesChanged; //!< true if number of primitives changed
- unsigned numTimeSteps; //!< number of time steps
- float fnumTimeSegments; //!< number of time segments (precalculation)
- RTCGeometryFlags flags; //!< flags of geometry
- bool enabled; //!< true if geometry is enabled
- bool modified; //!< true if geometry is modified
- void* userPtr; //!< user pointer
- unsigned mask; //!< for masking out geometry
- std::atomic<size_t> used; //!< counts by how many enabled instances this geometry is used
-
- public:
- RTCFilterFunc intersectionFilter1;
- RTCFilterFunc occlusionFilter1;
- RTCFilterFunc4 intersectionFilter4;
- RTCFilterFunc4 occlusionFilter4;
- RTCFilterFunc8 intersectionFilter8;
- RTCFilterFunc8 occlusionFilter8;
- RTCFilterFunc16 intersectionFilter16;
- RTCFilterFunc16 occlusionFilter16;
- RTCFilterFuncN intersectionFilterN;
- RTCFilterFuncN occlusionFilterN;
- public:
- enum { HAS_FILTER1 = 1, HAS_FILTER4 = 2, HAS_FILTER8 = 4, HAS_FILTER16 = 8, HAS_FILTERN = 16 };
- int hasIntersectionFilterMask;
- int hasOcclusionFilterMask;
- int ispcIntersectionFilterMask;
- int ispcOcclusionFilterMask;
- };
- #if defined(__SSE__)
- template<> __forceinline bool Geometry::hasIntersectionFilter<vfloat4>() const { return (hasIntersectionFilterMask & (HAS_FILTER4 | HAS_FILTERN)) != 0; }
- template<> __forceinline bool Geometry::hasOcclusionFilter <vfloat4>() const { return (hasOcclusionFilterMask & (HAS_FILTER4 | HAS_FILTERN)) != 0; }
- template<> __forceinline bool Geometry::hasISPCIntersectionFilter<vfloat4>() const { return (ispcIntersectionFilterMask & HAS_FILTER4) != 0; }
- template<> __forceinline bool Geometry::hasISPCOcclusionFilter <vfloat4>() const { return (ispcOcclusionFilterMask & HAS_FILTER4) != 0; }
- #endif
- #if defined(__AVX__)
- template<> __forceinline bool Geometry::hasIntersectionFilter<vfloat8>() const { return (hasIntersectionFilterMask & (HAS_FILTER8 | HAS_FILTERN)) != 0; }
- template<> __forceinline bool Geometry::hasOcclusionFilter <vfloat8>() const { return (hasOcclusionFilterMask & (HAS_FILTER8 | HAS_FILTERN)) != 0; }
- template<> __forceinline bool Geometry::hasISPCIntersectionFilter<vfloat8>() const { return (ispcIntersectionFilterMask & HAS_FILTER8) != 0; }
- template<> __forceinline bool Geometry::hasISPCOcclusionFilter <vfloat8>() const { return (ispcOcclusionFilterMask & HAS_FILTER8) != 0; }
- #endif
- #if defined(__AVX512F__)
- template<> __forceinline bool Geometry::hasIntersectionFilter<vfloat16>() const { return (hasIntersectionFilterMask & (HAS_FILTER16 | HAS_FILTERN)) != 0; }
- template<> __forceinline bool Geometry::hasOcclusionFilter <vfloat16>() const { return (hasOcclusionFilterMask & (HAS_FILTER16 | HAS_FILTERN)) != 0; }
- template<> __forceinline bool Geometry::hasISPCIntersectionFilter<vfloat16>() const { return (ispcIntersectionFilterMask & HAS_FILTER16) != 0; }
- template<> __forceinline bool Geometry::hasISPCOcclusionFilter <vfloat16>() const { return (ispcOcclusionFilterMask & HAS_FILTER16) != 0; }
- #endif
- /* calculate time segment itime and fractional time ftime */
- __forceinline int getTimeSegment(float time, float numTimeSegments, float& ftime)
- {
- const float timeScaled = time * numTimeSegments;
- const float itimef = clamp(floor(timeScaled), 0.0f, numTimeSegments-1.0f);
- ftime = timeScaled - itimef;
- return int(itimef);
- }
- template<int N>
- __forceinline vint<N> getTimeSegment(const vfloat<N>& time, const vfloat<N>& numTimeSegments, vfloat<N>& ftime)
- {
- const vfloat<N> timeScaled = time * numTimeSegments;
- const vfloat<N> itimef = clamp(floor(timeScaled), vfloat<N>(zero), numTimeSegments-1.0f);
- ftime = timeScaled - itimef;
- return vint<N>(itimef);
- }
- }
|