warp-lang 1.7.2rc1__py3-none-win_amd64.whl → 1.8.1__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 +130 -26
- warp/builtins.py +1907 -384
- warp/codegen.py +272 -104
- warp/config.py +12 -1
- warp/constants.py +1 -1
- warp/context.py +770 -238
- 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_callable.py +34 -4
- warp/examples/interop/example_jax_ffi_callback.py +2 -2
- warp/examples/interop/example_jax_kernel.py +27 -1
- 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 +99 -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 +181 -95
- 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 +210 -67
- warp/jax_experimental/xla_ffi.py +37 -24
- warp/math.py +171 -1
- warp/native/array.h +103 -4
- warp/native/builtin.h +182 -35
- warp/native/coloring.cpp +6 -2
- warp/native/cuda_util.cpp +1 -1
- warp/native/exports.h +118 -63
- warp/native/intersect.h +5 -5
- warp/native/mat.h +8 -13
- warp/native/mathdx.cpp +11 -5
- warp/native/matnn.h +1 -123
- warp/native/mesh.h +1 -1
- warp/native/quat.h +34 -6
- warp/native/rand.h +7 -7
- warp/native/sparse.cpp +121 -258
- warp/native/sparse.cu +181 -274
- warp/native/spatial.h +305 -17
- warp/native/svd.h +23 -8
- warp/native/tile.h +603 -73
- warp/native/tile_radix_sort.h +1112 -0
- warp/native/tile_reduce.h +239 -13
- warp/native/tile_scan.h +240 -0
- warp/native/tuple.h +189 -0
- warp/native/vec.h +10 -20
- warp/native/warp.cpp +36 -4
- warp/native/warp.cu +588 -52
- 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 +110 -80
- warp/render/render_usd.py +124 -62
- warp/sim/__init__.py +9 -0
- warp/sim/collide.py +253 -80
- 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 +761 -322
- 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 +54 -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} +378 -112
- warp/tests/sim/test_collision.py +159 -51
- warp/tests/sim/test_coloring.py +91 -2
- warp/tests/test_array.py +254 -2
- warp/tests/test_array_reduce.py +2 -2
- warp/tests/test_assert.py +53 -0
- warp/tests/test_atomic_cas.py +312 -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 +23 -24
- warp/tests/test_quat.py +28 -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 +83 -2
- warp/tests/test_spatial.py +507 -1
- warp/tests/test_static.py +48 -0
- warp/tests/test_struct.py +2 -2
- warp/tests/test_tape.py +38 -0
- warp/tests/test_tuple.py +265 -0
- warp/tests/test_types.py +2 -2
- warp/tests/test_utils.py +24 -18
- warp/tests/test_vec.py +38 -408
- warp/tests/test_vec_constructors.py +325 -0
- warp/tests/tile/test_tile.py +438 -131
- warp/tests/tile/test_tile_mathdx.py +518 -14
- warp/tests/tile/test_tile_matmul.py +179 -0
- warp/tests/tile/test_tile_reduce.py +307 -5
- warp/tests/tile/test_tile_shared_memory.py +136 -7
- warp/tests/tile/test_tile_sort.py +121 -0
- warp/tests/unittest_suites.py +14 -6
- warp/types.py +462 -308
- warp/utils.py +647 -86
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/METADATA +20 -6
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/RECORD +190 -176
- 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.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.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),
|
|
@@ -1036,37 +1379,29 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1036
1379
|
edge_rest_length: wp.array(dtype=float),
|
|
1037
1380
|
edge_bending_properties: wp.array(dtype=float, ndim=2),
|
|
1038
1381
|
adjacency: ForceElementAdjacencyInfo,
|
|
1382
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1383
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1039
1384
|
# contact info
|
|
1040
|
-
# self contact
|
|
1041
1385
|
soft_contact_ke: float,
|
|
1386
|
+
soft_contact_kd: float,
|
|
1042
1387
|
friction_mu: float,
|
|
1043
1388
|
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
1389
|
# ground-particle contact
|
|
1059
1390
|
has_ground: bool,
|
|
1060
1391
|
ground: wp.array(dtype=float),
|
|
1392
|
+
particle_radius: wp.array(dtype=float),
|
|
1393
|
+
# output
|
|
1394
|
+
pos_new: wp.array(dtype=wp.vec3),
|
|
1061
1395
|
):
|
|
1062
1396
|
tid = wp.tid()
|
|
1063
1397
|
|
|
1064
1398
|
particle_index = particle_ids_in_color[tid]
|
|
1399
|
+
particle_pos = pos[particle_index]
|
|
1065
1400
|
|
|
1066
1401
|
if not particle_flags[particle_index] & PARTICLE_FLAG_ACTIVE:
|
|
1402
|
+
pos_new[particle_index] = particle_pos
|
|
1067
1403
|
return
|
|
1068
1404
|
|
|
1069
|
-
particle_pos = pos[particle_index]
|
|
1070
1405
|
particle_prev_pos = pos[particle_index]
|
|
1071
1406
|
|
|
1072
1407
|
dt_sqr_reciprocal = 1.0 / (dt * dt)
|
|
@@ -1144,38 +1479,6 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1144
1479
|
f = f + f_edge
|
|
1145
1480
|
h = h + h_edge
|
|
1146
1481
|
|
|
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
1482
|
if has_ground:
|
|
1180
1483
|
ground_normal = wp.vec3(ground[0], ground[1], ground[2])
|
|
1181
1484
|
ground_level = ground[3]
|
|
@@ -1186,14 +1489,17 @@ def VBD_solve_trimesh_no_self_contact(
|
|
|
1186
1489
|
ground_normal,
|
|
1187
1490
|
ground_level,
|
|
1188
1491
|
soft_contact_ke,
|
|
1492
|
+
soft_contact_kd,
|
|
1189
1493
|
friction_mu,
|
|
1190
1494
|
friction_epsilon,
|
|
1191
1495
|
dt,
|
|
1192
1496
|
)
|
|
1193
1497
|
|
|
1194
|
-
f
|
|
1195
|
-
h
|
|
1498
|
+
f += ground_contact_force
|
|
1499
|
+
h += ground_contact_hessian
|
|
1196
1500
|
|
|
1501
|
+
f += particle_forces[particle_index]
|
|
1502
|
+
h += particle_hessians[particle_index]
|
|
1197
1503
|
if abs(wp.determinant(h)) > 1e-5:
|
|
1198
1504
|
hInv = wp.inverse(h)
|
|
1199
1505
|
pos_new[particle_index] = particle_pos + hInv * f
|
|
@@ -1244,40 +1550,187 @@ def convert_body_particle_contact_data_kernel(
|
|
|
1244
1550
|
|
|
1245
1551
|
|
|
1246
1552
|
@wp.kernel
|
|
1247
|
-
def
|
|
1553
|
+
def VBD_accumulate_contact_force_and_hessian(
|
|
1554
|
+
# inputs
|
|
1248
1555
|
dt: float,
|
|
1249
|
-
|
|
1556
|
+
current_color: int,
|
|
1250
1557
|
pos_prev: wp.array(dtype=wp.vec3),
|
|
1251
1558
|
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),
|
|
1559
|
+
particle_colors: wp.array(dtype=int),
|
|
1257
1560
|
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
1561
|
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,
|
|
1562
|
+
# self contact
|
|
1563
|
+
collision_info_array: wp.array(dtype=TriMeshCollisionInfo),
|
|
1269
1564
|
collision_radius: float,
|
|
1270
1565
|
soft_contact_ke: float,
|
|
1566
|
+
soft_contact_kd: float,
|
|
1271
1567
|
friction_mu: float,
|
|
1272
1568
|
friction_epsilon: float,
|
|
1273
|
-
pos_prev_collision_detection: wp.array(dtype=wp.vec3),
|
|
1274
|
-
particle_conservative_bounds: wp.array(dtype=float),
|
|
1275
1569
|
edge_edge_parallel_epsilon: float,
|
|
1276
|
-
#
|
|
1570
|
+
# body-particle contact
|
|
1277
1571
|
particle_radius: wp.array(dtype=float),
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1572
|
+
soft_contact_particle: wp.array(dtype=int),
|
|
1573
|
+
contact_count: wp.array(dtype=int),
|
|
1574
|
+
contact_max: int,
|
|
1575
|
+
shape_materials: ModelShapeMaterials,
|
|
1576
|
+
shape_body: wp.array(dtype=int),
|
|
1577
|
+
body_q: wp.array(dtype=wp.transform),
|
|
1578
|
+
body_qd: wp.array(dtype=wp.spatial_vector),
|
|
1579
|
+
body_com: wp.array(dtype=wp.vec3),
|
|
1580
|
+
contact_shape: wp.array(dtype=int),
|
|
1581
|
+
contact_body_pos: wp.array(dtype=wp.vec3),
|
|
1582
|
+
contact_body_vel: wp.array(dtype=wp.vec3),
|
|
1583
|
+
contact_normal: wp.array(dtype=wp.vec3),
|
|
1584
|
+
# outputs: particle force and hessian
|
|
1585
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1586
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1587
|
+
):
|
|
1588
|
+
t_id = wp.tid()
|
|
1589
|
+
collision_info = collision_info_array[0]
|
|
1590
|
+
|
|
1591
|
+
# process edge-edge collisions
|
|
1592
|
+
if t_id * 2 < collision_info.edge_colliding_edges.shape[0]:
|
|
1593
|
+
e1_idx = collision_info.edge_colliding_edges[2 * t_id]
|
|
1594
|
+
e2_idx = collision_info.edge_colliding_edges[2 * t_id + 1]
|
|
1595
|
+
|
|
1596
|
+
if e1_idx != -1 and e2_idx != -1:
|
|
1597
|
+
e1_v1 = edge_indices[e1_idx, 2]
|
|
1598
|
+
e1_v2 = edge_indices[e1_idx, 3]
|
|
1599
|
+
if particle_colors[e1_v1] == current_color or particle_colors[e1_v2] == current_color:
|
|
1600
|
+
has_contact, collision_force_0, collision_force_1, collision_hessian_0, collision_hessian_1 = (
|
|
1601
|
+
evaluate_edge_edge_contact_2_vertices(
|
|
1602
|
+
e1_idx,
|
|
1603
|
+
e2_idx,
|
|
1604
|
+
pos,
|
|
1605
|
+
pos_prev,
|
|
1606
|
+
edge_indices,
|
|
1607
|
+
collision_radius,
|
|
1608
|
+
soft_contact_ke,
|
|
1609
|
+
soft_contact_kd,
|
|
1610
|
+
friction_mu,
|
|
1611
|
+
friction_epsilon,
|
|
1612
|
+
dt,
|
|
1613
|
+
edge_edge_parallel_epsilon,
|
|
1614
|
+
)
|
|
1615
|
+
)
|
|
1616
|
+
|
|
1617
|
+
if has_contact:
|
|
1618
|
+
# here we only handle the e1 side, because e2 will also detection this contact and add force and hessian on its own
|
|
1619
|
+
if particle_colors[e1_v1] == current_color:
|
|
1620
|
+
wp.atomic_add(particle_forces, e1_v1, collision_force_0)
|
|
1621
|
+
wp.atomic_add(particle_hessians, e1_v1, collision_hessian_0)
|
|
1622
|
+
if particle_colors[e1_v2] == current_color:
|
|
1623
|
+
wp.atomic_add(particle_forces, e1_v2, collision_force_1)
|
|
1624
|
+
wp.atomic_add(particle_hessians, e1_v2, collision_hessian_1)
|
|
1625
|
+
|
|
1626
|
+
# process vertex-triangle collisions
|
|
1627
|
+
if t_id * 2 < collision_info.vertex_colliding_triangles.shape[0]:
|
|
1628
|
+
particle_idx = collision_info.vertex_colliding_triangles[2 * t_id]
|
|
1629
|
+
tri_idx = collision_info.vertex_colliding_triangles[2 * t_id + 1]
|
|
1630
|
+
|
|
1631
|
+
if particle_idx != -1 and tri_idx != -1:
|
|
1632
|
+
tri_a = tri_indices[tri_idx, 0]
|
|
1633
|
+
tri_b = tri_indices[tri_idx, 1]
|
|
1634
|
+
tri_c = tri_indices[tri_idx, 2]
|
|
1635
|
+
if (
|
|
1636
|
+
particle_colors[particle_idx] == current_color
|
|
1637
|
+
or particle_colors[tri_a] == current_color
|
|
1638
|
+
or particle_colors[tri_b] == current_color
|
|
1639
|
+
or particle_colors[tri_c] == current_color
|
|
1640
|
+
):
|
|
1641
|
+
(
|
|
1642
|
+
has_contact,
|
|
1643
|
+
collision_force_0,
|
|
1644
|
+
collision_force_1,
|
|
1645
|
+
collision_force_2,
|
|
1646
|
+
collision_force_3,
|
|
1647
|
+
collision_hessian_0,
|
|
1648
|
+
collision_hessian_1,
|
|
1649
|
+
collision_hessian_2,
|
|
1650
|
+
collision_hessian_3,
|
|
1651
|
+
) = evaluate_vertex_triangle_collision_force_hessian_4_vertices(
|
|
1652
|
+
particle_idx,
|
|
1653
|
+
tri_idx,
|
|
1654
|
+
pos,
|
|
1655
|
+
pos_prev,
|
|
1656
|
+
tri_indices,
|
|
1657
|
+
collision_radius,
|
|
1658
|
+
soft_contact_ke,
|
|
1659
|
+
soft_contact_kd,
|
|
1660
|
+
friction_mu,
|
|
1661
|
+
friction_epsilon,
|
|
1662
|
+
dt,
|
|
1663
|
+
)
|
|
1664
|
+
|
|
1665
|
+
if has_contact:
|
|
1666
|
+
# particle
|
|
1667
|
+
if particle_colors[particle_idx] == current_color:
|
|
1668
|
+
wp.atomic_add(particle_forces, particle_idx, collision_force_3)
|
|
1669
|
+
wp.atomic_add(particle_hessians, particle_idx, collision_hessian_3)
|
|
1670
|
+
|
|
1671
|
+
# tri_a
|
|
1672
|
+
if particle_colors[tri_a] == current_color:
|
|
1673
|
+
wp.atomic_add(particle_forces, tri_a, collision_force_0)
|
|
1674
|
+
wp.atomic_add(particle_hessians, tri_a, collision_hessian_0)
|
|
1675
|
+
|
|
1676
|
+
# tri_b
|
|
1677
|
+
if particle_colors[tri_b] == current_color:
|
|
1678
|
+
wp.atomic_add(particle_forces, tri_b, collision_force_1)
|
|
1679
|
+
wp.atomic_add(particle_hessians, tri_b, collision_hessian_1)
|
|
1680
|
+
|
|
1681
|
+
# tri_c
|
|
1682
|
+
if particle_colors[tri_c] == current_color:
|
|
1683
|
+
wp.atomic_add(particle_forces, tri_c, collision_force_2)
|
|
1684
|
+
wp.atomic_add(particle_hessians, tri_c, collision_hessian_2)
|
|
1685
|
+
|
|
1686
|
+
particle_body_contact_count = min(contact_max, contact_count[0])
|
|
1687
|
+
|
|
1688
|
+
if t_id < particle_body_contact_count:
|
|
1689
|
+
particle_idx = soft_contact_particle[t_id]
|
|
1690
|
+
|
|
1691
|
+
if particle_colors[particle_idx] == current_color:
|
|
1692
|
+
body_contact_force, body_contact_hessian = evaluate_body_particle_contact(
|
|
1693
|
+
particle_idx,
|
|
1694
|
+
pos[particle_idx],
|
|
1695
|
+
pos_prev[particle_idx],
|
|
1696
|
+
t_id,
|
|
1697
|
+
soft_contact_ke,
|
|
1698
|
+
soft_contact_kd,
|
|
1699
|
+
friction_mu,
|
|
1700
|
+
friction_epsilon,
|
|
1701
|
+
particle_radius,
|
|
1702
|
+
shape_materials,
|
|
1703
|
+
shape_body,
|
|
1704
|
+
body_q,
|
|
1705
|
+
body_qd,
|
|
1706
|
+
body_com,
|
|
1707
|
+
contact_shape,
|
|
1708
|
+
contact_body_pos,
|
|
1709
|
+
contact_body_vel,
|
|
1710
|
+
contact_normal,
|
|
1711
|
+
dt,
|
|
1712
|
+
)
|
|
1713
|
+
wp.atomic_add(particle_forces, particle_idx, body_contact_force)
|
|
1714
|
+
wp.atomic_add(particle_hessians, particle_idx, body_contact_hessian)
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
@wp.kernel
|
|
1718
|
+
def VBD_accumulate_contact_force_and_hessian_no_self_contact(
|
|
1719
|
+
# inputs
|
|
1720
|
+
dt: float,
|
|
1721
|
+
current_color: int,
|
|
1722
|
+
pos_prev: wp.array(dtype=wp.vec3),
|
|
1723
|
+
pos: wp.array(dtype=wp.vec3),
|
|
1724
|
+
particle_colors: wp.array(dtype=int),
|
|
1725
|
+
# body-particle contact
|
|
1726
|
+
soft_contact_ke: float,
|
|
1727
|
+
soft_contact_kd: float,
|
|
1728
|
+
friction_mu: float,
|
|
1729
|
+
friction_epsilon: float,
|
|
1730
|
+
particle_radius: wp.array(dtype=float),
|
|
1731
|
+
soft_contact_particle: wp.array(dtype=int),
|
|
1732
|
+
contact_count: wp.array(dtype=int),
|
|
1733
|
+
contact_max: int,
|
|
1281
1734
|
shape_materials: ModelShapeMaterials,
|
|
1282
1735
|
shape_body: wp.array(dtype=int),
|
|
1283
1736
|
body_q: wp.array(dtype=wp.transform),
|
|
@@ -1287,9 +1740,76 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1287
1740
|
contact_body_pos: wp.array(dtype=wp.vec3),
|
|
1288
1741
|
contact_body_vel: wp.array(dtype=wp.vec3),
|
|
1289
1742
|
contact_normal: wp.array(dtype=wp.vec3),
|
|
1743
|
+
# outputs: particle force and hessian
|
|
1744
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1745
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1746
|
+
):
|
|
1747
|
+
t_id = wp.tid()
|
|
1748
|
+
|
|
1749
|
+
particle_body_contact_count = min(contact_max, contact_count[0])
|
|
1750
|
+
|
|
1751
|
+
if t_id < particle_body_contact_count:
|
|
1752
|
+
particle_idx = soft_contact_particle[t_id]
|
|
1753
|
+
|
|
1754
|
+
if particle_colors[particle_idx] == current_color:
|
|
1755
|
+
body_contact_force, body_contact_hessian = evaluate_body_particle_contact(
|
|
1756
|
+
particle_idx,
|
|
1757
|
+
pos[particle_idx],
|
|
1758
|
+
pos_prev[particle_idx],
|
|
1759
|
+
t_id,
|
|
1760
|
+
soft_contact_ke,
|
|
1761
|
+
soft_contact_kd,
|
|
1762
|
+
friction_mu,
|
|
1763
|
+
friction_epsilon,
|
|
1764
|
+
particle_radius,
|
|
1765
|
+
shape_materials,
|
|
1766
|
+
shape_body,
|
|
1767
|
+
body_q,
|
|
1768
|
+
body_qd,
|
|
1769
|
+
body_com,
|
|
1770
|
+
contact_shape,
|
|
1771
|
+
contact_body_pos,
|
|
1772
|
+
contact_body_vel,
|
|
1773
|
+
contact_normal,
|
|
1774
|
+
dt,
|
|
1775
|
+
)
|
|
1776
|
+
wp.atomic_add(particle_forces, particle_idx, body_contact_force)
|
|
1777
|
+
wp.atomic_add(particle_hessians, particle_idx, body_contact_hessian)
|
|
1778
|
+
|
|
1779
|
+
|
|
1780
|
+
@wp.kernel
|
|
1781
|
+
def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
1782
|
+
dt: float,
|
|
1783
|
+
particle_ids_in_color: wp.array(dtype=wp.int32),
|
|
1784
|
+
pos_prev: wp.array(dtype=wp.vec3),
|
|
1785
|
+
pos: wp.array(dtype=wp.vec3),
|
|
1786
|
+
vel: wp.array(dtype=wp.vec3),
|
|
1787
|
+
mass: wp.array(dtype=float),
|
|
1788
|
+
inertia: wp.array(dtype=wp.vec3),
|
|
1789
|
+
particle_flags: wp.array(dtype=wp.uint32),
|
|
1790
|
+
tri_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1791
|
+
tri_poses: wp.array(dtype=wp.mat22),
|
|
1792
|
+
tri_materials: wp.array(dtype=float, ndim=2),
|
|
1793
|
+
tri_areas: wp.array(dtype=float),
|
|
1794
|
+
edge_indices: wp.array(dtype=wp.int32, ndim=2),
|
|
1795
|
+
edge_rest_angles: wp.array(dtype=float),
|
|
1796
|
+
edge_rest_length: wp.array(dtype=float),
|
|
1797
|
+
edge_bending_properties: wp.array(dtype=float, ndim=2),
|
|
1798
|
+
adjacency: ForceElementAdjacencyInfo,
|
|
1799
|
+
particle_forces: wp.array(dtype=wp.vec3),
|
|
1800
|
+
particle_hessians: wp.array(dtype=wp.mat33),
|
|
1801
|
+
pos_prev_collision_detection: wp.array(dtype=wp.vec3),
|
|
1802
|
+
particle_conservative_bounds: wp.array(dtype=float),
|
|
1290
1803
|
# ground-particle contact
|
|
1291
1804
|
has_ground: bool,
|
|
1292
1805
|
ground: wp.array(dtype=float),
|
|
1806
|
+
soft_contact_ke: float,
|
|
1807
|
+
soft_contact_kd: float,
|
|
1808
|
+
friction_mu: float,
|
|
1809
|
+
friction_epsilon: float,
|
|
1810
|
+
particle_radius: wp.array(dtype=float),
|
|
1811
|
+
# output
|
|
1812
|
+
pos_new: wp.array(dtype=wp.vec3),
|
|
1293
1813
|
):
|
|
1294
1814
|
t_id = wp.tid()
|
|
1295
1815
|
|
|
@@ -1298,13 +1818,14 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1298
1818
|
particle_prev_pos = pos_prev[particle_index]
|
|
1299
1819
|
|
|
1300
1820
|
if not particle_flags[particle_index] & PARTICLE_FLAG_ACTIVE:
|
|
1821
|
+
pos_new[particle_index] = particle_pos
|
|
1301
1822
|
return
|
|
1302
1823
|
|
|
1303
1824
|
dt_sqr_reciprocal = 1.0 / (dt * dt)
|
|
1304
1825
|
|
|
1305
1826
|
# inertia force and hessian
|
|
1306
1827
|
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)
|
|
1828
|
+
h = particle_hessians[particle_index] + mass[particle_index] * dt_sqr_reciprocal * wp.identity(n=3, dtype=float)
|
|
1308
1829
|
|
|
1309
1830
|
# fmt: off
|
|
1310
1831
|
if wp.static("inertia_force_hessian" in VBD_DEBUG_PRINTING_OPTIONS):
|
|
@@ -1314,48 +1835,6 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1314
1835
|
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
1836
|
)
|
|
1316
1837
|
|
|
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
1838
|
# elastic force and hessian
|
|
1360
1839
|
for i_adj_tri in range(get_vertex_num_adjacent_faces(adjacency, particle_index)):
|
|
1361
1840
|
tri_index, vertex_order = get_vertex_adjacent_face_id_order(adjacency, particle_index, i_adj_tri)
|
|
@@ -1391,41 +1870,12 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1391
1870
|
k_d = tri_materials[tri_index, 2]
|
|
1392
1871
|
h_d = h_tri * (k_d / dt)
|
|
1393
1872
|
|
|
1394
|
-
f_d = h_d * (
|
|
1873
|
+
f_d = h_d * (particle_prev_pos - particle_pos)
|
|
1395
1874
|
|
|
1396
1875
|
f = f + f_tri + f_d
|
|
1397
1876
|
h = h + h_tri + h_d
|
|
1398
1877
|
|
|
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
1878
|
|
|
1428
|
-
# edge-edge collision force and hessian
|
|
1429
1879
|
for i_adj_edge in range(get_vertex_num_adjacent_edges(adjacency, particle_index)):
|
|
1430
1880
|
nei_edge_index, vertex_order_on_edge = get_vertex_adjacent_edge_id_order(adjacency, particle_index, i_adj_edge)
|
|
1431
1881
|
# vertex is on the edge; otherwise it only effects the bending energy n
|
|
@@ -1438,78 +1888,6 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1438
1888
|
f = f + f_edge
|
|
1439
1889
|
h = h + h_edge
|
|
1440
1890
|
|
|
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
1891
|
if has_ground:
|
|
1514
1892
|
ground_normal = wp.vec3(ground[0], ground[1], ground[2])
|
|
1515
1893
|
ground_level = ground[3]
|
|
@@ -1520,6 +1898,7 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1520
1898
|
ground_normal,
|
|
1521
1899
|
ground_level,
|
|
1522
1900
|
soft_contact_ke,
|
|
1901
|
+
soft_contact_kd,
|
|
1523
1902
|
friction_mu,
|
|
1524
1903
|
friction_epsilon,
|
|
1525
1904
|
dt,
|
|
@@ -1535,9 +1914,12 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
|
|
|
1535
1914
|
particle_index,
|
|
1536
1915
|
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
1916
|
)
|
|
1538
|
-
# fmt: on
|
|
1539
1917
|
|
|
1918
|
+
# # fmt: on
|
|
1919
|
+
h = h + particle_hessians[particle_index]
|
|
1920
|
+
f = f + particle_forces[particle_index]
|
|
1540
1921
|
if abs(wp.determinant(h)) > 1e-5:
|
|
1922
|
+
|
|
1541
1923
|
h_inv = wp.inverse(h)
|
|
1542
1924
|
particle_pos_new = pos[particle_index] + h_inv * f
|
|
1543
1925
|
|
|
@@ -1554,7 +1936,7 @@ class VBDIntegrator(Integrator):
|
|
|
1554
1936
|
|
|
1555
1937
|
Note that VBDIntegrator's constructor requires a :class:`Model` object as input, so that it can do some precomputation and preallocate the space.
|
|
1556
1938
|
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.
|
|
1939
|
+
Currently, you must manually provide particle coloring and assign it to `model.particle_color_groups` to make VBD work.
|
|
1558
1940
|
|
|
1559
1941
|
VBDIntegrator.simulate accepts three arguments: class:`Model`, :class:`State`, and :class:`Control` (optional) objects, this time-integrator
|
|
1560
1942
|
may be used to advance the simulation state forward in time.
|
|
@@ -1564,7 +1946,7 @@ class VBDIntegrator(Integrator):
|
|
|
1564
1946
|
|
|
1565
1947
|
.. code-block:: python
|
|
1566
1948
|
|
|
1567
|
-
model.
|
|
1949
|
+
model.particle_color_groups = # load or generate particle coloring
|
|
1568
1950
|
integrator = wp.VBDIntegrator(model)
|
|
1569
1951
|
|
|
1570
1952
|
# simulation loop
|
|
@@ -1596,13 +1978,6 @@ class VBDIntegrator(Integrator):
|
|
|
1596
1978
|
|
|
1597
1979
|
self.adjacency = self.compute_force_element_adjacency(model).to(self.device)
|
|
1598
1980
|
|
|
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
1981
|
self.body_particle_contact_count = wp.zeros((model.particle_count,), dtype=wp.int32, device=self.device)
|
|
1607
1982
|
|
|
1608
1983
|
self.handle_self_contact = handle_self_contact
|
|
@@ -1626,11 +2001,27 @@ class VBDIntegrator(Integrator):
|
|
|
1626
2001
|
edge_edge_parallel_epsilon=edge_edge_parallel_epsilon,
|
|
1627
2002
|
)
|
|
1628
2003
|
|
|
2004
|
+
self.trimesh_collision_info = wp.array(
|
|
2005
|
+
[self.trimesh_collision_detector.collision_info], dtype=TriMeshCollisionInfo, device=self.device
|
|
2006
|
+
)
|
|
2007
|
+
|
|
2008
|
+
self.collision_evaluation_kernel_launch_size = max(
|
|
2009
|
+
self.trimesh_collision_detector.vertex_colliding_triangles.shape[0] // 2,
|
|
2010
|
+
self.trimesh_collision_detector.edge_colliding_edges.shape[0] // 2,
|
|
2011
|
+
self.model.soft_contact_max,
|
|
2012
|
+
)
|
|
2013
|
+
else:
|
|
2014
|
+
self.collision_evaluation_kernel_launch_size = self.model.soft_contact_max
|
|
2015
|
+
|
|
2016
|
+
# spaces for particle force and hessian
|
|
2017
|
+
self.particle_forces = wp.zeros(self.model.particle_count, dtype=wp.vec3, device=self.device)
|
|
2018
|
+
self.particle_hessians = wp.zeros(self.model.particle_count, dtype=wp.mat33, device=self.device)
|
|
2019
|
+
|
|
1629
2020
|
self.friction_epsilon = friction_epsilon
|
|
1630
2021
|
|
|
1631
|
-
if len(self.model.
|
|
2022
|
+
if len(self.model.particle_color_groups) == 0:
|
|
1632
2023
|
raise ValueError(
|
|
1633
|
-
"model.
|
|
2024
|
+
"model.particle_color_groups is empty! When using the VBDIntegrator you must call ModelBuilder.color() "
|
|
1634
2025
|
"or ModelBuilder.set_coloring() before calling ModelBuilder.finalize()."
|
|
1635
2026
|
)
|
|
1636
2027
|
|
|
@@ -1733,8 +2124,6 @@ class VBDIntegrator(Integrator):
|
|
|
1733
2124
|
def simulate_one_step_no_self_contact(
|
|
1734
2125
|
self, model: Model, state_in: State, state_out: State, dt: float, control: Control = None
|
|
1735
2126
|
):
|
|
1736
|
-
self.convert_body_particle_contact_data()
|
|
1737
|
-
|
|
1738
2127
|
wp.launch(
|
|
1739
2128
|
kernel=forward_step,
|
|
1740
2129
|
inputs=[
|
|
@@ -1753,15 +2142,48 @@ class VBDIntegrator(Integrator):
|
|
|
1753
2142
|
)
|
|
1754
2143
|
|
|
1755
2144
|
for _iter in range(self.iterations):
|
|
1756
|
-
|
|
2145
|
+
self.particle_forces.zero_()
|
|
2146
|
+
self.particle_hessians.zero_()
|
|
2147
|
+
for color in range(len(self.model.particle_color_groups)):
|
|
2148
|
+
wp.launch(
|
|
2149
|
+
kernel=VBD_accumulate_contact_force_and_hessian_no_self_contact,
|
|
2150
|
+
dim=self.collision_evaluation_kernel_launch_size,
|
|
2151
|
+
inputs=[
|
|
2152
|
+
dt,
|
|
2153
|
+
color,
|
|
2154
|
+
self.particle_q_prev,
|
|
2155
|
+
state_in.particle_q,
|
|
2156
|
+
self.model.particle_colors,
|
|
2157
|
+
# body-particle contact
|
|
2158
|
+
self.model.soft_contact_ke,
|
|
2159
|
+
self.model.soft_contact_kd,
|
|
2160
|
+
self.model.soft_contact_mu,
|
|
2161
|
+
self.friction_epsilon,
|
|
2162
|
+
self.model.particle_radius,
|
|
2163
|
+
self.model.soft_contact_particle,
|
|
2164
|
+
self.model.soft_contact_count,
|
|
2165
|
+
self.model.soft_contact_max,
|
|
2166
|
+
self.model.shape_materials,
|
|
2167
|
+
self.model.shape_body,
|
|
2168
|
+
self.model.body_q,
|
|
2169
|
+
self.model.body_qd,
|
|
2170
|
+
self.model.body_com,
|
|
2171
|
+
self.model.soft_contact_shape,
|
|
2172
|
+
self.model.soft_contact_body_pos,
|
|
2173
|
+
self.model.soft_contact_body_vel,
|
|
2174
|
+
self.model.soft_contact_normal,
|
|
2175
|
+
],
|
|
2176
|
+
outputs=[self.particle_forces, self.particle_hessians],
|
|
2177
|
+
device=self.device,
|
|
2178
|
+
)
|
|
2179
|
+
|
|
1757
2180
|
wp.launch(
|
|
1758
2181
|
kernel=VBD_solve_trimesh_no_self_contact,
|
|
1759
2182
|
inputs=[
|
|
1760
2183
|
dt,
|
|
1761
|
-
self.model.
|
|
2184
|
+
self.model.particle_color_groups[color],
|
|
1762
2185
|
self.particle_q_prev,
|
|
1763
2186
|
state_in.particle_q,
|
|
1764
|
-
state_out.particle_q,
|
|
1765
2187
|
state_in.particle_qd,
|
|
1766
2188
|
self.model.particle_mass,
|
|
1767
2189
|
self.inertia,
|
|
@@ -1775,34 +2197,28 @@ class VBDIntegrator(Integrator):
|
|
|
1775
2197
|
self.model.edge_rest_length,
|
|
1776
2198
|
self.model.edge_bending_properties,
|
|
1777
2199
|
self.adjacency,
|
|
2200
|
+
self.particle_forces,
|
|
2201
|
+
self.particle_hessians,
|
|
1778
2202
|
self.model.soft_contact_ke,
|
|
2203
|
+
self.model.soft_contact_kd,
|
|
1779
2204
|
self.model.soft_contact_mu,
|
|
1780
2205
|
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,
|
|
2206
|
+
# ground-particle contact
|
|
1795
2207
|
self.model.ground,
|
|
1796
2208
|
self.model.ground_plane,
|
|
2209
|
+
self.model.particle_radius,
|
|
2210
|
+
],
|
|
2211
|
+
outputs=[
|
|
2212
|
+
state_out.particle_q,
|
|
1797
2213
|
],
|
|
1798
|
-
dim=self.model.
|
|
2214
|
+
dim=self.model.particle_color_groups[color].size,
|
|
1799
2215
|
device=self.device,
|
|
1800
2216
|
)
|
|
1801
2217
|
|
|
1802
2218
|
wp.launch(
|
|
1803
2219
|
kernel=VBD_copy_particle_positions_back,
|
|
1804
|
-
inputs=[self.model.
|
|
1805
|
-
dim=self.model.
|
|
2220
|
+
inputs=[self.model.particle_color_groups[color], state_in.particle_q, state_out.particle_q],
|
|
2221
|
+
dim=self.model.particle_color_groups[color].size,
|
|
1806
2222
|
device=self.device,
|
|
1807
2223
|
)
|
|
1808
2224
|
|
|
@@ -1816,7 +2232,6 @@ class VBDIntegrator(Integrator):
|
|
|
1816
2232
|
def simulate_one_step_with_collisions_penetration_free(
|
|
1817
2233
|
self, model: Model, state_in: State, state_out: State, dt: float, control: Control = None
|
|
1818
2234
|
):
|
|
1819
|
-
self.convert_body_particle_contact_data()
|
|
1820
2235
|
# collision detection before initialization to compute conservative bounds for initialization
|
|
1821
2236
|
self.collision_detection_penetration_free(state_in, dt)
|
|
1822
2237
|
|
|
@@ -1843,42 +2258,34 @@ class VBDIntegrator(Integrator):
|
|
|
1843
2258
|
self.collision_detection_penetration_free(state_in, dt)
|
|
1844
2259
|
|
|
1845
2260
|
for _iter in range(self.iterations):
|
|
1846
|
-
|
|
2261
|
+
self.particle_forces.zero_()
|
|
2262
|
+
self.particle_hessians.zero_()
|
|
2263
|
+
|
|
2264
|
+
for color in range(len(self.model.particle_color_groups)):
|
|
1847
2265
|
wp.launch(
|
|
1848
|
-
kernel=
|
|
2266
|
+
kernel=VBD_accumulate_contact_force_and_hessian,
|
|
2267
|
+
dim=self.collision_evaluation_kernel_launch_size,
|
|
1849
2268
|
inputs=[
|
|
1850
2269
|
dt,
|
|
1851
|
-
|
|
2270
|
+
color,
|
|
1852
2271
|
self.particle_q_prev,
|
|
1853
2272
|
state_in.particle_q,
|
|
1854
|
-
|
|
1855
|
-
state_in.particle_qd,
|
|
1856
|
-
self.model.particle_mass,
|
|
1857
|
-
self.inertia,
|
|
1858
|
-
self.model.particle_flags,
|
|
2273
|
+
self.model.particle_colors,
|
|
1859
2274
|
self.model.tri_indices,
|
|
1860
|
-
self.model.tri_poses,
|
|
1861
|
-
self.model.tri_materials,
|
|
1862
|
-
self.model.tri_areas,
|
|
1863
2275
|
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,
|
|
2276
|
+
# self-contact
|
|
2277
|
+
self.trimesh_collision_info,
|
|
1870
2278
|
self.model.soft_contact_radius,
|
|
1871
2279
|
self.model.soft_contact_ke,
|
|
2280
|
+
self.model.soft_contact_kd,
|
|
1872
2281
|
self.model.soft_contact_mu,
|
|
1873
2282
|
self.friction_epsilon,
|
|
1874
|
-
self.pos_prev_collision_detection,
|
|
1875
|
-
self.particle_conservative_bounds,
|
|
1876
2283
|
self.trimesh_collision_detector.edge_edge_parallel_epsilon,
|
|
1877
|
-
#
|
|
2284
|
+
# body-particle contact
|
|
1878
2285
|
self.model.particle_radius,
|
|
1879
|
-
self.
|
|
1880
|
-
self.
|
|
1881
|
-
self.
|
|
2286
|
+
self.model.soft_contact_particle,
|
|
2287
|
+
self.model.soft_contact_count,
|
|
2288
|
+
self.model.soft_contact_max,
|
|
1882
2289
|
self.model.shape_materials,
|
|
1883
2290
|
self.model.shape_body,
|
|
1884
2291
|
self.model.body_q,
|
|
@@ -1888,17 +2295,54 @@ class VBDIntegrator(Integrator):
|
|
|
1888
2295
|
self.model.soft_contact_body_pos,
|
|
1889
2296
|
self.model.soft_contact_body_vel,
|
|
1890
2297
|
self.model.soft_contact_normal,
|
|
2298
|
+
],
|
|
2299
|
+
outputs=[self.particle_forces, self.particle_hessians],
|
|
2300
|
+
device=self.device,
|
|
2301
|
+
)
|
|
2302
|
+
|
|
2303
|
+
wp.launch(
|
|
2304
|
+
kernel=VBD_solve_trimesh_with_self_contact_penetration_free,
|
|
2305
|
+
dim=self.model.particle_color_groups[color].shape[0],
|
|
2306
|
+
inputs=[
|
|
2307
|
+
dt,
|
|
2308
|
+
self.model.particle_color_groups[color],
|
|
2309
|
+
self.particle_q_prev,
|
|
2310
|
+
state_in.particle_q,
|
|
2311
|
+
state_in.particle_qd,
|
|
2312
|
+
self.model.particle_mass,
|
|
2313
|
+
self.inertia,
|
|
2314
|
+
self.model.particle_flags,
|
|
2315
|
+
self.model.tri_indices,
|
|
2316
|
+
self.model.tri_poses,
|
|
2317
|
+
self.model.tri_materials,
|
|
2318
|
+
self.model.tri_areas,
|
|
2319
|
+
self.model.edge_indices,
|
|
2320
|
+
self.model.edge_rest_angle,
|
|
2321
|
+
self.model.edge_rest_length,
|
|
2322
|
+
self.model.edge_bending_properties,
|
|
2323
|
+
self.adjacency,
|
|
2324
|
+
self.particle_forces,
|
|
2325
|
+
self.particle_hessians,
|
|
2326
|
+
self.pos_prev_collision_detection,
|
|
2327
|
+
self.particle_conservative_bounds,
|
|
1891
2328
|
self.model.ground,
|
|
1892
2329
|
self.model.ground_plane,
|
|
2330
|
+
self.model.soft_contact_ke,
|
|
2331
|
+
self.model.soft_contact_kd,
|
|
2332
|
+
self.model.soft_contact_mu,
|
|
2333
|
+
self.friction_epsilon,
|
|
2334
|
+
self.model.particle_radius,
|
|
2335
|
+
],
|
|
2336
|
+
outputs=[
|
|
2337
|
+
state_out.particle_q,
|
|
1893
2338
|
],
|
|
1894
|
-
dim=self.model.particle_coloring[i_color].shape[0],
|
|
1895
2339
|
device=self.device,
|
|
1896
2340
|
)
|
|
1897
2341
|
|
|
1898
2342
|
wp.launch(
|
|
1899
2343
|
kernel=VBD_copy_particle_positions_back,
|
|
1900
|
-
inputs=[self.model.
|
|
1901
|
-
dim=self.model.
|
|
2344
|
+
inputs=[self.model.particle_color_groups[color], state_in.particle_q, state_out.particle_q],
|
|
2345
|
+
dim=self.model.particle_color_groups[color].size,
|
|
1902
2346
|
device=self.device,
|
|
1903
2347
|
)
|
|
1904
2348
|
|
|
@@ -1930,21 +2374,16 @@ class VBDIntegrator(Integrator):
|
|
|
1930
2374
|
device=self.device,
|
|
1931
2375
|
)
|
|
1932
2376
|
|
|
1933
|
-
def
|
|
1934
|
-
self
|
|
2377
|
+
def rebuild_bvh(self, state: State):
|
|
2378
|
+
"""This function will rebuild the BVHs used for detecting self-contacts using the input `state`.
|
|
1935
2379
|
|
|
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
|
-
)
|
|
2380
|
+
When the simulated object deforms significantly, simply refitting the BVH can lead to deterioration of the BVH's
|
|
2381
|
+
quality. In these cases, rebuilding the entire tree is necessary to achieve better querying efficiency.
|
|
2382
|
+
|
|
2383
|
+
Args:
|
|
2384
|
+
state (wp.sim.State): The state whose particle positions (:attr:`State.particle_q`) will be used for rebuilding the BVHs.
|
|
2385
|
+
"""
|
|
2386
|
+
self.trimesh_collision_detector.rebuild(state.particle_q)
|
|
1948
2387
|
|
|
1949
2388
|
@wp.kernel
|
|
1950
2389
|
def count_num_adjacent_edges(
|