warp-lang 1.7.2rc1__py3-none-win_amd64.whl → 1.8.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 +3 -1
- warp/__init__.pyi +3489 -1
- warp/autograd.py +45 -122
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +241 -252
- warp/build_dll.py +125 -26
- warp/builtins.py +1907 -384
- warp/codegen.py +257 -101
- warp/config.py +12 -1
- warp/constants.py +1 -1
- warp/context.py +657 -223
- warp/dlpack.py +1 -1
- warp/examples/benchmarks/benchmark_cloth.py +2 -2
- warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
- warp/examples/core/example_sample_mesh.py +1 -1
- warp/examples/core/example_spin_lock.py +93 -0
- warp/examples/core/example_work_queue.py +118 -0
- warp/examples/fem/example_adaptive_grid.py +5 -5
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_burgers.py +1 -1
- warp/examples/fem/example_convection_diffusion.py +9 -6
- warp/examples/fem/example_darcy_ls_optimization.py +489 -0
- warp/examples/fem/example_deformed_geometry.py +1 -1
- warp/examples/fem/example_diffusion.py +2 -2
- warp/examples/fem/example_diffusion_3d.py +1 -1
- warp/examples/fem/example_distortion_energy.py +1 -1
- warp/examples/fem/example_elastic_shape_optimization.py +387 -0
- warp/examples/fem/example_magnetostatics.py +5 -3
- warp/examples/fem/example_mixed_elasticity.py +5 -3
- warp/examples/fem/example_navier_stokes.py +11 -9
- warp/examples/fem/example_nonconforming_contact.py +5 -3
- warp/examples/fem/example_streamlines.py +8 -3
- warp/examples/fem/utils.py +9 -8
- warp/examples/interop/example_jax_ffi_callback.py +2 -2
- warp/examples/optim/example_drone.py +1 -1
- warp/examples/sim/example_cloth.py +1 -1
- warp/examples/sim/example_cloth_self_contact.py +48 -54
- warp/examples/tile/example_tile_block_cholesky.py +502 -0
- warp/examples/tile/example_tile_cholesky.py +2 -1
- warp/examples/tile/example_tile_convolution.py +1 -1
- warp/examples/tile/example_tile_filtering.py +1 -1
- warp/examples/tile/example_tile_matmul.py +1 -1
- warp/examples/tile/example_tile_mlp.py +2 -0
- warp/fabric.py +7 -7
- warp/fem/__init__.py +5 -0
- warp/fem/adaptivity.py +1 -1
- warp/fem/cache.py +152 -63
- warp/fem/dirichlet.py +2 -2
- warp/fem/domain.py +136 -6
- warp/fem/field/field.py +141 -99
- warp/fem/field/nodal_field.py +85 -39
- warp/fem/field/virtual.py +97 -52
- warp/fem/geometry/adaptive_nanogrid.py +91 -86
- warp/fem/geometry/closest_point.py +13 -0
- warp/fem/geometry/deformed_geometry.py +102 -40
- warp/fem/geometry/element.py +56 -2
- warp/fem/geometry/geometry.py +323 -22
- warp/fem/geometry/grid_2d.py +157 -62
- warp/fem/geometry/grid_3d.py +116 -20
- warp/fem/geometry/hexmesh.py +86 -20
- warp/fem/geometry/nanogrid.py +166 -86
- warp/fem/geometry/partition.py +59 -25
- warp/fem/geometry/quadmesh.py +86 -135
- warp/fem/geometry/tetmesh.py +47 -119
- warp/fem/geometry/trimesh.py +77 -270
- warp/fem/integrate.py +107 -52
- warp/fem/linalg.py +25 -58
- warp/fem/operator.py +124 -27
- warp/fem/quadrature/pic_quadrature.py +36 -14
- warp/fem/quadrature/quadrature.py +40 -16
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/basis_function_space.py +66 -46
- warp/fem/space/basis_space.py +17 -4
- warp/fem/space/dof_mapper.py +1 -1
- warp/fem/space/function_space.py +2 -2
- warp/fem/space/grid_2d_function_space.py +4 -1
- warp/fem/space/hexmesh_function_space.py +4 -2
- warp/fem/space/nanogrid_function_space.py +3 -1
- warp/fem/space/partition.py +11 -2
- warp/fem/space/quadmesh_function_space.py +4 -1
- warp/fem/space/restriction.py +5 -2
- warp/fem/space/shape/__init__.py +10 -8
- warp/fem/space/tetmesh_function_space.py +4 -1
- warp/fem/space/topology.py +52 -21
- warp/fem/space/trimesh_function_space.py +4 -1
- warp/fem/utils.py +53 -8
- warp/jax.py +1 -2
- warp/jax_experimental/ffi.py +12 -17
- warp/jax_experimental/xla_ffi.py +37 -24
- warp/math.py +171 -1
- warp/native/array.h +99 -0
- warp/native/builtin.h +174 -31
- warp/native/coloring.cpp +1 -1
- warp/native/exports.h +118 -63
- warp/native/intersect.h +3 -3
- warp/native/mat.h +5 -10
- warp/native/mathdx.cpp +11 -5
- warp/native/matnn.h +1 -123
- warp/native/quat.h +28 -4
- warp/native/sparse.cpp +121 -258
- warp/native/sparse.cu +181 -274
- warp/native/spatial.h +305 -17
- warp/native/tile.h +583 -72
- warp/native/tile_radix_sort.h +1108 -0
- warp/native/tile_reduce.h +237 -2
- warp/native/tile_scan.h +240 -0
- warp/native/tuple.h +189 -0
- warp/native/vec.h +6 -16
- warp/native/warp.cpp +36 -4
- warp/native/warp.cu +574 -51
- warp/native/warp.h +47 -74
- warp/optim/linear.py +5 -1
- warp/paddle.py +7 -8
- warp/py.typed +0 -0
- warp/render/render_opengl.py +58 -29
- warp/render/render_usd.py +124 -61
- warp/sim/__init__.py +9 -0
- warp/sim/collide.py +252 -78
- warp/sim/graph_coloring.py +8 -1
- warp/sim/import_mjcf.py +4 -3
- warp/sim/import_usd.py +11 -7
- warp/sim/integrator.py +5 -2
- warp/sim/integrator_euler.py +1 -1
- warp/sim/integrator_featherstone.py +1 -1
- warp/sim/integrator_vbd.py +751 -320
- warp/sim/integrator_xpbd.py +1 -1
- warp/sim/model.py +265 -260
- warp/sim/utils.py +10 -7
- warp/sparse.py +303 -166
- warp/tape.py +52 -51
- warp/tests/cuda/test_conditional_captures.py +1046 -0
- warp/tests/cuda/test_streams.py +1 -1
- warp/tests/geometry/test_volume.py +2 -2
- warp/tests/interop/test_dlpack.py +9 -9
- warp/tests/interop/test_jax.py +0 -1
- warp/tests/run_coverage_serial.py +1 -1
- warp/tests/sim/disabled_kinematics.py +2 -2
- warp/tests/sim/{test_vbd.py → test_cloth.py} +296 -113
- warp/tests/sim/test_collision.py +159 -51
- warp/tests/sim/test_coloring.py +15 -1
- warp/tests/test_array.py +254 -2
- warp/tests/test_array_reduce.py +2 -2
- warp/tests/test_atomic_cas.py +299 -0
- warp/tests/test_codegen.py +142 -19
- warp/tests/test_conditional.py +47 -1
- warp/tests/test_ctypes.py +0 -20
- warp/tests/test_devices.py +8 -0
- warp/tests/test_fabricarray.py +4 -2
- warp/tests/test_fem.py +58 -25
- warp/tests/test_func.py +42 -1
- warp/tests/test_grad.py +1 -1
- warp/tests/test_lerp.py +1 -3
- warp/tests/test_map.py +481 -0
- warp/tests/test_mat.py +1 -24
- warp/tests/test_quat.py +6 -15
- warp/tests/test_rounding.py +10 -38
- warp/tests/test_runlength_encode.py +7 -7
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +51 -2
- warp/tests/test_spatial.py +507 -1
- warp/tests/test_struct.py +2 -2
- warp/tests/test_tuple.py +265 -0
- warp/tests/test_types.py +2 -2
- warp/tests/test_utils.py +24 -18
- warp/tests/tile/test_tile.py +420 -1
- warp/tests/tile/test_tile_mathdx.py +518 -14
- warp/tests/tile/test_tile_reduce.py +213 -0
- warp/tests/tile/test_tile_shared_memory.py +130 -1
- warp/tests/tile/test_tile_sort.py +117 -0
- warp/tests/unittest_suites.py +4 -6
- warp/types.py +462 -308
- warp/utils.py +647 -86
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/METADATA +20 -6
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/RECORD +178 -166
- warp/stubs.py +0 -3381
- warp/tests/sim/test_xpbd.py +0 -399
- warp/tests/test_mlp.py +0 -282
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/top_level.txt +0 -0
warp/sim/integrator_vbd.py
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
|
-
|
|
16
15
|
import numpy as np
|
|
17
16
|
|
|
18
17
|
import warp as wp
|
|
@@ -21,22 +20,16 @@ from ..types import float32, matrix
|
|
|
21
20
|
from .collide import (
|
|
22
21
|
TriMeshCollisionDetector,
|
|
23
22
|
TriMeshCollisionInfo,
|
|
24
|
-
get_edge_colliding_edges,
|
|
25
|
-
get_edge_colliding_edges_count,
|
|
26
|
-
get_triangle_colliding_vertices,
|
|
27
|
-
get_triangle_colliding_vertices_count,
|
|
28
|
-
get_vertex_colliding_triangles,
|
|
29
|
-
get_vertex_colliding_triangles_count,
|
|
30
23
|
triangle_closest_point,
|
|
31
24
|
)
|
|
32
25
|
from .integrator import Integrator
|
|
33
26
|
from .model import PARTICLE_FLAG_ACTIVE, Control, Model, ModelShapeMaterials, State
|
|
34
27
|
|
|
35
|
-
wp.set_module_options({"enable_backward": False})
|
|
36
|
-
|
|
37
28
|
VBD_DEBUG_PRINTING_OPTIONS = {
|
|
38
29
|
# "elasticity_force_hessian",
|
|
39
30
|
# "contact_force_hessian",
|
|
31
|
+
# "contact_force_hessian_vt",
|
|
32
|
+
# "contact_force_hessian_ee",
|
|
40
33
|
# "overall_force_hessian",
|
|
41
34
|
# "inertia_force_hessian",
|
|
42
35
|
# "connectivity",
|
|
@@ -52,15 +45,19 @@ class mat32(matrix(shape=(3, 2), dtype=float32)):
|
|
|
52
45
|
pass
|
|
53
46
|
|
|
54
47
|
|
|
48
|
+
class mat43(matrix(shape=(4, 3), dtype=float32)):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
55
52
|
@wp.struct
|
|
56
53
|
class ForceElementAdjacencyInfo:
|
|
57
54
|
r"""
|
|
58
55
|
- vertex_adjacent_[element]: the flatten adjacency information. Its size is \sum_{i\inV} 2*N_i, where N_i is the
|
|
59
|
-
number of vertex i
|
|
56
|
+
number of vertex i's adjacent [element]. For each adjacent element it stores 2 information:
|
|
60
57
|
- the id of the adjacent element
|
|
61
58
|
- the order of the vertex in the element, which is essential to compute the force and hessian for the vertex
|
|
62
|
-
- vertex_adjacent_[element]_offsets: stores where each vertex
|
|
63
|
-
Its size is |V|+1 such that the number of vertex i
|
|
59
|
+
- vertex_adjacent_[element]_offsets: stores where each vertex information starts in the flatten adjacency array.
|
|
60
|
+
Its size is |V|+1 such that the number of vertex i's adjacent [element] can be computed as
|
|
64
61
|
vertex_adjacent_[element]_offsets[i+1]-vertex_adjacent_[element]_offsets[i].
|
|
65
62
|
"""
|
|
66
63
|
|
|
@@ -520,6 +517,7 @@ def evaluate_ground_contact_force_hessian(
|
|
|
520
517
|
ground_normal: wp.vec3,
|
|
521
518
|
ground_level: float,
|
|
522
519
|
soft_contact_ke: float,
|
|
520
|
+
soft_contact_kd: float,
|
|
523
521
|
friction_mu: float,
|
|
524
522
|
friction_epsilon: float,
|
|
525
523
|
dt: float,
|
|
@@ -533,6 +531,11 @@ def evaluate_ground_contact_force_hessian(
|
|
|
533
531
|
|
|
534
532
|
dx = particle_pos - particle_prev_pos
|
|
535
533
|
|
|
534
|
+
if wp.dot(dx, ground_normal) < 0:
|
|
535
|
+
damping_hessian = (soft_contact_kd / dt) * ground_contact_hessian
|
|
536
|
+
ground_contact_hessian = ground_contact_hessian + damping_hessian
|
|
537
|
+
ground_contact_force = ground_contact_force - damping_hessian * dx
|
|
538
|
+
|
|
536
539
|
# friction
|
|
537
540
|
e0, e1 = build_orthonormal_basis(ground_normal)
|
|
538
541
|
|
|
@@ -559,6 +562,7 @@ def evaluate_body_particle_contact(
|
|
|
559
562
|
particle_prev_pos: wp.vec3,
|
|
560
563
|
contact_index: int,
|
|
561
564
|
soft_contact_ke: float,
|
|
565
|
+
soft_contact_kd: float,
|
|
562
566
|
friction_mu: float,
|
|
563
567
|
friction_epsilon: float,
|
|
564
568
|
particle_radius: wp.array(dtype=float),
|
|
@@ -594,10 +598,15 @@ def evaluate_body_particle_contact(
|
|
|
594
598
|
body_contact_force = n * body_contact_force_norm
|
|
595
599
|
body_contact_hessian = soft_contact_ke * wp.outer(n, n)
|
|
596
600
|
|
|
597
|
-
mu =
|
|
601
|
+
mu = shape_materials.mu[shape_index]
|
|
598
602
|
|
|
599
603
|
dx = particle_pos - particle_prev_pos
|
|
600
604
|
|
|
605
|
+
if wp.dot(n, dx) < 0:
|
|
606
|
+
damping_hessian = (soft_contact_kd / dt) * body_contact_hessian
|
|
607
|
+
body_contact_hessian = body_contact_hessian + damping_hessian
|
|
608
|
+
body_contact_force = body_contact_force - damping_hessian * dx
|
|
609
|
+
|
|
601
610
|
# body velocity
|
|
602
611
|
body_v_s = wp.spatial_vector()
|
|
603
612
|
if body_index >= 0:
|
|
@@ -652,6 +661,22 @@ def evaluate_self_contact_force_norm(dis: float, collision_radius: float, k: flo
|
|
|
652
661
|
return dEdD, d2E_dDdD
|
|
653
662
|
|
|
654
663
|
|
|
664
|
+
@wp.func
|
|
665
|
+
def damp_collision(
|
|
666
|
+
displacement: wp.vec3,
|
|
667
|
+
collision_normal: wp.vec3,
|
|
668
|
+
collision_hessian: wp.mat33,
|
|
669
|
+
collision_damping: float,
|
|
670
|
+
dt: float,
|
|
671
|
+
):
|
|
672
|
+
if wp.dot(displacement, collision_normal) > 0:
|
|
673
|
+
damping_hessian = (collision_damping / dt) * collision_hessian
|
|
674
|
+
damping_force = damping_hessian * displacement
|
|
675
|
+
return damping_force, damping_hessian
|
|
676
|
+
else:
|
|
677
|
+
return wp.vec3(0.0), wp.mat33(0.0)
|
|
678
|
+
|
|
679
|
+
|
|
655
680
|
@wp.func
|
|
656
681
|
def evaluate_edge_edge_contact(
|
|
657
682
|
v: int,
|
|
@@ -663,6 +688,7 @@ def evaluate_edge_edge_contact(
|
|
|
663
688
|
edge_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
664
689
|
collision_radius: float,
|
|
665
690
|
collision_stiffness: float,
|
|
691
|
+
collision_damping: float,
|
|
666
692
|
friction_coefficient: float,
|
|
667
693
|
friction_epsilon: float,
|
|
668
694
|
dt: float,
|
|
@@ -676,10 +702,12 @@ def evaluate_edge_edge_contact(
|
|
|
676
702
|
e0
|
|
677
703
|
e1
|
|
678
704
|
pos
|
|
705
|
+
pos_prev,
|
|
679
706
|
edge_indices
|
|
680
707
|
collision_radius
|
|
681
708
|
collision_stiffness
|
|
682
709
|
dt
|
|
710
|
+
edge_edge_parallel_epsilon: threshold to determine whether 2 edges are parallel
|
|
683
711
|
"""
|
|
684
712
|
e1_v1 = edge_indices[e1, 2]
|
|
685
713
|
e1_v2 = edge_indices[e1, 3]
|
|
@@ -721,15 +749,14 @@ def evaluate_edge_edge_contact(
|
|
|
721
749
|
c2_prev = pos_prev[e2_v1] + (pos_prev[e2_v2] - pos_prev[e2_v1]) * t
|
|
722
750
|
|
|
723
751
|
dx = (c1 - c1_prev) - (c2 - c2_prev)
|
|
724
|
-
|
|
725
|
-
axis_2 = wp.normalize(wp.cross(e1_vec_normalized, collision_normal))
|
|
752
|
+
axis_1, axis_2 = build_orthonormal_basis(collision_normal)
|
|
726
753
|
|
|
727
754
|
T = mat32(
|
|
728
|
-
|
|
755
|
+
axis_1[0],
|
|
729
756
|
axis_2[0],
|
|
730
|
-
|
|
757
|
+
axis_1[1],
|
|
731
758
|
axis_2[1],
|
|
732
|
-
|
|
759
|
+
axis_1[2],
|
|
733
760
|
axis_2[2],
|
|
734
761
|
)
|
|
735
762
|
|
|
@@ -737,7 +764,7 @@ def evaluate_edge_edge_contact(
|
|
|
737
764
|
eps_U = friction_epsilon * dt
|
|
738
765
|
|
|
739
766
|
# fmt: off
|
|
740
|
-
if wp.static("
|
|
767
|
+
if wp.static("contact_force_hessian_ee" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
741
768
|
wp.printf(
|
|
742
769
|
" collision force:\n %f %f %f,\n collision hessian:\n %f %f %f,\n %f %f %f,\n %f %f %f\n",
|
|
743
770
|
collision_force[0], collision_force[1], collision_force[2], collision_hessian[0, 0], collision_hessian[0, 1], collision_hessian[0, 2], collision_hessian[1, 0], collision_hessian[1, 1], collision_hessian[1, 2], collision_hessian[2, 0], collision_hessian[2, 1], collision_hessian[2, 2],
|
|
@@ -748,21 +775,174 @@ def evaluate_edge_edge_contact(
|
|
|
748
775
|
friction_force = friction_force * v_bary
|
|
749
776
|
friction_hessian = friction_hessian * v_bary * v_bary
|
|
750
777
|
|
|
778
|
+
# # fmt: off
|
|
779
|
+
# if wp.static("contact_force_hessian_ee" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
780
|
+
# wp.printf(
|
|
781
|
+
# " friction force:\n %f %f %f,\n friction hessian:\n %f %f %f,\n %f %f %f,\n %f %f %f\n",
|
|
782
|
+
# friction_force[0], friction_force[1], friction_force[2], friction_hessian[0, 0], friction_hessian[0, 1], friction_hessian[0, 2], friction_hessian[1, 0], friction_hessian[1, 1], friction_hessian[1, 2], friction_hessian[2, 0], friction_hessian[2, 1], friction_hessian[2, 2],
|
|
783
|
+
# )
|
|
784
|
+
# # fmt: on
|
|
785
|
+
|
|
786
|
+
if v_order == 0:
|
|
787
|
+
displacement = pos_prev[e1_v1] - e1_v1_pos
|
|
788
|
+
elif v_order == 1:
|
|
789
|
+
displacement = pos_prev[e1_v2] - e1_v2_pos
|
|
790
|
+
elif v_order == 2:
|
|
791
|
+
displacement = pos_prev[e2_v1] - e2_v1_pos
|
|
792
|
+
else:
|
|
793
|
+
displacement = pos_prev[e2_v2] - e2_v2_pos
|
|
794
|
+
|
|
795
|
+
collision_normal_normal_sign = wp.vec4(1.0, 1.0, -1.0, -1.0)
|
|
796
|
+
if wp.dot(displacement, collision_normal * collision_normal_normal_sign[v_order]) > 0:
|
|
797
|
+
damping_hessian = (collision_damping / dt) * collision_hessian
|
|
798
|
+
collision_hessian = collision_hessian + damping_hessian
|
|
799
|
+
collision_force = collision_force + damping_hessian * displacement
|
|
800
|
+
|
|
801
|
+
collision_force = collision_force + friction_force
|
|
802
|
+
collision_hessian = collision_hessian + friction_hessian
|
|
803
|
+
else:
|
|
804
|
+
collision_force = wp.vec3(0.0, 0.0, 0.0)
|
|
805
|
+
collision_hessian = wp.mat33(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
|
806
|
+
|
|
807
|
+
return collision_force, collision_hessian
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
@wp.func
|
|
811
|
+
def evaluate_edge_edge_contact_2_vertices(
|
|
812
|
+
e1: int,
|
|
813
|
+
e2: int,
|
|
814
|
+
pos: wp.array(dtype=wp.vec3),
|
|
815
|
+
pos_prev: wp.array(dtype=wp.vec3),
|
|
816
|
+
edge_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
817
|
+
collision_radius: float,
|
|
818
|
+
collision_stiffness: float,
|
|
819
|
+
collision_damping: float,
|
|
820
|
+
friction_coefficient: float,
|
|
821
|
+
friction_epsilon: float,
|
|
822
|
+
dt: float,
|
|
823
|
+
edge_edge_parallel_epsilon: float,
|
|
824
|
+
):
|
|
825
|
+
r"""
|
|
826
|
+
Returns the edge-edge contact force and hessian, including the friction force.
|
|
827
|
+
Args:
|
|
828
|
+
v:
|
|
829
|
+
v_order: \in {0, 1, 2, 3}, 0, 1 is vertex 0, 1 of e1, 2,3 is vertex 0, 1 of e2
|
|
830
|
+
e0
|
|
831
|
+
e1
|
|
832
|
+
pos
|
|
833
|
+
edge_indices
|
|
834
|
+
collision_radius
|
|
835
|
+
collision_stiffness
|
|
836
|
+
dt
|
|
837
|
+
"""
|
|
838
|
+
e1_v1 = edge_indices[e1, 2]
|
|
839
|
+
e1_v2 = edge_indices[e1, 3]
|
|
840
|
+
|
|
841
|
+
e1_v1_pos = pos[e1_v1]
|
|
842
|
+
e1_v2_pos = pos[e1_v2]
|
|
843
|
+
|
|
844
|
+
e2_v1 = edge_indices[e2, 2]
|
|
845
|
+
e2_v2 = edge_indices[e2, 3]
|
|
846
|
+
|
|
847
|
+
e2_v1_pos = pos[e2_v1]
|
|
848
|
+
e2_v2_pos = pos[e2_v2]
|
|
849
|
+
|
|
850
|
+
st = wp.closest_point_edge_edge(e1_v1_pos, e1_v2_pos, e2_v1_pos, e2_v2_pos, edge_edge_parallel_epsilon)
|
|
851
|
+
s = st[0]
|
|
852
|
+
t = st[1]
|
|
853
|
+
e1_vec = e1_v2_pos - e1_v1_pos
|
|
854
|
+
e2_vec = e2_v2_pos - e2_v1_pos
|
|
855
|
+
c1 = e1_v1_pos + e1_vec * s
|
|
856
|
+
c2 = e2_v1_pos + e2_vec * t
|
|
857
|
+
|
|
858
|
+
# c1, c2, s, t = closest_point_edge_edge_2(e1_v1_pos, e1_v2_pos, e2_v1_pos, e2_v2_pos)
|
|
859
|
+
|
|
860
|
+
diff = c1 - c2
|
|
861
|
+
dis = st[2]
|
|
862
|
+
collision_normal = diff / dis
|
|
863
|
+
|
|
864
|
+
if dis < collision_radius:
|
|
865
|
+
bs = wp.vec4(1.0 - s, s, -1.0 + t, -t)
|
|
866
|
+
|
|
867
|
+
dEdD, d2E_dDdD = evaluate_self_contact_force_norm(dis, collision_radius, collision_stiffness)
|
|
868
|
+
|
|
869
|
+
collision_force = -dEdD * collision_normal
|
|
870
|
+
collision_hessian = d2E_dDdD * wp.outer(collision_normal, collision_normal)
|
|
871
|
+
|
|
872
|
+
# friction
|
|
873
|
+
c1_prev = pos_prev[e1_v1] + (pos_prev[e1_v2] - pos_prev[e1_v1]) * s
|
|
874
|
+
c2_prev = pos_prev[e2_v1] + (pos_prev[e2_v2] - pos_prev[e2_v1]) * t
|
|
875
|
+
|
|
876
|
+
dx = (c1 - c1_prev) - (c2 - c2_prev)
|
|
877
|
+
axis_1, axis_2 = build_orthonormal_basis(collision_normal)
|
|
878
|
+
|
|
879
|
+
T = mat32(
|
|
880
|
+
axis_1[0],
|
|
881
|
+
axis_2[0],
|
|
882
|
+
axis_1[1],
|
|
883
|
+
axis_2[1],
|
|
884
|
+
axis_1[2],
|
|
885
|
+
axis_2[2],
|
|
886
|
+
)
|
|
887
|
+
|
|
888
|
+
u = wp.transpose(T) * dx
|
|
889
|
+
eps_U = friction_epsilon * dt
|
|
890
|
+
|
|
751
891
|
# fmt: off
|
|
752
|
-
if wp.static("
|
|
892
|
+
if wp.static("contact_force_hessian_ee" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
753
893
|
wp.printf(
|
|
754
|
-
"
|
|
755
|
-
|
|
894
|
+
" collision force:\n %f %f %f,\n collision hessian:\n %f %f %f,\n %f %f %f,\n %f %f %f\n",
|
|
895
|
+
collision_force[0], collision_force[1], collision_force[2], collision_hessian[0, 0], collision_hessian[0, 1], collision_hessian[0, 2], collision_hessian[1, 0], collision_hessian[1, 1], collision_hessian[1, 2], collision_hessian[2, 0], collision_hessian[2, 1], collision_hessian[2, 2],
|
|
756
896
|
)
|
|
757
897
|
# fmt: on
|
|
758
898
|
|
|
759
|
-
|
|
760
|
-
|
|
899
|
+
friction_force, friction_hessian = compute_friction(friction_coefficient, -dEdD, T, u, eps_U)
|
|
900
|
+
|
|
901
|
+
# # fmt: off
|
|
902
|
+
# if wp.static("contact_force_hessian_ee" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
903
|
+
# wp.printf(
|
|
904
|
+
# " friction force:\n %f %f %f,\n friction hessian:\n %f %f %f,\n %f %f %f,\n %f %f %f\n",
|
|
905
|
+
# friction_force[0], friction_force[1], friction_force[2], friction_hessian[0, 0], friction_hessian[0, 1], friction_hessian[0, 2], friction_hessian[1, 0], friction_hessian[1, 1], friction_hessian[1, 2], friction_hessian[2, 0], friction_hessian[2, 1], friction_hessian[2, 2],
|
|
906
|
+
# )
|
|
907
|
+
# # fmt: on
|
|
908
|
+
|
|
909
|
+
displacement_0 = pos_prev[e1_v1] - e1_v1_pos
|
|
910
|
+
displacement_1 = pos_prev[e1_v2] - e1_v2_pos
|
|
911
|
+
|
|
912
|
+
collision_force_0 = collision_force * bs[0]
|
|
913
|
+
collision_force_1 = collision_force * bs[1]
|
|
914
|
+
|
|
915
|
+
collision_hessian_0 = collision_hessian * bs[0] * bs[0]
|
|
916
|
+
collision_hessian_1 = collision_hessian * bs[1] * bs[1]
|
|
917
|
+
|
|
918
|
+
collision_normal_normal_sign = wp.vec4(1.0, 1.0, -1.0, -1.0)
|
|
919
|
+
damping_force, damping_hessian = damp_collision(
|
|
920
|
+
displacement_0,
|
|
921
|
+
collision_normal * collision_normal_normal_sign[0],
|
|
922
|
+
collision_hessian_0,
|
|
923
|
+
collision_damping,
|
|
924
|
+
dt,
|
|
925
|
+
)
|
|
926
|
+
|
|
927
|
+
collision_force_0 += damping_force + bs[0] * friction_force
|
|
928
|
+
collision_hessian_0 += damping_hessian + bs[0] * bs[0] * friction_hessian
|
|
929
|
+
|
|
930
|
+
damping_force, damping_hessian = damp_collision(
|
|
931
|
+
displacement_1,
|
|
932
|
+
collision_normal * collision_normal_normal_sign[1],
|
|
933
|
+
collision_hessian_1,
|
|
934
|
+
collision_damping,
|
|
935
|
+
dt,
|
|
936
|
+
)
|
|
937
|
+
collision_force_1 += damping_force + bs[1] * friction_force
|
|
938
|
+
collision_hessian_1 += damping_hessian + bs[1] * bs[1] * friction_hessian
|
|
939
|
+
|
|
940
|
+
return True, collision_force_0, collision_force_1, collision_hessian_0, collision_hessian_1
|
|
761
941
|
else:
|
|
762
942
|
collision_force = wp.vec3(0.0, 0.0, 0.0)
|
|
763
943
|
collision_hessian = wp.mat33(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
|
764
944
|
|
|
765
|
-
|
|
945
|
+
return False, collision_force, collision_force, collision_hessian, collision_hessian
|
|
766
946
|
|
|
767
947
|
|
|
768
948
|
@wp.func
|
|
@@ -775,6 +955,7 @@ def evaluate_vertex_triangle_collision_force_hessian(
|
|
|
775
955
|
tri_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
776
956
|
collision_radius: float,
|
|
777
957
|
collision_stiffness: float,
|
|
958
|
+
collision_damping: float,
|
|
778
959
|
friction_coefficient: float,
|
|
779
960
|
friction_epsilon: float,
|
|
780
961
|
dt: float,
|
|
@@ -811,8 +992,7 @@ def evaluate_vertex_triangle_collision_force_hessian(
|
|
|
811
992
|
|
|
812
993
|
dx = dx_v - (closest_p - closest_p_prev)
|
|
813
994
|
|
|
814
|
-
e0 =
|
|
815
|
-
e1 = wp.normalize(wp.cross(e0, collision_normal))
|
|
995
|
+
e0, e1 = build_orthonormal_basis(collision_normal)
|
|
816
996
|
|
|
817
997
|
T = mat32(e0[0], e1[0], e0[1], e1[1], e0[2], e1[2])
|
|
818
998
|
|
|
@@ -822,7 +1002,7 @@ def evaluate_vertex_triangle_collision_force_hessian(
|
|
|
822
1002
|
friction_force, friction_hessian = compute_friction(friction_coefficient, -dEdD, T, u, eps_U)
|
|
823
1003
|
|
|
824
1004
|
# fmt: off
|
|
825
|
-
if wp.static("
|
|
1005
|
+
if wp.static("contact_force_hessian_vt" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
826
1006
|
wp.printf(
|
|
827
1007
|
"v: %d dEdD: %f\nnormal force: %f %f %f\nfriction force: %f %f %f\n",
|
|
828
1008
|
v,
|
|
@@ -831,6 +1011,21 @@ def evaluate_vertex_triangle_collision_force_hessian(
|
|
|
831
1011
|
)
|
|
832
1012
|
# fmt: on
|
|
833
1013
|
|
|
1014
|
+
if v_order == 0:
|
|
1015
|
+
displacement = pos_prev[tri_indices[tri, 0]] - a
|
|
1016
|
+
elif v_order == 1:
|
|
1017
|
+
displacement = pos_prev[tri_indices[tri, 1]] - b
|
|
1018
|
+
elif v_order == 2:
|
|
1019
|
+
displacement = pos_prev[tri_indices[tri, 2]] - c
|
|
1020
|
+
else:
|
|
1021
|
+
displacement = pos_prev[v] - p
|
|
1022
|
+
|
|
1023
|
+
collision_normal_normal_sign = wp.vec4(-1.0, -1.0, -1.0, 1.0)
|
|
1024
|
+
if wp.dot(displacement, collision_normal * collision_normal_normal_sign[v_order]) > 0:
|
|
1025
|
+
damping_hessian = (collision_damping / dt) * collision_hessian
|
|
1026
|
+
collision_hessian = collision_hessian + damping_hessian
|
|
1027
|
+
collision_force = collision_force + damping_hessian * displacement
|
|
1028
|
+
|
|
834
1029
|
collision_force = collision_force + v_bary * friction_force
|
|
835
1030
|
collision_hessian = collision_hessian + v_bary * v_bary * friction_hessian
|
|
836
1031
|
else:
|
|
@@ -840,6 +1035,155 @@ def evaluate_vertex_triangle_collision_force_hessian(
|
|
|
840
1035
|
return collision_force, collision_hessian
|
|
841
1036
|
|
|
842
1037
|
|
|
1038
|
+
@wp.func
|
|
1039
|
+
def evaluate_vertex_triangle_collision_force_hessian_4_vertices(
|
|
1040
|
+
v: int,
|
|
1041
|
+
tri: int,
|
|
1042
|
+
pos: wp.array(dtype=wp.vec3),
|
|
1043
|
+
pos_prev: wp.array(dtype=wp.vec3),
|
|
1044
|
+
tri_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1045
|
+
collision_radius: float,
|
|
1046
|
+
collision_stiffness: float,
|
|
1047
|
+
collision_damping: float,
|
|
1048
|
+
friction_coefficient: float,
|
|
1049
|
+
friction_epsilon: float,
|
|
1050
|
+
dt: float,
|
|
1051
|
+
):
|
|
1052
|
+
a = pos[tri_indices[tri, 0]]
|
|
1053
|
+
b = pos[tri_indices[tri, 1]]
|
|
1054
|
+
c = pos[tri_indices[tri, 2]]
|
|
1055
|
+
|
|
1056
|
+
p = pos[v]
|
|
1057
|
+
|
|
1058
|
+
closest_p, bary, feature_type = triangle_closest_point(a, b, c, p)
|
|
1059
|
+
|
|
1060
|
+
diff = p - closest_p
|
|
1061
|
+
dis = wp.length(diff)
|
|
1062
|
+
collision_normal = diff / dis
|
|
1063
|
+
|
|
1064
|
+
if dis < collision_radius:
|
|
1065
|
+
bs = wp.vec4(-bary[0], -bary[1], -bary[2], 1.0)
|
|
1066
|
+
|
|
1067
|
+
dEdD, d2E_dDdD = evaluate_self_contact_force_norm(dis, collision_radius, collision_stiffness)
|
|
1068
|
+
|
|
1069
|
+
collision_force = -dEdD * collision_normal
|
|
1070
|
+
collision_hessian = d2E_dDdD * wp.outer(collision_normal, collision_normal)
|
|
1071
|
+
|
|
1072
|
+
# friction force
|
|
1073
|
+
dx_v = p - pos_prev[v]
|
|
1074
|
+
|
|
1075
|
+
closest_p_prev = (
|
|
1076
|
+
bary[0] * pos_prev[tri_indices[tri, 0]]
|
|
1077
|
+
+ bary[1] * pos_prev[tri_indices[tri, 1]]
|
|
1078
|
+
+ bary[2] * pos_prev[tri_indices[tri, 2]]
|
|
1079
|
+
)
|
|
1080
|
+
|
|
1081
|
+
dx = dx_v - (closest_p - closest_p_prev)
|
|
1082
|
+
|
|
1083
|
+
e0, e1 = build_orthonormal_basis(collision_normal)
|
|
1084
|
+
|
|
1085
|
+
T = mat32(e0[0], e1[0], e0[1], e1[1], e0[2], e1[2])
|
|
1086
|
+
|
|
1087
|
+
u = wp.transpose(T) * dx
|
|
1088
|
+
eps_U = friction_epsilon * dt
|
|
1089
|
+
|
|
1090
|
+
friction_force, friction_hessian = compute_friction(friction_coefficient, -dEdD, T, u, eps_U)
|
|
1091
|
+
|
|
1092
|
+
# fmt: off
|
|
1093
|
+
if wp.static("contact_force_hessian_vt" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1094
|
+
wp.printf(
|
|
1095
|
+
"v: %d dEdD: %f\nnormal force: %f %f %f\nfriction force: %f %f %f\n",
|
|
1096
|
+
v,
|
|
1097
|
+
dEdD,
|
|
1098
|
+
collision_force[0], collision_force[1], collision_force[2], friction_force[0], friction_force[1],
|
|
1099
|
+
friction_force[2],
|
|
1100
|
+
)
|
|
1101
|
+
# fmt: on
|
|
1102
|
+
|
|
1103
|
+
displacement_0 = pos_prev[tri_indices[tri, 0]] - a
|
|
1104
|
+
displacement_1 = pos_prev[tri_indices[tri, 1]] - b
|
|
1105
|
+
displacement_2 = pos_prev[tri_indices[tri, 2]] - c
|
|
1106
|
+
displacement_3 = pos_prev[v] - p
|
|
1107
|
+
|
|
1108
|
+
collision_force_0 = collision_force * bs[0]
|
|
1109
|
+
collision_force_1 = collision_force * bs[1]
|
|
1110
|
+
collision_force_2 = collision_force * bs[2]
|
|
1111
|
+
collision_force_3 = collision_force * bs[3]
|
|
1112
|
+
|
|
1113
|
+
collision_hessian_0 = collision_hessian * bs[0] * bs[0]
|
|
1114
|
+
collision_hessian_1 = collision_hessian * bs[1] * bs[1]
|
|
1115
|
+
collision_hessian_2 = collision_hessian * bs[2] * bs[2]
|
|
1116
|
+
collision_hessian_3 = collision_hessian * bs[3] * bs[3]
|
|
1117
|
+
|
|
1118
|
+
collision_normal_normal_sign = wp.vec4(-1.0, -1.0, -1.0, 1.0)
|
|
1119
|
+
damping_force, damping_hessian = damp_collision(
|
|
1120
|
+
displacement_0,
|
|
1121
|
+
collision_normal * collision_normal_normal_sign[0],
|
|
1122
|
+
collision_hessian_0,
|
|
1123
|
+
collision_damping,
|
|
1124
|
+
dt,
|
|
1125
|
+
)
|
|
1126
|
+
|
|
1127
|
+
collision_force_0 += damping_force + bs[0] * friction_force
|
|
1128
|
+
collision_hessian_0 += damping_hessian + bs[0] * bs[0] * friction_hessian
|
|
1129
|
+
|
|
1130
|
+
damping_force, damping_hessian = damp_collision(
|
|
1131
|
+
displacement_1,
|
|
1132
|
+
collision_normal * collision_normal_normal_sign[1],
|
|
1133
|
+
collision_hessian_1,
|
|
1134
|
+
collision_damping,
|
|
1135
|
+
dt,
|
|
1136
|
+
)
|
|
1137
|
+
collision_force_1 += damping_force + bs[1] * friction_force
|
|
1138
|
+
collision_hessian_1 += damping_hessian + bs[1] * bs[1] * friction_hessian
|
|
1139
|
+
|
|
1140
|
+
damping_force, damping_hessian = damp_collision(
|
|
1141
|
+
displacement_2,
|
|
1142
|
+
collision_normal * collision_normal_normal_sign[2],
|
|
1143
|
+
collision_hessian_2,
|
|
1144
|
+
collision_damping,
|
|
1145
|
+
dt,
|
|
1146
|
+
)
|
|
1147
|
+
collision_force_2 += damping_force + bs[2] * friction_force
|
|
1148
|
+
collision_hessian_2 += damping_hessian + bs[2] * bs[2] * friction_hessian
|
|
1149
|
+
|
|
1150
|
+
damping_force, damping_hessian = damp_collision(
|
|
1151
|
+
displacement_3,
|
|
1152
|
+
collision_normal * collision_normal_normal_sign[3],
|
|
1153
|
+
collision_hessian_3,
|
|
1154
|
+
collision_damping,
|
|
1155
|
+
dt,
|
|
1156
|
+
)
|
|
1157
|
+
collision_force_3 += damping_force + bs[3] * friction_force
|
|
1158
|
+
collision_hessian_3 += damping_hessian + bs[3] * bs[3] * friction_hessian
|
|
1159
|
+
return (
|
|
1160
|
+
True,
|
|
1161
|
+
collision_force_0,
|
|
1162
|
+
collision_force_1,
|
|
1163
|
+
collision_force_2,
|
|
1164
|
+
collision_force_3,
|
|
1165
|
+
collision_hessian_0,
|
|
1166
|
+
collision_hessian_1,
|
|
1167
|
+
collision_hessian_2,
|
|
1168
|
+
collision_hessian_3,
|
|
1169
|
+
)
|
|
1170
|
+
else:
|
|
1171
|
+
collision_force = wp.vec3(0.0, 0.0, 0.0)
|
|
1172
|
+
collision_hessian = wp.mat33(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
|
1173
|
+
|
|
1174
|
+
return (
|
|
1175
|
+
False,
|
|
1176
|
+
collision_force,
|
|
1177
|
+
collision_force,
|
|
1178
|
+
collision_force,
|
|
1179
|
+
collision_force,
|
|
1180
|
+
collision_hessian,
|
|
1181
|
+
collision_hessian,
|
|
1182
|
+
collision_hessian,
|
|
1183
|
+
collision_hessian,
|
|
1184
|
+
)
|
|
1185
|
+
|
|
1186
|
+
|
|
843
1187
|
@wp.func
|
|
844
1188
|
def compute_friction(mu: float, normal_contact_force: float, T: mat32, u: wp.vec2, eps_u: float):
|
|
845
1189
|
"""
|
|
@@ -1022,7 +1366,6 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1022
1366
|
particle_ids_in_color: wp.array(dtype=wp.int32),
|
|
1023
1367
|
prev_pos: wp.array(dtype=wp.vec3),
|
|
1024
1368
|
pos: wp.array(dtype=wp.vec3),
|
|
1025
|
-
pos_new: wp.array(dtype=wp.vec3),
|
|
1026
1369
|
vel: wp.array(dtype=wp.vec3),
|
|
1027
1370
|
mass: wp.array(dtype=float),
|
|
1028
1371
|
inertia: wp.array(dtype=wp.vec3),
|
|
@@ -1037,36 +1380,26 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1037
1380
|
edge_bending_properties: wp.array(dtype=float, ndim=2),
|
|
1038
1381
|
adjacency: ForceElementAdjacencyInfo,
|
|
1039
1382
|
# contact info
|
|
1040
|
-
# self contact
|
|
1041
1383
|
soft_contact_ke: float,
|
|
1384
|
+
soft_contact_kd: float,
|
|
1042
1385
|
friction_mu: float,
|
|
1043
1386
|
friction_epsilon: float,
|
|
1044
|
-
# body-particle contact
|
|
1045
|
-
particle_radius: wp.array(dtype=float),
|
|
1046
|
-
body_particle_contact_buffer_pre_alloc: int,
|
|
1047
|
-
body_particle_contact_buffer: wp.array(dtype=int),
|
|
1048
|
-
body_particle_contact_count: wp.array(dtype=int),
|
|
1049
|
-
shape_materials: ModelShapeMaterials,
|
|
1050
|
-
shape_body: wp.array(dtype=int),
|
|
1051
|
-
body_q: wp.array(dtype=wp.transform),
|
|
1052
|
-
body_qd: wp.array(dtype=wp.spatial_vector),
|
|
1053
|
-
body_com: wp.array(dtype=wp.vec3),
|
|
1054
|
-
contact_shape: wp.array(dtype=int),
|
|
1055
|
-
contact_body_pos: wp.array(dtype=wp.vec3),
|
|
1056
|
-
contact_body_vel: wp.array(dtype=wp.vec3),
|
|
1057
|
-
contact_normal: wp.array(dtype=wp.vec3),
|
|
1058
1387
|
# ground-particle contact
|
|
1059
1388
|
has_ground: bool,
|
|
1060
1389
|
ground: wp.array(dtype=float),
|
|
1390
|
+
particle_radius: wp.array(dtype=float),
|
|
1391
|
+
# output
|
|
1392
|
+
pos_new: wp.array(dtype=wp.vec3),
|
|
1061
1393
|
):
|
|
1062
1394
|
tid = wp.tid()
|
|
1063
1395
|
|
|
1064
1396
|
particle_index = particle_ids_in_color[tid]
|
|
1397
|
+
particle_pos = pos[particle_index]
|
|
1065
1398
|
|
|
1066
1399
|
if not particle_flags[particle_index] & PARTICLE_FLAG_ACTIVE:
|
|
1400
|
+
pos_new[particle_index] = particle_pos
|
|
1067
1401
|
return
|
|
1068
1402
|
|
|
1069
|
-
particle_pos = pos[particle_index]
|
|
1070
1403
|
particle_prev_pos = pos[particle_index]
|
|
1071
1404
|
|
|
1072
1405
|
dt_sqr_reciprocal = 1.0 / (dt * dt)
|
|
@@ -1144,38 +1477,6 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1144
1477
|
f = f + f_edge
|
|
1145
1478
|
h = h + h_edge
|
|
1146
1479
|
|
|
1147
|
-
# body-particle contact
|
|
1148
|
-
particle_contact_count = min(body_particle_contact_count[particle_index], body_particle_contact_buffer_pre_alloc)
|
|
1149
|
-
|
|
1150
|
-
offset = body_particle_contact_buffer_pre_alloc * particle_index
|
|
1151
|
-
for contact_counter in range(particle_contact_count):
|
|
1152
|
-
# the index to access body-particle data, which is size-variable and only contains active contact
|
|
1153
|
-
contact_index = body_particle_contact_buffer[offset + contact_counter]
|
|
1154
|
-
|
|
1155
|
-
body_contact_force, body_contact_hessian = evaluate_body_particle_contact(
|
|
1156
|
-
particle_index,
|
|
1157
|
-
particle_pos,
|
|
1158
|
-
particle_prev_pos,
|
|
1159
|
-
contact_index,
|
|
1160
|
-
soft_contact_ke,
|
|
1161
|
-
friction_mu,
|
|
1162
|
-
friction_epsilon,
|
|
1163
|
-
particle_radius,
|
|
1164
|
-
shape_materials,
|
|
1165
|
-
shape_body,
|
|
1166
|
-
body_q,
|
|
1167
|
-
body_qd,
|
|
1168
|
-
body_com,
|
|
1169
|
-
contact_shape,
|
|
1170
|
-
contact_body_pos,
|
|
1171
|
-
contact_body_vel,
|
|
1172
|
-
contact_normal,
|
|
1173
|
-
dt,
|
|
1174
|
-
)
|
|
1175
|
-
|
|
1176
|
-
f = f + body_contact_force
|
|
1177
|
-
h = h + body_contact_hessian
|
|
1178
|
-
|
|
1179
1480
|
if has_ground:
|
|
1180
1481
|
ground_normal = wp.vec3(ground[0], ground[1], ground[2])
|
|
1181
1482
|
ground_level = ground[3]
|
|
@@ -1186,6 +1487,7 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1186
1487
|
ground_normal,
|
|
1187
1488
|
ground_level,
|
|
1188
1489
|
soft_contact_ke,
|
|
1490
|
+
soft_contact_kd,
|
|
1189
1491
|
friction_mu,
|
|
1190
1492
|
friction_epsilon,
|
|
1191
1493
|
dt,
|
|
@@ -1244,40 +1546,28 @@ def convert_body_particle_contact_data_kernel(
|
|
|
1244
1546
|
|
|
1245
1547
|
|
|
1246
1548
|
@wp.kernel
|
|
1247
|
-
def
|
|
1549
|
+
def VBD_accumulate_contact_force_and_hessian(
|
|
1550
|
+
# inputs
|
|
1248
1551
|
dt: float,
|
|
1249
|
-
|
|
1552
|
+
current_color: int,
|
|
1250
1553
|
pos_prev: wp.array(dtype=wp.vec3),
|
|
1251
1554
|
pos: wp.array(dtype=wp.vec3),
|
|
1252
|
-
|
|
1253
|
-
vel: wp.array(dtype=wp.vec3),
|
|
1254
|
-
mass: wp.array(dtype=float),
|
|
1255
|
-
inertia: wp.array(dtype=wp.vec3),
|
|
1256
|
-
particle_flags: wp.array(dtype=wp.uint32),
|
|
1555
|
+
particle_colors: wp.array(dtype=int),
|
|
1257
1556
|
tri_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1258
|
-
tri_poses: wp.array(dtype=wp.mat22),
|
|
1259
|
-
tri_materials: wp.array(dtype=float, ndim=2),
|
|
1260
|
-
tri_areas: wp.array(dtype=float),
|
|
1261
1557
|
edge_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
edge_bending_properties: wp.array(dtype=float, ndim=2),
|
|
1265
|
-
adjacency: ForceElementAdjacencyInfo,
|
|
1266
|
-
# contact info
|
|
1267
|
-
# self contact
|
|
1268
|
-
collision_info: TriMeshCollisionInfo,
|
|
1558
|
+
# self contact
|
|
1559
|
+
collision_info_array: wp.array(dtype=TriMeshCollisionInfo),
|
|
1269
1560
|
collision_radius: float,
|
|
1270
1561
|
soft_contact_ke: float,
|
|
1562
|
+
soft_contact_kd: float,
|
|
1271
1563
|
friction_mu: float,
|
|
1272
1564
|
friction_epsilon: float,
|
|
1273
|
-
pos_prev_collision_detection: wp.array(dtype=wp.vec3),
|
|
1274
|
-
particle_conservative_bounds: wp.array(dtype=float),
|
|
1275
1565
|
edge_edge_parallel_epsilon: float,
|
|
1276
|
-
#
|
|
1566
|
+
# body-particle contact
|
|
1277
1567
|
particle_radius: wp.array(dtype=float),
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1568
|
+
soft_contact_particle: wp.array(dtype=int),
|
|
1569
|
+
contact_count: wp.array(dtype=int),
|
|
1570
|
+
contact_max: int,
|
|
1281
1571
|
shape_materials: ModelShapeMaterials,
|
|
1282
1572
|
shape_body: wp.array(dtype=int),
|
|
1283
1573
|
body_q: wp.array(dtype=wp.transform),
|
|
@@ -1287,9 +1577,235 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1287
1577
|
contact_body_pos: wp.array(dtype=wp.vec3),
|
|
1288
1578
|
contact_body_vel: wp.array(dtype=wp.vec3),
|
|
1289
1579
|
contact_normal: wp.array(dtype=wp.vec3),
|
|
1580
|
+
# outputs: particle force and hessian
|
|
1581
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1582
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1583
|
+
):
|
|
1584
|
+
t_id = wp.tid()
|
|
1585
|
+
collision_info = collision_info_array[0]
|
|
1586
|
+
|
|
1587
|
+
# process edge-edge collisions
|
|
1588
|
+
if t_id * 2 < collision_info.edge_colliding_edges.shape[0]:
|
|
1589
|
+
e1_idx = collision_info.edge_colliding_edges[2 * t_id]
|
|
1590
|
+
e2_idx = collision_info.edge_colliding_edges[2 * t_id + 1]
|
|
1591
|
+
|
|
1592
|
+
if e1_idx != -1 and e2_idx != -1:
|
|
1593
|
+
e1_v1 = edge_indices[e1_idx, 2]
|
|
1594
|
+
e1_v2 = edge_indices[e1_idx, 3]
|
|
1595
|
+
if particle_colors[e1_v1] == current_color or particle_colors[e1_v2] == current_color:
|
|
1596
|
+
has_contact, collision_force_0, collision_force_1, collision_hessian_0, collision_hessian_1 = (
|
|
1597
|
+
evaluate_edge_edge_contact_2_vertices(
|
|
1598
|
+
e1_idx,
|
|
1599
|
+
e2_idx,
|
|
1600
|
+
pos,
|
|
1601
|
+
pos_prev,
|
|
1602
|
+
edge_indices,
|
|
1603
|
+
collision_radius,
|
|
1604
|
+
soft_contact_ke,
|
|
1605
|
+
soft_contact_kd,
|
|
1606
|
+
friction_mu,
|
|
1607
|
+
friction_epsilon,
|
|
1608
|
+
dt,
|
|
1609
|
+
edge_edge_parallel_epsilon,
|
|
1610
|
+
)
|
|
1611
|
+
)
|
|
1612
|
+
|
|
1613
|
+
if has_contact:
|
|
1614
|
+
# here we only handle the e1 side, because e2 will also detection this contact and add force and hessian on its own
|
|
1615
|
+
if particle_colors[e1_v1] == current_color:
|
|
1616
|
+
wp.atomic_add(particle_forces, e1_v1, collision_force_0)
|
|
1617
|
+
wp.atomic_add(particle_hessians, e1_v1, collision_hessian_0)
|
|
1618
|
+
if particle_colors[e1_v2] == current_color:
|
|
1619
|
+
wp.atomic_add(particle_forces, e1_v2, collision_force_1)
|
|
1620
|
+
wp.atomic_add(particle_hessians, e1_v2, collision_hessian_1)
|
|
1621
|
+
|
|
1622
|
+
# process vertex-triangle collisions
|
|
1623
|
+
if t_id * 2 < collision_info.vertex_colliding_triangles.shape[0]:
|
|
1624
|
+
particle_idx = collision_info.vertex_colliding_triangles[2 * t_id]
|
|
1625
|
+
tri_idx = collision_info.vertex_colliding_triangles[2 * t_id + 1]
|
|
1626
|
+
|
|
1627
|
+
if particle_idx != -1 and tri_idx != -1:
|
|
1628
|
+
tri_a = tri_indices[tri_idx, 0]
|
|
1629
|
+
tri_b = tri_indices[tri_idx, 1]
|
|
1630
|
+
tri_c = tri_indices[tri_idx, 2]
|
|
1631
|
+
if (
|
|
1632
|
+
particle_colors[particle_idx] == current_color
|
|
1633
|
+
or particle_colors[tri_a] == current_color
|
|
1634
|
+
or particle_colors[tri_b] == current_color
|
|
1635
|
+
or particle_colors[tri_c] == current_color
|
|
1636
|
+
):
|
|
1637
|
+
(
|
|
1638
|
+
has_contact,
|
|
1639
|
+
collision_force_0,
|
|
1640
|
+
collision_force_1,
|
|
1641
|
+
collision_force_2,
|
|
1642
|
+
collision_force_3,
|
|
1643
|
+
collision_hessian_0,
|
|
1644
|
+
collision_hessian_1,
|
|
1645
|
+
collision_hessian_2,
|
|
1646
|
+
collision_hessian_3,
|
|
1647
|
+
) = evaluate_vertex_triangle_collision_force_hessian_4_vertices(
|
|
1648
|
+
particle_idx,
|
|
1649
|
+
tri_idx,
|
|
1650
|
+
pos,
|
|
1651
|
+
pos_prev,
|
|
1652
|
+
tri_indices,
|
|
1653
|
+
collision_radius,
|
|
1654
|
+
soft_contact_ke,
|
|
1655
|
+
soft_contact_kd,
|
|
1656
|
+
friction_mu,
|
|
1657
|
+
friction_epsilon,
|
|
1658
|
+
dt,
|
|
1659
|
+
)
|
|
1660
|
+
|
|
1661
|
+
if has_contact:
|
|
1662
|
+
# particle
|
|
1663
|
+
if particle_colors[particle_idx] == current_color:
|
|
1664
|
+
wp.atomic_add(particle_forces, particle_idx, collision_force_3)
|
|
1665
|
+
wp.atomic_add(particle_hessians, particle_idx, collision_hessian_3)
|
|
1666
|
+
|
|
1667
|
+
# tri_a
|
|
1668
|
+
if particle_colors[tri_a] == current_color:
|
|
1669
|
+
wp.atomic_add(particle_forces, tri_a, collision_force_0)
|
|
1670
|
+
wp.atomic_add(particle_hessians, tri_a, collision_hessian_0)
|
|
1671
|
+
|
|
1672
|
+
# tri_b
|
|
1673
|
+
if particle_colors[tri_b] == current_color:
|
|
1674
|
+
wp.atomic_add(particle_forces, tri_b, collision_force_1)
|
|
1675
|
+
wp.atomic_add(particle_hessians, tri_b, collision_hessian_1)
|
|
1676
|
+
|
|
1677
|
+
# tri_c
|
|
1678
|
+
if particle_colors[tri_c] == current_color:
|
|
1679
|
+
wp.atomic_add(particle_forces, tri_c, collision_force_2)
|
|
1680
|
+
wp.atomic_add(particle_hessians, tri_c, collision_hessian_2)
|
|
1681
|
+
|
|
1682
|
+
particle_body_contact_count = min(contact_max, contact_count[0])
|
|
1683
|
+
|
|
1684
|
+
if t_id < particle_body_contact_count:
|
|
1685
|
+
particle_idx = soft_contact_particle[t_id]
|
|
1686
|
+
|
|
1687
|
+
if particle_colors[particle_idx] == current_color:
|
|
1688
|
+
body_contact_force, body_contact_hessian = evaluate_body_particle_contact(
|
|
1689
|
+
particle_idx,
|
|
1690
|
+
pos[particle_idx],
|
|
1691
|
+
pos_prev[particle_idx],
|
|
1692
|
+
t_id,
|
|
1693
|
+
soft_contact_ke,
|
|
1694
|
+
soft_contact_kd,
|
|
1695
|
+
friction_mu,
|
|
1696
|
+
friction_epsilon,
|
|
1697
|
+
particle_radius,
|
|
1698
|
+
shape_materials,
|
|
1699
|
+
shape_body,
|
|
1700
|
+
body_q,
|
|
1701
|
+
body_qd,
|
|
1702
|
+
body_com,
|
|
1703
|
+
contact_shape,
|
|
1704
|
+
contact_body_pos,
|
|
1705
|
+
contact_body_vel,
|
|
1706
|
+
contact_normal,
|
|
1707
|
+
dt,
|
|
1708
|
+
)
|
|
1709
|
+
wp.atomic_add(particle_forces, particle_idx, body_contact_force)
|
|
1710
|
+
wp.atomic_add(particle_hessians, particle_idx, body_contact_hessian)
|
|
1711
|
+
|
|
1712
|
+
|
|
1713
|
+
@wp.kernel
|
|
1714
|
+
def VBD_accumulate_contact_force_and_hessian_no_self_contact(
|
|
1715
|
+
# inputs
|
|
1716
|
+
dt: float,
|
|
1717
|
+
current_color: int,
|
|
1718
|
+
pos_prev: wp.array(dtype=wp.vec3),
|
|
1719
|
+
pos: wp.array(dtype=wp.vec3),
|
|
1720
|
+
particle_colors: wp.array(dtype=int),
|
|
1721
|
+
# body-particle contact
|
|
1722
|
+
soft_contact_ke: float,
|
|
1723
|
+
soft_contact_kd: float,
|
|
1724
|
+
friction_mu: float,
|
|
1725
|
+
friction_epsilon: float,
|
|
1726
|
+
particle_radius: wp.array(dtype=float),
|
|
1727
|
+
soft_contact_particle: wp.array(dtype=int),
|
|
1728
|
+
contact_count: wp.array(dtype=int),
|
|
1729
|
+
contact_max: int,
|
|
1730
|
+
shape_materials: ModelShapeMaterials,
|
|
1731
|
+
shape_body: wp.array(dtype=int),
|
|
1732
|
+
body_q: wp.array(dtype=wp.transform),
|
|
1733
|
+
body_qd: wp.array(dtype=wp.spatial_vector),
|
|
1734
|
+
body_com: wp.array(dtype=wp.vec3),
|
|
1735
|
+
contact_shape: wp.array(dtype=int),
|
|
1736
|
+
contact_body_pos: wp.array(dtype=wp.vec3),
|
|
1737
|
+
contact_body_vel: wp.array(dtype=wp.vec3),
|
|
1738
|
+
contact_normal: wp.array(dtype=wp.vec3),
|
|
1739
|
+
# outputs: particle force and hessian
|
|
1740
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1741
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1742
|
+
):
|
|
1743
|
+
t_id = wp.tid()
|
|
1744
|
+
|
|
1745
|
+
particle_body_contact_count = min(contact_max, contact_count[0])
|
|
1746
|
+
|
|
1747
|
+
if t_id < particle_body_contact_count:
|
|
1748
|
+
particle_idx = soft_contact_particle[t_id]
|
|
1749
|
+
|
|
1750
|
+
if particle_colors[particle_idx] == current_color:
|
|
1751
|
+
body_contact_force, body_contact_hessian = evaluate_body_particle_contact(
|
|
1752
|
+
particle_idx,
|
|
1753
|
+
pos[particle_idx],
|
|
1754
|
+
pos_prev[particle_idx],
|
|
1755
|
+
t_id,
|
|
1756
|
+
soft_contact_ke,
|
|
1757
|
+
soft_contact_kd,
|
|
1758
|
+
friction_mu,
|
|
1759
|
+
friction_epsilon,
|
|
1760
|
+
particle_radius,
|
|
1761
|
+
shape_materials,
|
|
1762
|
+
shape_body,
|
|
1763
|
+
body_q,
|
|
1764
|
+
body_qd,
|
|
1765
|
+
body_com,
|
|
1766
|
+
contact_shape,
|
|
1767
|
+
contact_body_pos,
|
|
1768
|
+
contact_body_vel,
|
|
1769
|
+
contact_normal,
|
|
1770
|
+
dt,
|
|
1771
|
+
)
|
|
1772
|
+
wp.atomic_add(particle_forces, particle_idx, body_contact_force)
|
|
1773
|
+
wp.atomic_add(particle_hessians, particle_idx, body_contact_hessian)
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
@wp.kernel
|
|
1777
|
+
def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
1778
|
+
dt: float,
|
|
1779
|
+
particle_ids_in_color: wp.array(dtype=wp.int32),
|
|
1780
|
+
pos_prev: wp.array(dtype=wp.vec3),
|
|
1781
|
+
pos: wp.array(dtype=wp.vec3),
|
|
1782
|
+
vel: wp.array(dtype=wp.vec3),
|
|
1783
|
+
mass: wp.array(dtype=float),
|
|
1784
|
+
inertia: wp.array(dtype=wp.vec3),
|
|
1785
|
+
particle_flags: wp.array(dtype=wp.uint32),
|
|
1786
|
+
tri_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1787
|
+
tri_poses: wp.array(dtype=wp.mat22),
|
|
1788
|
+
tri_materials: wp.array(dtype=float, ndim=2),
|
|
1789
|
+
tri_areas: wp.array(dtype=float),
|
|
1790
|
+
edge_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1791
|
+
edge_rest_angles: wp.array(dtype=float),
|
|
1792
|
+
edge_rest_length: wp.array(dtype=float),
|
|
1793
|
+
edge_bending_properties: wp.array(dtype=float, ndim=2),
|
|
1794
|
+
adjacency: ForceElementAdjacencyInfo,
|
|
1795
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1796
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1797
|
+
pos_prev_collision_detection: wp.array(dtype=wp.vec3),
|
|
1798
|
+
particle_conservative_bounds: wp.array(dtype=float),
|
|
1290
1799
|
# ground-particle contact
|
|
1291
1800
|
has_ground: bool,
|
|
1292
1801
|
ground: wp.array(dtype=float),
|
|
1802
|
+
soft_contact_ke: float,
|
|
1803
|
+
soft_contact_kd: float,
|
|
1804
|
+
friction_mu: float,
|
|
1805
|
+
friction_epsilon: float,
|
|
1806
|
+
particle_radius: wp.array(dtype=float),
|
|
1807
|
+
# output
|
|
1808
|
+
pos_new: wp.array(dtype=wp.vec3),
|
|
1293
1809
|
):
|
|
1294
1810
|
t_id = wp.tid()
|
|
1295
1811
|
|
|
@@ -1298,13 +1814,14 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1298
1814
|
particle_prev_pos = pos_prev[particle_index]
|
|
1299
1815
|
|
|
1300
1816
|
if not particle_flags[particle_index] & PARTICLE_FLAG_ACTIVE:
|
|
1817
|
+
pos_new[particle_index] = particle_pos
|
|
1301
1818
|
return
|
|
1302
1819
|
|
|
1303
1820
|
dt_sqr_reciprocal = 1.0 / (dt * dt)
|
|
1304
1821
|
|
|
1305
1822
|
# inertia force and hessian
|
|
1306
1823
|
f = mass[particle_index] * (inertia[particle_index] - pos[particle_index]) * (dt_sqr_reciprocal)
|
|
1307
|
-
h = mass[particle_index] * dt_sqr_reciprocal * wp.identity(n=3, dtype=float)
|
|
1824
|
+
h = particle_hessians[particle_index] + mass[particle_index] * dt_sqr_reciprocal * wp.identity(n=3, dtype=float)
|
|
1308
1825
|
|
|
1309
1826
|
# fmt: off
|
|
1310
1827
|
if wp.static("inertia_force_hessian" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
@@ -1314,48 +1831,6 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1314
1831
|
f[0], f[1], f[2], h[0, 0], h[0, 1], h[0, 2], h[1, 0], h[1, 1], h[1, 2], h[2, 0], h[2, 1], h[2, 2],
|
|
1315
1832
|
)
|
|
1316
1833
|
|
|
1317
|
-
# v-side of the v-f collision force
|
|
1318
|
-
if wp.static("contact_info" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1319
|
-
wp.printf("Has %d colliding triangles\n", get_vertex_colliding_triangles_count(collision_info, particle_index))
|
|
1320
|
-
for i_v_collision in range(get_vertex_colliding_triangles_count(collision_info, particle_index)):
|
|
1321
|
-
colliding_t = get_vertex_colliding_triangles(collision_info, particle_index, i_v_collision)
|
|
1322
|
-
if wp.static("contact_info" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1323
|
-
wp.printf(
|
|
1324
|
-
"vertex %d is colliding with triangle: %d-(%d, %d, %d)",
|
|
1325
|
-
particle_index,
|
|
1326
|
-
colliding_t,
|
|
1327
|
-
tri_indices[colliding_t, 0],
|
|
1328
|
-
tri_indices[colliding_t, 1],
|
|
1329
|
-
tri_indices[colliding_t, 2],
|
|
1330
|
-
)
|
|
1331
|
-
# fmt: on
|
|
1332
|
-
|
|
1333
|
-
collision_force, collision_hessian = evaluate_vertex_triangle_collision_force_hessian(
|
|
1334
|
-
particle_index,
|
|
1335
|
-
3,
|
|
1336
|
-
colliding_t,
|
|
1337
|
-
pos,
|
|
1338
|
-
pos_prev,
|
|
1339
|
-
tri_indices,
|
|
1340
|
-
collision_radius,
|
|
1341
|
-
soft_contact_ke,
|
|
1342
|
-
friction_mu,
|
|
1343
|
-
friction_epsilon,
|
|
1344
|
-
dt,
|
|
1345
|
-
)
|
|
1346
|
-
f = f + collision_force
|
|
1347
|
-
h = h + collision_hessian
|
|
1348
|
-
|
|
1349
|
-
# fmt: off
|
|
1350
|
-
if wp.static("contact_force_hessian" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1351
|
-
wp.printf(
|
|
1352
|
-
"vertex: %d collision %d:\nforce:\n %f %f %f, \nhessian:, \n%f %f %f, \n%f %f %f, \n%f %f %f\n",
|
|
1353
|
-
particle_index,
|
|
1354
|
-
i_v_collision,
|
|
1355
|
-
collision_force[0], collision_force[1], collision_force[2], collision_hessian[0, 0], collision_hessian[0, 1], collision_hessian[0, 2], collision_hessian[1, 0], collision_hessian[1, 1], collision_hessian[1, 2], collision_hessian[2, 0], collision_hessian[2, 1], collision_hessian[2, 2],
|
|
1356
|
-
)
|
|
1357
|
-
# fmt: on
|
|
1358
|
-
|
|
1359
1834
|
# elastic force and hessian
|
|
1360
1835
|
for i_adj_tri in range(get_vertex_num_adjacent_faces(adjacency, particle_index)):
|
|
1361
1836
|
tri_index, vertex_order = get_vertex_adjacent_face_id_order(adjacency, particle_index, i_adj_tri)
|
|
@@ -1391,41 +1866,12 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1391
1866
|
k_d = tri_materials[tri_index, 2]
|
|
1392
1867
|
h_d = h_tri * (k_d / dt)
|
|
1393
1868
|
|
|
1394
|
-
f_d = h_d * (
|
|
1869
|
+
f_d = h_d * (particle_prev_pos - particle_pos)
|
|
1395
1870
|
|
|
1396
1871
|
f = f + f_tri + f_d
|
|
1397
1872
|
h = h + h_tri + h_d
|
|
1398
1873
|
|
|
1399
|
-
# t-side of vt-collision from the neighbor triangles
|
|
1400
|
-
# fmt: off
|
|
1401
|
-
if wp.static("contact_info" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1402
|
-
wp.printf(
|
|
1403
|
-
"Nei triangle %d has %d colliding vertice\n",
|
|
1404
|
-
tri_index,
|
|
1405
|
-
get_triangle_colliding_vertices_count(collision_info, tri_index),
|
|
1406
|
-
)
|
|
1407
|
-
# fmt: on
|
|
1408
|
-
for i_t_collision in range(get_triangle_colliding_vertices_count(collision_info, tri_index)):
|
|
1409
|
-
colliding_v = get_triangle_colliding_vertices(collision_info, tri_index, i_t_collision)
|
|
1410
|
-
|
|
1411
|
-
collision_force, collision_hessian = evaluate_vertex_triangle_collision_force_hessian(
|
|
1412
|
-
colliding_v,
|
|
1413
|
-
vertex_order,
|
|
1414
|
-
tri_index,
|
|
1415
|
-
pos,
|
|
1416
|
-
pos_prev,
|
|
1417
|
-
tri_indices,
|
|
1418
|
-
collision_radius,
|
|
1419
|
-
soft_contact_ke,
|
|
1420
|
-
friction_mu,
|
|
1421
|
-
friction_epsilon,
|
|
1422
|
-
dt,
|
|
1423
|
-
)
|
|
1424
|
-
|
|
1425
|
-
f = f + collision_force
|
|
1426
|
-
h = h + collision_hessian
|
|
1427
1874
|
|
|
1428
|
-
# edge-edge collision force and hessian
|
|
1429
1875
|
for i_adj_edge in range(get_vertex_num_adjacent_edges(adjacency, particle_index)):
|
|
1430
1876
|
nei_edge_index, vertex_order_on_edge = get_vertex_adjacent_edge_id_order(adjacency, particle_index, i_adj_edge)
|
|
1431
1877
|
# vertex is on the edge; otherwise it only effects the bending energy n
|
|
@@ -1438,78 +1884,6 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1438
1884
|
f = f + f_edge
|
|
1439
1885
|
h = h + h_edge
|
|
1440
1886
|
|
|
1441
|
-
if vertex_order_on_edge == 2 or vertex_order_on_edge == 3:
|
|
1442
|
-
# collisions of neighbor triangles
|
|
1443
|
-
if wp.static("contact_info" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1444
|
-
wp.printf(
|
|
1445
|
-
"Nei edge %d has %d colliding edge\n",
|
|
1446
|
-
nei_edge_index,
|
|
1447
|
-
get_edge_colliding_edges_count(collision_info, nei_edge_index),
|
|
1448
|
-
)
|
|
1449
|
-
for i_e_collision in range(get_edge_colliding_edges_count(collision_info, nei_edge_index)):
|
|
1450
|
-
colliding_e = get_edge_colliding_edges(collision_info, nei_edge_index, i_e_collision)
|
|
1451
|
-
|
|
1452
|
-
collision_force, collision_hessian = evaluate_edge_edge_contact(
|
|
1453
|
-
particle_index,
|
|
1454
|
-
vertex_order_on_edge - 2,
|
|
1455
|
-
nei_edge_index,
|
|
1456
|
-
colliding_e,
|
|
1457
|
-
pos,
|
|
1458
|
-
pos_prev,
|
|
1459
|
-
edge_indices,
|
|
1460
|
-
collision_radius,
|
|
1461
|
-
soft_contact_ke,
|
|
1462
|
-
friction_mu,
|
|
1463
|
-
friction_epsilon,
|
|
1464
|
-
dt,
|
|
1465
|
-
edge_edge_parallel_epsilon,
|
|
1466
|
-
)
|
|
1467
|
-
f = f + collision_force
|
|
1468
|
-
h = h + collision_hessian
|
|
1469
|
-
|
|
1470
|
-
# fmt: off
|
|
1471
|
-
if wp.static("contact_force_hessian" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
1472
|
-
wp.printf(
|
|
1473
|
-
"vertex: %d edge %d collision %d:\nforce:\n %f %f %f, \nhessian:, \n%f %f %f, \n%f %f %f, \n%f %f %f\n",
|
|
1474
|
-
particle_index,
|
|
1475
|
-
nei_edge_index,
|
|
1476
|
-
i_e_collision,
|
|
1477
|
-
collision_force[0], collision_force[1], collision_force[2], collision_hessian[0, 0], collision_hessian[0, 1], collision_hessian[0, 2], collision_hessian[1, 0], collision_hessian[1, 1], collision_hessian[1, 2], collision_hessian[2, 0], collision_hessian[2, 1], collision_hessian[2, 2],
|
|
1478
|
-
)
|
|
1479
|
-
# fmt: on
|
|
1480
|
-
|
|
1481
|
-
# body-particle contact
|
|
1482
|
-
particle_contact_count = min(body_particle_contact_count[particle_index], body_particle_contact_buffer_pre_alloc)
|
|
1483
|
-
|
|
1484
|
-
offset = body_particle_contact_buffer_pre_alloc * particle_index
|
|
1485
|
-
for contact_counter in range(particle_contact_count):
|
|
1486
|
-
# the index to access body-particle data, which is size-variable and only contains active contact
|
|
1487
|
-
contact_index = body_particle_contact_buffer[offset + contact_counter]
|
|
1488
|
-
|
|
1489
|
-
body_contact_force, body_contact_hessian = evaluate_body_particle_contact(
|
|
1490
|
-
particle_index,
|
|
1491
|
-
particle_pos,
|
|
1492
|
-
particle_prev_pos,
|
|
1493
|
-
contact_index,
|
|
1494
|
-
soft_contact_ke,
|
|
1495
|
-
friction_mu,
|
|
1496
|
-
friction_epsilon,
|
|
1497
|
-
particle_radius,
|
|
1498
|
-
shape_materials,
|
|
1499
|
-
shape_body,
|
|
1500
|
-
body_q,
|
|
1501
|
-
body_qd,
|
|
1502
|
-
body_com,
|
|
1503
|
-
contact_shape,
|
|
1504
|
-
contact_body_pos,
|
|
1505
|
-
contact_body_vel,
|
|
1506
|
-
contact_normal,
|
|
1507
|
-
dt,
|
|
1508
|
-
)
|
|
1509
|
-
|
|
1510
|
-
f = f + body_contact_force
|
|
1511
|
-
h = h + body_contact_hessian
|
|
1512
|
-
|
|
1513
1887
|
if has_ground:
|
|
1514
1888
|
ground_normal = wp.vec3(ground[0], ground[1], ground[2])
|
|
1515
1889
|
ground_level = ground[3]
|
|
@@ -1520,6 +1894,7 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1520
1894
|
ground_normal,
|
|
1521
1895
|
ground_level,
|
|
1522
1896
|
soft_contact_ke,
|
|
1897
|
+
soft_contact_kd,
|
|
1523
1898
|
friction_mu,
|
|
1524
1899
|
friction_epsilon,
|
|
1525
1900
|
dt,
|
|
@@ -1535,9 +1910,12 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1535
1910
|
particle_index,
|
|
1536
1911
|
f[0], f[1], f[2], h[0, 0], h[0, 1], h[0, 2], h[1, 0], h[1, 1], h[1, 2], h[2, 0], h[2, 1], h[2, 2],
|
|
1537
1912
|
)
|
|
1538
|
-
# fmt: on
|
|
1539
1913
|
|
|
1914
|
+
# # fmt: on
|
|
1915
|
+
h = h + particle_hessians[particle_index]
|
|
1916
|
+
f = f + particle_forces[particle_index]
|
|
1540
1917
|
if abs(wp.determinant(h)) > 1e-5:
|
|
1918
|
+
|
|
1541
1919
|
h_inv = wp.inverse(h)
|
|
1542
1920
|
particle_pos_new = pos[particle_index] + h_inv * f
|
|
1543
1921
|
|
|
@@ -1554,7 +1932,7 @@ class VBDIntegrator(Integrator):
|
|
|
1554
1932
|
|
|
1555
1933
|
Note that VBDIntegrator's constructor requires a :class:`Model` object as input, so that it can do some precomputation and preallocate the space.
|
|
1556
1934
|
After construction, you must provide the same :class:`Model` object that you used that was used during construction.
|
|
1557
|
-
Currently, you must manually provide particle coloring and assign it to `model.
|
|
1935
|
+
Currently, you must manually provide particle coloring and assign it to `model.particle_color_groups` to make VBD work.
|
|
1558
1936
|
|
|
1559
1937
|
VBDIntegrator.simulate accepts three arguments: class:`Model`, :class:`State`, and :class:`Control` (optional) objects, this time-integrator
|
|
1560
1938
|
may be used to advance the simulation state forward in time.
|
|
@@ -1564,7 +1942,7 @@ class VBDIntegrator(Integrator):
|
|
|
1564
1942
|
|
|
1565
1943
|
.. code-block:: python
|
|
1566
1944
|
|
|
1567
|
-
model.
|
|
1945
|
+
model.particle_color_groups = # load or generate particle coloring
|
|
1568
1946
|
integrator = wp.VBDIntegrator(model)
|
|
1569
1947
|
|
|
1570
1948
|
# simulation loop
|
|
@@ -1596,13 +1974,6 @@ class VBDIntegrator(Integrator):
|
|
|
1596
1974
|
|
|
1597
1975
|
self.adjacency = self.compute_force_element_adjacency(model).to(self.device)
|
|
1598
1976
|
|
|
1599
|
-
# data for body-particle collision
|
|
1600
|
-
self.body_particle_contact_buffer_pre_alloc = body_particle_contact_buffer_pre_alloc
|
|
1601
|
-
self.body_particle_contact_buffer = wp.zeros(
|
|
1602
|
-
(self.body_particle_contact_buffer_pre_alloc * model.particle_count,),
|
|
1603
|
-
dtype=wp.int32,
|
|
1604
|
-
device=self.device,
|
|
1605
|
-
)
|
|
1606
1977
|
self.body_particle_contact_count = wp.zeros((model.particle_count,), dtype=wp.int32, device=self.device)
|
|
1607
1978
|
|
|
1608
1979
|
self.handle_self_contact = handle_self_contact
|
|
@@ -1626,11 +1997,27 @@ class VBDIntegrator(Integrator):
|
|
|
1626
1997
|
edge_edge_parallel_epsilon=edge_edge_parallel_epsilon,
|
|
1627
1998
|
)
|
|
1628
1999
|
|
|
2000
|
+
self.trimesh_collision_info = wp.array(
|
|
2001
|
+
[self.trimesh_collision_detector.collision_info], dtype=TriMeshCollisionInfo, device=self.device
|
|
2002
|
+
)
|
|
2003
|
+
|
|
2004
|
+
self.collision_evaluation_kernel_launch_size = max(
|
|
2005
|
+
self.trimesh_collision_detector.vertex_colliding_triangles.shape[0] // 2,
|
|
2006
|
+
self.trimesh_collision_detector.edge_colliding_edges.shape[0] // 2,
|
|
2007
|
+
self.model.soft_contact_max,
|
|
2008
|
+
)
|
|
2009
|
+
else:
|
|
2010
|
+
self.collision_evaluation_kernel_launch_size = self.model.soft_contact_max
|
|
2011
|
+
|
|
2012
|
+
# spaces for particle force and hessian
|
|
2013
|
+
self.particle_forces = wp.zeros(self.model.particle_count, dtype=wp.vec3, device=self.device)
|
|
2014
|
+
self.particle_hessians = wp.zeros(self.model.particle_count, dtype=wp.mat33, device=self.device)
|
|
2015
|
+
|
|
1629
2016
|
self.friction_epsilon = friction_epsilon
|
|
1630
2017
|
|
|
1631
|
-
if len(self.model.
|
|
2018
|
+
if len(self.model.particle_color_groups) == 0:
|
|
1632
2019
|
raise ValueError(
|
|
1633
|
-
"model.
|
|
2020
|
+
"model.particle_color_groups is empty! When using the VBDIntegrator you must call ModelBuilder.color() "
|
|
1634
2021
|
"or ModelBuilder.set_coloring() before calling ModelBuilder.finalize()."
|
|
1635
2022
|
)
|
|
1636
2023
|
|
|
@@ -1733,8 +2120,6 @@ class VBDIntegrator(Integrator):
|
|
|
1733
2120
|
def simulate_one_step_no_self_contact(
|
|
1734
2121
|
self, model: Model, state_in: State, state_out: State, dt: float, control: Control = None
|
|
1735
2122
|
):
|
|
1736
|
-
self.convert_body_particle_contact_data()
|
|
1737
|
-
|
|
1738
2123
|
wp.launch(
|
|
1739
2124
|
kernel=forward_step,
|
|
1740
2125
|
inputs=[
|
|
@@ -1753,15 +2138,46 @@ class VBDIntegrator(Integrator):
|
|
|
1753
2138
|
)
|
|
1754
2139
|
|
|
1755
2140
|
for _iter in range(self.iterations):
|
|
1756
|
-
for
|
|
2141
|
+
for color in range(len(self.model.particle_color_groups)):
|
|
2142
|
+
wp.launch(
|
|
2143
|
+
kernel=VBD_accumulate_contact_force_and_hessian_no_self_contact,
|
|
2144
|
+
dim=self.collision_evaluation_kernel_launch_size,
|
|
2145
|
+
inputs=[
|
|
2146
|
+
dt,
|
|
2147
|
+
color,
|
|
2148
|
+
self.particle_q_prev,
|
|
2149
|
+
state_in.particle_q,
|
|
2150
|
+
self.model.particle_colors,
|
|
2151
|
+
# body-particle contact
|
|
2152
|
+
self.model.soft_contact_ke,
|
|
2153
|
+
self.model.soft_contact_kd,
|
|
2154
|
+
self.model.soft_contact_mu,
|
|
2155
|
+
self.friction_epsilon,
|
|
2156
|
+
self.model.particle_radius,
|
|
2157
|
+
self.model.soft_contact_particle,
|
|
2158
|
+
self.model.soft_contact_count,
|
|
2159
|
+
self.model.soft_contact_max,
|
|
2160
|
+
self.model.shape_materials,
|
|
2161
|
+
self.model.shape_body,
|
|
2162
|
+
self.model.body_q,
|
|
2163
|
+
self.model.body_qd,
|
|
2164
|
+
self.model.body_com,
|
|
2165
|
+
self.model.soft_contact_shape,
|
|
2166
|
+
self.model.soft_contact_body_pos,
|
|
2167
|
+
self.model.soft_contact_body_vel,
|
|
2168
|
+
self.model.soft_contact_normal,
|
|
2169
|
+
],
|
|
2170
|
+
outputs=[self.particle_forces, self.particle_hessians],
|
|
2171
|
+
device=self.device,
|
|
2172
|
+
)
|
|
2173
|
+
|
|
1757
2174
|
wp.launch(
|
|
1758
2175
|
kernel=VBD_solve_trimesh_no_self_contact,
|
|
1759
2176
|
inputs=[
|
|
1760
2177
|
dt,
|
|
1761
|
-
self.model.
|
|
2178
|
+
self.model.particle_color_groups[color],
|
|
1762
2179
|
self.particle_q_prev,
|
|
1763
2180
|
state_in.particle_q,
|
|
1764
|
-
state_out.particle_q,
|
|
1765
2181
|
state_in.particle_qd,
|
|
1766
2182
|
self.model.particle_mass,
|
|
1767
2183
|
self.inertia,
|
|
@@ -1776,33 +2192,25 @@ class VBDIntegrator(Integrator):
|
|
|
1776
2192
|
self.model.edge_bending_properties,
|
|
1777
2193
|
self.adjacency,
|
|
1778
2194
|
self.model.soft_contact_ke,
|
|
2195
|
+
self.model.soft_contact_kd,
|
|
1779
2196
|
self.model.soft_contact_mu,
|
|
1780
2197
|
self.friction_epsilon,
|
|
1781
|
-
#
|
|
1782
|
-
self.model.particle_radius,
|
|
1783
|
-
self.body_particle_contact_buffer_pre_alloc,
|
|
1784
|
-
self.body_particle_contact_buffer,
|
|
1785
|
-
self.body_particle_contact_count,
|
|
1786
|
-
self.model.shape_materials,
|
|
1787
|
-
self.model.shape_body,
|
|
1788
|
-
self.model.body_q,
|
|
1789
|
-
self.model.body_qd,
|
|
1790
|
-
self.model.body_com,
|
|
1791
|
-
self.model.soft_contact_shape,
|
|
1792
|
-
self.model.soft_contact_body_pos,
|
|
1793
|
-
self.model.soft_contact_body_vel,
|
|
1794
|
-
self.model.soft_contact_normal,
|
|
2198
|
+
# ground-particle contact
|
|
1795
2199
|
self.model.ground,
|
|
1796
2200
|
self.model.ground_plane,
|
|
2201
|
+
self.model.particle_radius,
|
|
2202
|
+
],
|
|
2203
|
+
outputs=[
|
|
2204
|
+
state_out.particle_q,
|
|
1797
2205
|
],
|
|
1798
|
-
dim=self.model.
|
|
2206
|
+
dim=self.model.particle_color_groups[color].size,
|
|
1799
2207
|
device=self.device,
|
|
1800
2208
|
)
|
|
1801
2209
|
|
|
1802
2210
|
wp.launch(
|
|
1803
2211
|
kernel=VBD_copy_particle_positions_back,
|
|
1804
|
-
inputs=[self.model.
|
|
1805
|
-
dim=self.model.
|
|
2212
|
+
inputs=[self.model.particle_color_groups[color], state_in.particle_q, state_out.particle_q],
|
|
2213
|
+
dim=self.model.particle_color_groups[color].size,
|
|
1806
2214
|
device=self.device,
|
|
1807
2215
|
)
|
|
1808
2216
|
|
|
@@ -1816,7 +2224,6 @@ class VBDIntegrator(Integrator):
|
|
|
1816
2224
|
def simulate_one_step_with_collisions_penetration_free(
|
|
1817
2225
|
self, model: Model, state_in: State, state_out: State, dt: float, control: Control = None
|
|
1818
2226
|
):
|
|
1819
|
-
self.convert_body_particle_contact_data()
|
|
1820
2227
|
# collision detection before initialization to compute conservative bounds for initialization
|
|
1821
2228
|
self.collision_detection_penetration_free(state_in, dt)
|
|
1822
2229
|
|
|
@@ -1843,42 +2250,34 @@ class VBDIntegrator(Integrator):
|
|
|
1843
2250
|
self.collision_detection_penetration_free(state_in, dt)
|
|
1844
2251
|
|
|
1845
2252
|
for _iter in range(self.iterations):
|
|
1846
|
-
|
|
2253
|
+
self.particle_forces.zero_()
|
|
2254
|
+
self.particle_hessians.zero_()
|
|
2255
|
+
|
|
2256
|
+
for color in range(len(self.model.particle_color_groups)):
|
|
1847
2257
|
wp.launch(
|
|
1848
|
-
kernel=
|
|
2258
|
+
kernel=VBD_accumulate_contact_force_and_hessian,
|
|
2259
|
+
dim=self.collision_evaluation_kernel_launch_size,
|
|
1849
2260
|
inputs=[
|
|
1850
2261
|
dt,
|
|
1851
|
-
|
|
2262
|
+
color,
|
|
1852
2263
|
self.particle_q_prev,
|
|
1853
2264
|
state_in.particle_q,
|
|
1854
|
-
|
|
1855
|
-
state_in.particle_qd,
|
|
1856
|
-
self.model.particle_mass,
|
|
1857
|
-
self.inertia,
|
|
1858
|
-
self.model.particle_flags,
|
|
2265
|
+
self.model.particle_colors,
|
|
1859
2266
|
self.model.tri_indices,
|
|
1860
|
-
self.model.tri_poses,
|
|
1861
|
-
self.model.tri_materials,
|
|
1862
|
-
self.model.tri_areas,
|
|
1863
2267
|
self.model.edge_indices,
|
|
1864
|
-
self
|
|
1865
|
-
self.
|
|
1866
|
-
self.model.edge_bending_properties,
|
|
1867
|
-
self.adjacency,
|
|
1868
|
-
# self-contact
|
|
1869
|
-
self.trimesh_collision_detector.collision_info,
|
|
2268
|
+
# self-contact
|
|
2269
|
+
self.trimesh_collision_info,
|
|
1870
2270
|
self.model.soft_contact_radius,
|
|
1871
2271
|
self.model.soft_contact_ke,
|
|
2272
|
+
self.model.soft_contact_kd,
|
|
1872
2273
|
self.model.soft_contact_mu,
|
|
1873
2274
|
self.friction_epsilon,
|
|
1874
|
-
self.pos_prev_collision_detection,
|
|
1875
|
-
self.particle_conservative_bounds,
|
|
1876
2275
|
self.trimesh_collision_detector.edge_edge_parallel_epsilon,
|
|
1877
|
-
#
|
|
2276
|
+
# body-particle contact
|
|
1878
2277
|
self.model.particle_radius,
|
|
1879
|
-
self.
|
|
1880
|
-
self.
|
|
1881
|
-
self.
|
|
2278
|
+
self.model.soft_contact_particle,
|
|
2279
|
+
self.model.soft_contact_count,
|
|
2280
|
+
self.model.soft_contact_max,
|
|
1882
2281
|
self.model.shape_materials,
|
|
1883
2282
|
self.model.shape_body,
|
|
1884
2283
|
self.model.body_q,
|
|
@@ -1888,17 +2287,54 @@ class VBDIntegrator(Integrator):
|
|
|
1888
2287
|
self.model.soft_contact_body_pos,
|
|
1889
2288
|
self.model.soft_contact_body_vel,
|
|
1890
2289
|
self.model.soft_contact_normal,
|
|
2290
|
+
],
|
|
2291
|
+
outputs=[self.particle_forces, self.particle_hessians],
|
|
2292
|
+
device=self.device,
|
|
2293
|
+
)
|
|
2294
|
+
|
|
2295
|
+
wp.launch(
|
|
2296
|
+
kernel=VBD_solve_trimesh_with_self_contact_penetration_free,
|
|
2297
|
+
dim=self.model.particle_color_groups[color].shape[0],
|
|
2298
|
+
inputs=[
|
|
2299
|
+
dt,
|
|
2300
|
+
self.model.particle_color_groups[color],
|
|
2301
|
+
self.particle_q_prev,
|
|
2302
|
+
state_in.particle_q,
|
|
2303
|
+
state_in.particle_qd,
|
|
2304
|
+
self.model.particle_mass,
|
|
2305
|
+
self.inertia,
|
|
2306
|
+
self.model.particle_flags,
|
|
2307
|
+
self.model.tri_indices,
|
|
2308
|
+
self.model.tri_poses,
|
|
2309
|
+
self.model.tri_materials,
|
|
2310
|
+
self.model.tri_areas,
|
|
2311
|
+
self.model.edge_indices,
|
|
2312
|
+
self.model.edge_rest_angle,
|
|
2313
|
+
self.model.edge_rest_length,
|
|
2314
|
+
self.model.edge_bending_properties,
|
|
2315
|
+
self.adjacency,
|
|
2316
|
+
self.particle_forces,
|
|
2317
|
+
self.particle_hessians,
|
|
2318
|
+
self.pos_prev_collision_detection,
|
|
2319
|
+
self.particle_conservative_bounds,
|
|
1891
2320
|
self.model.ground,
|
|
1892
2321
|
self.model.ground_plane,
|
|
2322
|
+
self.model.soft_contact_ke,
|
|
2323
|
+
self.model.soft_contact_kd,
|
|
2324
|
+
self.model.soft_contact_mu,
|
|
2325
|
+
self.friction_epsilon,
|
|
2326
|
+
self.model.particle_radius,
|
|
2327
|
+
],
|
|
2328
|
+
outputs=[
|
|
2329
|
+
state_out.particle_q,
|
|
1893
2330
|
],
|
|
1894
|
-
dim=self.model.particle_coloring[i_color].shape[0],
|
|
1895
2331
|
device=self.device,
|
|
1896
2332
|
)
|
|
1897
2333
|
|
|
1898
2334
|
wp.launch(
|
|
1899
2335
|
kernel=VBD_copy_particle_positions_back,
|
|
1900
|
-
inputs=[self.model.
|
|
1901
|
-
dim=self.model.
|
|
2336
|
+
inputs=[self.model.particle_color_groups[color], state_in.particle_q, state_out.particle_q],
|
|
2337
|
+
dim=self.model.particle_color_groups[color].size,
|
|
1902
2338
|
device=self.device,
|
|
1903
2339
|
)
|
|
1904
2340
|
|
|
@@ -1930,21 +2366,16 @@ class VBDIntegrator(Integrator):
|
|
|
1930
2366
|
device=self.device,
|
|
1931
2367
|
)
|
|
1932
2368
|
|
|
1933
|
-
def
|
|
1934
|
-
self
|
|
2369
|
+
def rebuild_bvh(self, state: State):
|
|
2370
|
+
"""This function will rebuild the BVHs used for detecting self-contacts using the input `state`.
|
|
1935
2371
|
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
],
|
|
1944
|
-
outputs=[self.body_particle_contact_buffer, self.body_particle_contact_count],
|
|
1945
|
-
dim=self.model.soft_contact_max,
|
|
1946
|
-
device=self.device,
|
|
1947
|
-
)
|
|
2372
|
+
When the simulated object deforms significantly, simply refitting the BVH can lead to deterioration of the BVH's
|
|
2373
|
+
quality. In these cases, rebuilding the entire tree is necessary to achieve better querying efficiency.
|
|
2374
|
+
|
|
2375
|
+
Args:
|
|
2376
|
+
state (wp.sim.State): The state whose particle positions (:attr:`State.particle_q`) will be used for rebuilding the BVHs.
|
|
2377
|
+
"""
|
|
2378
|
+
self.trimesh_collision_detector.rebuild(state.particle_q)
|
|
1948
2379
|
|
|
1949
2380
|
@wp.kernel
|
|
1950
2381
|
def count_num_adjacent_edges(
|