warp-lang 1.0.1__py3-none-manylinux2014_x86_64.whl → 1.1.0__py3-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +108 -97
- warp/__init__.pyi +1 -1
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +115 -113
- warp/build_dll.py +383 -375
- warp/builtins.py +3425 -3354
- warp/codegen.py +2878 -2792
- warp/config.py +40 -36
- warp/constants.py +45 -45
- warp/context.py +5194 -5102
- warp/dlpack.py +442 -442
- warp/examples/__init__.py +16 -16
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -110
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -92
- warp/examples/assets/nv_humanoid.xml +183 -183
- warp/examples/assets/quadruped.urdf +267 -267
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +383 -383
- warp/examples/benchmarks/benchmark_cloth.py +278 -279
- warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -88
- warp/examples/benchmarks/benchmark_cloth_jax.py +97 -100
- warp/examples/benchmarks/benchmark_cloth_numba.py +146 -142
- warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -77
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -86
- warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -112
- warp/examples/benchmarks/benchmark_cloth_warp.py +146 -146
- warp/examples/benchmarks/benchmark_launches.py +295 -295
- warp/examples/browse.py +29 -28
- warp/examples/core/example_dem.py +234 -221
- warp/examples/core/example_fluid.py +293 -267
- warp/examples/core/example_graph_capture.py +144 -129
- warp/examples/core/example_marching_cubes.py +188 -176
- warp/examples/core/example_mesh.py +174 -154
- warp/examples/core/example_mesh_intersect.py +205 -193
- warp/examples/core/example_nvdb.py +176 -169
- warp/examples/core/example_raycast.py +105 -89
- warp/examples/core/example_raymarch.py +199 -178
- warp/examples/core/example_render_opengl.py +185 -141
- warp/examples/core/example_sph.py +405 -389
- warp/examples/core/example_torch.py +222 -181
- warp/examples/core/example_wave.py +263 -249
- warp/examples/fem/bsr_utils.py +378 -380
- warp/examples/fem/example_apic_fluid.py +407 -391
- warp/examples/fem/example_convection_diffusion.py +182 -168
- warp/examples/fem/example_convection_diffusion_dg.py +219 -209
- warp/examples/fem/example_convection_diffusion_dg0.py +204 -194
- warp/examples/fem/example_deformed_geometry.py +177 -159
- warp/examples/fem/example_diffusion.py +201 -173
- warp/examples/fem/example_diffusion_3d.py +177 -152
- warp/examples/fem/example_diffusion_mgpu.py +221 -214
- warp/examples/fem/example_mixed_elasticity.py +244 -222
- warp/examples/fem/example_navier_stokes.py +259 -243
- warp/examples/fem/example_stokes.py +220 -192
- warp/examples/fem/example_stokes_transfer.py +265 -249
- warp/examples/fem/mesh_utils.py +133 -109
- warp/examples/fem/plot_utils.py +292 -287
- warp/examples/optim/example_bounce.py +260 -248
- warp/examples/optim/example_cloth_throw.py +222 -210
- warp/examples/optim/example_diffray.py +566 -535
- warp/examples/optim/example_drone.py +864 -835
- warp/examples/optim/example_inverse_kinematics.py +176 -169
- warp/examples/optim/example_inverse_kinematics_torch.py +185 -170
- warp/examples/optim/example_spring_cage.py +239 -234
- warp/examples/optim/example_trajectory.py +223 -201
- warp/examples/optim/example_walker.py +306 -292
- warp/examples/sim/example_cartpole.py +139 -128
- warp/examples/sim/example_cloth.py +196 -184
- warp/examples/sim/example_granular.py +124 -113
- warp/examples/sim/example_granular_collision_sdf.py +197 -185
- warp/examples/sim/example_jacobian_ik.py +236 -213
- warp/examples/sim/example_particle_chain.py +118 -106
- warp/examples/sim/example_quadruped.py +193 -179
- warp/examples/sim/example_rigid_chain.py +197 -189
- warp/examples/sim/example_rigid_contact.py +189 -176
- warp/examples/sim/example_rigid_force.py +127 -126
- warp/examples/sim/example_rigid_gyroscopic.py +109 -97
- warp/examples/sim/example_rigid_soft_contact.py +134 -124
- warp/examples/sim/example_soft_body.py +190 -178
- warp/fabric.py +337 -335
- warp/fem/__init__.py +60 -27
- warp/fem/cache.py +401 -388
- warp/fem/dirichlet.py +178 -179
- warp/fem/domain.py +262 -263
- warp/fem/field/__init__.py +100 -101
- warp/fem/field/field.py +148 -149
- warp/fem/field/nodal_field.py +298 -299
- warp/fem/field/restriction.py +22 -21
- warp/fem/field/test.py +180 -181
- warp/fem/field/trial.py +183 -183
- warp/fem/geometry/__init__.py +15 -19
- warp/fem/geometry/closest_point.py +69 -70
- warp/fem/geometry/deformed_geometry.py +270 -271
- warp/fem/geometry/element.py +744 -744
- warp/fem/geometry/geometry.py +184 -186
- warp/fem/geometry/grid_2d.py +380 -373
- warp/fem/geometry/grid_3d.py +441 -435
- warp/fem/geometry/hexmesh.py +953 -953
- warp/fem/geometry/partition.py +374 -376
- warp/fem/geometry/quadmesh_2d.py +532 -532
- warp/fem/geometry/tetmesh.py +840 -840
- warp/fem/geometry/trimesh_2d.py +577 -577
- warp/fem/integrate.py +1630 -1615
- warp/fem/operator.py +190 -191
- warp/fem/polynomial.py +214 -213
- warp/fem/quadrature/__init__.py +2 -2
- warp/fem/quadrature/pic_quadrature.py +243 -245
- warp/fem/quadrature/quadrature.py +295 -294
- warp/fem/space/__init__.py +294 -292
- warp/fem/space/basis_space.py +488 -489
- warp/fem/space/collocated_function_space.py +100 -105
- warp/fem/space/dof_mapper.py +236 -236
- warp/fem/space/function_space.py +148 -145
- warp/fem/space/grid_2d_function_space.py +267 -267
- warp/fem/space/grid_3d_function_space.py +305 -306
- warp/fem/space/hexmesh_function_space.py +350 -352
- warp/fem/space/partition.py +350 -350
- warp/fem/space/quadmesh_2d_function_space.py +368 -369
- warp/fem/space/restriction.py +158 -160
- warp/fem/space/shape/__init__.py +13 -15
- warp/fem/space/shape/cube_shape_function.py +738 -738
- warp/fem/space/shape/shape_function.py +102 -103
- warp/fem/space/shape/square_shape_function.py +611 -611
- warp/fem/space/shape/tet_shape_function.py +565 -567
- warp/fem/space/shape/triangle_shape_function.py +429 -429
- warp/fem/space/tetmesh_function_space.py +294 -292
- warp/fem/space/topology.py +297 -295
- warp/fem/space/trimesh_2d_function_space.py +223 -221
- warp/fem/types.py +77 -77
- warp/fem/utils.py +495 -495
- warp/jax.py +166 -141
- warp/jax_experimental.py +341 -339
- warp/native/array.h +1072 -1025
- warp/native/builtin.h +1560 -1560
- warp/native/bvh.cpp +398 -398
- warp/native/bvh.cu +525 -525
- warp/native/bvh.h +429 -429
- warp/native/clang/clang.cpp +495 -464
- warp/native/crt.cpp +31 -31
- warp/native/crt.h +334 -334
- warp/native/cuda_crt.h +1049 -1049
- warp/native/cuda_util.cpp +549 -540
- warp/native/cuda_util.h +288 -203
- warp/native/cutlass_gemm.cpp +34 -34
- warp/native/cutlass_gemm.cu +372 -372
- warp/native/error.cpp +66 -66
- warp/native/error.h +27 -27
- warp/native/fabric.h +228 -228
- warp/native/hashgrid.cpp +301 -278
- warp/native/hashgrid.cu +78 -77
- warp/native/hashgrid.h +227 -227
- warp/native/initializer_array.h +32 -32
- warp/native/intersect.h +1204 -1204
- warp/native/intersect_adj.h +365 -365
- warp/native/intersect_tri.h +322 -322
- warp/native/marching.cpp +2 -2
- warp/native/marching.cu +497 -497
- warp/native/marching.h +2 -2
- warp/native/mat.h +1498 -1498
- warp/native/matnn.h +333 -333
- warp/native/mesh.cpp +203 -203
- warp/native/mesh.cu +293 -293
- warp/native/mesh.h +1887 -1887
- warp/native/nanovdb/NanoVDB.h +4782 -4782
- warp/native/nanovdb/PNanoVDB.h +2553 -2553
- warp/native/nanovdb/PNanoVDBWrite.h +294 -294
- warp/native/noise.h +850 -850
- warp/native/quat.h +1084 -1084
- warp/native/rand.h +299 -299
- warp/native/range.h +108 -108
- warp/native/reduce.cpp +156 -156
- warp/native/reduce.cu +348 -348
- warp/native/runlength_encode.cpp +61 -61
- warp/native/runlength_encode.cu +46 -46
- warp/native/scan.cpp +30 -30
- warp/native/scan.cu +36 -36
- warp/native/scan.h +7 -7
- warp/native/solid_angle.h +442 -442
- warp/native/sort.cpp +94 -94
- warp/native/sort.cu +97 -97
- warp/native/sort.h +14 -14
- warp/native/sparse.cpp +337 -337
- warp/native/sparse.cu +544 -544
- warp/native/spatial.h +630 -630
- warp/native/svd.h +562 -562
- warp/native/temp_buffer.h +30 -30
- warp/native/vec.h +1132 -1132
- warp/native/volume.cpp +297 -297
- warp/native/volume.cu +32 -32
- warp/native/volume.h +538 -538
- warp/native/volume_builder.cu +425 -425
- warp/native/volume_builder.h +19 -19
- warp/native/warp.cpp +1057 -1052
- warp/native/warp.cu +2943 -2828
- warp/native/warp.h +313 -305
- warp/optim/__init__.py +9 -9
- warp/optim/adam.py +120 -120
- warp/optim/linear.py +1104 -939
- warp/optim/sgd.py +104 -92
- warp/render/__init__.py +10 -10
- warp/render/render_opengl.py +3217 -3204
- warp/render/render_usd.py +768 -749
- warp/render/utils.py +152 -150
- warp/sim/__init__.py +52 -59
- warp/sim/articulation.py +685 -685
- warp/sim/collide.py +1594 -1590
- warp/sim/import_mjcf.py +489 -481
- warp/sim/import_snu.py +220 -221
- warp/sim/import_urdf.py +536 -516
- warp/sim/import_usd.py +887 -881
- warp/sim/inertia.py +316 -317
- warp/sim/integrator.py +234 -233
- warp/sim/integrator_euler.py +1956 -1956
- warp/sim/integrator_featherstone.py +1910 -1991
- warp/sim/integrator_xpbd.py +3294 -3312
- warp/sim/model.py +4473 -4314
- warp/sim/particles.py +113 -112
- warp/sim/render.py +417 -403
- warp/sim/utils.py +413 -410
- warp/sparse.py +1227 -1227
- warp/stubs.py +2109 -2469
- warp/tape.py +1162 -225
- warp/tests/__init__.py +1 -1
- warp/tests/__main__.py +4 -4
- warp/tests/assets/torus.usda +105 -105
- warp/tests/aux_test_class_kernel.py +26 -26
- warp/tests/aux_test_compile_consts_dummy.py +10 -10
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -21
- warp/tests/aux_test_dependent.py +22 -22
- warp/tests/aux_test_grad_customs.py +23 -23
- warp/tests/aux_test_reference.py +11 -11
- warp/tests/aux_test_reference_reference.py +10 -10
- warp/tests/aux_test_square.py +17 -17
- warp/tests/aux_test_unresolved_func.py +14 -14
- warp/tests/aux_test_unresolved_symbol.py +14 -14
- warp/tests/disabled_kinematics.py +239 -239
- warp/tests/run_coverage_serial.py +31 -31
- warp/tests/test_adam.py +157 -157
- warp/tests/test_arithmetic.py +1124 -1124
- warp/tests/test_array.py +2417 -2326
- warp/tests/test_array_reduce.py +150 -150
- warp/tests/test_async.py +668 -656
- warp/tests/test_atomic.py +141 -141
- warp/tests/test_bool.py +204 -149
- warp/tests/test_builtins_resolution.py +1292 -1292
- warp/tests/test_bvh.py +164 -171
- warp/tests/test_closest_point_edge_edge.py +228 -228
- warp/tests/test_codegen.py +566 -553
- warp/tests/test_compile_consts.py +97 -101
- warp/tests/test_conditional.py +246 -246
- warp/tests/test_copy.py +232 -215
- warp/tests/test_ctypes.py +632 -632
- warp/tests/test_dense.py +67 -67
- warp/tests/test_devices.py +91 -98
- warp/tests/test_dlpack.py +530 -529
- warp/tests/test_examples.py +400 -378
- warp/tests/test_fabricarray.py +955 -955
- warp/tests/test_fast_math.py +62 -54
- warp/tests/test_fem.py +1277 -1278
- warp/tests/test_fp16.py +130 -130
- warp/tests/test_func.py +338 -337
- warp/tests/test_generics.py +571 -571
- warp/tests/test_grad.py +746 -640
- warp/tests/test_grad_customs.py +333 -336
- warp/tests/test_hash_grid.py +210 -164
- warp/tests/test_import.py +39 -39
- warp/tests/test_indexedarray.py +1134 -1134
- warp/tests/test_intersect.py +67 -67
- warp/tests/test_jax.py +307 -307
- warp/tests/test_large.py +167 -164
- warp/tests/test_launch.py +354 -354
- warp/tests/test_lerp.py +261 -261
- warp/tests/test_linear_solvers.py +191 -171
- warp/tests/test_lvalue.py +421 -493
- warp/tests/test_marching_cubes.py +65 -65
- warp/tests/test_mat.py +1801 -1827
- warp/tests/test_mat_lite.py +115 -115
- warp/tests/test_mat_scalar_ops.py +2907 -2889
- warp/tests/test_math.py +126 -193
- warp/tests/test_matmul.py +500 -499
- warp/tests/test_matmul_lite.py +410 -410
- warp/tests/test_mempool.py +188 -190
- warp/tests/test_mesh.py +284 -324
- warp/tests/test_mesh_query_aabb.py +228 -241
- warp/tests/test_mesh_query_point.py +692 -702
- warp/tests/test_mesh_query_ray.py +292 -303
- warp/tests/test_mlp.py +276 -276
- warp/tests/test_model.py +110 -110
- warp/tests/test_modules_lite.py +39 -39
- warp/tests/test_multigpu.py +163 -163
- warp/tests/test_noise.py +248 -248
- warp/tests/test_operators.py +250 -250
- warp/tests/test_options.py +123 -125
- warp/tests/test_peer.py +133 -137
- warp/tests/test_pinned.py +78 -78
- warp/tests/test_print.py +54 -54
- warp/tests/test_quat.py +2086 -2086
- warp/tests/test_rand.py +288 -288
- warp/tests/test_reload.py +217 -217
- warp/tests/test_rounding.py +179 -179
- warp/tests/test_runlength_encode.py +190 -190
- warp/tests/test_sim_grad.py +243 -0
- warp/tests/test_sim_kinematics.py +91 -97
- warp/tests/test_smoothstep.py +168 -168
- warp/tests/test_snippet.py +305 -266
- warp/tests/test_sparse.py +468 -460
- warp/tests/test_spatial.py +2148 -2148
- warp/tests/test_streams.py +486 -473
- warp/tests/test_struct.py +710 -675
- warp/tests/test_tape.py +173 -148
- warp/tests/test_torch.py +743 -743
- warp/tests/test_transient_module.py +87 -87
- warp/tests/test_types.py +556 -659
- warp/tests/test_utils.py +490 -499
- warp/tests/test_vec.py +1264 -1268
- warp/tests/test_vec_lite.py +73 -73
- warp/tests/test_vec_scalar_ops.py +2099 -2099
- warp/tests/test_verify_fp.py +94 -94
- warp/tests/test_volume.py +737 -736
- warp/tests/test_volume_write.py +255 -265
- warp/tests/unittest_serial.py +37 -37
- warp/tests/unittest_suites.py +363 -359
- warp/tests/unittest_utils.py +603 -578
- warp/tests/unused_test_misc.py +71 -71
- warp/tests/walkthrough_debug.py +85 -85
- warp/thirdparty/appdirs.py +598 -598
- warp/thirdparty/dlpack.py +143 -143
- warp/thirdparty/unittest_parallel.py +566 -561
- warp/torch.py +321 -295
- warp/types.py +4504 -4450
- warp/utils.py +1008 -821
- {warp_lang-1.0.1.dist-info → warp_lang-1.1.0.dist-info}/LICENSE.md +126 -126
- {warp_lang-1.0.1.dist-info → warp_lang-1.1.0.dist-info}/METADATA +338 -400
- warp_lang-1.1.0.dist-info/RECORD +352 -0
- warp/examples/assets/cube.usda +0 -42
- warp/examples/assets/sphere.usda +0 -56
- warp/examples/assets/torus.usda +0 -105
- warp_lang-1.0.1.dist-info/RECORD +0 -352
- {warp_lang-1.0.1.dist-info → warp_lang-1.1.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.0.1.dist-info → warp_lang-1.1.0.dist-info}/top_level.txt +0 -0
warp/native/bvh.cpp
CHANGED
|
@@ -1,398 +1,398 @@
|
|
|
1
|
-
/** Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
-
* NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
-
* and proprietary rights in and to this software, related documentation
|
|
4
|
-
* and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
-
* distribution of this software and related documentation without an express
|
|
6
|
-
* license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
#include <vector>
|
|
10
|
-
#include <algorithm>
|
|
11
|
-
|
|
12
|
-
#include "bvh.h"
|
|
13
|
-
#include "warp.h"
|
|
14
|
-
#include "cuda_util.h"
|
|
15
|
-
|
|
16
|
-
#include <map>
|
|
17
|
-
|
|
18
|
-
using namespace wp;
|
|
19
|
-
|
|
20
|
-
namespace wp
|
|
21
|
-
{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
25
|
-
|
|
26
|
-
class MedianBVHBuilder
|
|
27
|
-
{
|
|
28
|
-
public:
|
|
29
|
-
|
|
30
|
-
void build(BVH& bvh, const vec3* lowers, const vec3* uppers, int n);
|
|
31
|
-
|
|
32
|
-
private:
|
|
33
|
-
|
|
34
|
-
bounds3 calc_bounds(const vec3* lowers, const vec3* uppers, const int* indices, int start, int end);
|
|
35
|
-
|
|
36
|
-
int partition_median(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds);
|
|
37
|
-
int partition_midpoint(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds);
|
|
38
|
-
int partition_sah(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds);
|
|
39
|
-
|
|
40
|
-
int build_recursive(BVH& bvh, const vec3* lowers, const vec3* uppers, int* indices, int start, int end, int depth, int parent);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
//////////////////////////////////////////////////////////////////////
|
|
44
|
-
|
|
45
|
-
void MedianBVHBuilder::build(BVH& bvh, const vec3* lowers, const vec3* uppers, int n)
|
|
46
|
-
{
|
|
47
|
-
bvh.max_depth = 0;
|
|
48
|
-
bvh.max_nodes = 2*n-1;
|
|
49
|
-
|
|
50
|
-
bvh.node_lowers = new BVHPackedNodeHalf[bvh.max_nodes];
|
|
51
|
-
bvh.node_uppers = new BVHPackedNodeHalf[bvh.max_nodes];
|
|
52
|
-
bvh.node_parents = new int[bvh.max_nodes];
|
|
53
|
-
bvh.node_counts = NULL;
|
|
54
|
-
|
|
55
|
-
// root is always in first slot for top down builders
|
|
56
|
-
bvh.root = new int[1];
|
|
57
|
-
bvh.root[0] = 0;
|
|
58
|
-
|
|
59
|
-
if (n == 0)
|
|
60
|
-
return;
|
|
61
|
-
|
|
62
|
-
std::vector<int> indices(n);
|
|
63
|
-
for (int i=0; i < n; ++i)
|
|
64
|
-
indices[i] = i;
|
|
65
|
-
|
|
66
|
-
build_recursive(bvh, lowers, uppers, &indices[0], 0, n, 0, -1);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
bounds3 MedianBVHBuilder::calc_bounds(const vec3* lowers, const vec3* uppers, const int* indices, int start, int end)
|
|
71
|
-
{
|
|
72
|
-
bounds3 u;
|
|
73
|
-
|
|
74
|
-
for (int i=start; i < end; ++i)
|
|
75
|
-
{
|
|
76
|
-
u.add_point(lowers[indices[i]]);
|
|
77
|
-
u.add_point(uppers[indices[i]]);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return u;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
struct PartitionPredicateMedian
|
|
84
|
-
{
|
|
85
|
-
PartitionPredicateMedian(const vec3* lowers, const vec3* uppers, int a) : lowers(lowers), uppers(uppers), axis(a) {}
|
|
86
|
-
|
|
87
|
-
bool operator()(int a, int b) const
|
|
88
|
-
{
|
|
89
|
-
vec3 a_center = 0.5f*(lowers[a] + uppers[a]);
|
|
90
|
-
vec3 b_center = 0.5f*(lowers[b] + uppers[b]);
|
|
91
|
-
|
|
92
|
-
return a_center[axis] < b_center[axis];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const vec3* lowers;
|
|
96
|
-
const vec3* uppers;
|
|
97
|
-
int axis;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
int MedianBVHBuilder::partition_median(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds)
|
|
102
|
-
{
|
|
103
|
-
assert(end-start >= 2);
|
|
104
|
-
|
|
105
|
-
vec3 edges = range_bounds.edges();
|
|
106
|
-
|
|
107
|
-
int axis = longest_axis(edges);
|
|
108
|
-
|
|
109
|
-
const int k = (start+end)/2;
|
|
110
|
-
|
|
111
|
-
std::nth_element(&indices[start], &indices[k], &indices[end], PartitionPredicateMedian(lowers, uppers, axis));
|
|
112
|
-
|
|
113
|
-
return k;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
struct PartitionPredictateMidPoint
|
|
117
|
-
{
|
|
118
|
-
PartitionPredictateMidPoint(const vec3* lowers, const vec3* uppers, int a, float m) : lowers(lowers), uppers(uppers), axis(a), mid(m) {}
|
|
119
|
-
|
|
120
|
-
bool operator()(int index) const
|
|
121
|
-
{
|
|
122
|
-
vec3 center = 0.5f*(lowers[index] + uppers[index]);
|
|
123
|
-
|
|
124
|
-
return center[axis] <= mid;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const vec3* lowers;
|
|
128
|
-
const vec3* uppers;
|
|
129
|
-
|
|
130
|
-
int axis;
|
|
131
|
-
float mid;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
int MedianBVHBuilder::partition_midpoint(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds)
|
|
136
|
-
{
|
|
137
|
-
assert(end-start >= 2);
|
|
138
|
-
|
|
139
|
-
vec3 edges = range_bounds.edges();
|
|
140
|
-
vec3 center = range_bounds.center();
|
|
141
|
-
|
|
142
|
-
int axis = longest_axis(edges);
|
|
143
|
-
float mid = center[axis];
|
|
144
|
-
|
|
145
|
-
int* upper = std::partition(indices+start, indices+end, PartitionPredictateMidPoint(lowers, uppers, axis, mid));
|
|
146
|
-
|
|
147
|
-
int k = upper-indices;
|
|
148
|
-
|
|
149
|
-
// if we failed to split items then just split in the middle
|
|
150
|
-
if (k == start || k == end)
|
|
151
|
-
k = (start+end)/2;
|
|
152
|
-
|
|
153
|
-
return k;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// disable std::sort workaround for macOS error
|
|
157
|
-
#if 0
|
|
158
|
-
int MedianBVHBuilder::partition_sah(const bounds3* bounds, int* indices, int start, int end, bounds3 range_bounds)
|
|
159
|
-
{
|
|
160
|
-
assert(end-start >= 2);
|
|
161
|
-
|
|
162
|
-
int n = end-start;
|
|
163
|
-
vec3 edges = range_bounds.edges();
|
|
164
|
-
|
|
165
|
-
int longestAxis = longest_axis(edges);
|
|
166
|
-
|
|
167
|
-
// sort along longest axis
|
|
168
|
-
std::sort(&indices[0]+start, &indices[0]+end, PartitionPredicateMedian(&bounds[0], longestAxis));
|
|
169
|
-
|
|
170
|
-
// total area for range from [0, split]
|
|
171
|
-
std::vector<float> left_areas(n);
|
|
172
|
-
// total area for range from (split, end]
|
|
173
|
-
std::vector<float> right_areas(n);
|
|
174
|
-
|
|
175
|
-
bounds3 left;
|
|
176
|
-
bounds3 right;
|
|
177
|
-
|
|
178
|
-
// build cumulative bounds and area from left and right
|
|
179
|
-
for (int i=0; i < n; ++i)
|
|
180
|
-
{
|
|
181
|
-
left = bounds_union(left, bounds[indices[start+i]]);
|
|
182
|
-
right = bounds_union(right, bounds[indices[end-i-1]]);
|
|
183
|
-
|
|
184
|
-
left_areas[i] = left.area();
|
|
185
|
-
right_areas[n-i-1] = right.area();
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
float invTotalArea = 1.0f/range_bounds.area();
|
|
189
|
-
|
|
190
|
-
// find split point i that minimizes area(left[i]) + area(right[i])
|
|
191
|
-
int minSplit = 0;
|
|
192
|
-
float minCost = FLT_MAX;
|
|
193
|
-
|
|
194
|
-
for (int i=0; i < n; ++i)
|
|
195
|
-
{
|
|
196
|
-
float pBelow = left_areas[i]*invTotalArea;
|
|
197
|
-
float pAbove = right_areas[i]*invTotalArea;
|
|
198
|
-
|
|
199
|
-
float cost = pBelow*i + pAbove*(n-i);
|
|
200
|
-
|
|
201
|
-
if (cost < minCost)
|
|
202
|
-
{
|
|
203
|
-
minCost = cost;
|
|
204
|
-
minSplit = i;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return start + minSplit + 1;
|
|
209
|
-
}
|
|
210
|
-
#endif
|
|
211
|
-
|
|
212
|
-
int MedianBVHBuilder::build_recursive(BVH& bvh, const vec3* lowers, const vec3* uppers, int* indices, int start, int end, int depth, int parent)
|
|
213
|
-
{
|
|
214
|
-
assert(start < end);
|
|
215
|
-
|
|
216
|
-
const int n = end-start;
|
|
217
|
-
const int node_index = bvh.num_nodes++;
|
|
218
|
-
|
|
219
|
-
assert(node_index < bvh.max_nodes);
|
|
220
|
-
|
|
221
|
-
if (depth > bvh.max_depth)
|
|
222
|
-
bvh.max_depth = depth;
|
|
223
|
-
|
|
224
|
-
bounds3 b = calc_bounds(lowers, uppers, indices, start, end);
|
|
225
|
-
|
|
226
|
-
const int kMaxItemsPerLeaf = 1;
|
|
227
|
-
|
|
228
|
-
if (n <= kMaxItemsPerLeaf)
|
|
229
|
-
{
|
|
230
|
-
bvh.node_lowers[node_index] = make_node(b.lower, indices[start], true);
|
|
231
|
-
bvh.node_uppers[node_index] = make_node(b.upper, indices[start], false);
|
|
232
|
-
bvh.node_parents[node_index] = parent;
|
|
233
|
-
}
|
|
234
|
-
else
|
|
235
|
-
{
|
|
236
|
-
//int split = partition_midpoint(bounds, indices, start, end, b);
|
|
237
|
-
int split = partition_median(lowers, uppers, indices, start, end, b);
|
|
238
|
-
//int split = partition_sah(bounds, indices, start, end, b);
|
|
239
|
-
|
|
240
|
-
if (split == start || split == end)
|
|
241
|
-
{
|
|
242
|
-
// partitioning failed, split down the middle
|
|
243
|
-
split = (start+end)/2;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
int left_child = build_recursive(bvh, lowers, uppers, indices, start, split, depth+1, node_index);
|
|
247
|
-
int right_child = build_recursive(bvh, lowers, uppers, indices, split, end, depth+1, node_index);
|
|
248
|
-
|
|
249
|
-
bvh.node_lowers[node_index] = make_node(b.lower, left_child, false);
|
|
250
|
-
bvh.node_uppers[node_index] = make_node(b.upper, right_child, false);
|
|
251
|
-
bvh.node_parents[node_index] = parent;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return node_index;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
void bvh_refit_recursive(BVH& bvh, int index)
|
|
259
|
-
{
|
|
260
|
-
BVHPackedNodeHalf& lower = bvh.node_lowers[index];
|
|
261
|
-
BVHPackedNodeHalf& upper = bvh.node_uppers[index];
|
|
262
|
-
|
|
263
|
-
if (lower.b)
|
|
264
|
-
{
|
|
265
|
-
const int leaf_index = lower.i;
|
|
266
|
-
|
|
267
|
-
// update leaf from items
|
|
268
|
-
(vec3&)lower = bvh.item_lowers[leaf_index];
|
|
269
|
-
(vec3&)upper = bvh.item_uppers[leaf_index];
|
|
270
|
-
}
|
|
271
|
-
else
|
|
272
|
-
{
|
|
273
|
-
int left_index = lower.i;
|
|
274
|
-
int right_index = upper.i;
|
|
275
|
-
|
|
276
|
-
bvh_refit_recursive(bvh, left_index);
|
|
277
|
-
bvh_refit_recursive(bvh, right_index);
|
|
278
|
-
|
|
279
|
-
// compute union of children
|
|
280
|
-
const vec3& left_lower = (vec3&)bvh.node_lowers[left_index];
|
|
281
|
-
const vec3& left_upper = (vec3&)bvh.node_uppers[left_index];
|
|
282
|
-
|
|
283
|
-
const vec3& right_lower = (vec3&)bvh.node_lowers[right_index];
|
|
284
|
-
const vec3& right_upper = (vec3&)bvh.node_uppers[right_index];
|
|
285
|
-
|
|
286
|
-
// union of child bounds
|
|
287
|
-
vec3 new_lower = min(left_lower, right_lower);
|
|
288
|
-
vec3 new_upper = max(left_upper, right_upper);
|
|
289
|
-
|
|
290
|
-
// write new BVH nodes
|
|
291
|
-
(vec3&)lower = new_lower;
|
|
292
|
-
(vec3&)upper = new_upper;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
void bvh_refit_host(BVH& bvh)
|
|
297
|
-
{
|
|
298
|
-
bvh_refit_recursive(bvh, 0);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
} // namespace wp
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
// making the class accessible from python
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
namespace
|
|
309
|
-
{
|
|
310
|
-
// host-side copy of bvh descriptors, maps GPU bvh address (id) to a CPU desc
|
|
311
|
-
std::map<uint64_t, BVH> g_bvh_descriptors;
|
|
312
|
-
|
|
313
|
-
} // anonymous namespace
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
namespace wp
|
|
317
|
-
{
|
|
318
|
-
|
|
319
|
-
bool bvh_get_descriptor(uint64_t id, BVH& bvh)
|
|
320
|
-
{
|
|
321
|
-
const auto& iter = g_bvh_descriptors.find(id);
|
|
322
|
-
if (iter == g_bvh_descriptors.end())
|
|
323
|
-
return false;
|
|
324
|
-
else
|
|
325
|
-
bvh = iter->second;
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
void bvh_add_descriptor(uint64_t id, const BVH& bvh)
|
|
330
|
-
{
|
|
331
|
-
g_bvh_descriptors[id] = bvh;
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
void bvh_rem_descriptor(uint64_t id)
|
|
336
|
-
{
|
|
337
|
-
g_bvh_descriptors.erase(id);
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
void bvh_destroy_host(BVH& bvh)
|
|
343
|
-
{
|
|
344
|
-
delete[] bvh.node_lowers;
|
|
345
|
-
delete[] bvh.node_uppers;
|
|
346
|
-
delete[] bvh.node_parents;
|
|
347
|
-
delete[] bvh.root;
|
|
348
|
-
|
|
349
|
-
bvh.node_lowers = NULL;
|
|
350
|
-
bvh.node_uppers = NULL;
|
|
351
|
-
bvh.node_parents = NULL;
|
|
352
|
-
bvh.root = NULL;
|
|
353
|
-
|
|
354
|
-
bvh.max_nodes = 0;
|
|
355
|
-
bvh.num_items = 0;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
} // namespace wp
|
|
359
|
-
|
|
360
|
-
uint64_t bvh_create_host(vec3* lowers, vec3* uppers, int num_items)
|
|
361
|
-
{
|
|
362
|
-
BVH* bvh = new BVH();
|
|
363
|
-
memset(bvh, 0, sizeof(BVH));
|
|
364
|
-
|
|
365
|
-
bvh->context = NULL;
|
|
366
|
-
|
|
367
|
-
bvh->item_lowers = lowers;
|
|
368
|
-
bvh->item_uppers = uppers;
|
|
369
|
-
bvh->num_items = num_items;
|
|
370
|
-
|
|
371
|
-
MedianBVHBuilder builder;
|
|
372
|
-
builder.build(*bvh, lowers, uppers, num_items);
|
|
373
|
-
|
|
374
|
-
return (uint64_t)bvh;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
void bvh_refit_host(uint64_t id)
|
|
378
|
-
{
|
|
379
|
-
BVH* bvh = (BVH*)(id);
|
|
380
|
-
bvh_refit_host(*bvh);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
void bvh_destroy_host(uint64_t id)
|
|
384
|
-
{
|
|
385
|
-
BVH* bvh = (BVH*)(id);
|
|
386
|
-
bvh_destroy_host(*bvh);
|
|
387
|
-
delete bvh;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
// stubs for non-CUDA platforms
|
|
392
|
-
#if !WP_ENABLE_CUDA
|
|
393
|
-
|
|
394
|
-
uint64_t bvh_create_device(void* context, wp::vec3* lowers, wp::vec3* uppers, int num_items) { return 0; }
|
|
395
|
-
void bvh_refit_device(uint64_t id) {}
|
|
396
|
-
void bvh_destroy_device(uint64_t id) {}
|
|
397
|
-
|
|
398
|
-
#endif // !WP_ENABLE_CUDA
|
|
1
|
+
/** Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
* NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
* and proprietary rights in and to this software, related documentation
|
|
4
|
+
* and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
* distribution of this software and related documentation without an express
|
|
6
|
+
* license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <vector>
|
|
10
|
+
#include <algorithm>
|
|
11
|
+
|
|
12
|
+
#include "bvh.h"
|
|
13
|
+
#include "warp.h"
|
|
14
|
+
#include "cuda_util.h"
|
|
15
|
+
|
|
16
|
+
#include <map>
|
|
17
|
+
|
|
18
|
+
using namespace wp;
|
|
19
|
+
|
|
20
|
+
namespace wp
|
|
21
|
+
{
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
25
|
+
|
|
26
|
+
class MedianBVHBuilder
|
|
27
|
+
{
|
|
28
|
+
public:
|
|
29
|
+
|
|
30
|
+
void build(BVH& bvh, const vec3* lowers, const vec3* uppers, int n);
|
|
31
|
+
|
|
32
|
+
private:
|
|
33
|
+
|
|
34
|
+
bounds3 calc_bounds(const vec3* lowers, const vec3* uppers, const int* indices, int start, int end);
|
|
35
|
+
|
|
36
|
+
int partition_median(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds);
|
|
37
|
+
int partition_midpoint(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds);
|
|
38
|
+
int partition_sah(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds);
|
|
39
|
+
|
|
40
|
+
int build_recursive(BVH& bvh, const vec3* lowers, const vec3* uppers, int* indices, int start, int end, int depth, int parent);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
//////////////////////////////////////////////////////////////////////
|
|
44
|
+
|
|
45
|
+
void MedianBVHBuilder::build(BVH& bvh, const vec3* lowers, const vec3* uppers, int n)
|
|
46
|
+
{
|
|
47
|
+
bvh.max_depth = 0;
|
|
48
|
+
bvh.max_nodes = 2*n-1;
|
|
49
|
+
|
|
50
|
+
bvh.node_lowers = new BVHPackedNodeHalf[bvh.max_nodes];
|
|
51
|
+
bvh.node_uppers = new BVHPackedNodeHalf[bvh.max_nodes];
|
|
52
|
+
bvh.node_parents = new int[bvh.max_nodes];
|
|
53
|
+
bvh.node_counts = NULL;
|
|
54
|
+
|
|
55
|
+
// root is always in first slot for top down builders
|
|
56
|
+
bvh.root = new int[1];
|
|
57
|
+
bvh.root[0] = 0;
|
|
58
|
+
|
|
59
|
+
if (n == 0)
|
|
60
|
+
return;
|
|
61
|
+
|
|
62
|
+
std::vector<int> indices(n);
|
|
63
|
+
for (int i=0; i < n; ++i)
|
|
64
|
+
indices[i] = i;
|
|
65
|
+
|
|
66
|
+
build_recursive(bvh, lowers, uppers, &indices[0], 0, n, 0, -1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
bounds3 MedianBVHBuilder::calc_bounds(const vec3* lowers, const vec3* uppers, const int* indices, int start, int end)
|
|
71
|
+
{
|
|
72
|
+
bounds3 u;
|
|
73
|
+
|
|
74
|
+
for (int i=start; i < end; ++i)
|
|
75
|
+
{
|
|
76
|
+
u.add_point(lowers[indices[i]]);
|
|
77
|
+
u.add_point(uppers[indices[i]]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return u;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
struct PartitionPredicateMedian
|
|
84
|
+
{
|
|
85
|
+
PartitionPredicateMedian(const vec3* lowers, const vec3* uppers, int a) : lowers(lowers), uppers(uppers), axis(a) {}
|
|
86
|
+
|
|
87
|
+
bool operator()(int a, int b) const
|
|
88
|
+
{
|
|
89
|
+
vec3 a_center = 0.5f*(lowers[a] + uppers[a]);
|
|
90
|
+
vec3 b_center = 0.5f*(lowers[b] + uppers[b]);
|
|
91
|
+
|
|
92
|
+
return a_center[axis] < b_center[axis];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const vec3* lowers;
|
|
96
|
+
const vec3* uppers;
|
|
97
|
+
int axis;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
int MedianBVHBuilder::partition_median(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds)
|
|
102
|
+
{
|
|
103
|
+
assert(end-start >= 2);
|
|
104
|
+
|
|
105
|
+
vec3 edges = range_bounds.edges();
|
|
106
|
+
|
|
107
|
+
int axis = longest_axis(edges);
|
|
108
|
+
|
|
109
|
+
const int k = (start+end)/2;
|
|
110
|
+
|
|
111
|
+
std::nth_element(&indices[start], &indices[k], &indices[end], PartitionPredicateMedian(lowers, uppers, axis));
|
|
112
|
+
|
|
113
|
+
return k;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
struct PartitionPredictateMidPoint
|
|
117
|
+
{
|
|
118
|
+
PartitionPredictateMidPoint(const vec3* lowers, const vec3* uppers, int a, float m) : lowers(lowers), uppers(uppers), axis(a), mid(m) {}
|
|
119
|
+
|
|
120
|
+
bool operator()(int index) const
|
|
121
|
+
{
|
|
122
|
+
vec3 center = 0.5f*(lowers[index] + uppers[index]);
|
|
123
|
+
|
|
124
|
+
return center[axis] <= mid;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const vec3* lowers;
|
|
128
|
+
const vec3* uppers;
|
|
129
|
+
|
|
130
|
+
int axis;
|
|
131
|
+
float mid;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
int MedianBVHBuilder::partition_midpoint(const vec3* lowers, const vec3* uppers, int* indices, int start, int end, bounds3 range_bounds)
|
|
136
|
+
{
|
|
137
|
+
assert(end-start >= 2);
|
|
138
|
+
|
|
139
|
+
vec3 edges = range_bounds.edges();
|
|
140
|
+
vec3 center = range_bounds.center();
|
|
141
|
+
|
|
142
|
+
int axis = longest_axis(edges);
|
|
143
|
+
float mid = center[axis];
|
|
144
|
+
|
|
145
|
+
int* upper = std::partition(indices+start, indices+end, PartitionPredictateMidPoint(lowers, uppers, axis, mid));
|
|
146
|
+
|
|
147
|
+
int k = upper-indices;
|
|
148
|
+
|
|
149
|
+
// if we failed to split items then just split in the middle
|
|
150
|
+
if (k == start || k == end)
|
|
151
|
+
k = (start+end)/2;
|
|
152
|
+
|
|
153
|
+
return k;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// disable std::sort workaround for macOS error
|
|
157
|
+
#if 0
|
|
158
|
+
int MedianBVHBuilder::partition_sah(const bounds3* bounds, int* indices, int start, int end, bounds3 range_bounds)
|
|
159
|
+
{
|
|
160
|
+
assert(end-start >= 2);
|
|
161
|
+
|
|
162
|
+
int n = end-start;
|
|
163
|
+
vec3 edges = range_bounds.edges();
|
|
164
|
+
|
|
165
|
+
int longestAxis = longest_axis(edges);
|
|
166
|
+
|
|
167
|
+
// sort along longest axis
|
|
168
|
+
std::sort(&indices[0]+start, &indices[0]+end, PartitionPredicateMedian(&bounds[0], longestAxis));
|
|
169
|
+
|
|
170
|
+
// total area for range from [0, split]
|
|
171
|
+
std::vector<float> left_areas(n);
|
|
172
|
+
// total area for range from (split, end]
|
|
173
|
+
std::vector<float> right_areas(n);
|
|
174
|
+
|
|
175
|
+
bounds3 left;
|
|
176
|
+
bounds3 right;
|
|
177
|
+
|
|
178
|
+
// build cumulative bounds and area from left and right
|
|
179
|
+
for (int i=0; i < n; ++i)
|
|
180
|
+
{
|
|
181
|
+
left = bounds_union(left, bounds[indices[start+i]]);
|
|
182
|
+
right = bounds_union(right, bounds[indices[end-i-1]]);
|
|
183
|
+
|
|
184
|
+
left_areas[i] = left.area();
|
|
185
|
+
right_areas[n-i-1] = right.area();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
float invTotalArea = 1.0f/range_bounds.area();
|
|
189
|
+
|
|
190
|
+
// find split point i that minimizes area(left[i]) + area(right[i])
|
|
191
|
+
int minSplit = 0;
|
|
192
|
+
float minCost = FLT_MAX;
|
|
193
|
+
|
|
194
|
+
for (int i=0; i < n; ++i)
|
|
195
|
+
{
|
|
196
|
+
float pBelow = left_areas[i]*invTotalArea;
|
|
197
|
+
float pAbove = right_areas[i]*invTotalArea;
|
|
198
|
+
|
|
199
|
+
float cost = pBelow*i + pAbove*(n-i);
|
|
200
|
+
|
|
201
|
+
if (cost < minCost)
|
|
202
|
+
{
|
|
203
|
+
minCost = cost;
|
|
204
|
+
minSplit = i;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return start + minSplit + 1;
|
|
209
|
+
}
|
|
210
|
+
#endif
|
|
211
|
+
|
|
212
|
+
int MedianBVHBuilder::build_recursive(BVH& bvh, const vec3* lowers, const vec3* uppers, int* indices, int start, int end, int depth, int parent)
|
|
213
|
+
{
|
|
214
|
+
assert(start < end);
|
|
215
|
+
|
|
216
|
+
const int n = end-start;
|
|
217
|
+
const int node_index = bvh.num_nodes++;
|
|
218
|
+
|
|
219
|
+
assert(node_index < bvh.max_nodes);
|
|
220
|
+
|
|
221
|
+
if (depth > bvh.max_depth)
|
|
222
|
+
bvh.max_depth = depth;
|
|
223
|
+
|
|
224
|
+
bounds3 b = calc_bounds(lowers, uppers, indices, start, end);
|
|
225
|
+
|
|
226
|
+
const int kMaxItemsPerLeaf = 1;
|
|
227
|
+
|
|
228
|
+
if (n <= kMaxItemsPerLeaf)
|
|
229
|
+
{
|
|
230
|
+
bvh.node_lowers[node_index] = make_node(b.lower, indices[start], true);
|
|
231
|
+
bvh.node_uppers[node_index] = make_node(b.upper, indices[start], false);
|
|
232
|
+
bvh.node_parents[node_index] = parent;
|
|
233
|
+
}
|
|
234
|
+
else
|
|
235
|
+
{
|
|
236
|
+
//int split = partition_midpoint(bounds, indices, start, end, b);
|
|
237
|
+
int split = partition_median(lowers, uppers, indices, start, end, b);
|
|
238
|
+
//int split = partition_sah(bounds, indices, start, end, b);
|
|
239
|
+
|
|
240
|
+
if (split == start || split == end)
|
|
241
|
+
{
|
|
242
|
+
// partitioning failed, split down the middle
|
|
243
|
+
split = (start+end)/2;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
int left_child = build_recursive(bvh, lowers, uppers, indices, start, split, depth+1, node_index);
|
|
247
|
+
int right_child = build_recursive(bvh, lowers, uppers, indices, split, end, depth+1, node_index);
|
|
248
|
+
|
|
249
|
+
bvh.node_lowers[node_index] = make_node(b.lower, left_child, false);
|
|
250
|
+
bvh.node_uppers[node_index] = make_node(b.upper, right_child, false);
|
|
251
|
+
bvh.node_parents[node_index] = parent;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return node_index;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
void bvh_refit_recursive(BVH& bvh, int index)
|
|
259
|
+
{
|
|
260
|
+
BVHPackedNodeHalf& lower = bvh.node_lowers[index];
|
|
261
|
+
BVHPackedNodeHalf& upper = bvh.node_uppers[index];
|
|
262
|
+
|
|
263
|
+
if (lower.b)
|
|
264
|
+
{
|
|
265
|
+
const int leaf_index = lower.i;
|
|
266
|
+
|
|
267
|
+
// update leaf from items
|
|
268
|
+
(vec3&)lower = bvh.item_lowers[leaf_index];
|
|
269
|
+
(vec3&)upper = bvh.item_uppers[leaf_index];
|
|
270
|
+
}
|
|
271
|
+
else
|
|
272
|
+
{
|
|
273
|
+
int left_index = lower.i;
|
|
274
|
+
int right_index = upper.i;
|
|
275
|
+
|
|
276
|
+
bvh_refit_recursive(bvh, left_index);
|
|
277
|
+
bvh_refit_recursive(bvh, right_index);
|
|
278
|
+
|
|
279
|
+
// compute union of children
|
|
280
|
+
const vec3& left_lower = (vec3&)bvh.node_lowers[left_index];
|
|
281
|
+
const vec3& left_upper = (vec3&)bvh.node_uppers[left_index];
|
|
282
|
+
|
|
283
|
+
const vec3& right_lower = (vec3&)bvh.node_lowers[right_index];
|
|
284
|
+
const vec3& right_upper = (vec3&)bvh.node_uppers[right_index];
|
|
285
|
+
|
|
286
|
+
// union of child bounds
|
|
287
|
+
vec3 new_lower = min(left_lower, right_lower);
|
|
288
|
+
vec3 new_upper = max(left_upper, right_upper);
|
|
289
|
+
|
|
290
|
+
// write new BVH nodes
|
|
291
|
+
(vec3&)lower = new_lower;
|
|
292
|
+
(vec3&)upper = new_upper;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
void bvh_refit_host(BVH& bvh)
|
|
297
|
+
{
|
|
298
|
+
bvh_refit_recursive(bvh, 0);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
} // namespace wp
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
// making the class accessible from python
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
namespace
|
|
309
|
+
{
|
|
310
|
+
// host-side copy of bvh descriptors, maps GPU bvh address (id) to a CPU desc
|
|
311
|
+
std::map<uint64_t, BVH> g_bvh_descriptors;
|
|
312
|
+
|
|
313
|
+
} // anonymous namespace
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
namespace wp
|
|
317
|
+
{
|
|
318
|
+
|
|
319
|
+
bool bvh_get_descriptor(uint64_t id, BVH& bvh)
|
|
320
|
+
{
|
|
321
|
+
const auto& iter = g_bvh_descriptors.find(id);
|
|
322
|
+
if (iter == g_bvh_descriptors.end())
|
|
323
|
+
return false;
|
|
324
|
+
else
|
|
325
|
+
bvh = iter->second;
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
void bvh_add_descriptor(uint64_t id, const BVH& bvh)
|
|
330
|
+
{
|
|
331
|
+
g_bvh_descriptors[id] = bvh;
|
|
332
|
+
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
void bvh_rem_descriptor(uint64_t id)
|
|
336
|
+
{
|
|
337
|
+
g_bvh_descriptors.erase(id);
|
|
338
|
+
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
void bvh_destroy_host(BVH& bvh)
|
|
343
|
+
{
|
|
344
|
+
delete[] bvh.node_lowers;
|
|
345
|
+
delete[] bvh.node_uppers;
|
|
346
|
+
delete[] bvh.node_parents;
|
|
347
|
+
delete[] bvh.root;
|
|
348
|
+
|
|
349
|
+
bvh.node_lowers = NULL;
|
|
350
|
+
bvh.node_uppers = NULL;
|
|
351
|
+
bvh.node_parents = NULL;
|
|
352
|
+
bvh.root = NULL;
|
|
353
|
+
|
|
354
|
+
bvh.max_nodes = 0;
|
|
355
|
+
bvh.num_items = 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
} // namespace wp
|
|
359
|
+
|
|
360
|
+
uint64_t bvh_create_host(vec3* lowers, vec3* uppers, int num_items)
|
|
361
|
+
{
|
|
362
|
+
BVH* bvh = new BVH();
|
|
363
|
+
memset(bvh, 0, sizeof(BVH));
|
|
364
|
+
|
|
365
|
+
bvh->context = NULL;
|
|
366
|
+
|
|
367
|
+
bvh->item_lowers = lowers;
|
|
368
|
+
bvh->item_uppers = uppers;
|
|
369
|
+
bvh->num_items = num_items;
|
|
370
|
+
|
|
371
|
+
MedianBVHBuilder builder;
|
|
372
|
+
builder.build(*bvh, lowers, uppers, num_items);
|
|
373
|
+
|
|
374
|
+
return (uint64_t)bvh;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
void bvh_refit_host(uint64_t id)
|
|
378
|
+
{
|
|
379
|
+
BVH* bvh = (BVH*)(id);
|
|
380
|
+
bvh_refit_host(*bvh);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
void bvh_destroy_host(uint64_t id)
|
|
384
|
+
{
|
|
385
|
+
BVH* bvh = (BVH*)(id);
|
|
386
|
+
bvh_destroy_host(*bvh);
|
|
387
|
+
delete bvh;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
// stubs for non-CUDA platforms
|
|
392
|
+
#if !WP_ENABLE_CUDA
|
|
393
|
+
|
|
394
|
+
uint64_t bvh_create_device(void* context, wp::vec3* lowers, wp::vec3* uppers, int num_items) { return 0; }
|
|
395
|
+
void bvh_refit_device(uint64_t id) {}
|
|
396
|
+
void bvh_destroy_device(uint64_t id) {}
|
|
397
|
+
|
|
398
|
+
#endif // !WP_ENABLE_CUDA
|