warp-lang 0.9.0__py3-none-win_amd64.whl → 0.11.0__py3-none-win_amd64.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 +15 -7
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +22 -443
- warp/build_dll.py +384 -0
- warp/builtins.py +998 -488
- warp/codegen.py +1307 -739
- warp/config.py +5 -3
- warp/constants.py +6 -0
- warp/context.py +1291 -548
- warp/dlpack.py +31 -31
- warp/fabric.py +326 -0
- warp/fem/__init__.py +27 -0
- warp/fem/cache.py +389 -0
- warp/fem/dirichlet.py +181 -0
- warp/fem/domain.py +263 -0
- warp/fem/field/__init__.py +101 -0
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +299 -0
- warp/fem/field/restriction.py +21 -0
- warp/fem/field/test.py +181 -0
- warp/fem/field/trial.py +183 -0
- warp/fem/geometry/__init__.py +19 -0
- warp/fem/geometry/closest_point.py +70 -0
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +744 -0
- warp/fem/geometry/geometry.py +186 -0
- warp/fem/geometry/grid_2d.py +373 -0
- warp/fem/geometry/grid_3d.py +435 -0
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +376 -0
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +840 -0
- warp/fem/geometry/trimesh_2d.py +577 -0
- warp/fem/integrate.py +1616 -0
- warp/fem/operator.py +191 -0
- warp/fem/polynomial.py +213 -0
- warp/fem/quadrature/__init__.py +2 -0
- warp/fem/quadrature/pic_quadrature.py +245 -0
- warp/fem/quadrature/quadrature.py +294 -0
- warp/fem/space/__init__.py +292 -0
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +236 -0
- warp/fem/space/function_space.py +145 -0
- warp/fem/space/grid_2d_function_space.py +267 -0
- warp/fem/space/grid_3d_function_space.py +306 -0
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +350 -0
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +160 -0
- warp/fem/space/shape/__init__.py +15 -0
- warp/fem/space/shape/cube_shape_function.py +738 -0
- warp/fem/space/shape/shape_function.py +103 -0
- warp/fem/space/shape/square_shape_function.py +611 -0
- warp/fem/space/shape/tet_shape_function.py +567 -0
- warp/fem/space/shape/triangle_shape_function.py +429 -0
- warp/fem/space/tetmesh_function_space.py +292 -0
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +221 -0
- warp/fem/types.py +77 -0
- warp/fem/utils.py +495 -0
- warp/native/array.h +164 -55
- warp/native/builtin.h +150 -174
- warp/native/bvh.cpp +75 -328
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +37 -45
- warp/native/clang/clang.cpp +136 -24
- warp/native/crt.cpp +1 -76
- warp/native/crt.h +111 -104
- warp/native/cuda_crt.h +1049 -0
- warp/native/cuda_util.cpp +15 -3
- warp/native/cuda_util.h +3 -1
- warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
- warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
- warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
- warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
- warp/native/cutlass/tools/library/scripts/library.py +799 -0
- warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
- warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
- warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
- warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
- warp/native/cutlass/tools/library/scripts/rt.py +796 -0
- warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
- warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
- warp/native/cutlass_gemm.cu +5 -3
- warp/native/exports.h +1240 -949
- warp/native/fabric.h +228 -0
- warp/native/hashgrid.cpp +4 -4
- warp/native/hashgrid.h +22 -2
- warp/native/initializer_array.h +2 -2
- warp/native/intersect.h +22 -7
- warp/native/intersect_adj.h +8 -8
- warp/native/intersect_tri.h +13 -16
- warp/native/marching.cu +157 -161
- warp/native/mat.h +119 -19
- warp/native/matnn.h +2 -2
- warp/native/mesh.cpp +108 -83
- warp/native/mesh.cu +243 -6
- warp/native/mesh.h +1547 -458
- warp/native/nanovdb/NanoVDB.h +1 -1
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +45 -35
- warp/native/range.h +6 -2
- warp/native/reduce.cpp +157 -0
- warp/native/reduce.cu +348 -0
- warp/native/runlength_encode.cpp +62 -0
- warp/native/runlength_encode.cu +46 -0
- warp/native/scan.cu +11 -13
- warp/native/scan.h +1 -0
- warp/native/solid_angle.h +442 -0
- warp/native/sort.cpp +13 -0
- warp/native/sort.cu +9 -1
- warp/native/sparse.cpp +338 -0
- warp/native/sparse.cu +545 -0
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +30 -0
- warp/native/vec.h +126 -24
- warp/native/volume.h +120 -0
- warp/native/warp.cpp +658 -53
- warp/native/warp.cu +660 -68
- warp/native/warp.h +112 -12
- warp/optim/__init__.py +1 -0
- warp/optim/linear.py +922 -0
- warp/optim/sgd.py +92 -0
- warp/render/render_opengl.py +392 -152
- warp/render/render_usd.py +11 -11
- warp/sim/__init__.py +2 -2
- warp/sim/articulation.py +385 -185
- warp/sim/collide.py +21 -8
- warp/sim/import_mjcf.py +297 -106
- warp/sim/import_urdf.py +389 -210
- warp/sim/import_usd.py +198 -97
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_euler.py +14 -8
- warp/sim/integrator_xpbd.py +161 -19
- warp/sim/model.py +795 -291
- warp/sim/optimizer.py +2 -6
- warp/sim/render.py +65 -3
- warp/sim/utils.py +3 -0
- warp/sparse.py +1227 -0
- warp/stubs.py +665 -223
- warp/tape.py +66 -15
- warp/tests/__main__.py +3 -6
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/assets/torus.usda +105 -105
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/disabled_kinematics.py +239 -0
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +103 -106
- warp/tests/test_arithmetic.py +128 -74
- warp/tests/test_array.py +1497 -211
- warp/tests/test_array_reduce.py +150 -0
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +99 -0
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +75 -43
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +233 -128
- warp/tests/test_compile_consts.py +28 -20
- warp/tests/test_conditional.py +108 -24
- warp/tests/test_copy.py +10 -12
- warp/tests/test_ctypes.py +112 -88
- warp/tests/test_dense.py +21 -14
- warp/tests/test_devices.py +98 -0
- warp/tests/test_dlpack.py +136 -108
- warp/tests/test_examples.py +277 -0
- warp/tests/test_fabricarray.py +955 -0
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1271 -0
- warp/tests/test_fp16.py +53 -19
- warp/tests/test_func.py +187 -74
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +180 -116
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +52 -37
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +577 -24
- warp/tests/test_intersect.py +18 -9
- warp/tests/test_large.py +141 -0
- warp/tests/test_launch.py +251 -15
- warp/tests/test_lerp.py +64 -65
- warp/tests/test_linear_solvers.py +154 -0
- warp/tests/test_lvalue.py +493 -0
- warp/tests/test_marching_cubes.py +12 -13
- warp/tests/test_mat.py +508 -2778
- warp/tests/test_mat_lite.py +115 -0
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +103 -9
- warp/tests/test_matmul.py +305 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +71 -14
- warp/tests/test_mesh_query_aabb.py +41 -25
- warp/tests/test_mesh_query_point.py +325 -34
- warp/tests/test_mesh_query_ray.py +39 -22
- warp/tests/test_mlp.py +30 -22
- warp/tests/test_model.py +92 -89
- warp/tests/test_modules_lite.py +39 -0
- warp/tests/test_multigpu.py +88 -114
- warp/tests/test_noise.py +12 -11
- warp/tests/test_operators.py +16 -20
- warp/tests/test_options.py +11 -11
- warp/tests/test_pinned.py +17 -18
- warp/tests/test_print.py +32 -11
- warp/tests/test_quat.py +275 -129
- warp/tests/test_rand.py +18 -16
- warp/tests/test_reload.py +38 -34
- warp/tests/test_rounding.py +50 -43
- warp/tests/test_runlength_encode.py +190 -0
- warp/tests/test_smoothstep.py +9 -11
- warp/tests/test_snippet.py +143 -0
- warp/tests/test_sparse.py +460 -0
- warp/tests/test_spatial.py +276 -243
- warp/tests/test_streams.py +110 -85
- warp/tests/test_struct.py +331 -85
- warp/tests/test_tape.py +39 -21
- warp/tests/test_torch.py +118 -89
- warp/tests/test_transient_module.py +12 -13
- warp/tests/test_types.py +614 -0
- warp/tests/test_utils.py +494 -0
- warp/tests/test_vec.py +354 -1987
- warp/tests/test_vec_lite.py +73 -0
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +457 -293
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +341 -0
- warp/tests/unittest_utils.py +568 -0
- warp/tests/unused_test_misc.py +71 -0
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +549 -0
- warp/torch.py +72 -30
- warp/types.py +1744 -713
- warp/utils.py +360 -350
- warp_lang-0.11.0.dist-info/LICENSE.md +36 -0
- warp_lang-0.11.0.dist-info/METADATA +238 -0
- warp_lang-0.11.0.dist-info/RECORD +332 -0
- {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
- warp/bin/warp-clang.exp +0 -0
- warp/bin/warp-clang.lib +0 -0
- warp/bin/warp.exp +0 -0
- warp/bin/warp.lib +0 -0
- warp/tests/test_all.py +0 -215
- warp/tests/test_array_scan.py +0 -60
- warp/tests/test_base.py +0 -208
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- warp_lang-0.9.0.dist-info/METADATA +0 -20
- warp_lang-0.9.0.dist-info/RECORD +0 -177
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
warp/native/mesh.h
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include "bvh.h"
|
|
13
13
|
#include "intersect.h"
|
|
14
14
|
#include "array.h"
|
|
15
|
+
#include "solid_angle.h"
|
|
15
16
|
|
|
16
17
|
#define BVH_DEBUG 0
|
|
17
18
|
|
|
@@ -21,38 +22,49 @@ namespace wp
|
|
|
21
22
|
struct Mesh
|
|
22
23
|
{
|
|
23
24
|
array_t<vec3> points;
|
|
24
|
-
|
|
25
|
+
array_t<vec3> velocities;
|
|
25
26
|
|
|
26
27
|
array_t<int> indices;
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
vec3* lowers;
|
|
30
|
+
vec3* uppers;
|
|
31
|
+
|
|
32
|
+
SolidAngleProps* solid_angle_props;
|
|
29
33
|
|
|
30
34
|
int num_points;
|
|
31
35
|
int num_tris;
|
|
32
36
|
|
|
33
37
|
BVH bvh;
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
39
|
+
void* context;
|
|
40
|
+
float average_edge_length;
|
|
41
|
+
|
|
42
|
+
inline CUDA_CALLABLE Mesh(int id = 0)
|
|
43
|
+
{
|
|
44
|
+
// for backward a = 0 initialization syntax
|
|
45
|
+
lowers = nullptr;
|
|
46
|
+
uppers = nullptr;
|
|
47
|
+
num_points = 0;
|
|
48
|
+
num_tris = 0;
|
|
49
|
+
context = nullptr;
|
|
50
|
+
solid_angle_props = nullptr;
|
|
51
|
+
average_edge_length = 0.0f;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
inline CUDA_CALLABLE Mesh(
|
|
55
|
+
array_t<vec3> points,
|
|
56
|
+
array_t<vec3> velocities,
|
|
57
|
+
array_t<int> indices,
|
|
58
|
+
int num_points,
|
|
59
|
+
int num_tris,
|
|
60
|
+
void* context = nullptr
|
|
61
|
+
) : points(points), velocities(velocities), indices(indices), num_points(num_points), num_tris(num_tris), context(context)
|
|
62
|
+
{
|
|
63
|
+
lowers = nullptr;
|
|
64
|
+
uppers = nullptr;
|
|
65
|
+
solid_angle_props = nullptr;
|
|
66
|
+
average_edge_length = 0.0f;
|
|
67
|
+
}
|
|
56
68
|
};
|
|
57
69
|
|
|
58
70
|
CUDA_CALLABLE inline Mesh mesh_get(uint64_t id)
|
|
@@ -62,409 +74,1497 @@ CUDA_CALLABLE inline Mesh mesh_get(uint64_t id)
|
|
|
62
74
|
|
|
63
75
|
|
|
64
76
|
CUDA_CALLABLE inline Mesh& operator += (Mesh& a, const Mesh& b) {
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
// dummy operator needed for adj_select involving meshes
|
|
78
|
+
return a;
|
|
67
79
|
}
|
|
68
80
|
|
|
69
81
|
CUDA_CALLABLE inline float distance_to_aabb_sq(const vec3& p, const vec3& lower, const vec3& upper)
|
|
70
82
|
{
|
|
71
|
-
|
|
83
|
+
vec3 cp = closest_point_to_aabb(p, lower, upper);
|
|
72
84
|
|
|
73
|
-
|
|
85
|
+
return length_sq(p-cp);
|
|
74
86
|
}
|
|
75
87
|
|
|
88
|
+
CUDA_CALLABLE inline float furthest_distance_to_aabb_sq(const vec3& p, const vec3& lower, const vec3& upper)
|
|
89
|
+
{
|
|
90
|
+
vec3 c0 = vec3(lower[0], lower[1], lower[2]);
|
|
91
|
+
vec3 c1 = vec3(lower[0], lower[1], upper[2]);
|
|
92
|
+
vec3 c2 = vec3(lower[0], upper[1], lower[2]);
|
|
93
|
+
vec3 c3 = vec3(lower[0], upper[1], upper[2]);
|
|
94
|
+
vec3 c4 = vec3(upper[0], lower[1], lower[2]);
|
|
95
|
+
vec3 c5 = vec3(upper[0], lower[1], upper[2]);
|
|
96
|
+
vec3 c6 = vec3(upper[0], upper[1], lower[2]);
|
|
97
|
+
vec3 c7 = vec3(upper[0], upper[1], upper[2]);
|
|
98
|
+
|
|
99
|
+
float max_dist_sq = 0.0;
|
|
100
|
+
float d;
|
|
101
|
+
|
|
102
|
+
d = length_sq(p-c0);
|
|
103
|
+
if (d > max_dist_sq)
|
|
104
|
+
max_dist_sq = d;
|
|
105
|
+
|
|
106
|
+
d = length_sq(p-c1);
|
|
107
|
+
if (d > max_dist_sq)
|
|
108
|
+
max_dist_sq = d;
|
|
109
|
+
|
|
110
|
+
d = length_sq(p-c2);
|
|
111
|
+
if (d > max_dist_sq)
|
|
112
|
+
max_dist_sq = d;
|
|
113
|
+
|
|
114
|
+
d = length_sq(p-c3);
|
|
115
|
+
if (d > max_dist_sq)
|
|
116
|
+
max_dist_sq = d;
|
|
117
|
+
|
|
118
|
+
d = length_sq(p-c4);
|
|
119
|
+
if (d > max_dist_sq)
|
|
120
|
+
max_dist_sq = d;
|
|
121
|
+
|
|
122
|
+
d = length_sq(p-c5);
|
|
123
|
+
if (d > max_dist_sq)
|
|
124
|
+
max_dist_sq = d;
|
|
125
|
+
|
|
126
|
+
d = length_sq(p-c6);
|
|
127
|
+
if (d > max_dist_sq)
|
|
128
|
+
max_dist_sq = d;
|
|
129
|
+
|
|
130
|
+
d = length_sq(p-c7);
|
|
131
|
+
if (d > max_dist_sq)
|
|
132
|
+
max_dist_sq = d;
|
|
133
|
+
|
|
134
|
+
return max_dist_sq;
|
|
135
|
+
}
|
|
76
136
|
|
|
77
|
-
// fwd
|
|
78
137
|
CUDA_CALLABLE inline float mesh_query_inside(uint64_t id, const vec3& p);
|
|
79
138
|
|
|
80
|
-
|
|
81
139
|
// returns true if there is a point (strictly) < distance max_dist
|
|
82
140
|
CUDA_CALLABLE inline bool mesh_query_point(uint64_t id, const vec3& point, float max_dist, float& inside, int& face, float& u, float& v)
|
|
83
141
|
{
|
|
84
142
|
Mesh mesh = mesh_get(id);
|
|
85
143
|
|
|
86
|
-
|
|
87
|
-
|
|
144
|
+
int stack[32];
|
|
145
|
+
stack[0] = *mesh.bvh.root;
|
|
146
|
+
|
|
147
|
+
int count = 1;
|
|
88
148
|
|
|
89
|
-
|
|
90
|
-
|
|
149
|
+
float min_dist_sq = max_dist*max_dist;
|
|
150
|
+
int min_face;
|
|
151
|
+
float min_v;
|
|
152
|
+
float min_w;
|
|
91
153
|
|
|
92
|
-
|
|
154
|
+
#if BVH_DEBUG
|
|
155
|
+
int tests = 0;
|
|
156
|
+
int secondary_culls = 0;
|
|
157
|
+
|
|
158
|
+
std::vector<int> test_history;
|
|
159
|
+
std::vector<vec3> test_centers;
|
|
160
|
+
std::vector<vec3> test_extents;
|
|
161
|
+
#endif
|
|
162
|
+
|
|
163
|
+
while (count)
|
|
164
|
+
{
|
|
165
|
+
const int nodeIndex = stack[--count];
|
|
166
|
+
|
|
167
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
168
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
169
|
+
|
|
170
|
+
// re-test distance
|
|
171
|
+
float node_dist_sq = distance_to_aabb_sq(point, vec3(lower.x, lower.y, lower.z), vec3(upper.x, upper.y, upper.z));
|
|
172
|
+
if (node_dist_sq > min_dist_sq)
|
|
173
|
+
{
|
|
174
|
+
#if BVH_DEBUG
|
|
175
|
+
secondary_culls++;
|
|
176
|
+
#endif
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const int left_index = lower.i;
|
|
181
|
+
const int right_index = upper.i;
|
|
93
182
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
183
|
+
if (lower.b)
|
|
184
|
+
{
|
|
185
|
+
// compute closest point on tri
|
|
186
|
+
int i = mesh.indices[left_index*3+0];
|
|
187
|
+
int j = mesh.indices[left_index*3+1];
|
|
188
|
+
int k = mesh.indices[left_index*3+2];
|
|
189
|
+
|
|
190
|
+
vec3 p = mesh.points[i];
|
|
191
|
+
vec3 q = mesh.points[j];
|
|
192
|
+
vec3 r = mesh.points[k];
|
|
193
|
+
|
|
194
|
+
vec3 e0 = q-p;
|
|
195
|
+
vec3 e1 = r-p;
|
|
196
|
+
vec3 e2 = r-q;
|
|
197
|
+
vec3 normal = cross(e0, e1);
|
|
198
|
+
|
|
199
|
+
// sliver detection
|
|
200
|
+
if (length(normal)/(dot(e0,e0) + dot(e1,e1) + dot(e2,e2)) < 1.e-6f)
|
|
201
|
+
continue;
|
|
202
|
+
|
|
203
|
+
vec2 barycentric = closest_point_to_triangle(p, q, r, point);
|
|
204
|
+
float u = barycentric[0];
|
|
205
|
+
float v = barycentric[1];
|
|
206
|
+
float w = 1.f - u - v;
|
|
207
|
+
vec3 c = u*p + v*q + w*r;
|
|
208
|
+
|
|
209
|
+
float dist_sq = length_sq(c-point);
|
|
210
|
+
|
|
211
|
+
if (dist_sq < min_dist_sq)
|
|
212
|
+
{
|
|
213
|
+
min_dist_sq = dist_sq;
|
|
214
|
+
min_v = v;
|
|
215
|
+
min_w = w;
|
|
216
|
+
min_face = left_index;
|
|
217
|
+
}
|
|
98
218
|
|
|
99
219
|
#if BVH_DEBUG
|
|
100
|
-
int tests = 0;
|
|
101
|
-
int secondary_culls = 0;
|
|
102
220
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
221
|
+
tests++;
|
|
222
|
+
|
|
223
|
+
bounds3 b;
|
|
224
|
+
b = bounds_union(b, p);
|
|
225
|
+
b = bounds_union(b, q);
|
|
226
|
+
b = bounds_union(b, r);
|
|
227
|
+
|
|
228
|
+
if (distance_to_aabb_sq(point, b.lower, b.upper) < max_dist*max_dist)
|
|
229
|
+
{
|
|
230
|
+
//if (dist_sq < max_dist*max_dist)
|
|
231
|
+
test_history.push_back(left_index);
|
|
232
|
+
test_centers.push_back(b.center());
|
|
233
|
+
test_extents.push_back(b.edges());
|
|
234
|
+
}
|
|
106
235
|
#endif
|
|
107
236
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
237
|
+
}
|
|
238
|
+
else
|
|
239
|
+
{
|
|
240
|
+
BVHPackedNodeHalf left_lower = mesh.bvh.node_lowers[left_index];
|
|
241
|
+
BVHPackedNodeHalf left_upper = mesh.bvh.node_uppers[left_index];
|
|
242
|
+
|
|
243
|
+
BVHPackedNodeHalf right_lower = mesh.bvh.node_lowers[right_index];
|
|
244
|
+
BVHPackedNodeHalf right_upper = mesh.bvh.node_uppers[right_index];
|
|
245
|
+
|
|
246
|
+
float left_dist_sq = distance_to_aabb_sq(point, vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z));
|
|
247
|
+
float right_dist_sq = distance_to_aabb_sq(point, vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z));
|
|
248
|
+
|
|
249
|
+
float left_score = left_dist_sq;
|
|
250
|
+
float right_score = right_dist_sq;
|
|
251
|
+
|
|
252
|
+
if (left_score < right_score)
|
|
253
|
+
{
|
|
254
|
+
// put left on top of the stack
|
|
255
|
+
if (right_dist_sq < min_dist_sq)
|
|
256
|
+
stack[count++] = right_index;
|
|
257
|
+
|
|
258
|
+
if (left_dist_sq < min_dist_sq)
|
|
259
|
+
stack[count++] = left_index;
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
{
|
|
263
|
+
// put right on top of the stack
|
|
264
|
+
if (left_dist_sq < min_dist_sq)
|
|
265
|
+
stack[count++] = left_index;
|
|
266
|
+
|
|
267
|
+
if (right_dist_sq < min_dist_sq)
|
|
268
|
+
stack[count++] = right_index;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
#if BVH_DEBUG
|
|
275
|
+
printf("%d\n", tests);
|
|
276
|
+
|
|
277
|
+
static int max_tests = 0;
|
|
278
|
+
static vec3 max_point;
|
|
279
|
+
static float max_point_dist = 0.0f;
|
|
280
|
+
static int max_secondary_culls = 0;
|
|
281
|
+
|
|
282
|
+
if (secondary_culls > max_secondary_culls)
|
|
283
|
+
max_secondary_culls = secondary_culls;
|
|
284
|
+
|
|
285
|
+
if (tests > max_tests)
|
|
286
|
+
{
|
|
287
|
+
max_tests = tests;
|
|
288
|
+
max_point = point;
|
|
289
|
+
max_point_dist = sqrtf(min_dist_sq);
|
|
290
|
+
|
|
291
|
+
printf("max_tests: %d max_point: %f %f %f max_point_dist: %f max_second_culls: %d\n", max_tests, max_point[0], max_point[1], max_point[2], max_point_dist, max_secondary_culls);
|
|
292
|
+
|
|
293
|
+
FILE* f = fopen("test_history.txt", "w");
|
|
294
|
+
for (int i=0; i < test_history.size(); ++i)
|
|
295
|
+
{
|
|
296
|
+
fprintf(f, "%d, %f, %f, %f, %f, %f, %f\n",
|
|
297
|
+
test_history[i],
|
|
298
|
+
test_centers[i][0], test_centers[i][1], test_centers[i][2],
|
|
299
|
+
test_extents[i][0], test_extents[i][1], test_extents[i][2]);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
fclose(f);
|
|
303
|
+
}
|
|
304
|
+
#endif
|
|
305
|
+
|
|
306
|
+
// check if we found a point, and write outputs
|
|
307
|
+
if (min_dist_sq < max_dist*max_dist)
|
|
308
|
+
{
|
|
309
|
+
u = 1.0f - min_v - min_w;
|
|
310
|
+
v = min_v;
|
|
311
|
+
face = min_face;
|
|
312
|
+
|
|
313
|
+
// determine inside outside using ray-cast parity check
|
|
314
|
+
inside = mesh_query_inside(id, point);
|
|
315
|
+
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
else
|
|
319
|
+
{
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// returns true if there is a point (strictly) < distance max_dist
|
|
325
|
+
CUDA_CALLABLE inline bool mesh_query_point_no_sign(uint64_t id, const vec3& point, float max_dist, int& face, float& u, float& v)
|
|
326
|
+
{
|
|
327
|
+
Mesh mesh = mesh_get(id);
|
|
328
|
+
|
|
329
|
+
int stack[32];
|
|
330
|
+
stack[0] = *mesh.bvh.root;
|
|
331
|
+
|
|
332
|
+
int count = 1;
|
|
333
|
+
|
|
334
|
+
float min_dist_sq = max_dist*max_dist;
|
|
335
|
+
int min_face;
|
|
336
|
+
float min_v;
|
|
337
|
+
float min_w;
|
|
338
|
+
|
|
339
|
+
#if BVH_DEBUG
|
|
340
|
+
int tests = 0;
|
|
341
|
+
int secondary_culls = 0;
|
|
342
|
+
|
|
343
|
+
std::vector<int> test_history;
|
|
344
|
+
std::vector<vec3> test_centers;
|
|
345
|
+
std::vector<vec3> test_extents;
|
|
346
|
+
#endif
|
|
347
|
+
|
|
348
|
+
while (count)
|
|
349
|
+
{
|
|
350
|
+
const int nodeIndex = stack[--count];
|
|
351
|
+
|
|
352
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
353
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
354
|
+
|
|
355
|
+
// re-test distance
|
|
356
|
+
float node_dist_sq = distance_to_aabb_sq(point, vec3(lower.x, lower.y, lower.z), vec3(upper.x, upper.y, upper.z));
|
|
357
|
+
if (node_dist_sq > min_dist_sq)
|
|
358
|
+
{
|
|
119
359
|
#if BVH_DEBUG
|
|
120
|
-
|
|
360
|
+
secondary_culls++;
|
|
121
361
|
#endif
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const int left_index = lower.i;
|
|
366
|
+
const int right_index = upper.i;
|
|
367
|
+
|
|
368
|
+
if (lower.b)
|
|
369
|
+
{
|
|
370
|
+
// compute closest point on tri
|
|
371
|
+
int i = mesh.indices[left_index*3+0];
|
|
372
|
+
int j = mesh.indices[left_index*3+1];
|
|
373
|
+
int k = mesh.indices[left_index*3+2];
|
|
374
|
+
|
|
375
|
+
vec3 p = mesh.points[i];
|
|
376
|
+
vec3 q = mesh.points[j];
|
|
377
|
+
vec3 r = mesh.points[k];
|
|
378
|
+
|
|
379
|
+
vec3 e0 = q-p;
|
|
380
|
+
vec3 e1 = r-p;
|
|
381
|
+
vec3 e2 = r-q;
|
|
382
|
+
vec3 normal = cross(e0, e1);
|
|
383
|
+
|
|
384
|
+
// sliver detection
|
|
385
|
+
if (length(normal)/(dot(e0,e0) + dot(e1,e1) + dot(e2,e2)) < 1.e-6f)
|
|
386
|
+
continue;
|
|
387
|
+
|
|
388
|
+
vec2 barycentric = closest_point_to_triangle(p, q, r, point);
|
|
389
|
+
float u = barycentric[0];
|
|
390
|
+
float v = barycentric[1];
|
|
391
|
+
float w = 1.f - u - v;
|
|
392
|
+
vec3 c = u*p + v*q + w*r;
|
|
393
|
+
|
|
394
|
+
float dist_sq = length_sq(c-point);
|
|
395
|
+
|
|
396
|
+
if (dist_sq < min_dist_sq)
|
|
397
|
+
{
|
|
398
|
+
min_dist_sq = dist_sq;
|
|
399
|
+
min_v = v;
|
|
400
|
+
min_w = w;
|
|
401
|
+
min_face = left_index;
|
|
402
|
+
}
|
|
163
403
|
|
|
164
404
|
#if BVH_DEBUG
|
|
165
405
|
|
|
166
|
-
|
|
406
|
+
tests++;
|
|
407
|
+
|
|
408
|
+
bounds3 b;
|
|
409
|
+
b = bounds_union(b, p);
|
|
410
|
+
b = bounds_union(b, q);
|
|
411
|
+
b = bounds_union(b, r);
|
|
412
|
+
|
|
413
|
+
if (distance_to_aabb_sq(point, b.lower, b.upper) < max_dist*max_dist)
|
|
414
|
+
{
|
|
415
|
+
//if (dist_sq < max_dist*max_dist)
|
|
416
|
+
test_history.push_back(left_index);
|
|
417
|
+
test_centers.push_back(b.center());
|
|
418
|
+
test_extents.push_back(b.edges());
|
|
419
|
+
}
|
|
420
|
+
#endif
|
|
421
|
+
|
|
422
|
+
}
|
|
423
|
+
else
|
|
424
|
+
{
|
|
425
|
+
BVHPackedNodeHalf left_lower = mesh.bvh.node_lowers[left_index];
|
|
426
|
+
BVHPackedNodeHalf left_upper = mesh.bvh.node_uppers[left_index];
|
|
427
|
+
|
|
428
|
+
BVHPackedNodeHalf right_lower = mesh.bvh.node_lowers[right_index];
|
|
429
|
+
BVHPackedNodeHalf right_upper = mesh.bvh.node_uppers[right_index];
|
|
430
|
+
|
|
431
|
+
float left_dist_sq = distance_to_aabb_sq(point, vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z));
|
|
432
|
+
float right_dist_sq = distance_to_aabb_sq(point, vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z));
|
|
433
|
+
|
|
434
|
+
float left_score = left_dist_sq;
|
|
435
|
+
float right_score = right_dist_sq;
|
|
436
|
+
|
|
437
|
+
if (left_score < right_score)
|
|
438
|
+
{
|
|
439
|
+
// put left on top of the stack
|
|
440
|
+
if (right_dist_sq < min_dist_sq)
|
|
441
|
+
stack[count++] = right_index;
|
|
442
|
+
|
|
443
|
+
if (left_dist_sq < min_dist_sq)
|
|
444
|
+
stack[count++] = left_index;
|
|
445
|
+
}
|
|
446
|
+
else
|
|
447
|
+
{
|
|
448
|
+
// put right on top of the stack
|
|
449
|
+
if (left_dist_sq < min_dist_sq)
|
|
450
|
+
stack[count++] = left_index;
|
|
451
|
+
|
|
452
|
+
if (right_dist_sq < min_dist_sq)
|
|
453
|
+
stack[count++] = right_index;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
167
458
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
459
|
+
#if BVH_DEBUG
|
|
460
|
+
printf("%d\n", tests);
|
|
461
|
+
|
|
462
|
+
static int max_tests = 0;
|
|
463
|
+
static vec3 max_point;
|
|
464
|
+
static float max_point_dist = 0.0f;
|
|
465
|
+
static int max_secondary_culls = 0;
|
|
466
|
+
|
|
467
|
+
if (secondary_culls > max_secondary_culls)
|
|
468
|
+
max_secondary_culls = secondary_culls;
|
|
469
|
+
|
|
470
|
+
if (tests > max_tests)
|
|
471
|
+
{
|
|
472
|
+
max_tests = tests;
|
|
473
|
+
max_point = point;
|
|
474
|
+
max_point_dist = sqrtf(min_dist_sq);
|
|
475
|
+
|
|
476
|
+
printf("max_tests: %d max_point: %f %f %f max_point_dist: %f max_second_culls: %d\n", max_tests, max_point[0], max_point[1], max_point[2], max_point_dist, max_secondary_culls);
|
|
477
|
+
|
|
478
|
+
FILE* f = fopen("test_history.txt", "w");
|
|
479
|
+
for (int i=0; i < test_history.size(); ++i)
|
|
480
|
+
{
|
|
481
|
+
fprintf(f, "%d, %f, %f, %f, %f, %f, %f\n",
|
|
482
|
+
test_history[i],
|
|
483
|
+
test_centers[i][0], test_centers[i][1], test_centers[i][2],
|
|
484
|
+
test_extents[i][0], test_extents[i][1], test_extents[i][2]);
|
|
485
|
+
}
|
|
172
486
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
//if (dist_sq < max_dist*max_dist)
|
|
176
|
-
test_history.push_back(left_index);
|
|
177
|
-
test_centers.push_back(b.center());
|
|
178
|
-
test_extents.push_back(b.edges());
|
|
179
|
-
}
|
|
487
|
+
fclose(f);
|
|
488
|
+
}
|
|
180
489
|
#endif
|
|
181
490
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
491
|
+
// check if we found a point, and write outputs
|
|
492
|
+
if (min_dist_sq < max_dist*max_dist)
|
|
493
|
+
{
|
|
494
|
+
u = 1.0f - min_v - min_w;
|
|
495
|
+
v = min_v;
|
|
496
|
+
face = min_face;
|
|
497
|
+
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
else
|
|
501
|
+
{
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// returns true if there is a point (strictly) > distance min_dist
|
|
507
|
+
CUDA_CALLABLE inline bool mesh_query_furthest_point_no_sign(uint64_t id, const vec3& point, float min_dist, int& face, float& u, float& v)
|
|
508
|
+
{
|
|
509
|
+
Mesh mesh = mesh_get(id);
|
|
510
|
+
|
|
511
|
+
int stack[32];
|
|
512
|
+
stack[0] = *mesh.bvh.root;
|
|
513
|
+
|
|
514
|
+
int count = 1;
|
|
515
|
+
|
|
516
|
+
float max_dist_sq = min_dist*min_dist;
|
|
517
|
+
int min_face;
|
|
518
|
+
float min_v;
|
|
519
|
+
float min_w;
|
|
187
520
|
|
|
188
|
-
|
|
189
|
-
|
|
521
|
+
#if BVH_DEBUG
|
|
522
|
+
int tests = 0;
|
|
523
|
+
int secondary_culls = 0;
|
|
190
524
|
|
|
191
|
-
|
|
192
|
-
|
|
525
|
+
std::vector<int> test_history;
|
|
526
|
+
std::vector<vec3> test_centers;
|
|
527
|
+
std::vector<vec3> test_extents;
|
|
528
|
+
#endif
|
|
193
529
|
|
|
530
|
+
while (count)
|
|
531
|
+
{
|
|
532
|
+
const int nodeIndex = stack[--count];
|
|
533
|
+
|
|
534
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
535
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
536
|
+
|
|
537
|
+
// re-test distance
|
|
538
|
+
float node_dist_sq = furthest_distance_to_aabb_sq(point, vec3(lower.x, lower.y, lower.z), vec3(upper.x, upper.y, upper.z));
|
|
539
|
+
|
|
540
|
+
// if maximum distance to this node is less than our existing furthest max then skip
|
|
541
|
+
if (node_dist_sq < max_dist_sq)
|
|
542
|
+
{
|
|
543
|
+
#if BVH_DEBUG
|
|
544
|
+
secondary_culls++;
|
|
545
|
+
#endif
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
194
548
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
//float right_score = bounds3(vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z)).area();
|
|
549
|
+
const int left_index = lower.i;
|
|
550
|
+
const int right_index = upper.i;
|
|
198
551
|
|
|
199
|
-
|
|
200
|
-
|
|
552
|
+
if (lower.b)
|
|
553
|
+
{
|
|
554
|
+
// compute closest point on tri
|
|
555
|
+
int i = mesh.indices[left_index*3+0];
|
|
556
|
+
int j = mesh.indices[left_index*3+1];
|
|
557
|
+
int k = mesh.indices[left_index*3+2];
|
|
558
|
+
|
|
559
|
+
vec3 p = mesh.points[i];
|
|
560
|
+
vec3 q = mesh.points[j];
|
|
561
|
+
vec3 r = mesh.points[k];
|
|
562
|
+
|
|
563
|
+
vec3 e0 = q-p;
|
|
564
|
+
vec3 e1 = r-p;
|
|
565
|
+
vec3 e2 = r-q;
|
|
566
|
+
vec3 normal = cross(e0, e1);
|
|
567
|
+
|
|
568
|
+
// sliver detection
|
|
569
|
+
if (length(normal)/(dot(e0,e0) + dot(e1,e1) + dot(e2,e2)) < 1.e-6f)
|
|
570
|
+
continue;
|
|
571
|
+
|
|
572
|
+
vec2 barycentric = furthest_point_to_triangle(p, q, r, point);
|
|
573
|
+
float u = barycentric[0];
|
|
574
|
+
float v = barycentric[1];
|
|
575
|
+
float w = 1.f - u - v;
|
|
576
|
+
vec3 c = u*p + v*q + w*r;
|
|
577
|
+
|
|
578
|
+
float dist_sq = length_sq(c-point);
|
|
579
|
+
|
|
580
|
+
if (dist_sq > max_dist_sq)
|
|
581
|
+
{
|
|
582
|
+
max_dist_sq = dist_sq;
|
|
583
|
+
min_v = v;
|
|
584
|
+
min_w = w;
|
|
585
|
+
min_face = left_index;
|
|
586
|
+
}
|
|
201
587
|
|
|
202
|
-
|
|
203
|
-
// if (left_score == right_score)
|
|
204
|
-
// {
|
|
205
|
-
// // use distance from box centroid to order children
|
|
206
|
-
// //left_score = -length_sq(point-bounds3(vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z)).center());
|
|
207
|
-
// //right_score = -length_sq(point-bounds3(vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z)).center());
|
|
208
|
-
// left_score = bounds3(vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z)).area();
|
|
209
|
-
// right_score = bounds3(vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z)).area();
|
|
588
|
+
#if BVH_DEBUG
|
|
210
589
|
|
|
211
|
-
|
|
590
|
+
tests++;
|
|
212
591
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (right_dist_sq < min_dist_sq)
|
|
218
|
-
stack[count++] = right_index;
|
|
592
|
+
bounds3 b;
|
|
593
|
+
b = bounds_union(b, p);
|
|
594
|
+
b = bounds_union(b, q);
|
|
595
|
+
b = bounds_union(b, r);
|
|
219
596
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
597
|
+
if (distance_to_aabb_sq(point, b.lower, b.upper) > max_dist*max_dist)
|
|
598
|
+
{
|
|
599
|
+
//if (dist_sq < max_dist*max_dist)
|
|
600
|
+
test_history.push_back(left_index);
|
|
601
|
+
test_centers.push_back(b.center());
|
|
602
|
+
test_extents.push_back(b.edges());
|
|
603
|
+
}
|
|
604
|
+
#endif
|
|
228
605
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
606
|
+
}
|
|
607
|
+
else
|
|
608
|
+
{
|
|
609
|
+
BVHPackedNodeHalf left_lower = mesh.bvh.node_lowers[left_index];
|
|
610
|
+
BVHPackedNodeHalf left_upper = mesh.bvh.node_uppers[left_index];
|
|
611
|
+
|
|
612
|
+
BVHPackedNodeHalf right_lower = mesh.bvh.node_lowers[right_index];
|
|
613
|
+
BVHPackedNodeHalf right_upper = mesh.bvh.node_uppers[right_index];
|
|
614
|
+
|
|
615
|
+
float left_dist_sq = furthest_distance_to_aabb_sq(point, vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z));
|
|
616
|
+
float right_dist_sq = furthest_distance_to_aabb_sq(point, vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z));
|
|
617
|
+
|
|
618
|
+
float left_score = left_dist_sq;
|
|
619
|
+
float right_score = right_dist_sq;
|
|
620
|
+
|
|
621
|
+
if (left_score > right_score)
|
|
622
|
+
{
|
|
623
|
+
// put left on top of the stack
|
|
624
|
+
if (right_dist_sq > max_dist_sq)
|
|
625
|
+
stack[count++] = right_index;
|
|
626
|
+
|
|
627
|
+
if (left_dist_sq > max_dist_sq)
|
|
628
|
+
stack[count++] = left_index;
|
|
629
|
+
}
|
|
630
|
+
else
|
|
631
|
+
{
|
|
632
|
+
// put right on top of the stack
|
|
633
|
+
if (left_dist_sq > max_dist_sq)
|
|
634
|
+
stack[count++] = left_index;
|
|
635
|
+
|
|
636
|
+
if (right_dist_sq > max_dist_sq)
|
|
637
|
+
stack[count++] = right_index;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
234
641
|
|
|
235
642
|
|
|
236
643
|
#if BVH_DEBUG
|
|
237
|
-
|
|
644
|
+
printf("%d\n", tests);
|
|
238
645
|
|
|
239
646
|
static int max_tests = 0;
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
647
|
+
static vec3 max_point;
|
|
648
|
+
static float max_point_dist = 0.0f;
|
|
649
|
+
static int max_secondary_culls = 0;
|
|
243
650
|
|
|
244
|
-
|
|
245
|
-
|
|
651
|
+
if (secondary_culls > max_secondary_culls)
|
|
652
|
+
max_secondary_culls = secondary_culls;
|
|
246
653
|
|
|
247
654
|
if (tests > max_tests)
|
|
248
|
-
|
|
655
|
+
{
|
|
249
656
|
max_tests = tests;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
657
|
+
max_point = point;
|
|
658
|
+
max_point_dist = sqrtf(max_dist_sq);
|
|
659
|
+
|
|
660
|
+
printf("max_tests: %d max_point: %f %f %f max_point_dist: %f max_second_culls: %d\n", max_tests, max_point[0], max_point[1], max_point[2], max_point_dist, max_secondary_culls);
|
|
661
|
+
|
|
662
|
+
FILE* f = fopen("test_history.txt", "w");
|
|
663
|
+
for (int i=0; i < test_history.size(); ++i)
|
|
664
|
+
{
|
|
665
|
+
fprintf(f, "%d, %f, %f, %f, %f, %f, %f\n",
|
|
666
|
+
test_history[i],
|
|
667
|
+
test_centers[i][0], test_centers[i][1], test_centers[i][2],
|
|
668
|
+
test_extents[i][0], test_extents[i][1], test_extents[i][2]);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
fclose(f);
|
|
672
|
+
}
|
|
266
673
|
#endif
|
|
267
674
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
{
|
|
282
|
-
return false;
|
|
283
|
-
}
|
|
675
|
+
// check if we found a point, and write outputs
|
|
676
|
+
if (max_dist_sq > min_dist*min_dist)
|
|
677
|
+
{
|
|
678
|
+
u = 1.0f - min_v - min_w;
|
|
679
|
+
v = min_v;
|
|
680
|
+
face = min_face;
|
|
681
|
+
|
|
682
|
+
return true;
|
|
683
|
+
}
|
|
684
|
+
else
|
|
685
|
+
{
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
284
688
|
}
|
|
285
689
|
|
|
286
|
-
|
|
287
|
-
|
|
690
|
+
// returns true if there is a point (strictly) < distance max_dist
|
|
691
|
+
CUDA_CALLABLE inline bool mesh_query_point_sign_normal(uint64_t id, const vec3& point, float max_dist, float& inside, int& face, float& u, float& v, const float epsilon = 1e-3f)
|
|
288
692
|
{
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
// face is determined by BVH in forward pass
|
|
292
|
-
int i = mesh.indices[face*3+0];
|
|
293
|
-
int j = mesh.indices[face*3+1];
|
|
294
|
-
int k = mesh.indices[face*3+2];
|
|
693
|
+
Mesh mesh = mesh_get(id);
|
|
295
694
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
695
|
+
int stack[32];
|
|
696
|
+
stack[0] = *mesh.bvh.root;
|
|
697
|
+
int count = 1;
|
|
698
|
+
float min_dist = max_dist;
|
|
699
|
+
int min_face;
|
|
700
|
+
float min_v;
|
|
701
|
+
float min_w;
|
|
702
|
+
vec3 accumulated_angle_weighted_normal;
|
|
703
|
+
#if BVH_DEBUG
|
|
704
|
+
int tests = 0;
|
|
705
|
+
int secondary_culls = 0;
|
|
706
|
+
std::vector<int> test_history;
|
|
707
|
+
std::vector<vec3> test_centers;
|
|
708
|
+
std::vector<vec3> test_extents;
|
|
709
|
+
#endif
|
|
710
|
+
float epsilon_min_dist = mesh.average_edge_length * epsilon;
|
|
711
|
+
float epsilon_min_dist_sq = epsilon_min_dist*epsilon_min_dist;
|
|
712
|
+
while (count)
|
|
713
|
+
{
|
|
714
|
+
const int nodeIndex = stack[--count];
|
|
715
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
716
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
717
|
+
// re-test distance
|
|
718
|
+
float node_dist_sq = distance_to_aabb_sq(point, vec3(lower.x, lower.y, lower.z), vec3(upper.x, upper.y, upper.z));
|
|
719
|
+
if (node_dist_sq > (min_dist + epsilon_min_dist)*(min_dist + epsilon_min_dist))
|
|
720
|
+
{
|
|
721
|
+
#if BVH_DEBUG
|
|
722
|
+
secondary_culls++;
|
|
723
|
+
#endif
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
const int left_index = lower.i;
|
|
727
|
+
const int right_index = upper.i;
|
|
728
|
+
if (lower.b)
|
|
729
|
+
{
|
|
730
|
+
// compute closest point on tri
|
|
731
|
+
int i = mesh.indices[left_index*3+0];
|
|
732
|
+
int j = mesh.indices[left_index*3+1];
|
|
733
|
+
int k = mesh.indices[left_index*3+2];
|
|
734
|
+
vec3 p = mesh.points[i];
|
|
735
|
+
vec3 q = mesh.points[j];
|
|
736
|
+
vec3 r = mesh.points[k];
|
|
737
|
+
vec3 e0 = q-p;
|
|
738
|
+
vec3 e1 = r-p;
|
|
739
|
+
vec3 e2 = r-q;
|
|
740
|
+
vec3 normal = cross(e0, e1);
|
|
741
|
+
// sliver detection
|
|
742
|
+
float e0_norm_sq = dot(e0,e0);
|
|
743
|
+
float e1_norm_sq = dot(e1,e1);
|
|
744
|
+
float e2_norm_sq = dot(e2,e2);
|
|
745
|
+
if (length(normal)/(e0_norm_sq + e1_norm_sq + e2_norm_sq) < 1.e-6f)
|
|
746
|
+
continue;
|
|
747
|
+
vec2 barycentric = closest_point_to_triangle(p, q, r, point);
|
|
748
|
+
float u = barycentric[0];
|
|
749
|
+
float v = barycentric[1];
|
|
750
|
+
float w = 1.f - u - v;
|
|
751
|
+
vec3 c = u*p + v*q + w*r;
|
|
752
|
+
float dist = sqrtf(length_sq(c-point));
|
|
753
|
+
if (dist < min_dist + epsilon_min_dist)
|
|
754
|
+
{
|
|
755
|
+
float weight = 0.0f;
|
|
756
|
+
vec3 cp = c-p;
|
|
757
|
+
vec3 cq = c-q;
|
|
758
|
+
vec3 cr = c-r;
|
|
759
|
+
float len_cp_sq = length_sq(cp);
|
|
760
|
+
float len_cq_sq = length_sq(cq);
|
|
761
|
+
float len_cr_sq = length_sq(cr);
|
|
762
|
+
|
|
763
|
+
// Check if near vertex
|
|
764
|
+
if (len_cp_sq < epsilon_min_dist_sq)
|
|
765
|
+
{
|
|
766
|
+
// Vertex 0 is the closest feature
|
|
767
|
+
weight = acosf(dot(normalize(e0), normalize(e1)));
|
|
768
|
+
} else
|
|
769
|
+
if (len_cq_sq < epsilon_min_dist_sq)
|
|
770
|
+
{
|
|
771
|
+
// Vertex 1 is the closest feature
|
|
772
|
+
weight = acosf(dot(normalize(e2), normalize(-e0)));
|
|
773
|
+
} else
|
|
774
|
+
if (len_cr_sq < epsilon_min_dist_sq)
|
|
775
|
+
{
|
|
776
|
+
// Vertex 2 is the closest feature
|
|
777
|
+
weight = acosf(dot(normalize(-e1), normalize(-e2)));
|
|
778
|
+
} else
|
|
779
|
+
{
|
|
780
|
+
float e0cp = dot(e0, cp);
|
|
781
|
+
float e2cq = dot(e2, cq);
|
|
782
|
+
float e1cp = dot(e1, cp);
|
|
783
|
+
|
|
784
|
+
if ((len_cp_sq*e0_norm_sq-e0cp*e0cp < epsilon_min_dist_sq*e0_norm_sq) ||
|
|
785
|
+
(len_cq_sq*e2_norm_sq-e2cq*e2cq < epsilon_min_dist_sq*e2_norm_sq) ||
|
|
786
|
+
(len_cp_sq*e1_norm_sq-e1cp*e1cp < epsilon_min_dist_sq*e1_norm_sq)) {
|
|
787
|
+
// One of the edge
|
|
788
|
+
weight = 3.14159265359f; // PI
|
|
789
|
+
} else {
|
|
790
|
+
weight = 2.0f*3.14159265359f; // 2*PI
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
if (dist > min_dist - epsilon_min_dist)
|
|
795
|
+
{
|
|
796
|
+
// Treat as equal
|
|
797
|
+
accumulated_angle_weighted_normal += weight*normalize(normal);
|
|
798
|
+
if (dist < min_dist)
|
|
799
|
+
{
|
|
800
|
+
min_dist = dist;
|
|
801
|
+
min_v = v;
|
|
802
|
+
min_w = w;
|
|
803
|
+
min_face = left_index;
|
|
804
|
+
}
|
|
805
|
+
} else {
|
|
806
|
+
// Less
|
|
807
|
+
min_dist = dist;
|
|
808
|
+
min_v = v;
|
|
809
|
+
min_w = w;
|
|
810
|
+
min_face = left_index;
|
|
811
|
+
accumulated_angle_weighted_normal = weight*normalize(normal);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
#if BVH_DEBUG
|
|
815
|
+
tests++;
|
|
816
|
+
bounds3 b;
|
|
817
|
+
b = bounds_union(b, p);
|
|
818
|
+
b = bounds_union(b, q);
|
|
819
|
+
b = bounds_union(b, r);
|
|
820
|
+
if (distance_to_aabb_sq(point, b.lower, b.upper) < (max_dist+epsilon_min_dist)*(max_dist+epsilon_min_dist))
|
|
821
|
+
{
|
|
822
|
+
//if (dist_sq < max_dist*max_dist)
|
|
823
|
+
test_history.push_back(left_index);
|
|
824
|
+
test_centers.push_back(b.center());
|
|
825
|
+
test_extents.push_back(b.edges());
|
|
826
|
+
}
|
|
827
|
+
#endif
|
|
828
|
+
}
|
|
829
|
+
else
|
|
830
|
+
{
|
|
831
|
+
BVHPackedNodeHalf left_lower = mesh.bvh.node_lowers[left_index];
|
|
832
|
+
BVHPackedNodeHalf left_upper = mesh.bvh.node_uppers[left_index];
|
|
833
|
+
BVHPackedNodeHalf right_lower = mesh.bvh.node_lowers[right_index];
|
|
834
|
+
BVHPackedNodeHalf right_upper = mesh.bvh.node_uppers[right_index];
|
|
835
|
+
|
|
836
|
+
float left_dist_sq = distance_to_aabb_sq(point, vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z));
|
|
837
|
+
float right_dist_sq = distance_to_aabb_sq(point, vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z));
|
|
838
|
+
|
|
839
|
+
float left_score = left_dist_sq;
|
|
840
|
+
float right_score = right_dist_sq;
|
|
841
|
+
|
|
842
|
+
if (left_score < right_score)
|
|
843
|
+
{
|
|
844
|
+
// put left on top of the stack
|
|
845
|
+
if (right_dist_sq < (min_dist + epsilon_min_dist) * (min_dist + epsilon_min_dist))
|
|
846
|
+
stack[count++] = right_index;
|
|
847
|
+
if (left_dist_sq < (min_dist + epsilon_min_dist) * (min_dist + epsilon_min_dist))
|
|
848
|
+
stack[count++] = left_index;
|
|
849
|
+
}
|
|
850
|
+
else
|
|
851
|
+
{
|
|
852
|
+
// put right on top of the stack
|
|
853
|
+
if (left_dist_sq < (min_dist + epsilon_min_dist) * (min_dist + epsilon_min_dist))
|
|
854
|
+
stack[count++] = left_index;
|
|
855
|
+
if (right_dist_sq < (min_dist + epsilon_min_dist) * (min_dist + epsilon_min_dist))
|
|
856
|
+
stack[count++] = right_index;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
#if BVH_DEBUG
|
|
861
|
+
printf("%d\n", tests);
|
|
862
|
+
static int max_tests = 0;
|
|
863
|
+
static vec3 max_point;
|
|
864
|
+
static float max_point_dist = 0.0f;
|
|
865
|
+
static int max_secondary_culls = 0;
|
|
866
|
+
if (secondary_culls > max_secondary_culls)
|
|
867
|
+
max_secondary_culls = secondary_culls;
|
|
868
|
+
if (tests > max_tests)
|
|
869
|
+
{
|
|
870
|
+
max_tests = tests;
|
|
871
|
+
max_point = point;
|
|
872
|
+
max_point_dist = min_dist;
|
|
873
|
+
printf("max_tests: %d max_point: %f %f %f max_point_dist: %f max_second_culls: %d\n", max_tests, max_point[0], max_point[1], max_point[2], max_point_dist, max_secondary_culls);
|
|
874
|
+
FILE* f = fopen("test_history.txt", "w");
|
|
875
|
+
for (int i=0; i < test_history.size(); ++i)
|
|
876
|
+
{
|
|
877
|
+
fprintf(f, "%d, %f, %f, %f, %f, %f, %f\n",
|
|
878
|
+
test_history[i],
|
|
879
|
+
test_centers[i][0], test_centers[i][1], test_centers[i][2],
|
|
880
|
+
test_extents[i][0], test_extents[i][1], test_extents[i][2]);
|
|
881
|
+
}
|
|
882
|
+
fclose(f);
|
|
883
|
+
}
|
|
884
|
+
#endif
|
|
885
|
+
// check if we found a point, and write outputs
|
|
886
|
+
if (min_dist < max_dist)
|
|
887
|
+
{
|
|
888
|
+
u = 1.0f - min_v - min_w;
|
|
889
|
+
v = min_v;
|
|
890
|
+
face = min_face;
|
|
891
|
+
// determine inside outside using ray-cast parity check
|
|
892
|
+
//inside = mesh_query_inside(id, point);
|
|
893
|
+
int i = mesh.indices[min_face*3+0];
|
|
894
|
+
int j = mesh.indices[min_face*3+1];
|
|
895
|
+
int k = mesh.indices[min_face*3+2];
|
|
896
|
+
vec3 p = mesh.points[i];
|
|
897
|
+
vec3 q = mesh.points[j];
|
|
898
|
+
vec3 r = mesh.points[k];
|
|
899
|
+
vec3 closest_point = p*u+q*v+r*min_w;
|
|
900
|
+
if (dot(accumulated_angle_weighted_normal, point-closest_point) > 0.0)
|
|
901
|
+
{
|
|
902
|
+
inside = 1.0f;
|
|
903
|
+
} else
|
|
904
|
+
{
|
|
905
|
+
inside = -1.0f;
|
|
906
|
+
}
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
909
|
+
else
|
|
910
|
+
{
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
CUDA_CALLABLE inline float solid_angle_iterative(uint64_t id, const vec3& p, const float accuracy_sq)
|
|
916
|
+
{
|
|
917
|
+
Mesh mesh = mesh_get(id);
|
|
299
918
|
|
|
300
|
-
|
|
919
|
+
int stack[32];
|
|
920
|
+
int at_child[32]; // 0 for left, 1 for right, 2 for done
|
|
921
|
+
float angle[32];
|
|
922
|
+
stack[0] = *mesh.bvh.root;
|
|
923
|
+
at_child[0] = 0;
|
|
301
924
|
|
|
302
|
-
|
|
925
|
+
int count = 1;
|
|
926
|
+
angle[0] = 0.0f;
|
|
303
927
|
|
|
304
|
-
|
|
928
|
+
while (count)
|
|
929
|
+
{
|
|
930
|
+
const int nodeIndex = stack[count - 1];
|
|
931
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
932
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
933
|
+
|
|
934
|
+
const int left_index = lower.i;
|
|
935
|
+
const int right_index = upper.i;
|
|
936
|
+
if (lower.b)
|
|
937
|
+
{
|
|
938
|
+
// compute closest point on tri
|
|
939
|
+
const int leaf_index = left_index;
|
|
940
|
+
angle[count - 1] = robust_solid_angle(mesh.points[mesh.indices[leaf_index*3+0]], mesh.points[mesh.indices[leaf_index*3+1]], mesh.points[mesh.indices[leaf_index*3+2]], p);
|
|
941
|
+
//printf("Leaf %d, got %f\n", leaf_index, my_data[count - 1]);
|
|
942
|
+
count--;
|
|
943
|
+
}
|
|
944
|
+
else
|
|
945
|
+
{
|
|
946
|
+
// See if I have to descend
|
|
947
|
+
if (at_child[count - 1] == 0)
|
|
948
|
+
{
|
|
949
|
+
// First visit
|
|
950
|
+
bool des = evaluate_node_solid_angle(p, &mesh.solid_angle_props[nodeIndex], angle[count - 1], accuracy_sq);
|
|
951
|
+
|
|
952
|
+
//printf("Non-Leaf %d, got %f\n", nodeIndex, angle[count - 1]);
|
|
953
|
+
if (des)
|
|
954
|
+
{
|
|
955
|
+
// Go left
|
|
956
|
+
stack[count] = left_index;
|
|
957
|
+
at_child[count - 1] = 1;
|
|
958
|
+
angle[count] = 0.0f;
|
|
959
|
+
at_child[count] = 0;
|
|
960
|
+
count++;
|
|
961
|
+
} else
|
|
962
|
+
{
|
|
963
|
+
// Does not descend done
|
|
964
|
+
count--;
|
|
965
|
+
}
|
|
966
|
+
} else
|
|
967
|
+
if (at_child[count - 1] == 1)
|
|
968
|
+
{
|
|
969
|
+
// Add data to parent
|
|
970
|
+
angle[count - 1] += angle[count];
|
|
971
|
+
// Go right
|
|
972
|
+
stack[count] = right_index;
|
|
973
|
+
at_child[count - 1] = 2;
|
|
974
|
+
angle[count] = 0.0f;
|
|
975
|
+
at_child[count] = 0;
|
|
976
|
+
count++;
|
|
977
|
+
} else {
|
|
978
|
+
// Descend both sides already
|
|
979
|
+
angle[count - 1] += angle[count];
|
|
980
|
+
count--;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return angle[0];
|
|
305
985
|
}
|
|
306
986
|
|
|
987
|
+
CUDA_CALLABLE inline float mesh_query_winding_number(uint64_t id, const vec3& p, const float accuracy)
|
|
988
|
+
{
|
|
989
|
+
float angle = solid_angle_iterative(id, p, accuracy*accuracy);
|
|
990
|
+
return angle * 0.07957747154; // divided by 4 PI
|
|
991
|
+
}
|
|
307
992
|
|
|
308
|
-
|
|
993
|
+
// returns true if there is a point (strictly) < distance max_dist
|
|
994
|
+
CUDA_CALLABLE inline bool mesh_query_point_sign_winding_number(uint64_t id, const vec3& point, float max_dist, float& inside, int& face, float& u, float& v, const float accuracy, const float winding_number_threshold)
|
|
995
|
+
{
|
|
996
|
+
Mesh mesh = mesh_get(id);
|
|
997
|
+
|
|
998
|
+
int stack[32];
|
|
999
|
+
stack[0] = *mesh.bvh.root;
|
|
1000
|
+
|
|
1001
|
+
int count = 1;
|
|
1002
|
+
|
|
1003
|
+
float min_dist_sq = max_dist*max_dist;
|
|
1004
|
+
int min_face;
|
|
1005
|
+
float min_v;
|
|
1006
|
+
float min_w;
|
|
1007
|
+
|
|
1008
|
+
#if BVH_DEBUG
|
|
1009
|
+
int tests = 0;
|
|
1010
|
+
int secondary_culls = 0;
|
|
1011
|
+
|
|
1012
|
+
std::vector<int> test_history;
|
|
1013
|
+
std::vector<vec3> test_centers;
|
|
1014
|
+
std::vector<vec3> test_extents;
|
|
1015
|
+
#endif
|
|
1016
|
+
|
|
1017
|
+
while (count)
|
|
1018
|
+
{
|
|
1019
|
+
const int nodeIndex = stack[--count];
|
|
1020
|
+
|
|
1021
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
1022
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
1023
|
+
|
|
1024
|
+
// re-test distance
|
|
1025
|
+
float node_dist_sq = distance_to_aabb_sq(point, vec3(lower.x, lower.y, lower.z), vec3(upper.x, upper.y, upper.z));
|
|
1026
|
+
if (node_dist_sq > min_dist_sq)
|
|
1027
|
+
{
|
|
1028
|
+
#if BVH_DEBUG
|
|
1029
|
+
secondary_culls++;
|
|
1030
|
+
#endif
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
const int left_index = lower.i;
|
|
1035
|
+
const int right_index = upper.i;
|
|
1036
|
+
|
|
1037
|
+
if (lower.b)
|
|
1038
|
+
{
|
|
1039
|
+
// compute closest point on tri
|
|
1040
|
+
int i = mesh.indices[left_index*3+0];
|
|
1041
|
+
int j = mesh.indices[left_index*3+1];
|
|
1042
|
+
int k = mesh.indices[left_index*3+2];
|
|
1043
|
+
|
|
1044
|
+
vec3 p = mesh.points[i];
|
|
1045
|
+
vec3 q = mesh.points[j];
|
|
1046
|
+
vec3 r = mesh.points[k];
|
|
1047
|
+
|
|
1048
|
+
vec3 e0 = q-p;
|
|
1049
|
+
vec3 e1 = r-p;
|
|
1050
|
+
vec3 e2 = r-q;
|
|
1051
|
+
vec3 normal = cross(e0, e1);
|
|
1052
|
+
|
|
1053
|
+
// sliver detection
|
|
1054
|
+
if (length(normal)/(dot(e0,e0) + dot(e1,e1) + dot(e2,e2)) < 1.e-6f)
|
|
1055
|
+
continue;
|
|
1056
|
+
|
|
1057
|
+
vec2 barycentric = closest_point_to_triangle(p, q, r, point);
|
|
1058
|
+
float u = barycentric[0];
|
|
1059
|
+
float v = barycentric[1];
|
|
1060
|
+
float w = 1.f - u - v;
|
|
1061
|
+
vec3 c = u*p + v*q + w*r;
|
|
1062
|
+
|
|
1063
|
+
float dist_sq = length_sq(c-point);
|
|
1064
|
+
|
|
1065
|
+
if (dist_sq < min_dist_sq)
|
|
1066
|
+
{
|
|
1067
|
+
min_dist_sq = dist_sq;
|
|
1068
|
+
min_v = v;
|
|
1069
|
+
min_w = w;
|
|
1070
|
+
min_face = left_index;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
#if BVH_DEBUG
|
|
1074
|
+
|
|
1075
|
+
tests++;
|
|
1076
|
+
|
|
1077
|
+
bounds3 b;
|
|
1078
|
+
b = bounds_union(b, p);
|
|
1079
|
+
b = bounds_union(b, q);
|
|
1080
|
+
b = bounds_union(b, r);
|
|
1081
|
+
|
|
1082
|
+
if (distance_to_aabb_sq(point, b.lower, b.upper) < max_dist*max_dist)
|
|
1083
|
+
{
|
|
1084
|
+
//if (dist_sq < max_dist*max_dist)
|
|
1085
|
+
test_history.push_back(left_index);
|
|
1086
|
+
test_centers.push_back(b.center());
|
|
1087
|
+
test_extents.push_back(b.edges());
|
|
1088
|
+
}
|
|
1089
|
+
#endif
|
|
1090
|
+
|
|
1091
|
+
}
|
|
1092
|
+
else
|
|
1093
|
+
{
|
|
1094
|
+
BVHPackedNodeHalf left_lower = mesh.bvh.node_lowers[left_index];
|
|
1095
|
+
BVHPackedNodeHalf left_upper = mesh.bvh.node_uppers[left_index];
|
|
1096
|
+
|
|
1097
|
+
BVHPackedNodeHalf right_lower = mesh.bvh.node_lowers[right_index];
|
|
1098
|
+
BVHPackedNodeHalf right_upper = mesh.bvh.node_uppers[right_index];
|
|
1099
|
+
|
|
1100
|
+
float left_dist_sq = distance_to_aabb_sq(point, vec3(left_lower.x, left_lower.y, left_lower.z), vec3(left_upper.x, left_upper.y, left_upper.z));
|
|
1101
|
+
float right_dist_sq = distance_to_aabb_sq(point, vec3(right_lower.x, right_lower.y, right_lower.z), vec3(right_upper.x, right_upper.y, right_upper.z));
|
|
1102
|
+
|
|
1103
|
+
float left_score = left_dist_sq;
|
|
1104
|
+
float right_score = right_dist_sq;
|
|
1105
|
+
|
|
1106
|
+
if (left_score < right_score)
|
|
1107
|
+
{
|
|
1108
|
+
// put left on top of the stack
|
|
1109
|
+
if (right_dist_sq < min_dist_sq)
|
|
1110
|
+
stack[count++] = right_index;
|
|
1111
|
+
|
|
1112
|
+
if (left_dist_sq < min_dist_sq)
|
|
1113
|
+
stack[count++] = left_index;
|
|
1114
|
+
}
|
|
1115
|
+
else
|
|
1116
|
+
{
|
|
1117
|
+
// put right on top of the stack
|
|
1118
|
+
if (left_dist_sq < min_dist_sq)
|
|
1119
|
+
stack[count++] = left_index;
|
|
1120
|
+
|
|
1121
|
+
if (right_dist_sq < min_dist_sq)
|
|
1122
|
+
stack[count++] = right_index;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
#if BVH_DEBUG
|
|
1129
|
+
printf("%d\n", tests);
|
|
1130
|
+
|
|
1131
|
+
static int max_tests = 0;
|
|
1132
|
+
static vec3 max_point;
|
|
1133
|
+
static float max_point_dist = 0.0f;
|
|
1134
|
+
static int max_secondary_culls = 0;
|
|
1135
|
+
|
|
1136
|
+
if (secondary_culls > max_secondary_culls)
|
|
1137
|
+
max_secondary_culls = secondary_culls;
|
|
1138
|
+
|
|
1139
|
+
if (tests > max_tests)
|
|
1140
|
+
{
|
|
1141
|
+
max_tests = tests;
|
|
1142
|
+
max_point = point;
|
|
1143
|
+
max_point_dist = sqrtf(min_dist_sq);
|
|
1144
|
+
|
|
1145
|
+
printf("max_tests: %d max_point: %f %f %f max_point_dist: %f max_second_culls: %d\n", max_tests, max_point[0], max_point[1], max_point[2], max_point_dist, max_secondary_culls);
|
|
1146
|
+
|
|
1147
|
+
FILE* f = fopen("test_history.txt", "w");
|
|
1148
|
+
for (int i=0; i < test_history.size(); ++i)
|
|
1149
|
+
{
|
|
1150
|
+
fprintf(f, "%d, %f, %f, %f, %f, %f, %f\n",
|
|
1151
|
+
test_history[i],
|
|
1152
|
+
test_centers[i][0], test_centers[i][1], test_centers[i][2],
|
|
1153
|
+
test_extents[i][0], test_extents[i][1], test_extents[i][2]);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
fclose(f);
|
|
1157
|
+
}
|
|
1158
|
+
#endif
|
|
1159
|
+
|
|
1160
|
+
// check if we found a point, and write outputs
|
|
1161
|
+
if (min_dist_sq < max_dist*max_dist)
|
|
1162
|
+
{
|
|
1163
|
+
u = 1.0f - min_v - min_w;
|
|
1164
|
+
v = min_v;
|
|
1165
|
+
face = min_face;
|
|
1166
|
+
|
|
1167
|
+
// determine inside outside using ray-cast parity check
|
|
1168
|
+
if (!mesh.solid_angle_props) {
|
|
1169
|
+
inside = mesh_query_inside(id, point);
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
float winding_number = mesh_query_winding_number(id, point, accuracy);
|
|
1173
|
+
inside = (winding_number > winding_number_threshold) ? -1.0f:1.0f;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
return true;
|
|
1177
|
+
}
|
|
1178
|
+
else
|
|
1179
|
+
{
|
|
1180
|
+
return false;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
CUDA_CALLABLE inline void adj_mesh_query_point_no_sign(uint64_t id, const vec3& point, float max_dist, const int& face, const float& u, const float& v,
|
|
1185
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, int& adj_face, float& adj_u, float& adj_v, bool& adj_ret)
|
|
1186
|
+
{
|
|
1187
|
+
Mesh mesh = mesh_get(id);
|
|
1188
|
+
|
|
1189
|
+
// face is determined by BVH in forward pass
|
|
1190
|
+
int i = mesh.indices[face*3+0];
|
|
1191
|
+
int j = mesh.indices[face*3+1];
|
|
1192
|
+
int k = mesh.indices[face*3+2];
|
|
1193
|
+
|
|
1194
|
+
vec3 p = mesh.points[i];
|
|
1195
|
+
vec3 q = mesh.points[j];
|
|
1196
|
+
vec3 r = mesh.points[k];
|
|
1197
|
+
|
|
1198
|
+
vec3 adj_p, adj_q, adj_r;
|
|
1199
|
+
|
|
1200
|
+
vec2 adj_uv(adj_u, adj_v);
|
|
1201
|
+
|
|
1202
|
+
adj_closest_point_to_triangle(p, q, r, point, adj_p, adj_q, adj_r, adj_point, adj_uv);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
CUDA_CALLABLE inline void adj_mesh_query_furthest_point_no_sign(uint64_t id, const vec3& point, float min_dist, const int& face, const float& u, const float& v,
|
|
1206
|
+
uint64_t adj_id, vec3& adj_point, float& adj_min_dist, int& adj_face, float& adj_u, float& adj_v, bool& adj_ret)
|
|
309
1207
|
{
|
|
310
1208
|
Mesh mesh = mesh_get(id);
|
|
1209
|
+
|
|
1210
|
+
// face is determined by BVH in forward pass
|
|
1211
|
+
int i = mesh.indices[face*3+0];
|
|
1212
|
+
int j = mesh.indices[face*3+1];
|
|
1213
|
+
int k = mesh.indices[face*3+2];
|
|
1214
|
+
|
|
1215
|
+
vec3 p = mesh.points[i];
|
|
1216
|
+
vec3 q = mesh.points[j];
|
|
1217
|
+
vec3 r = mesh.points[k];
|
|
1218
|
+
|
|
1219
|
+
vec3 adj_p, adj_q, adj_r;
|
|
1220
|
+
|
|
1221
|
+
vec2 adj_uv(adj_u, adj_v);
|
|
1222
|
+
|
|
1223
|
+
adj_closest_point_to_triangle(p, q, r, point, adj_p, adj_q, adj_r, adj_point, adj_uv); // Todo for Miles :>
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
CUDA_CALLABLE inline void adj_mesh_query_point(uint64_t id, const vec3& point, float max_dist, const float& inside, const int& face, const float& u, const float& v,
|
|
1227
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, float& adj_inside, int& adj_face, float& adj_u, float& adj_v, bool& adj_ret)
|
|
1228
|
+
{
|
|
1229
|
+
adj_mesh_query_point_no_sign(id, point, max_dist, face, u, v, adj_id, adj_point, adj_max_dist, adj_face, adj_u, adj_v, adj_ret);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
CUDA_CALLABLE inline void adj_mesh_query_point_sign_normal(uint64_t id, const vec3& point, float max_dist, const float& inside, const int& face, const float& u, const float& v, const float epsilon,
|
|
1233
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, float& adj_inside, int& adj_face, float& adj_u, float& adj_v, float& adj_epsilon, bool& adj_ret)
|
|
1234
|
+
{
|
|
1235
|
+
adj_mesh_query_point_no_sign(id, point, max_dist, face, u, v, adj_id, adj_point, adj_max_dist, adj_face, adj_u, adj_v, adj_ret);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
CUDA_CALLABLE inline void adj_mesh_query_point_sign_winding_number(uint64_t id, const vec3& point, float max_dist, const float& inside, const int& face, const float& u, const float& v, const float accuracy, const float winding_number_threshold,
|
|
1239
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, float& adj_inside, int& adj_face, float& adj_u, float& adj_v, float& adj_accuracy, float& adj_winding_number_threshold, bool& adj_ret)
|
|
1240
|
+
{
|
|
1241
|
+
adj_mesh_query_point_no_sign(id, point, max_dist, face, u, v, adj_id, adj_point, adj_max_dist, adj_face, adj_u, adj_v, adj_ret);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
|
|
1245
|
+
// Stores the result of querying the closest point on a mesh.
|
|
1246
|
+
struct mesh_query_point_t
|
|
1247
|
+
{
|
|
1248
|
+
CUDA_CALLABLE mesh_query_point_t()
|
|
1249
|
+
: result(false),
|
|
1250
|
+
sign(0.0f),
|
|
1251
|
+
face(0),
|
|
1252
|
+
u(0.0f),
|
|
1253
|
+
v(0.0f)
|
|
1254
|
+
{}
|
|
1255
|
+
|
|
1256
|
+
// Required for adjoint computations.
|
|
1257
|
+
CUDA_CALLABLE inline mesh_query_point_t& operator+=(const mesh_query_point_t& other)
|
|
1258
|
+
{
|
|
1259
|
+
result += other.result;
|
|
1260
|
+
sign += other.sign;
|
|
1261
|
+
face += other.face;
|
|
1262
|
+
u += other.u;
|
|
1263
|
+
v += other.v;
|
|
1264
|
+
return *this;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
bool result;
|
|
1268
|
+
float sign;
|
|
1269
|
+
int face;
|
|
1270
|
+
float u;
|
|
1271
|
+
float v;
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
CUDA_CALLABLE inline mesh_query_point_t mesh_query_point(uint64_t id, const vec3& point, float max_dist)
|
|
1275
|
+
{
|
|
1276
|
+
mesh_query_point_t query;
|
|
1277
|
+
query.result = mesh_query_point(id, point, max_dist, query.sign, query.face, query.u, query.v);
|
|
1278
|
+
return query;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
CUDA_CALLABLE inline mesh_query_point_t mesh_query_point_no_sign(uint64_t id, const vec3& point, float max_dist)
|
|
1282
|
+
{
|
|
1283
|
+
mesh_query_point_t query;
|
|
1284
|
+
query.sign = 0.0;
|
|
1285
|
+
query.result = mesh_query_point_no_sign(id, point, max_dist, query.face, query.u, query.v);
|
|
1286
|
+
return query;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
CUDA_CALLABLE inline mesh_query_point_t mesh_query_furthest_point_no_sign(uint64_t id, const vec3& point, float min_dist)
|
|
1290
|
+
{
|
|
1291
|
+
mesh_query_point_t query;
|
|
1292
|
+
query.sign = 0.0;
|
|
1293
|
+
query.result = mesh_query_furthest_point_no_sign(id, point, min_dist, query.face, query.u, query.v);
|
|
1294
|
+
return query;
|
|
1295
|
+
}
|
|
311
1296
|
|
|
312
|
-
|
|
313
|
-
|
|
1297
|
+
CUDA_CALLABLE inline mesh_query_point_t mesh_query_point_sign_normal(uint64_t id, const vec3& point, float max_dist, const float epsilon = 1e-3f)
|
|
1298
|
+
{
|
|
1299
|
+
mesh_query_point_t query;
|
|
1300
|
+
query.result = mesh_query_point_sign_normal(id, point, max_dist, query.sign, query.face, query.u, query.v, epsilon);
|
|
1301
|
+
return query;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
CUDA_CALLABLE inline mesh_query_point_t mesh_query_point_sign_winding_number(uint64_t id, const vec3& point, float max_dist, float accuracy, float winding_number_threshold)
|
|
1305
|
+
{
|
|
1306
|
+
mesh_query_point_t query;
|
|
1307
|
+
query.result = mesh_query_point_sign_winding_number(id, point, max_dist, query.sign, query.face, query.u, query.v, accuracy, winding_number_threshold);
|
|
1308
|
+
return query;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
CUDA_CALLABLE inline void adj_mesh_query_point(uint64_t id, const vec3& point, float max_dist, const mesh_query_point_t& ret,
|
|
1312
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, mesh_query_point_t& adj_ret)
|
|
1313
|
+
{
|
|
1314
|
+
adj_mesh_query_point(id, point, max_dist, ret.sign, ret.face, ret.u, ret.v,
|
|
1315
|
+
adj_id, adj_point, adj_max_dist, adj_ret.sign, adj_ret.face, adj_ret.u, adj_ret.v, adj_ret.result);
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
CUDA_CALLABLE inline void adj_mesh_query_point_no_sign(uint64_t id, const vec3& point, float max_dist, const mesh_query_point_t& ret,
|
|
1319
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, mesh_query_point_t& adj_ret)
|
|
1320
|
+
{
|
|
1321
|
+
adj_mesh_query_point_no_sign(id, point, max_dist, ret.face, ret.u, ret.v,
|
|
1322
|
+
adj_id, adj_point, adj_max_dist, adj_ret.face, adj_ret.u, adj_ret.v, adj_ret.result);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
CUDA_CALLABLE inline void adj_mesh_query_furthest_point_no_sign(uint64_t id, const vec3& point, float min_dist, const mesh_query_point_t& ret,
|
|
1326
|
+
uint64_t adj_id, vec3& adj_point, float& adj_min_dist, mesh_query_point_t& adj_ret)
|
|
1327
|
+
{
|
|
1328
|
+
adj_mesh_query_furthest_point_no_sign(id, point, min_dist, ret.face, ret.u, ret.v,
|
|
1329
|
+
adj_id, adj_point, adj_min_dist, adj_ret.face, adj_ret.u, adj_ret.v, adj_ret.result);
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
CUDA_CALLABLE inline void adj_mesh_query_point_sign_normal(uint64_t id, const vec3& point, float max_dist, float epsilon, const mesh_query_point_t& ret,
|
|
1333
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, float& adj_epsilon, mesh_query_point_t& adj_ret)
|
|
1334
|
+
{
|
|
1335
|
+
adj_mesh_query_point_sign_normal(id, point, max_dist, ret.sign, ret.face, ret.u, ret.v, epsilon,
|
|
1336
|
+
adj_id, adj_point, adj_max_dist, adj_ret.sign, adj_ret.face, adj_ret.u, adj_ret.v, epsilon, adj_ret.result);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
CUDA_CALLABLE inline void adj_mesh_query_point_sign_winding_number(uint64_t id, const vec3& point, float max_dist, float accuracy, float winding_number_threshold, const mesh_query_point_t& ret,
|
|
1340
|
+
uint64_t adj_id, vec3& adj_point, float& adj_max_dist, float& adj_accuracy, float& adj_winding_number_threshold, mesh_query_point_t& adj_ret)
|
|
1341
|
+
{
|
|
1342
|
+
adj_mesh_query_point_sign_winding_number(id, point, max_dist, ret.sign, ret.face, ret.u, ret.v, accuracy, winding_number_threshold,
|
|
1343
|
+
adj_id, adj_point, adj_max_dist, adj_ret.sign, adj_ret.face, adj_ret.u, adj_ret.v, adj_accuracy, adj_winding_number_threshold, adj_ret.result);
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
CUDA_CALLABLE inline bool mesh_query_ray(uint64_t id, const vec3& start, const vec3& dir, float max_t, float& t, float& u, float& v, float& sign, vec3& normal, int& face)
|
|
1347
|
+
{
|
|
1348
|
+
Mesh mesh = mesh_get(id);
|
|
314
1349
|
|
|
315
1350
|
int stack[32];
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
1351
|
+
stack[0] = *mesh.bvh.root;
|
|
1352
|
+
int count = 1;
|
|
1353
|
+
|
|
1354
|
+
vec3 rcp_dir = vec3(1.0f/dir[0], 1.0f/dir[1], 1.0f/dir[2]);
|
|
1355
|
+
|
|
1356
|
+
float min_t = max_t;
|
|
1357
|
+
int min_face;
|
|
1358
|
+
float min_u;
|
|
1359
|
+
float min_v;
|
|
1360
|
+
float min_sign = 1.0f;
|
|
1361
|
+
vec3 min_normal;
|
|
1362
|
+
|
|
1363
|
+
while (count)
|
|
1364
|
+
{
|
|
1365
|
+
const int nodeIndex = stack[--count];
|
|
1366
|
+
|
|
1367
|
+
BVHPackedNodeHalf lower = mesh.bvh.node_lowers[nodeIndex];
|
|
1368
|
+
BVHPackedNodeHalf upper = mesh.bvh.node_uppers[nodeIndex];
|
|
1369
|
+
|
|
1370
|
+
// todo: switch to robust ray-aabb, or expand bounds in build stage
|
|
1371
|
+
float eps = 1.e-3f;
|
|
1372
|
+
float t = 0.0f;
|
|
1373
|
+
bool hit = intersect_ray_aabb(start, rcp_dir, vec3(lower.x-eps, lower.y-eps, lower.z-eps), vec3(upper.x+eps, upper.y+eps, upper.z+eps), t);
|
|
1374
|
+
|
|
1375
|
+
if (hit && t < min_t)
|
|
1376
|
+
{
|
|
1377
|
+
const int left_index = lower.i;
|
|
1378
|
+
const int right_index = upper.i;
|
|
1379
|
+
|
|
1380
|
+
if (lower.b)
|
|
1381
|
+
{
|
|
1382
|
+
// compute closest point on tri
|
|
1383
|
+
int i = mesh.indices[left_index*3+0];
|
|
1384
|
+
int j = mesh.indices[left_index*3+1];
|
|
1385
|
+
int k = mesh.indices[left_index*3+2];
|
|
1386
|
+
|
|
1387
|
+
vec3 p = mesh.points[i];
|
|
1388
|
+
vec3 q = mesh.points[j];
|
|
1389
|
+
vec3 r = mesh.points[k];
|
|
1390
|
+
|
|
1391
|
+
float t, u, v, sign;
|
|
1392
|
+
vec3 n;
|
|
1393
|
+
|
|
1394
|
+
if (intersect_ray_tri_woop(start, dir, p, q, r, t, u, v, sign, &n))
|
|
1395
|
+
{
|
|
1396
|
+
if (t < min_t && t >= 0.0f)
|
|
1397
|
+
{
|
|
1398
|
+
min_t = t;
|
|
1399
|
+
min_face = left_index;
|
|
1400
|
+
min_u = u;
|
|
1401
|
+
min_v = v;
|
|
1402
|
+
min_sign = sign;
|
|
1403
|
+
min_normal = n;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
else
|
|
1408
|
+
{
|
|
1409
|
+
stack[count++] = left_index;
|
|
1410
|
+
stack[count++] = right_index;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
if (min_t < max_t)
|
|
1416
|
+
{
|
|
1417
|
+
// write outputs
|
|
1418
|
+
u = min_u;
|
|
1419
|
+
v = min_v;
|
|
1420
|
+
sign = min_sign;
|
|
1421
|
+
t = min_t;
|
|
1422
|
+
normal = normalize(min_normal);
|
|
1423
|
+
face = min_face;
|
|
1424
|
+
|
|
1425
|
+
return true;
|
|
1426
|
+
}
|
|
1427
|
+
else
|
|
1428
|
+
{
|
|
1429
|
+
return false;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
397
1432
|
}
|
|
398
1433
|
|
|
399
1434
|
|
|
400
1435
|
CUDA_CALLABLE inline void adj_mesh_query_ray(
|
|
401
|
-
|
|
402
|
-
|
|
1436
|
+
uint64_t id, const vec3& start, const vec3& dir, float max_t, float t, float u, float v, float sign, const vec3& n, int face,
|
|
1437
|
+
uint64_t adj_id, vec3& adj_start, vec3& adj_dir, float& adj_max_t, float& adj_t, float& adj_u, float& adj_v, float& adj_sign, vec3& adj_n, int& adj_face, bool& adj_ret)
|
|
403
1438
|
{
|
|
404
1439
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
1440
|
+
Mesh mesh = mesh_get(id);
|
|
1441
|
+
|
|
1442
|
+
// face is determined by BVH in forward pass
|
|
1443
|
+
int i = mesh.indices[face*3+0];
|
|
1444
|
+
int j = mesh.indices[face*3+1];
|
|
1445
|
+
int k = mesh.indices[face*3+2];
|
|
411
1446
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
1447
|
+
vec3 a = mesh.points[i];
|
|
1448
|
+
vec3 b = mesh.points[j];
|
|
1449
|
+
vec3 c = mesh.points[k];
|
|
415
1450
|
|
|
416
|
-
|
|
1451
|
+
vec3 adj_a, adj_b, adj_c;
|
|
417
1452
|
|
|
418
|
-
|
|
1453
|
+
adj_intersect_ray_tri_woop(start, dir, a, b, c, t, u, v, sign, n, adj_start, adj_dir, adj_a, adj_b, adj_c, adj_t, adj_u, adj_v, adj_sign, adj_n, adj_ret);
|
|
419
1454
|
|
|
420
1455
|
}
|
|
421
1456
|
|
|
422
1457
|
|
|
1458
|
+
// Stores the result of querying the closest point on a mesh.
|
|
1459
|
+
struct mesh_query_ray_t
|
|
1460
|
+
{
|
|
1461
|
+
CUDA_CALLABLE mesh_query_ray_t()
|
|
1462
|
+
: result(false),
|
|
1463
|
+
sign(0.0f),
|
|
1464
|
+
face(0),
|
|
1465
|
+
t(0.0f),
|
|
1466
|
+
u(0.0f),
|
|
1467
|
+
v(0.0f),
|
|
1468
|
+
normal()
|
|
1469
|
+
{
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
// Required for adjoint computations.
|
|
1473
|
+
CUDA_CALLABLE inline mesh_query_ray_t& operator+=(const mesh_query_ray_t& other)
|
|
1474
|
+
{
|
|
1475
|
+
result += other.result;
|
|
1476
|
+
sign += other.sign;
|
|
1477
|
+
face += other.face;
|
|
1478
|
+
t += other.t;
|
|
1479
|
+
u += other.u;
|
|
1480
|
+
v += other.v;
|
|
1481
|
+
normal += other.normal;
|
|
1482
|
+
return *this;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
bool result;
|
|
1486
|
+
float sign;
|
|
1487
|
+
int face;
|
|
1488
|
+
float t;
|
|
1489
|
+
float u;
|
|
1490
|
+
float v;
|
|
1491
|
+
vec3 normal;
|
|
1492
|
+
};
|
|
1493
|
+
|
|
1494
|
+
CUDA_CALLABLE inline mesh_query_ray_t mesh_query_ray(uint64_t id, const vec3& start, const vec3& dir, float max_t)
|
|
1495
|
+
{
|
|
1496
|
+
mesh_query_ray_t query;
|
|
1497
|
+
query.result = mesh_query_ray(id, start, dir, max_t, query.t, query.u, query.v, query.sign, query.normal, query.face);
|
|
1498
|
+
return query;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
CUDA_CALLABLE inline void
|
|
1502
|
+
adj_mesh_query_ray(
|
|
1503
|
+
uint64_t id, const vec3& start, const vec3& dir, float max_t, const mesh_query_ray_t& ret,
|
|
1504
|
+
uint64_t adj_id, vec3& adj_start, vec3& adj_dir, float& adj_max_t, mesh_query_ray_t& adj_ret
|
|
1505
|
+
)
|
|
1506
|
+
{
|
|
1507
|
+
adj_mesh_query_ray(
|
|
1508
|
+
id, start, dir, max_t, ret.t, ret.u, ret.v, ret.sign, ret.normal, ret.face,
|
|
1509
|
+
adj_id, adj_start, adj_dir, adj_max_t, adj_ret.t, adj_ret.u, adj_ret.v, adj_ret.sign, adj_ret.normal, adj_ret.face, adj_ret.result
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
|
|
423
1514
|
// determine if a point is inside (ret < 0 ) or outside the mesh (ret > 0)
|
|
424
1515
|
CUDA_CALLABLE inline float mesh_query_inside(uint64_t id, const vec3& p)
|
|
425
1516
|
{
|
|
426
1517
|
float t, u, v, sign;
|
|
427
|
-
|
|
428
|
-
|
|
1518
|
+
vec3 n;
|
|
1519
|
+
int face;
|
|
429
1520
|
|
|
430
|
-
|
|
1521
|
+
int vote = 0;
|
|
431
1522
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
1523
|
+
for(int i = 0; i <3; ++i)
|
|
1524
|
+
{
|
|
1525
|
+
if (mesh_query_ray(id, p, vec3(float(i==0), float(i==1), float(i==2)), FLT_MAX, t, u, v, sign, n, face) && sign < 0)
|
|
1526
|
+
{
|
|
1527
|
+
vote++;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
437
1530
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
1531
|
+
if (vote == 3)
|
|
1532
|
+
return -1.0f;
|
|
1533
|
+
else
|
|
1534
|
+
return 1.0f;
|
|
442
1535
|
}
|
|
443
1536
|
|
|
444
|
-
|
|
445
1537
|
// stores state required to traverse the BVH nodes that
|
|
446
1538
|
// overlap with a query AABB.
|
|
447
1539
|
struct mesh_query_aabb_t
|
|
448
1540
|
{
|
|
449
1541
|
CUDA_CALLABLE mesh_query_aabb_t()
|
|
1542
|
+
: mesh(),
|
|
1543
|
+
stack(),
|
|
1544
|
+
count(0),
|
|
1545
|
+
input_lower(),
|
|
1546
|
+
input_upper(),
|
|
1547
|
+
face(0)
|
|
1548
|
+
{}
|
|
1549
|
+
|
|
1550
|
+
// Required for adjoint computations.
|
|
1551
|
+
CUDA_CALLABLE inline mesh_query_aabb_t& operator+=(const mesh_query_aabb_t& other)
|
|
450
1552
|
{
|
|
1553
|
+
return *this;
|
|
451
1554
|
}
|
|
452
|
-
CUDA_CALLABLE mesh_query_aabb_t(int)
|
|
453
|
-
{
|
|
454
|
-
} // for backward pass
|
|
455
1555
|
|
|
456
1556
|
// Mesh Id
|
|
457
1557
|
Mesh mesh;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
1558
|
+
// BVH traversal stack:
|
|
1559
|
+
int stack[32];
|
|
1560
|
+
int count;
|
|
461
1561
|
|
|
462
1562
|
// inputs
|
|
463
1563
|
wp::vec3 input_lower;
|
|
464
1564
|
wp::vec3 input_upper;
|
|
465
1565
|
|
|
466
|
-
|
|
467
|
-
|
|
1566
|
+
// Face
|
|
1567
|
+
int face;
|
|
468
1568
|
};
|
|
469
1569
|
|
|
470
1570
|
|
|
@@ -473,72 +1573,62 @@ CUDA_CALLABLE inline mesh_query_aabb_t mesh_query_aabb(
|
|
|
473
1573
|
uint64_t id, const vec3& lower, const vec3& upper)
|
|
474
1574
|
{
|
|
475
1575
|
// This routine traverses the BVH tree until it finds
|
|
476
|
-
|
|
1576
|
+
// the first triangle with an overlapping bvh.
|
|
477
1577
|
|
|
478
1578
|
// initialize empty
|
|
479
|
-
|
|
480
|
-
|
|
1579
|
+
mesh_query_aabb_t query;
|
|
1580
|
+
query.face = -1;
|
|
481
1581
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
if (mesh.bvh.num_nodes == 0)
|
|
488
|
-
{
|
|
489
|
-
query.count = 0;
|
|
490
|
-
return query;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// optimization: make the latest
|
|
494
|
-
|
|
495
|
-
query.stack[0] = mesh.bvh.root;
|
|
496
|
-
query.count = 1;
|
|
1582
|
+
Mesh mesh = mesh_get(id);
|
|
1583
|
+
query.mesh = mesh;
|
|
1584
|
+
|
|
1585
|
+
query.stack[0] = *mesh.bvh.root;
|
|
1586
|
+
query.count = 1;
|
|
497
1587
|
query.input_lower = lower;
|
|
498
1588
|
query.input_upper = upper;
|
|
499
1589
|
|
|
500
1590
|
wp::bounds3 input_bounds(query.input_lower, query.input_upper);
|
|
501
|
-
|
|
1591
|
+
|
|
502
1592
|
// Navigate through the bvh, find the first overlapping leaf node.
|
|
503
1593
|
while (query.count)
|
|
504
1594
|
{
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
1595
|
+
const int nodeIndex = query.stack[--query.count];
|
|
1596
|
+
BVHPackedNodeHalf node_lower = mesh.bvh.node_lowers[nodeIndex];
|
|
1597
|
+
BVHPackedNodeHalf node_upper = mesh.bvh.node_uppers[nodeIndex];
|
|
508
1598
|
|
|
509
|
-
|
|
510
|
-
|
|
1599
|
+
wp::vec3 lower_pos(node_lower.x, node_lower.y, node_lower.z);
|
|
1600
|
+
wp::vec3 upper_pos(node_upper.x, node_upper.y, node_upper.z);
|
|
511
1601
|
wp::bounds3 current_bounds(lower_pos, upper_pos);
|
|
512
1602
|
if (!input_bounds.overlaps(current_bounds))
|
|
513
1603
|
{
|
|
514
1604
|
// Skip this box, it doesn't overlap with our target box.
|
|
515
|
-
|
|
516
|
-
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
517
1607
|
|
|
518
|
-
|
|
519
|
-
|
|
1608
|
+
const int left_index = node_lower.i;
|
|
1609
|
+
const int right_index = node_upper.i;
|
|
520
1610
|
|
|
521
1611
|
// Make bounds from this AABB
|
|
522
1612
|
if (node_lower.b)
|
|
523
1613
|
{
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
1614
|
+
// found very first triangle index.
|
|
1615
|
+
// Back up one level and return
|
|
1616
|
+
query.stack[query.count++] = nodeIndex;
|
|
1617
|
+
return query;
|
|
528
1618
|
}
|
|
529
1619
|
else
|
|
530
1620
|
{
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
1621
|
+
query.stack[query.count++] = left_index;
|
|
1622
|
+
query.stack[query.count++] = right_index;
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
535
1625
|
|
|
536
|
-
|
|
1626
|
+
return query;
|
|
537
1627
|
}
|
|
538
1628
|
|
|
539
1629
|
//Stub
|
|
540
1630
|
CUDA_CALLABLE inline void adj_mesh_query_aabb(uint64_t id, const vec3& lower, const vec3& upper,
|
|
541
|
-
|
|
1631
|
+
uint64_t, vec3&, vec3&, mesh_query_aabb_t&)
|
|
542
1632
|
{
|
|
543
1633
|
|
|
544
1634
|
}
|
|
@@ -546,8 +1636,8 @@ CUDA_CALLABLE inline void adj_mesh_query_aabb(uint64_t id, const vec3& lower, co
|
|
|
546
1636
|
CUDA_CALLABLE inline bool mesh_query_aabb_next(mesh_query_aabb_t& query, int& index)
|
|
547
1637
|
{
|
|
548
1638
|
Mesh mesh = query.mesh;
|
|
549
|
-
|
|
550
|
-
|
|
1639
|
+
|
|
1640
|
+
wp::bounds3 input_bounds(query.input_lower, query.input_upper);
|
|
551
1641
|
// Navigate through the bvh, find the first overlapping leaf node.
|
|
552
1642
|
while (query.count)
|
|
553
1643
|
{
|
|
@@ -572,7 +1662,7 @@ CUDA_CALLABLE inline bool mesh_query_aabb_next(mesh_query_aabb_t& query, int& in
|
|
|
572
1662
|
{
|
|
573
1663
|
// found very first triangle index
|
|
574
1664
|
query.face = left_index;
|
|
575
|
-
|
|
1665
|
+
index = left_index;
|
|
576
1666
|
return true;
|
|
577
1667
|
}
|
|
578
1668
|
else
|
|
@@ -613,186 +1703,185 @@ CUDA_CALLABLE inline void adj_mesh_query_aabb_next(mesh_query_aabb_t& query, int
|
|
|
613
1703
|
|
|
614
1704
|
CUDA_CALLABLE inline vec3 mesh_eval_position(uint64_t id, int tri, float u, float v)
|
|
615
1705
|
{
|
|
616
|
-
|
|
1706
|
+
Mesh mesh = mesh_get(id);
|
|
617
1707
|
|
|
618
|
-
|
|
619
|
-
|
|
1708
|
+
if (!mesh.points)
|
|
1709
|
+
return vec3();
|
|
620
1710
|
|
|
621
|
-
|
|
1711
|
+
assert(tri < mesh.num_tris);
|
|
622
1712
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
1713
|
+
int i = mesh.indices[tri*3+0];
|
|
1714
|
+
int j = mesh.indices[tri*3+1];
|
|
1715
|
+
int k = mesh.indices[tri*3+2];
|
|
626
1716
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
1717
|
+
vec3 p = mesh.points[i];
|
|
1718
|
+
vec3 q = mesh.points[j];
|
|
1719
|
+
vec3 r = mesh.points[k];
|
|
630
1720
|
|
|
631
|
-
|
|
1721
|
+
return p*u + q*v + r*(1.0f-u-v);
|
|
632
1722
|
}
|
|
633
1723
|
|
|
634
1724
|
CUDA_CALLABLE inline vec3 mesh_eval_velocity(uint64_t id, int tri, float u, float v)
|
|
635
1725
|
{
|
|
636
|
-
|
|
1726
|
+
Mesh mesh = mesh_get(id);
|
|
637
1727
|
|
|
638
|
-
|
|
639
|
-
|
|
1728
|
+
if (!mesh.velocities)
|
|
1729
|
+
return vec3();
|
|
640
1730
|
|
|
641
|
-
|
|
1731
|
+
assert(tri < mesh.num_tris);
|
|
642
1732
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
1733
|
+
int i = mesh.indices[tri*3+0];
|
|
1734
|
+
int j = mesh.indices[tri*3+1];
|
|
1735
|
+
int k = mesh.indices[tri*3+2];
|
|
646
1736
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
1737
|
+
vec3 vp = mesh.velocities[i];
|
|
1738
|
+
vec3 vq = mesh.velocities[j];
|
|
1739
|
+
vec3 vr = mesh.velocities[k];
|
|
650
1740
|
|
|
651
|
-
|
|
1741
|
+
return vp*u + vq*v + vr*(1.0f-u-v);
|
|
652
1742
|
}
|
|
653
1743
|
|
|
654
1744
|
|
|
655
1745
|
CUDA_CALLABLE inline void adj_mesh_eval_position(uint64_t id, int tri, float u, float v,
|
|
656
|
-
|
|
1746
|
+
uint64_t& adj_id, int& adj_tri, float& adj_u, float& adj_v, const vec3& adj_ret)
|
|
657
1747
|
{
|
|
658
|
-
|
|
1748
|
+
Mesh mesh = mesh_get(id);
|
|
659
1749
|
|
|
660
|
-
|
|
661
|
-
|
|
1750
|
+
if (!mesh.points)
|
|
1751
|
+
return;
|
|
662
1752
|
|
|
663
|
-
|
|
1753
|
+
assert(tri < mesh.num_tris);
|
|
664
1754
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
1755
|
+
int i = mesh.indices[tri*3+0];
|
|
1756
|
+
int j = mesh.indices[tri*3+1];
|
|
1757
|
+
int k = mesh.indices[tri*3+2];
|
|
668
1758
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
1759
|
+
vec3 p = mesh.points[i];
|
|
1760
|
+
vec3 q = mesh.points[j];
|
|
1761
|
+
vec3 r = mesh.points[k];
|
|
672
1762
|
|
|
673
|
-
|
|
674
|
-
|
|
1763
|
+
adj_u += (p[0] - r[0]) * adj_ret[0] + (p[1] - r[1]) * adj_ret[1] + (p[2] - r[2]) * adj_ret[2];
|
|
1764
|
+
adj_v += (q[0] - r[0]) * adj_ret[0] + (q[1] - r[1]) * adj_ret[1] + (q[2] - r[2]) * adj_ret[2];
|
|
675
1765
|
}
|
|
676
1766
|
|
|
677
1767
|
CUDA_CALLABLE inline void adj_mesh_eval_velocity(uint64_t id, int tri, float u, float v,
|
|
678
|
-
|
|
1768
|
+
uint64_t& adj_id, int& adj_tri, float& adj_u, float& adj_v, const vec3& adj_ret)
|
|
679
1769
|
{
|
|
680
|
-
|
|
1770
|
+
Mesh mesh = mesh_get(id);
|
|
681
1771
|
|
|
682
|
-
|
|
683
|
-
|
|
1772
|
+
if (!mesh.velocities)
|
|
1773
|
+
return;
|
|
684
1774
|
|
|
685
|
-
|
|
1775
|
+
assert(tri < mesh.num_tris);
|
|
686
1776
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
1777
|
+
int i = mesh.indices[tri*3+0];
|
|
1778
|
+
int j = mesh.indices[tri*3+1];
|
|
1779
|
+
int k = mesh.indices[tri*3+2];
|
|
690
1780
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
1781
|
+
vec3 vp = mesh.velocities[i];
|
|
1782
|
+
vec3 vq = mesh.velocities[j];
|
|
1783
|
+
vec3 vr = mesh.velocities[k];
|
|
694
1784
|
|
|
695
|
-
|
|
696
|
-
|
|
1785
|
+
adj_u += (vp[0] - vr[0]) * adj_ret[0] + (vp[1] - vr[1]) * adj_ret[1] + (vp[2] - vr[2]) * adj_ret[2];
|
|
1786
|
+
adj_v += (vq[0] - vr[0]) * adj_ret[0] + (vq[1] - vr[1]) * adj_ret[1] + (vq[2] - vr[2]) * adj_ret[2];
|
|
697
1787
|
}
|
|
698
1788
|
|
|
699
1789
|
CUDA_CALLABLE inline vec3 mesh_eval_face_normal(uint64_t id, int tri)
|
|
700
1790
|
{
|
|
701
|
-
|
|
1791
|
+
Mesh mesh = mesh_get(id);
|
|
702
1792
|
|
|
703
|
-
|
|
704
|
-
|
|
1793
|
+
if (!mesh.points)
|
|
1794
|
+
return vec3();
|
|
705
1795
|
|
|
706
|
-
|
|
1796
|
+
assert(tri < mesh.num_tris);
|
|
707
1797
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
1798
|
+
int i = mesh.indices[tri*3+0];
|
|
1799
|
+
int j = mesh.indices[tri*3+1];
|
|
1800
|
+
int k = mesh.indices[tri*3+2];
|
|
711
1801
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
1802
|
+
vec3 p = mesh.points[i];
|
|
1803
|
+
vec3 q = mesh.points[j];
|
|
1804
|
+
vec3 r = mesh.points[k];
|
|
715
1805
|
|
|
716
|
-
|
|
1806
|
+
return normalize(cross(q - p, r - p));
|
|
717
1807
|
}
|
|
718
1808
|
|
|
719
1809
|
CUDA_CALLABLE inline void adj_mesh_eval_face_normal(uint64_t id, int tri,
|
|
720
|
-
|
|
1810
|
+
uint64_t& adj_id, int& adj_tri, const vec3& adj_ret)
|
|
721
1811
|
{
|
|
722
|
-
|
|
1812
|
+
// no-op
|
|
723
1813
|
}
|
|
724
1814
|
|
|
725
1815
|
CUDA_CALLABLE inline vec3 mesh_get_point(uint64_t id, int index)
|
|
726
1816
|
{
|
|
727
|
-
|
|
1817
|
+
Mesh mesh = mesh_get(id);
|
|
728
1818
|
|
|
729
|
-
|
|
730
|
-
|
|
1819
|
+
if (!mesh.points)
|
|
1820
|
+
return vec3();
|
|
731
1821
|
|
|
732
1822
|
#if FP_CHECK
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
1823
|
+
if (index >= mesh.num_tris * 3)
|
|
1824
|
+
{
|
|
1825
|
+
printf("mesh_get_point (%llu, %d) out of bounds at %s:%d\n", id, index, __FILE__, __LINE__);
|
|
1826
|
+
assert(0);
|
|
1827
|
+
}
|
|
738
1828
|
#endif
|
|
739
1829
|
|
|
740
|
-
|
|
741
|
-
|
|
1830
|
+
int i = mesh.indices[index];
|
|
1831
|
+
return mesh.points[i];
|
|
742
1832
|
}
|
|
743
1833
|
|
|
744
1834
|
CUDA_CALLABLE inline void adj_mesh_get_point(uint64_t id, int index,
|
|
745
|
-
|
|
1835
|
+
uint64_t& adj_id, int& adj_index, const vec3& adj_ret)
|
|
746
1836
|
{
|
|
747
|
-
|
|
1837
|
+
// no-op
|
|
748
1838
|
}
|
|
749
1839
|
|
|
750
1840
|
CUDA_CALLABLE inline vec3 mesh_get_velocity(uint64_t id, int index)
|
|
751
1841
|
{
|
|
752
|
-
|
|
1842
|
+
Mesh mesh = mesh_get(id);
|
|
753
1843
|
|
|
754
|
-
|
|
755
|
-
|
|
1844
|
+
if (!mesh.velocities)
|
|
1845
|
+
return vec3();
|
|
756
1846
|
|
|
757
1847
|
#if FP_CHECK
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
1848
|
+
if (index >= mesh.num_tris * 3)
|
|
1849
|
+
{
|
|
1850
|
+
printf("mesh_get_velocity (%llu, %d) out of bounds at %s:%d\n", id, index, __FILE__, __LINE__);
|
|
1851
|
+
assert(0);
|
|
1852
|
+
}
|
|
763
1853
|
#endif
|
|
764
1854
|
|
|
765
|
-
|
|
766
|
-
|
|
1855
|
+
int i = mesh.indices[index];
|
|
1856
|
+
return mesh.velocities[i];
|
|
767
1857
|
}
|
|
768
1858
|
|
|
769
1859
|
CUDA_CALLABLE inline void adj_mesh_get_velocity(uint64_t id, int index,
|
|
770
|
-
|
|
1860
|
+
uint64_t& adj_id, int& adj_index, const vec3& adj_ret)
|
|
771
1861
|
{
|
|
772
|
-
|
|
1862
|
+
// no-op
|
|
773
1863
|
}
|
|
774
1864
|
|
|
775
1865
|
CUDA_CALLABLE inline int mesh_get_index(uint64_t id, int face_vertex_index)
|
|
776
1866
|
{
|
|
777
|
-
|
|
1867
|
+
Mesh mesh = mesh_get(id);
|
|
778
1868
|
|
|
779
|
-
|
|
780
|
-
|
|
1869
|
+
if (!mesh.indices)
|
|
1870
|
+
return -1;
|
|
781
1871
|
|
|
782
|
-
|
|
1872
|
+
assert(face_vertex_index < mesh.num_tris * 3);
|
|
783
1873
|
|
|
784
|
-
|
|
1874
|
+
return mesh.indices[face_vertex_index];
|
|
785
1875
|
}
|
|
786
1876
|
|
|
787
1877
|
CUDA_CALLABLE inline void adj_mesh_get_index(uint64_t id, int index,
|
|
788
|
-
|
|
1878
|
+
uint64_t& adj_id, int& adj_index, const vec3& adj_ret)
|
|
789
1879
|
{
|
|
790
|
-
|
|
1880
|
+
// no-op
|
|
791
1881
|
}
|
|
792
1882
|
|
|
793
|
-
bool mesh_get_descriptor(uint64_t id, Mesh& mesh);
|
|
794
|
-
void mesh_add_descriptor(uint64_t id, const Mesh& mesh);
|
|
795
|
-
void mesh_rem_descriptor(uint64_t id);
|
|
796
|
-
|
|
1883
|
+
CUDA_CALLABLE bool mesh_get_descriptor(uint64_t id, Mesh& mesh);
|
|
1884
|
+
CUDA_CALLABLE void mesh_add_descriptor(uint64_t id, const Mesh& mesh);
|
|
1885
|
+
CUDA_CALLABLE void mesh_rem_descriptor(uint64_t id);
|
|
797
1886
|
|
|
798
1887
|
} // namespace wp
|