hoomd_bevy/representation/
surface_mesh.rs1use bevy::prelude::*;
9use itertools::{
10 EitherOrBoth::{Both, Left, Right},
11 Itertools,
12};
13use std::marker::PhantomData;
14
15#[derive(Component)]
28pub struct SurfaceMesh<T> {
29 marker: PhantomData<T>,
31}
32
33#[derive(Resource)]
35pub struct Representation<T> {
36 mesh: Handle<Mesh>,
38 material: Handle<StandardMaterial>,
40 marker: PhantomData<T>,
42}
43
44impl<T> Representation<T> {
45 #[must_use]
47 pub fn material(&self) -> &Handle<StandardMaterial> {
48 &self.material
49 }
50}
51
52impl<T: Send + Sync + 'static> SurfaceMesh<T> {
53 pub fn setup(
55 mesh_material: In<(Mesh, StandardMaterial)>,
56 mut commands: Commands,
57 mut meshes: ResMut<Assets<Mesh>>,
58 mut materials: ResMut<Assets<StandardMaterial>>,
59 ) {
60 let (mesh, material) = mesh_material.0;
61 let mesh = meshes.add(mesh);
62 let material = materials.add(material.clone());
63
64 commands.insert_resource(Representation::<T> {
65 mesh,
66 material,
67 marker: PhantomData,
68 });
69 }
70
71 pub fn sync<I>(
73 commands: &mut Commands,
74 triangle_mesh_representation: Res<Representation<T>>,
75 query: Query<(Entity, &mut Transform), With<Self>>,
76 triangle_meshes: I,
77 ) where
78 I: IntoIterator<Item = (Vec3, Quat)>,
79 {
80 for item in &mut query.into_iter().zip_longest(triangle_meshes) {
81 match item {
82 Both((_, mut transform), (position, rotation)) => {
83 transform.translation = position;
84 transform.rotation = rotation;
85 }
86 Left((entity, _)) => commands.entity(entity).despawn(),
87 Right((position, rotation)) => {
88 commands.spawn((
89 Mesh3d(triangle_mesh_representation.mesh.clone()),
90 MeshMaterial3d(triangle_mesh_representation.material.clone()),
91 Transform::from_translation(position).with_rotation(rotation),
92 Self {
93 marker: PhantomData,
94 },
95 ));
96 }
97 }
98 }
99 }
100}