Git Product home page Git Product logo

lbvh's Introduction

LBVH

An implementation of the following paper

  • Tero Karras, "Maximizing Parallelism in the Construction of BVHs, Octrees, and k-d Trees", High Performance Graphics (2012)

and the following blog posts

depending on thrust.

It can contain any object and also handles morton code overlap.

If the morton codes of objects are the same, it appends object index to the morton code and use the "extended" indices as described in the paper.

Also, nearest neighbor query based on the following paper is supported.

  • Nick Roussopoulos, Stephen Kelley, Frederic Vincent, "Nearest Neighbor Queries", ACM-SIGMOD (1995)

example code

struct object
{
    // any object you want.
    // For example, sphere.
    float4 xyzr;
};

struct aabb_getter
{
    // return aabb<float> if your object uses float.
    // if you chose double, return aabb<double>.
    __device__
    lbvh::aabb<float> operator()(const object& f) const noexcept
    {
        // calculate aabb of object ...
        const float r = f.xyzr.r;
        lbvh::aabb<float> box;
        box.upper = make_float4(f.xyzr.x + r, f.xyzr.y + r, f.xyzr.z + r, 0.0f);
        box.lower = make_float4(f.xyzr.x - r, f.xyzr.y - r, f.xyzr.z - r, 0.0f);
        return box;
    }
};

// this struct will be used in nearest neighbor query (If you don't need nearest
// neighbor query, you don't need to implement this).
struct distance_sq_calculator
{
    __device__
    float operator()(const float4 pos, const object& f) const noexcept
    {
        // calculate square distance...
        const float dx = pos.x - f.xyzr.x;
        const float dy = pos.y - f.xyzr.y;
        const float dz = pos.z - f.xyzr.z;
        return dx * dx + dy * dy + dz * dz;
    }
};

int main()
{
    std::vector<objects> objs;

    // initialize objs ...

    // construct a bvh
    lbvh::bvh<float, object, aabb_getter> bvh(objs.begin(), objs.end());

    // get a set of device (raw) pointers to use it in device functions.
    // Do not use this on host!
    const auto bvh_dev = bvh.get_device_repr();

    thrust::for_each(thrust::device,
        thrust::make_counting_iterator<unsigned int>(0),
        thrust::make_counting_iterator<unsigned int>(N),
        [bvh_dev] __device__ (const unsigned int idx)
        {
            unsigned int buffer[10];

            point_getter get_point;
            const auto self = get_point(bvh_dev.objects[idx]);

            // make a query box.
            const lbvh::aabb<float> box(
                    make_float4(self.x-0.1, self.y-0.1, self.z-0.1, 0),
                    make_float4(self.x+0.1, self.y+0.1, self.z+0.1, 0)
                );

            // send a query!
            const auto num_found = query_device(bvh_dev, overlaps(box), 10, buffer);

            for(unsigned int j=0; j<num_found; ++j)
            {
                const unsigned int other_idx = buffer[j];
                const object&      other     = bvh_dev.objects[other_idx];
                // do some stuff ...
            }

            const float3 pos = make_float3(0.0, 1.0, 2.0);
            const auto nearest = query_device(bvh_dev, nearest(pos), distance_sq_calculator());

            return ;
        });

    return 0;
}

Synopsis

AABB

template<typename T>
struct aabb
{
    /* T4 (float4 if T == float, double4 if T == double) */ upper;
    /* T4 (float4 if T == float, double4 if T == double) */ lower;
};

template<typename T>
__device__ __host__
inline bool intersects(const aabb<T>& lhs, const aabb<T>& rhs) noexcept;


template<typename T>
__device__ __host__
inline aabb<T> merge(const aabb<T>& lhs, const aabb<T>& rhs) noexcept

BVH

template<typename Real, typename Object, typename AABBGetter,
         typename MortonCodeCalculator = default_morton_code_calculator<Real, Object, AABBGetter>>
class bvh
{
  public:
    using real_type   = Real;
    using index_type = std::uint32_t;
    using object_type = Object;
    using aabb_type   = aabb<real_type>;
    using node_type   = detail::node;
    using point_getter_type = PointGetter;
    using aabb_getter_type  = AABBGetter;

    template<typename InputIterator>
    bvh(InputIterator first, InputIterator last)
        : objects_h_(first, last), objects_d_(objects_h_)
    {
        this->construct();
    }

    template<typename InputIterator>
    void assign(InputIterator first, InputIterator last);
    void clear();

    bvh_device<real_type, object_type>  get_device_repr()       noexcept;
    cbvh_device<real_type, object_type> get_device_repr() const noexcept;
};
namespace detail {
template<typename Real, typename Object, bool IsConst>
struct basic_device_bvh
{
    using real_type  = Real;
    using aabb_type  = aabb<real_type>;
    using node_type  = detail::node;
    using index_type = std::uint32_t;
    using object_type = Object;

    unsigned int num_nodes;   // (# of internal node) + (# of leaves), 2N+1
    unsigned int num_leaves;  // (# of leaves), N
    unsigned int num_objects; // (# of objects) ; can be larger than N

    /* const if IsConst is true */ node_type  * nodes;
    /* const if IsConst is true */ aabb_type  * aabbs;
    /* const if IsConst is true */ index_type * ranges;
    /* const if IsConst is true */ index_type * indices;
    /* const if IsConst is true */ object_type* objects;
};
}
template<typename Real, typename Object>
using  bvh_device = detail::basic_device_bvh<Real, Object, false>;
template<typename Real, typename Object>
using cbvh_device = detail::basic_device_bvh<Real, Object, true>;

queries

template<typename Real>
__device__ __host__
query_overlap<Real> overlaps(const aabb<Real>& region) noexcept;

template<typename Real>
__device__ __host__
inline query_nearest<Real> nearest(const /*Real4 or Real3*/& point) noexcept
{
    return query_nearest<Real>(point);
}

template<typename Real, typename Objects, bool IsConst, typename OutputIterator>
__device__
unsigned int query_device(
        const detail::basic_device_bvh<Real, Objects, IsConst>& bvh,
        const query_overlap<Real>& q, unsigned int max_buffer_size,
        OutputIterator outiter) noexcept;

template<typename Real, typename Objects, bool IsConst, typename DistanceCalculator>
__device__
thrust::pair<unsigned int, Real> query_device(
        const detail::basic_device_bvh<Real, Objects, IsConst>& bvh,
        const query_nearest<Real>& q, DistanceCalculator calc_dist) noexcept

lbvh's People

Contributors

aelphy avatar toruniina avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

lbvh's Issues

returns -1

Hi, I just got -1 as nest.first here const auto nest = lbvh::query_device(bvh_dev, lbvh::nearest(point), distance_calculator());
Could you help to explain what is the reason ?

Problem with return -1

Can you let me know if the problem with "return -1" have been solved or not?

It is observed at searching the closest line segments for set of points (after slight modifcation of your code - 2D case and all necessary functions are implemented for aabb construction for line segments and distance from point to line segment calculation).

Maybe you can describe the source of the problem?

I get an error when I try to build the project

I used msvs and cuda12.0

1>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include\cuda\std\detail/libcxx/include/type_traits(4404): error C2338: Attempt to use an extended device lambda in a context that requires querying its return type in host code. Use a named function object, a host device lambda, or cuda::proclaim_return_type instead.
1>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include\cuda\std\detail/libcxx/include/type_traits(4416): note: 查看对正在编译的 类 模板 实例化“cuda::std::__4::__invoke_of<_Fp,lbvh::aabb,lbvh::aabb>”的引用
1> with
1> [
1> _Fp=__nv_dl_wrapper_t<__nv_dl_tag<void (__cdecl lbvh::bvh<float,float4,aabb_getter,lbvh::default_morton_code_calculator<float,float4>>::* )(void),void lbvh::bvh<float,float4,aabb_getter,lbvh::default_morton_code_calculator<float,float4>>::construct(void),1>>
1> ]
1>C:\Users\91929\AppData\Local\Temp\tmpxft_00003454_00000000-7_main.cudafe1.stub.c(153): note: 查看对正在编译的 类 模板 实例化“cuda::std::__4::result_of<__nv_dl_wrapper_t<__nv_dl_tag<void (__cdecl lbvh::bvh<float,float4,aabb_getter,lbvh::default_morton_code_calculator<Real,Object>>::* )(void),void lbvh::bvh<Real,Object,aabb_getter,lbvh::default_morton_code_calculator<Real,Object>>::construct(void),1>> (lbvh::aabb,lbvh::aabb)>”的引用
1> with
1> [
1> Real=float,
1> Object=float4
1> ]
1>C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.0/include\cub/detail/type_traits.cuh(53): note: 查看对正在编译的 别名 模板 实例化“cub::detail::invoke_result_t<__nv_dl_wrapper_t<__nv_dl_tag<void (__cdecl lbvh::bvh<float,float4,aabb_getter,lbvh::default_morton_code_calculator<Real,Object>>::* )(void),void lbvh::bvh<Real,Object,aabb_getter,lbvh::default_morton_code_calculator<Real,Object>>::construct(void),1>>,lbvh::aabb,lbvh::aabb>”的引用
1> with
1> [
1> Real=float,
1> Object=float4
1> ]
1>C:\Users\91929\AppData\Local\Temp\tmpxft_00003454_00000000-7_main.cudafe1.stub.c(153): note: 查看对正在编译的 别名 模板 实例化“cub::detail::accumulator_t<__nv_dl_wrapper_t<__nv_dl_tag<void (__cdecl lbvh::bvh<float,float4,aabb_getter,lbvh::default_morton_code_calculator<Real,Object>>::* )(void),void lbvh::bvh<Real,Object,aabb_getter,lbvh::default_morton_code_calculator<Real,Object>>::construct(void),1>>,lbvh::aabb,lbvh::aabb>”的引用
1> with
1> [
1> Real=float,
1> Object=float4
1> ]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.