1use bevy::prelude::*;
8use wde_pbr::prelude::*;
9use wde_renderer::prelude::{Color, *};
10
11use crate::{
12 data::{GizmoLineData, GizmoLinesBinding, GizmoQuadData, GizmoQuadsBinding},
13 extract::{
14 ExtractedGizmoLines, ExtractedGizmoQuads, GizmoDrawCount, GizmoQuadDrawCount,
15 extract_gizmo_lines, update_gizmo_buffer, update_gizmo_quad_buffer
16 },
17 pipeline::{GizmoQuadRenderPipeline, GizmoRenderPipeline},
18 subpass::{SubRenderPassGizmoQuads, SubRenderPassGizmos}
19};
20
21mod data;
22mod extract;
23mod pipeline;
24mod subpass;
25
26#[doc(hidden)]
27pub mod prelude {
28 pub use crate::Gizmos;
29}
30
31#[derive(Resource, Default)]
32pub struct Gizmos {
33 lines: Vec<(Vec3, Vec3, Color)>,
34 quads: Vec<([Vec3; 4], Color)>
35}
36impl Gizmos {
37 pub fn line(&mut self, start: Vec3, end: Vec3, color: Color) {
38 self.lines.push((start, end, color));
39 }
40
41 pub fn quad(&mut self, corners: [Vec3; 4], color: Color) {
44 self.quads.push((corners, color));
45 }
46
47 pub fn cube(&mut self, transform: Transform, color: Color) {
48 let half_size = Vec3::splat(0.5);
49 let vertices = [
50 Vec3::new(-half_size.x, -half_size.y, -half_size.z),
51 Vec3::new(half_size.x, -half_size.y, -half_size.z),
52 Vec3::new(half_size.x, half_size.y, -half_size.z),
53 Vec3::new(-half_size.x, half_size.y, -half_size.z),
54 Vec3::new(-half_size.x, -half_size.y, half_size.z),
55 Vec3::new(half_size.x, -half_size.y, half_size.z),
56 Vec3::new(half_size.x, half_size.y, half_size.z),
57 Vec3::new(-half_size.x, half_size.y, half_size.z)
58 ];
59
60 let edges = [
61 (0, 1),
62 (1, 2),
63 (2, 3),
64 (3, 0), (4, 5),
66 (5, 6),
67 (6, 7),
68 (7, 4), (0, 4),
70 (1, 5),
71 (2, 6),
72 (3, 7) ];
74
75 for &(start_idx, end_idx) in &edges {
76 let start = transform.transform_point(vertices[start_idx]);
77 let end = transform.transform_point(vertices[end_idx]);
78 self.line(start, end, color);
79 }
80 }
81
82 fn take_lines(&mut self) -> Vec<(Vec3, Vec3, Color)> {
84 std::mem::take(&mut self.lines)
85 }
86
87 fn take_quads(&mut self) -> Vec<([Vec3; 4], Color)> {
89 std::mem::take(&mut self.quads)
90 }
91}
92
93pub struct GizmosPlugin;
94impl Plugin for GizmosPlugin {
95 fn build(&self, app: &mut App) {
96 app.init_resource::<Gizmos>();
97
98 app.add_plugins((
99 RenderDataRegisterPlugin::<GizmoLineData>::default(),
100 RenderBindingRegisterPlugin::<GizmoLinesBinding>::default(),
101 RenderPipelineRegisterPlugin::<GizmoRenderPipeline>::default(),
102 RenderDataRegisterPlugin::<GizmoQuadData>::default(),
103 RenderBindingRegisterPlugin::<GizmoQuadsBinding>::default(),
104 RenderPipelineRegisterPlugin::<GizmoQuadRenderPipeline>::default()
105 ));
106
107 app.get_sub_app_mut(RenderApp)
108 .unwrap()
109 .init_resource::<ExtractedGizmoLines>()
110 .init_resource::<ExtractedGizmoQuads>()
111 .init_resource::<GizmoDrawCount>()
112 .init_resource::<GizmoQuadDrawCount>()
113 .add_systems(Extract, extract_gizmo_lines)
114 .add_systems(
115 Render,
116 (update_gizmo_quad_buffer, update_gizmo_buffer).in_set(RenderSet::Prepare)
117 );
118 }
119
120 fn finish(&self, app: &mut App) {
121 app.get_sub_app_mut(RenderApp)
123 .unwrap()
124 .world_mut()
125 .get_resource_mut::<RenderGraph>()
126 .unwrap()
127 .add_sub_pass::<SubRenderPassGizmoQuads, RenderPassTransparent>()
128 .add_sub_pass::<SubRenderPassGizmos, RenderPassTransparent>();
129 }
130}