| 1 | // Copyright 2009-2021 Intel Corporation |
| 2 | // SPDX-License-Identifier: Apache-2.0 |
| 3 | |
| 4 | #pragma once |
| 5 | |
| 6 | #include "default.h" |
| 7 | #include "device.h" |
| 8 | #include "buffer.h" |
| 9 | #include "../common/point_query.h" |
| 10 | #include "../builders/priminfo.h" |
| 11 | |
| 12 | namespace embree |
| 13 | { |
| 14 | class Scene; |
| 15 | class Geometry; |
| 16 | |
| 17 | struct GeometryCounts |
| 18 | { |
| 19 | __forceinline GeometryCounts() |
| 20 | : numFilterFunctions(0), |
| 21 | numTriangles(0), numMBTriangles(0), |
| 22 | numQuads(0), numMBQuads(0), |
| 23 | numBezierCurves(0), numMBBezierCurves(0), |
| 24 | numLineSegments(0), numMBLineSegments(0), |
| 25 | numSubdivPatches(0), numMBSubdivPatches(0), |
| 26 | numUserGeometries(0), numMBUserGeometries(0), |
| 27 | numInstancesCheap(0), numMBInstancesCheap(0), |
| 28 | numInstancesExpensive(0), numMBInstancesExpensive(0), |
| 29 | numGrids(0), numMBGrids(0), |
| 30 | numPoints(0), numMBPoints(0) {} |
| 31 | |
| 32 | __forceinline size_t size() const { |
| 33 | return numTriangles + numQuads + numBezierCurves + numLineSegments + numSubdivPatches + numUserGeometries + numInstancesCheap + numInstancesExpensive + numGrids + numPoints |
| 34 | + numMBTriangles + numMBQuads + numMBBezierCurves + numMBLineSegments + numMBSubdivPatches + numMBUserGeometries + numMBInstancesCheap + numMBInstancesExpensive + numMBGrids + numMBPoints; |
| 35 | } |
| 36 | |
| 37 | __forceinline unsigned int enabledGeometryTypesMask() const |
| 38 | { |
| 39 | unsigned int mask = 0; |
| 40 | if (numTriangles) mask |= 1 << 0; |
| 41 | if (numQuads) mask |= 1 << 1; |
| 42 | if (numBezierCurves+numLineSegments) mask |= 1 << 2; |
| 43 | if (numSubdivPatches) mask |= 1 << 3; |
| 44 | if (numUserGeometries) mask |= 1 << 4; |
| 45 | if (numInstancesCheap) mask |= 1 << 5; |
| 46 | if (numInstancesExpensive) mask |= 1 << 6; |
| 47 | if (numGrids) mask |= 1 << 7; |
| 48 | if (numPoints) mask |= 1 << 8; |
| 49 | |
| 50 | unsigned int maskMB = 0; |
| 51 | if (numMBTriangles) maskMB |= 1 << 0; |
| 52 | if (numMBQuads) maskMB |= 1 << 1; |
| 53 | if (numMBBezierCurves+numMBLineSegments) maskMB |= 1 << 2; |
| 54 | if (numMBSubdivPatches) maskMB |= 1 << 3; |
| 55 | if (numMBUserGeometries) maskMB |= 1 << 4; |
| 56 | if (numMBInstancesCheap) maskMB |= 1 << 5; |
| 57 | if (numMBInstancesExpensive) maskMB |= 1 << 6; |
| 58 | if (numMBGrids) maskMB |= 1 << 7; |
| 59 | if (numMBPoints) maskMB |= 1 << 8; |
| 60 | |
| 61 | return (mask<<8) + maskMB; |
| 62 | } |
| 63 | |
| 64 | __forceinline GeometryCounts operator+ (GeometryCounts const & rhs) const |
| 65 | { |
| 66 | GeometryCounts ret; |
| 67 | ret.numFilterFunctions = numFilterFunctions + rhs.numFilterFunctions; |
| 68 | ret.numTriangles = numTriangles + rhs.numTriangles; |
| 69 | ret.numMBTriangles = numMBTriangles + rhs.numMBTriangles; |
| 70 | ret.numQuads = numQuads + rhs.numQuads; |
| 71 | ret.numMBQuads = numMBQuads + rhs.numMBQuads; |
| 72 | ret.numBezierCurves = numBezierCurves + rhs.numBezierCurves; |
| 73 | ret.numMBBezierCurves = numMBBezierCurves + rhs.numMBBezierCurves; |
| 74 | ret.numLineSegments = numLineSegments + rhs.numLineSegments; |
| 75 | ret.numMBLineSegments = numMBLineSegments + rhs.numMBLineSegments; |
| 76 | ret.numSubdivPatches = numSubdivPatches + rhs.numSubdivPatches; |
| 77 | ret.numMBSubdivPatches = numMBSubdivPatches + rhs.numMBSubdivPatches; |
| 78 | ret.numUserGeometries = numUserGeometries + rhs.numUserGeometries; |
| 79 | ret.numMBUserGeometries = numMBUserGeometries + rhs.numMBUserGeometries; |
| 80 | ret.numInstancesCheap = numInstancesCheap + rhs.numInstancesCheap; |
| 81 | ret.numMBInstancesCheap = numMBInstancesCheap + rhs.numMBInstancesCheap; |
| 82 | ret.numInstancesExpensive = numInstancesExpensive + rhs.numInstancesExpensive; |
| 83 | ret.numMBInstancesExpensive = numMBInstancesExpensive + rhs.numMBInstancesExpensive; |
| 84 | ret.numGrids = numGrids + rhs.numGrids; |
| 85 | ret.numMBGrids = numMBGrids + rhs.numMBGrids; |
| 86 | ret.numPoints = numPoints + rhs.numPoints; |
| 87 | ret.numMBPoints = numMBPoints + rhs.numMBPoints; |
| 88 | |
| 89 | return ret; |
| 90 | } |
| 91 | |
| 92 | size_t numFilterFunctions; //!< number of geometries with filter functions enabled |
| 93 | size_t numTriangles; //!< number of enabled triangles |
| 94 | size_t numMBTriangles; //!< number of enabled motion blured triangles |
| 95 | size_t numQuads; //!< number of enabled quads |
| 96 | size_t numMBQuads; //!< number of enabled motion blurred quads |
| 97 | size_t numBezierCurves; //!< number of enabled curves |
| 98 | size_t numMBBezierCurves; //!< number of enabled motion blurred curves |
| 99 | size_t numLineSegments; //!< number of enabled line segments |
| 100 | size_t numMBLineSegments; //!< number of enabled line motion blurred segments |
| 101 | size_t numSubdivPatches; //!< number of enabled subdivision patches |
| 102 | size_t numMBSubdivPatches; //!< number of enabled motion blured subdivision patches |
| 103 | size_t numUserGeometries; //!< number of enabled user geometries |
| 104 | size_t numMBUserGeometries; //!< number of enabled motion blurred user geometries |
| 105 | size_t numInstancesCheap; //!< number of enabled cheap instances |
| 106 | size_t numMBInstancesCheap; //!< number of enabled motion blurred cheap instances |
| 107 | size_t numInstancesExpensive; //!< number of enabled expensive instances |
| 108 | size_t numMBInstancesExpensive; //!< number of enabled motion blurred expensive instances |
| 109 | size_t numGrids; //!< number of enabled grid geometries |
| 110 | size_t numMBGrids; //!< number of enabled motion blurred grid geometries |
| 111 | size_t numPoints; //!< number of enabled points |
| 112 | size_t numMBPoints; //!< number of enabled motion blurred points |
| 113 | }; |
| 114 | |
| 115 | /*! Base class all geometries are derived from */ |
| 116 | class Geometry : public RefCount |
| 117 | { |
| 118 | friend class Scene; |
| 119 | public: |
| 120 | |
| 121 | /*! type of geometry */ |
| 122 | enum GType |
| 123 | { |
| 124 | GTY_FLAT_LINEAR_CURVE = 0, |
| 125 | GTY_ROUND_LINEAR_CURVE = 1, |
| 126 | GTY_ORIENTED_LINEAR_CURVE = 2, |
| 127 | GTY_CONE_LINEAR_CURVE = 3, |
| 128 | |
| 129 | GTY_FLAT_BEZIER_CURVE = 4, |
| 130 | GTY_ROUND_BEZIER_CURVE = 5, |
| 131 | GTY_ORIENTED_BEZIER_CURVE = 6, |
| 132 | |
| 133 | GTY_FLAT_BSPLINE_CURVE = 8, |
| 134 | GTY_ROUND_BSPLINE_CURVE = 9, |
| 135 | GTY_ORIENTED_BSPLINE_CURVE = 10, |
| 136 | |
| 137 | GTY_FLAT_HERMITE_CURVE = 12, |
| 138 | GTY_ROUND_HERMITE_CURVE = 13, |
| 139 | GTY_ORIENTED_HERMITE_CURVE = 14, |
| 140 | |
| 141 | GTY_FLAT_CATMULL_ROM_CURVE = 16, |
| 142 | GTY_ROUND_CATMULL_ROM_CURVE = 17, |
| 143 | GTY_ORIENTED_CATMULL_ROM_CURVE = 18, |
| 144 | |
| 145 | GTY_TRIANGLE_MESH = 20, |
| 146 | GTY_QUAD_MESH = 21, |
| 147 | GTY_GRID_MESH = 22, |
| 148 | GTY_SUBDIV_MESH = 23, |
| 149 | |
| 150 | GTY_SPHERE_POINT = 25, |
| 151 | GTY_DISC_POINT = 26, |
| 152 | GTY_ORIENTED_DISC_POINT = 27, |
| 153 | |
| 154 | GTY_USER_GEOMETRY = 29, |
| 155 | GTY_INSTANCE_CHEAP = 30, |
| 156 | GTY_INSTANCE_EXPENSIVE = 31, |
| 157 | GTY_END = 32, |
| 158 | |
| 159 | GTY_BASIS_LINEAR = 0, |
| 160 | GTY_BASIS_BEZIER = 4, |
| 161 | GTY_BASIS_BSPLINE = 8, |
| 162 | GTY_BASIS_HERMITE = 12, |
| 163 | GTY_BASIS_CATMULL_ROM = 16, |
| 164 | GTY_BASIS_MASK = 28, |
| 165 | |
| 166 | GTY_SUBTYPE_FLAT_CURVE = 0, |
| 167 | GTY_SUBTYPE_ROUND_CURVE = 1, |
| 168 | GTY_SUBTYPE_ORIENTED_CURVE = 2, |
| 169 | GTY_SUBTYPE_MASK = 3, |
| 170 | }; |
| 171 | |
| 172 | enum GSubType |
| 173 | { |
| 174 | GTY_SUBTYPE_DEFAULT= 0, |
| 175 | GTY_SUBTYPE_INSTANCE_LINEAR = 0, |
| 176 | GTY_SUBTYPE_INSTANCE_QUATERNION = 1 |
| 177 | }; |
| 178 | |
| 179 | enum GTypeMask |
| 180 | { |
| 181 | MTY_FLAT_LINEAR_CURVE = 1ul << GTY_FLAT_LINEAR_CURVE, |
| 182 | MTY_ROUND_LINEAR_CURVE = 1ul << GTY_ROUND_LINEAR_CURVE, |
| 183 | MTY_CONE_LINEAR_CURVE = 1ul << GTY_CONE_LINEAR_CURVE, |
| 184 | MTY_ORIENTED_LINEAR_CURVE = 1ul << GTY_ORIENTED_LINEAR_CURVE, |
| 185 | |
| 186 | MTY_FLAT_BEZIER_CURVE = 1ul << GTY_FLAT_BEZIER_CURVE, |
| 187 | MTY_ROUND_BEZIER_CURVE = 1ul << GTY_ROUND_BEZIER_CURVE, |
| 188 | MTY_ORIENTED_BEZIER_CURVE = 1ul << GTY_ORIENTED_BEZIER_CURVE, |
| 189 | |
| 190 | MTY_FLAT_BSPLINE_CURVE = 1ul << GTY_FLAT_BSPLINE_CURVE, |
| 191 | MTY_ROUND_BSPLINE_CURVE = 1ul << GTY_ROUND_BSPLINE_CURVE, |
| 192 | MTY_ORIENTED_BSPLINE_CURVE = 1ul << GTY_ORIENTED_BSPLINE_CURVE, |
| 193 | |
| 194 | MTY_FLAT_HERMITE_CURVE = 1ul << GTY_FLAT_HERMITE_CURVE, |
| 195 | MTY_ROUND_HERMITE_CURVE = 1ul << GTY_ROUND_HERMITE_CURVE, |
| 196 | MTY_ORIENTED_HERMITE_CURVE = 1ul << GTY_ORIENTED_HERMITE_CURVE, |
| 197 | |
| 198 | MTY_FLAT_CATMULL_ROM_CURVE = 1ul << GTY_FLAT_CATMULL_ROM_CURVE, |
| 199 | MTY_ROUND_CATMULL_ROM_CURVE = 1ul << GTY_ROUND_CATMULL_ROM_CURVE, |
| 200 | MTY_ORIENTED_CATMULL_ROM_CURVE = 1ul << GTY_ORIENTED_CATMULL_ROM_CURVE, |
| 201 | |
| 202 | MTY_CURVE2 = MTY_FLAT_LINEAR_CURVE | MTY_ROUND_LINEAR_CURVE | MTY_CONE_LINEAR_CURVE | MTY_ORIENTED_LINEAR_CURVE, |
| 203 | |
| 204 | MTY_CURVE4 = MTY_FLAT_BEZIER_CURVE | MTY_ROUND_BEZIER_CURVE | MTY_ORIENTED_BEZIER_CURVE | |
| 205 | MTY_FLAT_BSPLINE_CURVE | MTY_ROUND_BSPLINE_CURVE | MTY_ORIENTED_BSPLINE_CURVE | |
| 206 | MTY_FLAT_HERMITE_CURVE | MTY_ROUND_HERMITE_CURVE | MTY_ORIENTED_HERMITE_CURVE | |
| 207 | MTY_FLAT_CATMULL_ROM_CURVE | MTY_ROUND_CATMULL_ROM_CURVE | MTY_ORIENTED_CATMULL_ROM_CURVE, |
| 208 | |
| 209 | MTY_SPHERE_POINT = 1ul << GTY_SPHERE_POINT, |
| 210 | MTY_DISC_POINT = 1ul << GTY_DISC_POINT, |
| 211 | MTY_ORIENTED_DISC_POINT = 1ul << GTY_ORIENTED_DISC_POINT, |
| 212 | |
| 213 | MTY_POINTS = MTY_SPHERE_POINT | MTY_DISC_POINT | MTY_ORIENTED_DISC_POINT, |
| 214 | |
| 215 | MTY_CURVES = MTY_CURVE2 | MTY_CURVE4 | MTY_POINTS, |
| 216 | |
| 217 | MTY_TRIANGLE_MESH = 1ul << GTY_TRIANGLE_MESH, |
| 218 | MTY_QUAD_MESH = 1ul << GTY_QUAD_MESH, |
| 219 | MTY_GRID_MESH = 1ul << GTY_GRID_MESH, |
| 220 | MTY_SUBDIV_MESH = 1ul << GTY_SUBDIV_MESH, |
| 221 | MTY_USER_GEOMETRY = 1ul << GTY_USER_GEOMETRY, |
| 222 | |
| 223 | MTY_INSTANCE_CHEAP = 1ul << GTY_INSTANCE_CHEAP, |
| 224 | MTY_INSTANCE_EXPENSIVE = 1ul << GTY_INSTANCE_EXPENSIVE, |
| 225 | MTY_INSTANCE = MTY_INSTANCE_CHEAP | MTY_INSTANCE_EXPENSIVE |
| 226 | }; |
| 227 | |
| 228 | static const char* gtype_names[GTY_END]; |
| 229 | |
| 230 | enum class State : unsigned { |
| 231 | MODIFIED = 0, |
| 232 | COMMITTED = 1, |
| 233 | }; |
| 234 | |
| 235 | public: |
| 236 | |
| 237 | /*! Geometry constructor */ |
| 238 | Geometry (Device* device, GType gtype, unsigned int numPrimitives, unsigned int numTimeSteps); |
| 239 | |
| 240 | /*! Geometry destructor */ |
| 241 | virtual ~Geometry(); |
| 242 | |
| 243 | public: |
| 244 | |
| 245 | /*! tests if geometry is enabled */ |
| 246 | __forceinline bool isEnabled() const { return enabled; } |
| 247 | |
| 248 | /*! tests if geometry is disabled */ |
| 249 | __forceinline bool isDisabled() const { return !isEnabled(); } |
| 250 | |
| 251 | /*! tests if that geometry has some filter function set */ |
| 252 | __forceinline bool hasFilterFunctions () const { |
| 253 | return (intersectionFilterN != nullptr) || (occlusionFilterN != nullptr); |
| 254 | } |
| 255 | |
| 256 | /*! returns geometry type */ |
| 257 | __forceinline GType getType() const { return gtype; } |
| 258 | |
| 259 | /*! returns curve type */ |
| 260 | __forceinline GType getCurveType() const { return (GType)(gtype & GTY_SUBTYPE_MASK); } |
| 261 | |
| 262 | /*! returns curve basis */ |
| 263 | __forceinline GType getCurveBasis() const { return (GType)(gtype & GTY_BASIS_MASK); } |
| 264 | |
| 265 | /*! returns geometry type mask */ |
| 266 | __forceinline GTypeMask getTypeMask() const { return (GTypeMask)(1 << gtype); } |
| 267 | |
| 268 | /*! returns number of primitives */ |
| 269 | __forceinline size_t size() const { return numPrimitives; } |
| 270 | |
| 271 | /*! sets the number of primitives */ |
| 272 | virtual void setNumPrimitives(unsigned int numPrimitives_in); |
| 273 | |
| 274 | /*! sets number of time steps */ |
| 275 | virtual void setNumTimeSteps (unsigned int numTimeSteps_in); |
| 276 | |
| 277 | /*! sets motion blur time range */ |
| 278 | void setTimeRange (const BBox1f range); |
| 279 | |
| 280 | /*! sets number of vertex attributes */ |
| 281 | virtual void setVertexAttributeCount (unsigned int N) { |
| 282 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 283 | } |
| 284 | |
| 285 | /*! sets number of topologies */ |
| 286 | virtual void setTopologyCount (unsigned int N) { |
| 287 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 288 | } |
| 289 | |
| 290 | /*! sets the build quality */ |
| 291 | void setBuildQuality(RTCBuildQuality quality_in) |
| 292 | { |
| 293 | this->quality = quality_in; |
| 294 | Geometry::update(); |
| 295 | } |
| 296 | |
| 297 | /* calculate time segment itime and fractional time ftime */ |
| 298 | __forceinline int timeSegment(float time, float& ftime) const { |
| 299 | return getTimeSegment(time,start_time: time_range.lower,end_time: time_range.upper,numTimeSegments: fnumTimeSegments,ftime); |
| 300 | } |
| 301 | |
| 302 | template<int N> |
| 303 | __forceinline vint<N> timeSegment(const vfloat<N>& time, vfloat<N>& ftime) const { |
| 304 | return getTimeSegment<N>(time,vfloat<N>(time_range.lower),vfloat<N>(time_range.upper),vfloat<N>(fnumTimeSegments),ftime); |
| 305 | } |
| 306 | |
| 307 | /* calculate overlapping time segment range */ |
| 308 | __forceinline range<int> timeSegmentRange(const BBox1f& range) const { |
| 309 | return getTimeSegmentRange(range,time_range,numTimeSegments: fnumTimeSegments); |
| 310 | } |
| 311 | |
| 312 | /* returns time that corresponds to time step */ |
| 313 | __forceinline float timeStep(const int i) const { |
| 314 | assert(i>=0 && i<(int)numTimeSteps); |
| 315 | return time_range.lower + time_range.size()*float(i)/fnumTimeSegments; |
| 316 | } |
| 317 | |
| 318 | /*! for all geometries */ |
| 319 | public: |
| 320 | |
| 321 | /*! Enable geometry. */ |
| 322 | virtual void enable(); |
| 323 | |
| 324 | /*! Update geometry. */ |
| 325 | void update(); |
| 326 | |
| 327 | /*! commit of geometry */ |
| 328 | virtual void commit(); |
| 329 | |
| 330 | /*! Update geometry buffer. */ |
| 331 | virtual void updateBuffer(RTCBufferType type, unsigned int slot) { |
| 332 | update(); // update everything for geometries not supporting this call |
| 333 | } |
| 334 | |
| 335 | /*! Disable geometry. */ |
| 336 | virtual void disable(); |
| 337 | |
| 338 | /*! Verify the geometry */ |
| 339 | virtual bool verify() { return true; } |
| 340 | |
| 341 | /*! called before every build */ |
| 342 | virtual void preCommit(); |
| 343 | |
| 344 | /*! called after every build */ |
| 345 | virtual void postCommit(); |
| 346 | |
| 347 | virtual void addElementsToCount (GeometryCounts & counts) const { |
| 348 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 349 | }; |
| 350 | |
| 351 | /*! sets constant tessellation rate for the geometry */ |
| 352 | virtual void setTessellationRate(float N) { |
| 353 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 354 | } |
| 355 | |
| 356 | /*! Sets the maximal curve radius scale allowed by min-width feature. */ |
| 357 | virtual void setMaxRadiusScale(float s) { |
| 358 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 359 | } |
| 360 | |
| 361 | /*! Set user data pointer. */ |
| 362 | virtual void setUserData(void* ptr); |
| 363 | |
| 364 | /*! Get user data pointer. */ |
| 365 | __forceinline void* getUserData() const { |
| 366 | return userPtr; |
| 367 | } |
| 368 | |
| 369 | /*! interpolates user data to the specified u/v location */ |
| 370 | virtual void interpolate(const RTCInterpolateArguments* const args) { |
| 371 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 372 | } |
| 373 | |
| 374 | /*! interpolates user data to the specified u/v locations */ |
| 375 | virtual void interpolateN(const RTCInterpolateNArguments* const args); |
| 376 | |
| 377 | /* point query api */ |
| 378 | bool pointQuery(PointQuery* query, PointQueryContext* context); |
| 379 | |
| 380 | /*! for subdivision surfaces only */ |
| 381 | public: |
| 382 | virtual void setSubdivisionMode (unsigned topologyID, RTCSubdivisionMode mode) { |
| 383 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 384 | } |
| 385 | |
| 386 | virtual void setVertexAttributeTopology(unsigned int vertexBufferSlot, unsigned int indexBufferSlot) { |
| 387 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 388 | } |
| 389 | |
| 390 | /*! Set displacement function. */ |
| 391 | virtual void setDisplacementFunction (RTCDisplacementFunctionN filter) { |
| 392 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 393 | } |
| 394 | |
| 395 | virtual unsigned int getFirstHalfEdge(unsigned int faceID) { |
| 396 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 397 | } |
| 398 | |
| 399 | virtual unsigned int getFace(unsigned int edgeID) { |
| 400 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 401 | } |
| 402 | |
| 403 | virtual unsigned int getNextHalfEdge(unsigned int edgeID) { |
| 404 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 405 | } |
| 406 | |
| 407 | virtual unsigned int getPreviousHalfEdge(unsigned int edgeID) { |
| 408 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 409 | } |
| 410 | |
| 411 | virtual unsigned int getOppositeHalfEdge(unsigned int topologyID, unsigned int edgeID) { |
| 412 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 413 | } |
| 414 | |
| 415 | /*! get fast access to first vertex buffer if applicable */ |
| 416 | virtual float * getCompactVertexArray () const { |
| 417 | return nullptr; |
| 418 | } |
| 419 | |
| 420 | /*! Returns the modified counter - how many times the geo has been modified */ |
| 421 | __forceinline unsigned int getModCounter () const { |
| 422 | return modCounter_; |
| 423 | } |
| 424 | |
| 425 | /*! for triangle meshes and bezier curves only */ |
| 426 | public: |
| 427 | |
| 428 | |
| 429 | /*! Sets ray mask. */ |
| 430 | virtual void setMask(unsigned mask) { |
| 431 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 432 | } |
| 433 | |
| 434 | /*! Sets specified buffer. */ |
| 435 | virtual void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num) { |
| 436 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 437 | } |
| 438 | |
| 439 | /*! Gets specified buffer. */ |
| 440 | virtual void* getBuffer(RTCBufferType type, unsigned int slot) { |
| 441 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 442 | } |
| 443 | |
| 444 | /*! Set intersection filter function for ray packets of size N. */ |
| 445 | virtual void setIntersectionFilterFunctionN (RTCFilterFunctionN filterN); |
| 446 | |
| 447 | /*! Set occlusion filter function for ray packets of size N. */ |
| 448 | virtual void setOcclusionFilterFunctionN (RTCFilterFunctionN filterN); |
| 449 | |
| 450 | /*! for instances only */ |
| 451 | public: |
| 452 | |
| 453 | /*! Sets the instanced scene */ |
| 454 | virtual void setInstancedScene(const Ref<Scene>& scene) { |
| 455 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 456 | } |
| 457 | |
| 458 | /*! Sets transformation of the instance */ |
| 459 | virtual void setTransform(const AffineSpace3fa& transform, unsigned int timeStep) { |
| 460 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 461 | } |
| 462 | |
| 463 | /*! Sets transformation of the instance */ |
| 464 | virtual void setQuaternionDecomposition(const AffineSpace3ff& qd, unsigned int timeStep) { |
| 465 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 466 | } |
| 467 | |
| 468 | /*! Returns the transformation of the instance */ |
| 469 | virtual AffineSpace3fa getTransform(float time) { |
| 470 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 471 | } |
| 472 | |
| 473 | /*! for user geometries only */ |
| 474 | public: |
| 475 | |
| 476 | /*! Set bounds function. */ |
| 477 | virtual void setBoundsFunction (RTCBoundsFunction bounds, void* userPtr) { |
| 478 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 479 | } |
| 480 | |
| 481 | /*! Set intersect function for ray packets of size N. */ |
| 482 | virtual void setIntersectFunctionN (RTCIntersectFunctionN intersect) { |
| 483 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 484 | } |
| 485 | |
| 486 | /*! Set occlusion function for ray packets of size N. */ |
| 487 | virtual void setOccludedFunctionN (RTCOccludedFunctionN occluded) { |
| 488 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation not supported for this geometry" ); |
| 489 | } |
| 490 | |
| 491 | /*! Set point query function. */ |
| 492 | void setPointQueryFunction(RTCPointQueryFunction func); |
| 493 | |
| 494 | /*! returns number of time segments */ |
| 495 | __forceinline unsigned numTimeSegments () const { |
| 496 | return numTimeSteps-1; |
| 497 | } |
| 498 | |
| 499 | public: |
| 500 | |
| 501 | virtual PrimInfo createPrimRefArray(mvector<PrimRef>& prims, const range<size_t>& r, size_t k, unsigned int geomID) const { |
| 502 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"createPrimRefArray not implemented for this geometry" ); |
| 503 | } |
| 504 | |
| 505 | virtual PrimInfo createPrimRefArrayMB(mvector<PrimRef>& prims, size_t itime, const range<size_t>& r, size_t k, unsigned int geomID) const { |
| 506 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"createPrimRefMBArray not implemented for this geometry" ); |
| 507 | } |
| 508 | |
| 509 | virtual PrimInfoMB createPrimRefMBArray(mvector<PrimRefMB>& prims, const BBox1f& t0t1, const range<size_t>& r, size_t k, unsigned int geomID) const { |
| 510 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"createPrimRefMBArray not implemented for this geometry" ); |
| 511 | } |
| 512 | |
| 513 | virtual LinearSpace3fa computeAlignedSpace(const size_t primID) const { |
| 514 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"computeAlignedSpace not implemented for this geometry" ); |
| 515 | } |
| 516 | |
| 517 | virtual LinearSpace3fa computeAlignedSpaceMB(const size_t primID, const BBox1f time_range) const { |
| 518 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"computeAlignedSpace not implemented for this geometry" ); |
| 519 | } |
| 520 | |
| 521 | virtual Vec3fa computeDirection(unsigned int primID) const { |
| 522 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"computeDirection not implemented for this geometry" ); |
| 523 | } |
| 524 | |
| 525 | virtual Vec3fa computeDirection(unsigned int primID, size_t time) const { |
| 526 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"computeDirection not implemented for this geometry" ); |
| 527 | } |
| 528 | |
| 529 | virtual BBox3fa vbounds(size_t primID) const { |
| 530 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"vbounds not implemented for this geometry" ); |
| 531 | } |
| 532 | |
| 533 | virtual BBox3fa vbounds(const LinearSpace3fa& space, size_t primID) const { |
| 534 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"vbounds not implemented for this geometry" ); |
| 535 | } |
| 536 | |
| 537 | virtual BBox3fa vbounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t i, size_t itime = 0) const { |
| 538 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"vbounds not implemented for this geometry" ); |
| 539 | } |
| 540 | |
| 541 | virtual LBBox3fa vlinearBounds(size_t primID, const BBox1f& time_range) const { |
| 542 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"vlinearBounds not implemented for this geometry" ); |
| 543 | } |
| 544 | |
| 545 | virtual LBBox3fa vlinearBounds(const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const { |
| 546 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"vlinearBounds not implemented for this geometry" ); |
| 547 | } |
| 548 | |
| 549 | virtual LBBox3fa vlinearBounds(const Vec3fa& ofs, const float scale, const float r_scale0, const LinearSpace3fa& space, size_t primID, const BBox1f& time_range) const { |
| 550 | throw_RTCError(RTC_ERROR_INVALID_OPERATION,"vlinearBounds not implemented for this geometry" ); |
| 551 | } |
| 552 | |
| 553 | public: |
| 554 | __forceinline bool hasIntersectionFilter() const { return intersectionFilterN != nullptr; } |
| 555 | __forceinline bool hasOcclusionFilter() const { return occlusionFilterN != nullptr; } |
| 556 | |
| 557 | public: |
| 558 | Device* device; //!< device this geometry belongs to |
| 559 | |
| 560 | void* userPtr; //!< user pointer |
| 561 | unsigned int numPrimitives; //!< number of primitives of this geometry |
| 562 | |
| 563 | unsigned int numTimeSteps; //!< number of time steps |
| 564 | float fnumTimeSegments; //!< number of time segments (precalculation) |
| 565 | BBox1f time_range; //!< motion blur time range |
| 566 | |
| 567 | unsigned int mask; //!< for masking out geometry |
| 568 | unsigned int modCounter_ = 1; //!< counter for every modification - used to rebuild scenes when geo is modified |
| 569 | |
| 570 | struct { |
| 571 | GType gtype : 8; //!< geometry type |
| 572 | GSubType gsubtype : 8; //!< geometry subtype |
| 573 | RTCBuildQuality quality : 3; //!< build quality for geometry |
| 574 | unsigned state : 2; |
| 575 | bool enabled : 1; //!< true if geometry is enabled |
| 576 | }; |
| 577 | |
| 578 | RTCFilterFunctionN intersectionFilterN; |
| 579 | RTCFilterFunctionN occlusionFilterN; |
| 580 | RTCPointQueryFunction pointQueryFunc; |
| 581 | }; |
| 582 | } |
| 583 | |