honeycomb_render/render/
update.rs

1use bevy::math::{Quat, Vec3};
2use bevy::prelude::*;
3
4use crate::capture::ecs_data::{
5    CaptureId, DartBody, DartHead, DartId, Edge, FaceId, FaceNormals, MapVertices, Vertex,
6};
7use crate::capture::FocusedCapture;
8use crate::options::resource::{
9    DartHeadHandle, DartHeadMul, DartMatHandle, DartRenderColor, DartShrink, DartWidth,
10    EdgeMatHandle, EdgeRenderColor, EdgeWidth, VertexHandle, VertexMatHandle, VertexRenderColor,
11    VertexWidth,
12};
13
14// --- darts
15
16#[allow(clippy::missing_panics_doc)]
17/// Dart material handle update system.
18pub fn dart_mat_handle(
19    mut materials: ResMut<Assets<StandardMaterial>>,
20    handle: Res<DartMatHandle>,
21    render_color: Res<DartRenderColor>,
22) {
23    let mat = materials.get_mut(&handle.0).expect("unreachable");
24    mat.base_color = Color::Srgba(Srgba::from_u8_array(render_color.1.to_array()));
25}
26
27/// Dart render color and status update system.
28pub fn dart_render(
29    mut dart_comps: Query<(&CaptureId, &mut Visibility), With<DartId>>, // with dart_id == heads & bodies
30    focused_capture: Res<FocusedCapture>,
31    render_color: Res<DartRenderColor>,
32) {
33    dart_comps
34        .par_iter_mut()
35        .for_each(|(cap_id, mut visibility)| {
36            *visibility.as_mut() = if render_color.0 && (focused_capture.0 == *cap_id) {
37                Visibility::Visible
38            } else {
39                Visibility::Hidden
40            }
41        });
42}
43
44#[allow(clippy::missing_panics_doc)]
45/// Dart head mesh handle update system.
46pub fn dart_heads_handle(
47    mut meshes: ResMut<Assets<Mesh>>,
48    handle: Res<DartHeadHandle>,
49    dart_width: Res<DartWidth>,
50    dart_head_mul: Res<DartHeadMul>,
51) {
52    let mesh = meshes.get_mut(&handle.0).expect("unreachable");
53    let new_shape = Cone {
54        radius: dart_head_mul.0 * dart_width.0 / 2.,
55        height: dart_head_mul.0 * dart_width.0 / 2.,
56    };
57    *mesh = new_shape.into();
58}
59
60/// Dart head transform update system.
61pub fn dart_heads_transform(
62    mut heads: Query<(&mut Transform, &DartHead, &FaceId)>,
63    vertices: Res<MapVertices>,
64    normals: Res<FaceNormals>,
65    dart_shrink: Res<DartShrink>,
66) {
67    heads
68        .par_iter_mut()
69        .for_each(|(mut transform, head, face_id)| {
70            let (n1, n2) = (
71                &normals.0[&face_id.0][head.normals.0],
72                &normals.0[&face_id.0][head.normals.1],
73            );
74            let (ov1, ov2) = (&vertices.0[head.vertices.0], &vertices.0[head.vertices.1]);
75            let (v1, v2) = (*ov1 + (*n1 * dart_shrink.0), *ov2 + (*n2 * dart_shrink.0));
76            let (dir, len) = ((v2 - v1).normalize(), (v2 - v1).length());
77
78            transform.translation = (v1 + v2 + dir * len * (1. - dart_shrink.0.abs())) / 2.;
79            transform.rotation = if dir == Vec3::Y {
80                Quat::IDENTITY
81            } else {
82                Quat::from_rotation_arc(Vec3::Y, dir)
83            };
84        });
85}
86
87#[allow(clippy::missing_panics_doc)]
88/// Dart body mesh handles update system.
89pub fn dart_bodies_handles(
90    mut meshes: ResMut<Assets<Mesh>>,
91    mut bodies: Query<(&Handle<Mesh>, &DartBody, &FaceId)>,
92    vertices: Res<MapVertices>,
93    normals: Res<FaceNormals>,
94    dart_shrink: Res<DartShrink>,
95    dart_width: Res<DartWidth>,
96) {
97    bodies.iter_mut().for_each(|(handle, body, face_id)| {
98        let (n1, n2) = (
99            &normals.0[&face_id.0][body.normals.0],
100            &normals.0[&face_id.0][body.normals.1],
101        );
102        let (ov1, ov2) = (&vertices.0[body.vertices.0], &vertices.0[body.vertices.1]);
103        let (v1, v2) = (*ov1 + (*n1 * dart_shrink.0), *ov2 + (*n2 * dart_shrink.0));
104        let len = (v2 - v1).length();
105
106        let mesh = meshes.get_mut(handle).expect("unreachable");
107        *mesh = Cylinder::new(
108            dart_width.0 / 2.,
109            // FIXME: clunky
110            len * (1. - dart_shrink.0.abs()),
111        )
112        .into();
113    });
114}
115
116/// Dart body transform update system.
117pub fn dart_bodies_transform(
118    mut bodies: Query<(&mut Transform, &DartBody, &FaceId)>,
119    vertices: Res<MapVertices>,
120    normals: Res<FaceNormals>,
121    dart_shrink: Res<DartShrink>,
122) {
123    bodies
124        .par_iter_mut()
125        .for_each(|(mut transform, body, face_id)| {
126            let (n1, n2) = (
127                &normals.0[&face_id.0][body.normals.0],
128                &normals.0[&face_id.0][body.normals.1],
129            );
130            let (ov1, ov2) = (&vertices.0[body.vertices.0], &vertices.0[body.vertices.1]);
131            let (v1, v2) = (*ov1 + (*n1 * dart_shrink.0), *ov2 + (*n2 * dart_shrink.0));
132            let dir = (v2 - v1).normalize();
133
134            transform.translation = (v1 + v2) / 2.;
135            transform.rotation = if dir == Vec3::Y {
136                Quat::IDENTITY
137            } else {
138                Quat::from_rotation_arc(Vec3::Y, dir)
139            };
140        });
141}
142
143// --- vertices
144
145/// Vertex render color and status update system.
146pub fn vertices_render(
147    mut query: Query<(&CaptureId, &mut Visibility), With<Vertex>>,
148    focused_capture: Res<FocusedCapture>,
149    render_color: Res<VertexRenderColor>,
150) {
151    query.par_iter_mut().for_each(|(cap_id, mut visibility)| {
152        *visibility.as_mut() = if render_color.0 && (focused_capture.0 == *cap_id) {
153            Visibility::Visible
154        } else {
155            Visibility::Hidden
156        }
157    });
158}
159
160#[allow(clippy::missing_panics_doc)]
161/// Vertex mesh handle update system.
162pub fn vertices_handle(
163    mut meshes: ResMut<Assets<Mesh>>,
164    handle: Res<VertexHandle>,
165    vertex_width: Res<VertexWidth>,
166) {
167    let mesh = meshes.get_mut(&handle.0).expect("unreachable");
168    *mesh = Sphere::new(vertex_width.0 / 2.).into();
169}
170
171#[allow(clippy::missing_panics_doc)]
172/// Vertex material handle update system.
173pub fn vertices_mat_handle(
174    mut materials: ResMut<Assets<StandardMaterial>>,
175    handle: Res<VertexMatHandle>,
176    render_color: Res<VertexRenderColor>,
177) {
178    let mat = materials.get_mut(&handle.0).expect("unreachable");
179    mat.base_color = Color::Srgba(Srgba::from_u8_array(render_color.1.to_array()));
180}
181
182// --- edges
183
184/// Edge render color and status update system.
185pub fn edges_render(
186    mut query: Query<(&CaptureId, &mut Visibility), With<Edge>>,
187    focused_capture: Res<FocusedCapture>,
188    render_color: Res<EdgeRenderColor>,
189) {
190    query.par_iter_mut().for_each(|(cap_id, mut visibility)| {
191        *visibility.as_mut() = if render_color.0 && (focused_capture.0 == *cap_id) {
192            Visibility::Visible
193        } else {
194            Visibility::Hidden
195        }
196    });
197}
198
199#[allow(clippy::missing_panics_doc)]
200/// Edge mesh handles update system.
201pub fn edges_handle(
202    mut meshes: ResMut<Assets<Mesh>>,
203    handles: Query<(&Handle<Mesh>, &Edge)>,
204    vertices: Res<MapVertices>,
205    edge_width: Res<EdgeWidth>,
206) {
207    handles.iter().for_each(|(handle, edge)| {
208        let v1 = &vertices.0[edge.0];
209        let v2 = &vertices.0[edge.1];
210        let len = (*v2 - *v1).length();
211        let mesh = meshes.get_mut(handle).expect("unreachable");
212        *mesh = Cylinder::new(edge_width.0 / 2., len).into();
213    });
214}
215
216#[allow(clippy::missing_panics_doc)]
217/// Edge material handle update system.
218pub fn edges_mat_handle(
219    mut materials: ResMut<Assets<StandardMaterial>>,
220    handle: Res<EdgeMatHandle>,
221    render_color: Res<EdgeRenderColor>,
222) {
223    let mat = materials.get_mut(&handle.0).expect("unreachable");
224    mat.base_color = Color::Srgba(Srgba::from_u8_array(render_color.1.to_array()));
225}