From df2a8967d1fd763a82d47d6720857f8988fed425 Mon Sep 17 00:00:00 2001 From: Wei Hu Date: Tue, 4 Aug 2026 10:05:50 +0800 Subject: [PATCH] Apply MeshSet poses to sampled particles. --- genesis/engine/entities/particle_entity.py | 6 ++++- tests/particles/test_mpm.py | 28 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/genesis/engine/entities/particle_entity.py b/genesis/engine/entities/particle_entity.py index 85348502ef..76b785c8da 100644 --- a/genesis/engine/entities/particle_entity.py +++ b/genesis/engine/entities/particle_entity.py @@ -264,7 +264,11 @@ def sample(self): sampler=sampler, ) - particles_i += np.asarray(morph_i.pos, dtype=gs.np_float) + particles_i = gu.transform_by_trans_quat( + particles_i, + np.asarray(morph_i.pos, dtype=gs.np_float), + np.asarray(morph_i.quat, dtype=gs.np_float), + ) particles.append(particles_i) elif isinstance(self._morph, (gs.options.morphs.Primitive, gs.options.morphs.Mesh)): particles = self._vmesh.particlize(self._particle_size, self.sampler) diff --git a/tests/particles/test_mpm.py b/tests/particles/test_mpm.py index 40e6c7dbe7..5fbaaa70cf 100644 --- a/tests/particles/test_mpm.py +++ b/tests/particles/test_mpm.py @@ -1,9 +1,37 @@ +import numpy as np import pytest import torch +import trimesh import genesis as gs +@pytest.mark.required +def test_mesh_set_particle_transform(show_viewer): + pos = np.array((0.2, 0.1, 0.2)) + mesh = trimesh.creation.box(extents=(0.04, 0.12, 0.04)) + scene = gs.Scene( + mpm_options=gs.options.MPMOptions( + lower_bound=(-0.5, -0.5, -0.5), + upper_bound=(0.5, 0.5, 0.5), + particle_size=0.01, + ), + show_viewer=show_viewer, + ) + entity = scene.add_entity( + morph=gs.morphs.MeshSet( + files=(mesh,), + poss=(pos,), + eulers=((0.0, 0.0, 90.0),), + ), + material=gs.materials.MPM.Elastic(sampler="regular"), + ) + + particles = entity.init_particles + np.testing.assert_allclose(particles.mean(axis=0), pos, atol=1e-6) + np.testing.assert_allclose(np.ptp(particles, axis=0), (0.11, 0.03, 0.03), atol=1e-6) + + @pytest.mark.required def test_particle_constraints(show_viewer): scene = gs.Scene(