Path: blob/master/thirdparty/embree/kernels/common/accel.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "default.h"6#include "ray.h"7#include "point_query.h"8#include "context.h"910namespace embree11{12class Scene;1314/*! Base class for the acceleration structure data. */15class AccelData : public RefCount16{17ALIGNED_CLASS_(16);18public:19enum Type { TY_UNKNOWN = 0, TY_ACCELN = 1, TY_ACCEL_INSTANCE = 2, TY_BVH4 = 3, TY_BVH8 = 4, TY_GPU = 5 };2021public:22AccelData (const Type type)23: bounds(empty), type(type) {}2425/*! notifies the acceleration structure about the deletion of some geometry */26virtual void deleteGeometry(size_t geomID) {};2728/*! clears the acceleration structure data */29virtual void clear() = 0;3031/*! returns normal bounds */32__forceinline BBox3fa getBounds() const {33return bounds.bounds();34}3536/*! returns bounds for some time */37__forceinline BBox3fa getBounds(float t) const {38return bounds.interpolate(t);39}4041/*! returns linear bounds */42__forceinline LBBox3fa getLinearBounds() const {43return bounds;44}4546/*! checks if acceleration structure is empty */47__forceinline bool isEmpty() const {48return bounds.bounds0.lower.x == float(pos_inf);49}5051public:52LBBox3fa bounds; // linear bounds53Type type;54};5556/*! Base class for all intersectable and buildable acceleration structures. */57class Accel : public AccelData58{59ALIGNED_CLASS_(16);60public:6162struct Intersectors;6364/*! Type of collide function */65typedef void (*CollideFunc)(void* bvh0, void* bvh1, RTCCollideFunc callback, void* userPtr);6667/*! Type of point query function */68typedef bool(*PointQueryFunc)(Intersectors* This, /*!< this pointer to accel */69PointQuery* query, /*!< point query for lookup */70PointQueryContext* context); /*!< point query context */7172/*! Type of intersect function pointer for single rays. */73typedef void (*IntersectFunc)(Intersectors* This, /*!< this pointer to accel */74RTCRayHit& ray, /*!< ray to intersect */75RayQueryContext* context);7677/*! Type of intersect function pointer for ray packets of size 4. */78typedef void (*IntersectFunc4)(const void* valid, /*!< pointer to valid mask */79Intersectors* This, /*!< this pointer to accel */80RTCRayHit4& ray, /*!< ray packet to intersect */81RayQueryContext* context);8283/*! Type of intersect function pointer for ray packets of size 8. */84typedef void (*IntersectFunc8)(const void* valid, /*!< pointer to valid mask */85Intersectors* This, /*!< this pointer to accel */86RTCRayHit8& ray, /*!< ray packet to intersect */87RayQueryContext* context);8889/*! Type of intersect function pointer for ray packets of size 16. */90typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */91Intersectors* This, /*!< this pointer to accel */92RTCRayHit16& ray, /*!< ray packet to intersect */93RayQueryContext* context);9495/*! Type of occlusion function pointer for single rays. */96typedef void (*OccludedFunc) (Intersectors* This, /*!< this pointer to accel */97RTCRay& ray, /*!< ray to test occlusion */98RayQueryContext* context);99100/*! Type of occlusion function pointer for ray packets of size 4. */101typedef void (*OccludedFunc4) (const void* valid, /*!< pointer to valid mask */102Intersectors* This, /*!< this pointer to accel */103RTCRay4& ray, /*!< ray packet to test occlusion. */104RayQueryContext* context);105106/*! Type of occlusion function pointer for ray packets of size 8. */107typedef void (*OccludedFunc8) (const void* valid, /*!< pointer to valid mask */108Intersectors* This, /*!< this pointer to accel */109RTCRay8& ray, /*!< ray packet to test occlusion. */110RayQueryContext* context);111112/*! Type of occlusion function pointer for ray packets of size 16. */113typedef void (*OccludedFunc16) (const void* valid, /*!< pointer to valid mask */114Intersectors* This, /*!< this pointer to accel */115RTCRay16& ray, /*!< ray packet to test occlusion. */116RayQueryContext* context);117118typedef void (*ErrorFunc) ();119120struct Collider121{122Collider (ErrorFunc error = nullptr)123: collide((CollideFunc)error), name(nullptr) {}124125Collider (CollideFunc collide, const char* name)126: collide(collide), name(name) {}127128operator bool() const { return name; }129130public:131CollideFunc collide;132const char* name;133};134135struct Intersector1136{137Intersector1 (ErrorFunc error = nullptr)138: intersect((IntersectFunc)error), occluded((OccludedFunc)error), name(nullptr) {}139140Intersector1 (IntersectFunc intersect, OccludedFunc occluded, const char* name)141: intersect(intersect), occluded(occluded), pointQuery(nullptr), name(name) {}142143Intersector1 (IntersectFunc intersect, OccludedFunc occluded, PointQueryFunc pointQuery, const char* name)144: intersect(intersect), occluded(occluded), pointQuery(pointQuery), name(name) {}145146operator bool() const { return name; }147148public:149static const char* type;150IntersectFunc intersect;151OccludedFunc occluded;152PointQueryFunc pointQuery;153const char* name;154};155156struct Intersector4157{158Intersector4 (ErrorFunc error = nullptr)159: intersect((IntersectFunc4)error), occluded((OccludedFunc4)error), name(nullptr) {}160161Intersector4 (IntersectFunc4 intersect, OccludedFunc4 occluded, const char* name)162: intersect(intersect), occluded(occluded), name(name) {}163164operator bool() const { return name; }165166public:167static const char* type;168IntersectFunc4 intersect;169OccludedFunc4 occluded;170const char* name;171};172173struct Intersector8174{175Intersector8 (ErrorFunc error = nullptr)176: intersect((IntersectFunc8)error), occluded((OccludedFunc8)error), name(nullptr) {}177178Intersector8 (IntersectFunc8 intersect, OccludedFunc8 occluded, const char* name)179: intersect(intersect), occluded(occluded), name(name) {}180181operator bool() const { return name; }182183public:184static const char* type;185IntersectFunc8 intersect;186OccludedFunc8 occluded;187const char* name;188};189190struct Intersector16191{192Intersector16 (ErrorFunc error = nullptr)193: intersect((IntersectFunc16)error), occluded((OccludedFunc16)error), name(nullptr) {}194195Intersector16 (IntersectFunc16 intersect, OccludedFunc16 occluded, const char* name)196: intersect(intersect), occluded(occluded), name(name) {}197198operator bool() const { return name; }199200public:201static const char* type;202IntersectFunc16 intersect;203OccludedFunc16 occluded;204const char* name;205};206207struct Intersectors208{209Intersectors()210: ptr(nullptr), leafIntersector(nullptr), collider(nullptr), intersector1(nullptr), intersector4(nullptr), intersector8(nullptr), intersector16(nullptr) {}211212Intersectors (ErrorFunc error)213: ptr(nullptr), leafIntersector(nullptr), collider(error), intersector1(error), intersector4(error), intersector8(error), intersector16(error) {}214215void print(size_t ident)216{217if (collider.name) {218for (size_t i=0; i<ident; i++) std::cout << " ";219std::cout << "collider = " << collider.name << std::endl;220}221if (intersector1.name) {222for (size_t i=0; i<ident; i++) std::cout << " ";223std::cout << "intersector1 = " << intersector1.name << std::endl;224}225if (intersector4.name) {226for (size_t i=0; i<ident; i++) std::cout << " ";227std::cout << "intersector4 = " << intersector4.name << std::endl;228}229if (intersector8.name) {230for (size_t i=0; i<ident; i++) std::cout << " ";231std::cout << "intersector8 = " << intersector8.name << std::endl;232}233if (intersector16.name) {234for (size_t i=0; i<ident; i++) std::cout << " ";235std::cout << "intersector16 = " << intersector16.name << std::endl;236}237}238239void select(bool filter)240{241if (intersector4_filter) {242if (filter) intersector4 = intersector4_filter;243else intersector4 = intersector4_nofilter;244}245if (intersector8_filter) {246if (filter) intersector8 = intersector8_filter;247else intersector8 = intersector8_nofilter;248}249if (intersector16_filter) {250if (filter) intersector16 = intersector16_filter;251else intersector16 = intersector16_nofilter;252}253}254255__forceinline bool pointQuery (PointQuery* query, PointQueryContext* context) {256assert(intersector1.pointQuery);257return intersector1.pointQuery(this,query,context);258}259260/*! collides two scenes */261__forceinline void collide (Accel* scene0, Accel* scene1, RTCCollideFunc callback, void* userPtr) {262assert(collider.collide);263collider.collide(scene0->intersectors.ptr,scene1->intersectors.ptr,callback,userPtr);264}265266/*! Intersects a single ray with the scene. */267__forceinline void intersect (RTCRayHit& ray, RayQueryContext* context) {268assert(intersector1.intersect);269intersector1.intersect(this,ray,context);270}271272/*! Intersects a packet of 4 rays with the scene. */273__forceinline void intersect4 (const void* valid, RTCRayHit4& ray, RayQueryContext* context) {274assert(intersector4.intersect);275intersector4.intersect(valid,this,ray,context);276}277278/*! Intersects a packet of 8 rays with the scene. */279__forceinline void intersect8 (const void* valid, RTCRayHit8& ray, RayQueryContext* context) {280assert(intersector8.intersect);281intersector8.intersect(valid,this,ray,context);282}283284/*! Intersects a packet of 16 rays with the scene. */285__forceinline void intersect16 (const void* valid, RTCRayHit16& ray, RayQueryContext* context) {286assert(intersector16.intersect);287intersector16.intersect(valid,this,ray,context);288}289290/*! Intersects a packet of 4 rays with the scene. */291__forceinline void intersect (const void* valid, RTCRayHit4& ray, RayQueryContext* context) {292assert(intersector4.intersect);293intersector4.intersect(valid,this,ray,context);294}295296/*! Intersects a packet of 8 rays with the scene. */297__forceinline void intersect (const void* valid, RTCRayHit8& ray, RayQueryContext* context) {298assert(intersector8.intersect);299intersector8.intersect(valid,this,ray,context);300}301302/*! Intersects a packet of 16 rays with the scene. */303__forceinline void intersect (const void* valid, RTCRayHit16& ray, RayQueryContext* context) {304assert(intersector16.intersect);305intersector16.intersect(valid,this,ray,context);306}307308#if defined(__SSE__) || defined(__ARM_NEON)309__forceinline void intersect(const vbool4& valid, RayHitK<4>& ray, RayQueryContext* context) {310const vint<4> mask = valid.mask32();311intersect4(&mask,(RTCRayHit4&)ray,context);312}313#endif314#if defined(__AVX__)315__forceinline void intersect(const vbool8& valid, RayHitK<8>& ray, RayQueryContext* context) {316const vint<8> mask = valid.mask32();317intersect8(&mask,(RTCRayHit8&)ray,context);318}319#endif320#if defined(__AVX512F__)321__forceinline void intersect(const vbool16& valid, RayHitK<16>& ray, RayQueryContext* context) {322const vint<16> mask = valid.mask32();323intersect16(&mask,(RTCRayHit16&)ray,context);324}325#endif326327/*! Tests if single ray is occluded by the scene. */328__forceinline void occluded (RTCRay& ray, RayQueryContext* context) {329assert(intersector1.occluded);330intersector1.occluded(this,ray,context);331}332333/*! Tests if a packet of 4 rays is occluded by the scene. */334__forceinline void occluded4 (const void* valid, RTCRay4& ray, RayQueryContext* context) {335assert(intersector4.occluded);336intersector4.occluded(valid,this,ray,context);337}338339/*! Tests if a packet of 8 rays is occluded by the scene. */340__forceinline void occluded8 (const void* valid, RTCRay8& ray, RayQueryContext* context) {341assert(intersector8.occluded);342intersector8.occluded(valid,this,ray,context);343}344345/*! Tests if a packet of 16 rays is occluded by the scene. */346__forceinline void occluded16 (const void* valid, RTCRay16& ray, RayQueryContext* context) {347assert(intersector16.occluded);348intersector16.occluded(valid,this,ray,context);349}350351/*! Tests if a packet of 4 rays is occluded by the scene. */352__forceinline void occluded (const void* valid, RTCRay4& ray, RayQueryContext* context) {353assert(intersector4.occluded);354intersector4.occluded(valid,this,ray,context);355}356357/*! Tests if a packet of 8 rays is occluded by the scene. */358__forceinline void occluded (const void* valid, RTCRay8& ray, RayQueryContext* context) {359assert(intersector8.occluded);360intersector8.occluded(valid,this,ray,context);361}362363/*! Tests if a packet of 16 rays is occluded by the scene. */364__forceinline void occluded (const void* valid, RTCRay16& ray, RayQueryContext* context) {365assert(intersector16.occluded);366intersector16.occluded(valid,this,ray,context);367}368369#if defined(__SSE__) || defined(__ARM_NEON)370__forceinline void occluded(const vbool4& valid, RayK<4>& ray, RayQueryContext* context) {371const vint<4> mask = valid.mask32();372occluded4(&mask,(RTCRay4&)ray,context);373}374#endif375#if defined(__AVX__)376__forceinline void occluded(const vbool8& valid, RayK<8>& ray, RayQueryContext* context) {377const vint<8> mask = valid.mask32();378occluded8(&mask,(RTCRay8&)ray,context);379}380#endif381#if defined(__AVX512F__)382__forceinline void occluded(const vbool16& valid, RayK<16>& ray, RayQueryContext* context) {383const vint<16> mask = valid.mask32();384occluded16(&mask,(RTCRay16&)ray,context);385}386#endif387388/*! Tests if single ray is occluded by the scene. */389__forceinline void intersect(RTCRay& ray, RayQueryContext* context) {390occluded(ray, context);391}392393/*! Tests if a packet of K rays is occluded by the scene. */394template<int K>395__forceinline void intersect(const vbool<K>& valid, RayK<K>& ray, RayQueryContext* context) {396occluded(valid, ray, context);397}398399400public:401AccelData* ptr;402void* leafIntersector;403Collider collider;404Intersector1 intersector1;405Intersector4 intersector4;406Intersector4 intersector4_filter;407Intersector4 intersector4_nofilter;408Intersector8 intersector8;409Intersector8 intersector8_filter;410Intersector8 intersector8_nofilter;411Intersector16 intersector16;412Intersector16 intersector16_filter;413Intersector16 intersector16_nofilter;414};415416public:417418/*! Construction */419Accel (const AccelData::Type type)420: AccelData(type) {}421422/*! Construction */423Accel (const AccelData::Type type, const Intersectors& intersectors)424: AccelData(type), intersectors(intersectors) {}425426/*! Virtual destructor */427virtual ~Accel() {}428429/*! makes the acceleration structure immutable */430virtual void immutable () {}431432/*! build acceleration structure */433virtual void build () = 0;434435public:436Intersectors intersectors;437};438439#define DEFINE_COLLIDER(symbol,collider) \440Accel::Collider symbol() { \441return Accel::Collider((Accel::CollideFunc)collider::collide, \442TOSTRING(isa) "::" TOSTRING(symbol)); \443}444445#define DEFINE_INTERSECTOR1(symbol,intersector) \446Accel::Intersector1 symbol() { \447return Accel::Intersector1((Accel::IntersectFunc )intersector::intersect, \448(Accel::OccludedFunc )intersector::occluded, \449(Accel::PointQueryFunc)intersector::pointQuery,\450TOSTRING(isa) "::" TOSTRING(symbol)); \451}452453#define DEFINE_INTERSECTOR4(symbol,intersector) \454Accel::Intersector4 symbol() { \455return Accel::Intersector4((Accel::IntersectFunc4)intersector::intersect, \456(Accel::OccludedFunc4)intersector::occluded, \457TOSTRING(isa) "::" TOSTRING(symbol)); \458}459460#define DEFINE_INTERSECTOR8(symbol,intersector) \461Accel::Intersector8 symbol() { \462return Accel::Intersector8((Accel::IntersectFunc8)intersector::intersect, \463(Accel::OccludedFunc8)intersector::occluded, \464TOSTRING(isa) "::" TOSTRING(symbol)); \465}466467#define DEFINE_INTERSECTOR16(symbol,intersector) \468Accel::Intersector16 symbol() { \469return Accel::Intersector16((Accel::IntersectFunc16)intersector::intersect, \470(Accel::OccludedFunc16)intersector::occluded, \471TOSTRING(isa) "::" TOSTRING(symbol)); \472}473}474475476